diff --git a/blocksuite/affine/widgets/drag-handle/src/watchers/drag-event-watcher.ts b/blocksuite/affine/widgets/drag-handle/src/watchers/drag-event-watcher.ts index 74ac7bb159..d52018eaff 100644 --- a/blocksuite/affine/widgets/drag-handle/src/watchers/drag-event-watcher.ts +++ b/blocksuite/affine/widgets/drag-handle/src/watchers/drag-event-watcher.ts @@ -30,6 +30,7 @@ import { import { captureEventTarget, type DropTarget as DropResult, + findNoteBlockModel, getBlockComponentsExcludeSubtrees, getRectByBlockComponent, getScrollContainer, @@ -1247,20 +1248,50 @@ export class DragEventWatcher { console.error ); } - } else { - // create note to wrap the snapshot - const noteId = store.addBlock( - 'affine:note', - { - xywh: new Bound( - point.x, - point.y, - DEFAULT_NOTE_WIDTH, - DEFAULT_NOTE_HEIGHT - ).serialize(), - }, - this.widget.store.root! - ); + } + // create note to wrap the snapshot + else { + const originalModel = store.getModelById(snapshot.content[0].id); + const originalNote = originalModel + ? findNoteBlockModel(originalModel) + : null; + + let noteId: string; + if (originalNote) { + const placement = + originalNote.children[0].id === snapshot.content[0].id + ? 'before' + : 'after'; + + noteId = store.addSiblingBlocks( + originalNote, + [ + { + flavour: 'affine:note', + xywh: new Bound( + point.x, + point.y, + DEFAULT_NOTE_WIDTH, + DEFAULT_NOTE_HEIGHT + ).serialize(), + }, + ], + placement + )[0]; + } else { + noteId = store.addBlock( + 'affine:note', + { + xywh: new Bound( + point.x, + point.y, + DEFAULT_NOTE_WIDTH, + DEFAULT_NOTE_HEIGHT + ).serialize(), + }, + this.widget.store.root! + ); + } this._dropToModel( { diff --git a/tests/blocksuite/e2e/edgeless/note/drag-handle.spec.ts b/tests/blocksuite/e2e/edgeless/note/drag-handle.spec.ts index 63def08d0b..d230ee5600 100644 --- a/tests/blocksuite/e2e/edgeless/note/drag-handle.spec.ts +++ b/tests/blocksuite/e2e/edgeless/note/drag-handle.spec.ts @@ -2,17 +2,23 @@ import { expect } from '@playwright/test'; import { addNote, + changeNoteDisplayModeWithId, + createNote, + dragBlockToPoint, dragHandleFromBlockToBlockBottomById, enterPlaygroundRoom, focusRichText, initEmptyEdgelessState, initThreeParagraphs, + pressEnter, + pressEscape, setEdgelessTool, switchEditorMode, type, waitNextFrame, } from '../../utils/actions/index.js'; import { assertRectExist, assertRichTexts } from '../../utils/asserts.js'; +import { NoteDisplayMode } from '../../utils/bs-alternative.js'; import { test } from '../../utils/playwright.js'; const CENTER_X = 450; @@ -120,37 +126,85 @@ test('drag handle should work inside one note', async ({ page }) => { await assertRichTexts(page, ['456', '789', '123']); }); -test.fixme( - 'drag handle should work across multiple notes', - async ({ page }) => { - await enterPlaygroundRoom(page); - await initEmptyEdgelessState(page); - await initThreeParagraphs(page); - await assertRichTexts(page, ['123', '456', '789']); +test('drag handle should work across multiple notes', async ({ page }) => { + await enterPlaygroundRoom(page); + await initEmptyEdgelessState(page); + await initThreeParagraphs(page); + await assertRichTexts(page, ['123', '456', '789']); - await switchEditorMode(page); + await switchEditorMode(page); - await setEdgelessTool(page, 'note'); + await setEdgelessTool(page, 'note'); - await page.mouse.click(200, 200); - await focusRichText(page, 3); - await waitNextFrame(page); + await page.mouse.click(200, 200); + await focusRichText(page, 3); + await waitNextFrame(page); - // block id 7 - await type(page, '000'); + // block id 7 + await type(page, '000'); - await page.mouse.dblclick(CENTER_X, CENTER_Y - 20); - await dragHandleFromBlockToBlockBottomById(page, '3', '7'); - await expect(page.locator('.affine-drag-handle-container')).toBeHidden(); - await waitNextFrame(page); - await assertRichTexts(page, ['456', '789', '000', '123']); + await page.mouse.dblclick(CENTER_X, CENTER_Y - 20); + await dragHandleFromBlockToBlockBottomById(page, '3', '7'); + await expect(page.locator('.affine-drag-handle-container')).toBeHidden(); + await waitNextFrame(page); + await assertRichTexts(page, ['456', '789', '000', '123']); - // await page.mouse.dblclick(305, 305); - await dragHandleFromBlockToBlockBottomById(page, '3', '4'); - await waitNextFrame(page); - await expect(page.locator('.affine-drag-handle-container')).toBeHidden(); - await assertRichTexts(page, ['456', '123', '789', '000']); + await page + .locator('affine-edgeless-note') + .nth(1) + .locator('affine-paragraph') + .nth(1) + .click({ clickCount: 3 }); + await dragHandleFromBlockToBlockBottomById(page, '3', '4'); + await waitNextFrame(page); + await expect(page.locator('.affine-drag-handle-container')).toBeHidden(); + await assertRichTexts(page, ['456', '123', '789', '000']); - await expect(page.locator('selected > *')).toHaveCount(0); - } -); + await expect(page.locator('selected > *')).toHaveCount(0); +}); + +test('should keep relative order of new note when a block is dragged from note to canvas', async ({ + page, +}) => { + await enterPlaygroundRoom(page); + await initEmptyEdgelessState(page); + await focusRichText(page); + await type(page, '3'); + await switchEditorMode(page); + + const note2 = await createNote(page, [0, -200], '5'); + await pressEnter(page); + await type(page, '6'); + await pressEnter(page); + await type(page, '7'); + await pressEscape(page, 3); + await changeNoteDisplayModeWithId( + page, + note2, + NoteDisplayMode.DocAndEdgeless + ); + await pressEscape(page); + + const note3 = await createNote(page, [0, 200], '9'); + await pressEscape(page, 3); + await changeNoteDisplayModeWithId( + page, + note3, + NoteDisplayMode.DocAndEdgeless + ); + await pressEscape(page); + + await assertRichTexts(page, ['3', '5', '6', '7', '9']); + + const notes = page.locator('affine-edgeless-note'); + + await notes.nth(1).dblclick(); + await dragBlockToPoint(page, '5', { x: 50, y: 100 }); + await waitNextFrame(page); + await assertRichTexts(page, ['3', '5', '6', '7', '9']); + + await notes.nth(2).dblclick(); + await dragBlockToPoint(page, '7', { x: 50, y: 200 }); + await waitNextFrame(page); + await assertRichTexts(page, ['3', '5', '6', '7', '9']); +});