Skip to content

Commit

Permalink
Manage focus and selection
Browse files Browse the repository at this point in the history
  • Loading branch information
raimohanska committed Feb 24, 2024
1 parent 4e3eb6d commit a39fe3c
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 25 deletions.
3 changes: 2 additions & 1 deletion YJS_CRDT_WIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ The Y.js based collaborative editing support is under construction.

Must-haves

- UI: Manage focus etc. Now selection goes directly to text edit mode, even in multiselect. Make test stricter on that the initial text is shown and correctly replaced. Select all text on click.
- UI: Copy-pasting items should copy CRDT as well
- Undo buffer integration
- Mobile check
- Manage session on the server side: terminate YJS sockets when websocket session is terminated
- Performance testing
- Playwright tests
Expand Down
43 changes: 25 additions & 18 deletions frontend/src/board/CollaborativeTextView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,6 @@ export function CollaborativeTextView({
const fontSize = L.view(item, (i) => `${i.fontSize ? i.fontSize : 1}em`)
const color = L.view(item, getItemBackground, contrastingColor)

const setEditing = (e: boolean) => {
if (toolController.tool.get() === "connect") return // Don't switch to editing in middle of connecting
dispatch({ action: "item.front", boardId: board.get().id, itemIds: [id] })
focus.set(
e
? { status: "editing", itemId: id }
: { status: "selected", itemIds: new Set([id]), connectionIds: emptySet() },
)
}

const editingThis = L.atom(
L.view(itemFocus, (f) => f === "editing" || f === "selected"),
setEditing,
)

const quillEditor = L.atom<Quill | null>(null)

function initQuill(el: HTMLElement) {
Expand All @@ -71,21 +56,43 @@ export function CollaborativeTextView({
quillEditor.set(quill)
}

L.combine(quillEditor, editingThis, (q, e) => (e ? q : null)).forEach((q) => {
q && q.focus()
const editingThis = L.view(itemFocus, (f) => f === "editing")

editingThis.forEach((e) => {
const q = quillEditor.get()
if (q) {
if (e) {
if (item.get().type === "container") {
// For containers, select all text for quick rename
q.setSelection(0, 1000000)
}
} else {
// Clear text selecting when not editing
q.setSelection(null as any)
}
}
})

function handleClick() {
if (itemFocus.get() === "selected") {
focus.set({ status: "editing", itemId: id })
}
}

const pointerEvents = L.view(itemFocus, (f) => (f === "editing" || f === "selected" ? "auto" : "none"))

return (
<div
className="quill-wrapper text"
onKeyDown={(e) => e.stopPropagation()}
onKeyUp={(e) => e.stopPropagation()}
onKeyPress={(e) => e.stopPropagation()}
onDoubleClick={(e) => e.stopPropagation()}
onClick={handleClick}
>
<div
className="quill-editor"
style={L.combineTemplate({ fontSize, color, width: "100%", height: "100%" })}
style={L.combineTemplate({ fontSize, color, pointerEvents })}
ref={initQuill}
/>
</div>
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/style/board.scss
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,12 @@
}

> .quill-wrapper {
width: "100%";
height: "100%";
width: 100%;
height: 100%;
padding: 0;
> .quill-editor {
width: 100%;
height: 100%;
> .ql-editor {
padding: 0.1em;
}
Expand Down
15 changes: 11 additions & 4 deletions playwright/src/pages/BoardPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,20 +108,27 @@ export function BoardPage(page: Page) {
await page.keyboard.type(`${text}`)
await page.keyboard.press("Escape")
await expect(this.getNote(text)).toBeVisible()
return this.getNote(text)
const result = this.getNote(text)
await expect(result).toHaveText(text)
return result
},
async createText(x: number, y: number, text: string) {
await createNew(this.newTextOnPalette, x, y)
await expect(this.getText("")).toBeVisible()
await this.getText("HELLO").locator(".text").dblclick()
await page.keyboard.type(`${text}`)
await expect(this.getText(text)).toBeVisible()
return this.getText(text)
const result = this.getText(text)
await expect(result).toHaveText(text)

Check failure on line 121 in playwright/src/pages/BoardPage.ts

View workflow job for this annotation

GitHub Actions / test (18.x)

[firefox] › src/tests/board.spec.ts:12:9 › Basic board functionality › Can create text by dragging from palette

1) [firefox] › src/tests/board.spec.ts:12:9 › Basic board functionality › Can create text by dragging from palette Error: Timed out 5000ms waiting for expect(locator).toHaveText(expected) Locator: locator('.board > .text').filter({ hasText: 'note-54682' }) Expected string: "note-54682" Received string: "note-54682HELLO" Call log: - expect.toHaveText with timeout 5000ms - waiting for locator('.board > .text').filter({ hasText: 'note-54682' }) - locator resolved to <span title="" draggable="false" class="text color-non…>…</span> - unexpected value "note-54682HELLO" - locator resolved to <span title="" draggable="false" class="text color-non…>…</span> - unexpected value "note-54682HELLO" - locator resolved to <span title="" draggable="false" class="text color-non…>…</span> - unexpected value "note-54682HELLO" - locator resolved to <span title="" draggable="false" class="text color-non…>…</span> - unexpected value "note-54682HELLO" - locator resolved to <span title="" draggable="false" class="text color-non…>…</span> - unexpected value "note-54682HELLO" - locator resolved to <span title="" draggable="false" class="text color-non…>…</span> - unexpected value "note-54682HELLO" - locator resolved to <span title="" draggable="false" class="text color-non…>…</span> - unexpected value "note-54682HELLO" - locator resolved to <span title="" draggable="false" class="text color-non…>…</span> - unexpected value "note-54682HELLO" - locator resolved to <span title="" draggable="false" class="text color-non…>…</span> - unexpected value "note-54682HELLO" at src/pages/BoardPage.ts:121 119 | await expect(this.getText(text)).toBeVisible() 120 | const result = this.getText(text) > 121 | await expect(result).toHaveText(text) | ^ 122 | return result 123 | }, 124 | async createArea(x: number, y: number, text: string) { at Object.createText (/home/runner/work/ourboard/ourboard/playwright/src/pages/BoardPage.ts:121:34) at /home/runner/work/ourboard/ourboard/playwright/src/tests/board.spec.ts:15:9
return result
},
async createArea(x: number, y: number, text: string) {
await createNew(this.newContainerOnPalette, x, y)
await this.getArea("Unnamed area").locator(".text").dblclick()
await page.keyboard.type(`${text}`)
await expect(this.getArea(text)).toBeVisible()
return this.getArea(text)
const result = this.getArea(text)
await expect(result).toHaveText(text)
return result
},
async dragItem(item: Locator, x: number, y: number) {
await dragElementOnBoard(item, x, y)
Expand Down

0 comments on commit a39fe3c

Please sign in to comment.