mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-07-25 05:53:00 +00:00
Make dialogue prose selectable
This commit is contained in:
@@ -68,6 +68,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding-bottom: var(--keyboard-height, 0px);
|
padding-bottom: var(--keyboard-height, 0px);
|
||||||
|
user-select: text;
|
||||||
|
-webkit-user-select: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-host :global(button) {
|
.dialog-host :global(button) {
|
||||||
|
|||||||
@@ -12,6 +12,11 @@
|
|||||||
background-color: var(--text-muted);
|
background-color: var(--text-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.vpk-action-dialog__message {
|
||||||
|
user-select: text;
|
||||||
|
-webkit-user-select: text;
|
||||||
|
}
|
||||||
|
|
||||||
.conflict-dev-name {
|
.conflict-dev-name {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-width: 5em;
|
min-width: 5em;
|
||||||
|
|||||||
@@ -194,6 +194,28 @@ async function verifyRemoteSizeNoticeAndDialogue(): Promise<{
|
|||||||
.filter({ hasText: "Synchronisation paused for compatibility review" }),
|
.filter({ hasText: "Synchronisation paused for compatibility review" }),
|
||||||
});
|
});
|
||||||
await compatibilityReview.waitFor({ state: "visible", timeout: uiTimeoutMs });
|
await compatibilityReview.waitFor({ state: "visible", timeout: uiTimeoutMs });
|
||||||
|
const message = compatibilityReview.locator(".vpk-action-dialog__message");
|
||||||
|
const textSelection = await message.evaluate((element) => {
|
||||||
|
const selection = window.getSelection();
|
||||||
|
const range = document.createRange();
|
||||||
|
range.selectNodeContents(element);
|
||||||
|
selection?.removeAllRanges();
|
||||||
|
selection?.addRange(range);
|
||||||
|
const selectedText = selection?.toString() ?? "";
|
||||||
|
selection?.removeAllRanges();
|
||||||
|
return {
|
||||||
|
selectedText,
|
||||||
|
userSelect: getComputedStyle(element).userSelect,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
if (
|
||||||
|
textSelection.userSelect !== "text" ||
|
||||||
|
!textSelection.selectedText.includes("Remote synchronisation is paused on this device")
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
`Expected the action dialogue message to be selectable, received user-select=${textSelection.userSelect} and selected text '${textSelection.selectedText}'.`
|
||||||
|
);
|
||||||
|
}
|
||||||
const actions = compatibilityReview.locator(".vpk-action-dialog__actions--vertical");
|
const actions = compatibilityReview.locator(".vpk-action-dialog__actions--vertical");
|
||||||
await actions.waitFor({ state: "visible", timeout: uiTimeoutMs });
|
await actions.waitFor({ state: "visible", timeout: uiTimeoutMs });
|
||||||
const flexDirection = await actions.evaluate((element) => getComputedStyle(element).flexDirection);
|
const flexDirection = await actions.evaluate((element) => getComputedStyle(element).flexDirection);
|
||||||
@@ -286,12 +308,32 @@ async function verifyRemoteSelectionDialogue(mode: DialogueMode): Promise<string
|
|||||||
for (const label of ["CouchDB", "S3-compatible Object Storage", "Peer-to-Peer (P2P)"]) {
|
for (const label of ["CouchDB", "S3-compatible Object Storage", "Peer-to-Peer (P2P)"]) {
|
||||||
await dialogue.getByText(label, { exact: true }).waitFor({ state: "visible", timeout: uiTimeoutMs });
|
await dialogue.getByText(label, { exact: true }).waitFor({ state: "visible", timeout: uiTimeoutMs });
|
||||||
}
|
}
|
||||||
await dialogue
|
const p2pDescription = dialogue.getByText(
|
||||||
.getByText(
|
"No central data-storage server is required, but a signalling relay is required for peer discovery.",
|
||||||
"No central data-storage server is required, but a signalling relay is required for peer discovery.",
|
{ exact: false }
|
||||||
{ exact: false }
|
);
|
||||||
)
|
await p2pDescription.waitFor({ state: "visible", timeout: uiTimeoutMs });
|
||||||
.waitFor({ state: "visible", timeout: uiTimeoutMs });
|
const textSelection = await p2pDescription.evaluate((element) => {
|
||||||
|
const selection = window.getSelection();
|
||||||
|
const range = document.createRange();
|
||||||
|
range.selectNodeContents(element);
|
||||||
|
selection?.removeAllRanges();
|
||||||
|
selection?.addRange(range);
|
||||||
|
const selectedText = selection?.toString() ?? "";
|
||||||
|
selection?.removeAllRanges();
|
||||||
|
return {
|
||||||
|
selectedText,
|
||||||
|
userSelect: getComputedStyle(element).userSelect,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
if (
|
||||||
|
textSelection.userSelect !== "text" ||
|
||||||
|
!textSelection.selectedText.includes("signalling relay is required for peer discovery")
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
`Expected Svelte dialogue prose to be selectable, received user-select=${textSelection.userSelect} and selected text '${textSelection.selectedText}'.`
|
||||||
|
);
|
||||||
|
}
|
||||||
await modal
|
await modal
|
||||||
.getByRole("button", { name: "No, please take me back" })
|
.getByRole("button", { name: "No, please take me back" })
|
||||||
.waitFor({ state: "visible", timeout: uiTimeoutMs });
|
.waitFor({ state: "visible", timeout: uiTimeoutMs });
|
||||||
@@ -831,9 +873,13 @@ async function verifyHatchSurfacesAndSafeActions(): Promise<string> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, repairRunStateKey);
|
}, repairRunStateKey);
|
||||||
await liveSyncSettings.getByRole("button", { name: "Recreate all", exact: true }).click({
|
await page
|
||||||
timeout: uiTimeoutMs,
|
.locator(".sls-setting:visible")
|
||||||
});
|
.last()
|
||||||
|
.getByRole("button", { name: "Recreate current chunks", exact: true })
|
||||||
|
.click({
|
||||||
|
timeout: uiTimeoutMs,
|
||||||
|
});
|
||||||
await page.waitForFunction(
|
await page.waitForFunction(
|
||||||
(stateKey) =>
|
(stateKey) =>
|
||||||
(globalThis as unknown as Record<string, DialogueRunState | undefined>)[stateKey]?.done === true,
|
(globalThis as unknown as Record<string, DialogueRunState | undefined>)[stateKey]?.done === true,
|
||||||
@@ -848,9 +894,13 @@ async function verifyHatchSurfacesAndSafeActions(): Promise<string> {
|
|||||||
throw new Error(`Recreate missing chunks failed: ${repairState.error}`);
|
throw new Error(`Recreate missing chunks failed: ${repairState.error}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
await liveSyncSettings.getByRole("button", { name: "Verify all", exact: true }).click({
|
await page
|
||||||
timeout: uiTimeoutMs,
|
.locator(".sls-setting:visible")
|
||||||
});
|
.last()
|
||||||
|
.getByRole("button", { name: "Verify all", exact: true })
|
||||||
|
.click({
|
||||||
|
timeout: uiTimeoutMs,
|
||||||
|
});
|
||||||
await page
|
await page
|
||||||
.locator(".notice")
|
.locator(".notice")
|
||||||
.filter({ hasText: /^done$/u })
|
.filter({ hasText: /^done$/u })
|
||||||
|
|||||||
+2
-1
@@ -21,6 +21,7 @@ Earlier releases remain available in the 0.25 release history and the legacy rel
|
|||||||
- First-device P2P setup now accepts a successfully opened signalling room without requiring another peer to be online. Additional-device Fetch still requires selecting a source peer and completing `P2P Rebuild`.
|
- First-device P2P setup now accepts a successfully opened signalling room without requiring another peer to be online. Additional-device Fetch still requires selecting a source peer and completing `P2P Rebuild`.
|
||||||
- Manual CouchDB setup now distinguishes creating a first database from connecting an additional device to an existing one. Settings mode can save an unverified profile explicitly, while onboarding requires a successful connection, and each proposed server-configuration fix requires separate confirmation.
|
- Manual CouchDB setup now distinguishes creating a first database from connecting an additional device to an existing one. Settings mode can save an unverified profile explicitly, while onboarding requires a successful connection, and each proposed server-configuration fix requires separate confirmation.
|
||||||
- Differences limited to the chunk hash algorithm, chunk size, or splitter version are now aligned automatically by default. Existing content remains readable, while an explicit opt-out and any difference which also involves an incompatible setting retain manual review.
|
- Differences limited to the chunk hash algorithm, chunk size, or splitter version are now aligned automatically by default. Existing content remains readable, while an explicit opt-out and any difference which also involves an incompatible setting retain manual review.
|
||||||
|
- Text in setup and review dialogues can now be selected for copying or translation.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
@@ -31,7 +32,7 @@ Earlier releases remain available in the 0.25 release history and the legacy rel
|
|||||||
|
|
||||||
### Testing
|
### Testing
|
||||||
|
|
||||||
- Added regressions for revision repair, P2P configuration, the distinction between setting up the first device and using Fetch on an additional device, the P2P status pane, CouchDB setup policy, mobile dialogues, conflict-aware chunk reachability, device-progress safeguards, compaction timeouts, shared chunks, collection propagation, and content-addressed chunk recreation.
|
- Added regressions for revision repair, P2P configuration, the distinction between setting up the first device and using Fetch on an additional device, the P2P status pane, CouchDB setup policy, selectable and mobile dialogues, conflict-aware chunk reachability, device-progress safeguards, compaction timeouts, shared chunks, collection propagation, and content-addressed chunk recreation.
|
||||||
|
|
||||||
## 1.0.0-beta.2
|
## 1.0.0-beta.2
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user