From be15fed9e4052607ba7159913c73c1b03011e800 Mon Sep 17 00:00:00 2001 From: regischen Date: Fri, 27 Oct 2023 14:47:30 +0800 Subject: [PATCH 01/10] feat(edgeless): auto-connect --- packages/blocks/src/_common/icons/edgeless.ts | 19 +- .../edgeless-auto-connect-line.ts | 127 ++++++++++++ .../edgeless-auto-connect-sequence.ts | 94 +++++++++ .../block-portal/edgeless-block-portal.ts | 31 ++- .../component-toolbar/change-note-button.ts | 181 ++++++------------ .../component-toolbar/component-toolbar.ts | 7 +- .../blocks/src/surface-block/utils/vec.ts | 5 + 7 files changed, 321 insertions(+), 143 deletions(-) create mode 100644 packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts create mode 100644 packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-sequence.ts diff --git a/packages/blocks/src/_common/icons/edgeless.ts b/packages/blocks/src/_common/icons/edgeless.ts index 935cd8995971..3937f47e0865 100644 --- a/packages/blocks/src/_common/icons/edgeless.ts +++ b/packages/blocks/src/_common/icons/edgeless.ts @@ -1099,20 +1099,19 @@ export const TextAlignRightIcon = html``; export const HiddenIcon = html` -`; + `; export const CardIcon = html` { + this.requestUpdate(); + }) + ); + + _disposables.add( + surface.page.slots.blockUpdated.on(({ type, id }) => { + if (type === 'update' && isNoteBlock(surface.pickById(id))) { + this.requestUpdate(); + } + }) + ); + } + + protected override render() { + if (!this.show) return nothing; + const { viewport } = this.surface; + const notes = this.surface.getblocks(NOTE).filter(note => !note.hidden); + const points: [IVec, IVec][] = []; + for (let i = 1; i < notes.length; i++) { + const last = notes[i - 1]; + const current = notes[i]; + const lastBound = Bound.deserialize(last.xywh); + const currentBound = Bound.deserialize(current.xywh); + const start = viewport.toViewCoord(lastBound.center[0], lastBound.maxY); + const end = viewport.toViewCoord( + currentBound.center[0], + currentBound.maxY + ); + points.push([start, end]); + } + return repeat( + points, + (_, index) => index, + ([start, end]) => { + const width = Math.abs(start[0] - end[0]); + const height = Math.abs(start[1] - end[1]); + const style = styleMap({ + position: 'absolute', + transform: `translate(${Math.min(start[0], end[0])}px, ${Math.min( + start[1], + end[1] + )}px)`, + }); + const lineStart = [0, 0]; + const lineEnd = [width, height]; + if (start[0] > end[0]) { + lineStart[0] = width; + lineEnd[0] = 0; + } else { + lineStart[0] = 0; + lineEnd[0] = width; + } + + if (start[1] > end[1]) { + lineStart[1] = height; + lineEnd[1] = 0; + } else { + lineStart[1] = 0; + lineEnd[1] = height; + } + + const newstart = Vec.pointOffset(lineStart, lineEnd, 16); + const newend = Vec.pointOffset(lineEnd, lineStart, 16); + + return svg` + + + + + + + + + + `; + } + ); + } +} diff --git a/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-sequence.ts b/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-sequence.ts new file mode 100644 index 000000000000..e8931402a621 --- /dev/null +++ b/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-sequence.ts @@ -0,0 +1,94 @@ +import { WithDisposable } from '@blocksuite/lit'; +import { css, html, LitElement, nothing } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; +import { repeat } from 'lit/directives/repeat.js'; +import { styleMap } from 'lit/directives/style-map.js'; + +import { EdgelessBlockType } from '../../../../surface-block/edgeless-types.js'; +import { Bound } from '../../../../surface-block/index.js'; +import type { SurfaceBlockComponent } from '../../../../surface-block/surface-block.js'; +import { isNoteBlock } from '../../utils/query.js'; + +const { NOTE } = EdgelessBlockType; +@customElement('edgeless-auto-connect-sequence') +export class EdgelessAutoConnectSequence extends WithDisposable(LitElement) { + static override styles = css` + :host { + position: absolute; + top: 0; + left: 0; + z-index: 1; + } + + .edgeless-auto-connect-sequence { + font-size: 15px; + text-align: center; + height: 24px; + min-width: 12px; + padding: 0px 6px; + width: fit-content; + border-radius: 25px; + border: 1px solid #0000001a; + background: var(--affine-primary-color); + color: var(--affine-white); + cursor: pointer; + } + `; + + @property({ attribute: false }) + surface!: SurfaceBlockComponent; + + @property({ attribute: false }) + show = false; + + protected override firstUpdated(): void { + const { _disposables, surface } = this; + + _disposables.add( + surface.viewport.slots.viewportUpdated.on(() => { + this.requestUpdate(); + }) + ); + + _disposables.add( + surface.page.slots.blockUpdated.on(({ type, id }) => { + if (type === 'update' && isNoteBlock(surface.pickById(id))) { + this.requestUpdate(); + } + }) + ); + } + + protected override render() { + if (!this.show) return nothing; + const { viewport } = this.surface; + const { zoom } = viewport; + const notes = this.surface.getblocks(NOTE).filter(note => !note.hidden); + return repeat( + notes, + note => note.id, + (note, index) => { + const bound = Bound.deserialize(note.xywh); + const [left, right] = viewport.toViewCoord(bound.x, bound.y); + const [width, height] = [bound.w * zoom, bound.h * zoom]; + const style = styleMap({ + position: 'absolute', + transform: `translate(${left + width / 2 - 26 / 2}px, ${ + right + height - 14 + }px)`, + }); + return html` +
+ ${index + 1} +
+ `; + } + ); + } +} + +declare global { + interface HTMLElementTagNameMap { + 'edgeless-auto-connect-sequence': EdgelessAutoConnectSequence; + } +} diff --git a/packages/blocks/src/page-block/edgeless/components/block-portal/edgeless-block-portal.ts b/packages/blocks/src/page-block/edgeless/components/block-portal/edgeless-block-portal.ts index 95062e0d029f..7651f90d4403 100644 --- a/packages/blocks/src/page-block/edgeless/components/block-portal/edgeless-block-portal.ts +++ b/packages/blocks/src/page-block/edgeless/components/block-portal/edgeless-block-portal.ts @@ -6,11 +6,13 @@ import '../rects/edgeless-selected-rect.js'; import '../rects/edgeless-hover-rect.js'; import '../rects/edgeless-dragging-area-rect.js'; import '../note-status/index.js'; +import '../../components/auto-connect/edgeless-auto-connect-sequence.js'; +import '../../components/auto-connect/edgeless-auto-connect-line.js'; import { assertExists, throttle } from '@blocksuite/global/utils'; import { ShadowlessElement, WithDisposable } from '@blocksuite/lit'; import { nothing } from 'lit'; -import { customElement, property, query } from 'lit/decorators.js'; +import { customElement, property, query, state } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; import { html, literal, unsafeStatic } from 'lit/static-html.js'; @@ -24,7 +26,7 @@ import { EdgelessBlockType } from '../../../../surface-block/edgeless-types.js'; import { almostEqual, Bound } from '../../../../surface-block/index.js'; import type { EdgelessPageBlockComponent } from '../../edgeless-page-block.js'; import { NoteResizeObserver } from '../../utils/note-resize-observer.js'; -import { getBackgroundGrid } from '../../utils/query.js'; +import { getBackgroundGrid, isNoteBlock } from '../../utils/query.js'; const portalMap = { [EdgelessBlockType.FRAME]: 'edgeless-block-portal-frame', @@ -45,6 +47,9 @@ export class EdgelessBlockPortalContainer extends WithDisposable( @query('.affine-edgeless-layer') layer!: HTMLDivElement; + @state() + private _showAutoConnect = false; + private _cancelRestoreWillchange: (() => void) | null = null; private _noteResizeObserver = new NoteResizeObserver(); @@ -183,6 +188,17 @@ export class EdgelessBlockPortalContainer extends WithDisposable( this.requestUpdate(); }) ); + + _disposables.add( + edgeless.selectionManager.slots.updated.on(() => { + const { elements } = edgeless.selectionManager; + if (elements.length === 1 && isNoteBlock(elements[0])) { + this._showAutoConnect = true; + } else { + this._showAutoConnect = false; + } + }) + ); } override render() { @@ -197,6 +213,11 @@ export class EdgelessBlockPortalContainer extends WithDisposable( const { readonly } = this.edgeless.page; return html`
+ +
@@ -226,7 +247,11 @@ export class EdgelessBlockPortalContainer extends WithDisposable( .edgeless=${edgeless} > - + + `; } } diff --git a/packages/blocks/src/page-block/edgeless/components/component-toolbar/change-note-button.ts b/packages/blocks/src/page-block/edgeless/components/component-toolbar/change-note-button.ts index 21d098f88d10..de36e96f95d4 100644 --- a/packages/blocks/src/page-block/edgeless/components/component-toolbar/change-note-button.ts +++ b/packages/blocks/src/page-block/edgeless/components/component-toolbar/change-note-button.ts @@ -4,7 +4,6 @@ import '../panel/color-panel.js'; import { assertExists } from '@blocksuite/global/utils'; import { WithDisposable } from '@blocksuite/lit'; -import { type Page } from '@blocksuite/store'; import { css, html, LitElement, nothing } from 'lit'; import { customElement, property, query, state } from 'lit/decorators.js'; import { styleMap } from 'lit/directives/style-map.js'; @@ -16,6 +15,7 @@ import { NOTE_COLORS, type NoteBlockModel, } from '../../../../note-block/note-model.js'; +import type { SurfaceBlockComponent } from '../../../../surface-block/surface-block.js'; import type { EdgelessSelectionSlots } from '../../edgeless-page-block.js'; import type { ColorEvent } from '../panel/color-panel.js'; import { createButtonPopper } from '../utils.js'; @@ -29,7 +29,6 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) { fill: currentColor; align-items: center; justify-content: center; - gap: 10px; } edgeless-color-panel { @@ -60,85 +59,29 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) { font-size: 12px; } - .note-status { - display: flex; - align-items: center; - text-align: center; - justify-content: center; - gap: 10px; - width: 24px; - height: 24px; - background: var(--affine-blue-600); - border-radius: 4px; - color: var(--affine-white); + .show { font-size: 12px; + color: var(--affine-text-secondary-color); font-weight: 600; - line-height: 16px; - } - - .note-status > span { - display: flex; - padding: 4px 6px; - width: 24px; - flex-direction: column; - } - - .note-status.hidden > span { - display: flex; - padding: 4px; - } - - .note-status-button { display: flex; - justify-content: center; align-items: center; - color: var(--affine-text-secondary-color); - width: 74px; - height: 24px; - padding: 4px 8px; - } - - .note-status-button.hidden { - width: 126px; + justify-content: center; + gap: 4px; + height: 30px; + cursor: pointer; } - .note-status-button:hover { + .show:hover { background: var(--affine-hover-color); border-radius: 8px; } - - .note-status-button .hover { - display: none; - } - .note-status-button:hover .hover { - display: flex; - } - .note-status-button:hover .unhover { - display: none; - } - - .note-status-button svg { - width: 20px; - height: 20px; - } - - .note-status-button > span { - font-size: 12px; - font-style: normal; - font-weight: 600; - line-height: 16px; - display: flex; - justify-content: center; - align-items: center; - gap: 2px; - } `; @property({ attribute: false }) notes: NoteBlockModel[] = []; @property({ attribute: false }) - page!: Page; + surface!: SurfaceBlockComponent; @property({ attribute: false }) slots!: EdgelessSelectionSlots; @@ -164,14 +107,14 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) { private _setBlockBackground(color: CssVariableName) { this.notes.forEach(note => { - this.page.updateBlock(note, { background: color }); + this.surface.page.updateBlock(note, { background: color }); }); } private _setNoteHidden(note: NoteBlockModel, hidden: boolean) { - this.page.updateBlock(note, { hidden }); + this.surface.page.updateBlock(note, { hidden }); - const noteParent = this.page.getParent(note); + const noteParent = this.surface.page.getParent(note); assertExists(noteParent); const noteParentChildNotes = noteParent.children.filter(block => matchFlavours(block, ['affine:note']) @@ -181,7 +124,12 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) { if (!hidden && note !== noteParentLastNote) { // move to the end - this.page.moveBlocks([note], noteParent, noteParentLastNote, false); + this.surface.page.moveBlocks( + [note], + noteParent, + noteParentLastNote, + false + ); } this.requestUpdate(); } @@ -204,64 +152,45 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) { override render() { if (this.notes.length !== 1) return nothing; - const note = this.notes[0]; - const noteParent = this.page.getParent(note); - assertExists(noteParent); - const allNotes = noteParent.children.filter( - block => matchFlavours(block, ['affine:note']) && !block.hidden - ); + const note = this.notes[0]; const selectedBackground = note.background; - const noteIndex = allNotes.indexOf(note) + 1; - - const enableIndex = this.page.awarenessStore.getFlag('enable_note_index'); - - if (note.hidden) { - return html` - ${enableIndex - ? html`` - : nothing} -
this._setNoteHidden(note, !note.hidden)} - class="note-status-button hidden" - > - Hidden on page mode - ${NoteIcon}Show on page -
- `; - } else { - return html` - ${enableIndex - ? html`
- ${noteIndex} -
` - : nothing} -
this._setNoteHidden(note, !note.hidden)} - class="note-status-button unhover" - > - ${NoteIcon}On page - ${HiddenIcon}Hidden -
- this._colorSelectorPopper?.toggle()} - > - ${this._renderSelectedColor(selectedBackground)} - - { - this._setBlockBackground(event.detail); - }} - > - `; - } + const enableIndex = + this.surface.page.awarenessStore.getFlag('enable_note_index'); + + return html` + ${enableIndex + ? html`
this._setNoteHidden(note, !note.hidden)} + > + ${note.hidden + ? html`${NoteIcon}On page` + : html` + ${HiddenIcon} +
${'Hidden on page mode'}
+ `} +
` + : nothing} + this._colorSelectorPopper?.toggle()} + > + ${this._renderSelectedColor(selectedBackground)} + + { + this._setBlockBackground(event.detail); + }} + > + `; } } diff --git a/packages/blocks/src/page-block/edgeless/components/component-toolbar/component-toolbar.ts b/packages/blocks/src/page-block/edgeless/components/component-toolbar/component-toolbar.ts index ecc613337f57..63075b3c3b5c 100644 --- a/packages/blocks/src/page-block/edgeless/components/component-toolbar/component-toolbar.ts +++ b/packages/blocks/src/page-block/edgeless/components/component-toolbar/component-toolbar.ts @@ -149,11 +149,10 @@ export class EdgelessComponentToolbar extends WithDisposable(LitElement) { : nothing; } - private _getNoteButton(nots?: NoteBlockModel[]) { - return nots?.length === 1 + private _getNoteButton(notes?: NoteBlockModel[]) { + return notes?.length === 1 ? html` diff --git a/packages/blocks/src/surface-block/utils/vec.ts b/packages/blocks/src/surface-block/utils/vec.ts index 100b712704bc..9ba3d7aacecd 100644 --- a/packages/blocks/src/surface-block/utils/vec.ts +++ b/packages/blocks/src/surface-block/utils/vec.ts @@ -562,6 +562,11 @@ export class Vec { }); }; + static pointOffset = (A: IVec, B: IVec, offset: number): IVec => { + const u = Vec.uni(Vec.sub(B, A)); + return Vec.add(A, Vec.mul(u, offset)); + }; + /** * Get the slope between two points. * @param A From 4f0009f480a39133ed493d083e154bb4531f7fc3 Mon Sep 17 00:00:00 2001 From: regischen Date: Fri, 27 Oct 2023 14:53:00 +0800 Subject: [PATCH 02/10] style: adjust line --- .../edgeless-auto-connect-line.ts | 26 ++++++++++--------- .../edgeless-auto-connect-sequence.ts | 4 +++ .../component-toolbar/change-note-button.ts | 1 + 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts b/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts index 35df003e0e6f..6435b28d3667 100644 --- a/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts +++ b/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts @@ -46,6 +46,7 @@ export class EdgelessAutoConnectLine extends WithDisposable(LitElement) { protected override render() { if (!this.show) return nothing; + const { viewport } = this.surface; const notes = this.surface.getblocks(NOTE).filter(note => !note.hidden); const points: [IVec, IVec][] = []; @@ -61,6 +62,7 @@ export class EdgelessAutoConnectLine extends WithDisposable(LitElement) { ); points.push([start, end]); } + return repeat( points, (_, index) => index, @@ -97,18 +99,18 @@ export class EdgelessAutoConnectLine extends WithDisposable(LitElement) { return svg` - - - - - + + + + + !note.hidden); + return repeat( notes, note => note.id, @@ -77,6 +80,7 @@ export class EdgelessAutoConnectSequence extends WithDisposable(LitElement) { right + height - 14 }px)`, }); + return html`
${index + 1} diff --git a/packages/blocks/src/page-block/edgeless/components/component-toolbar/change-note-button.ts b/packages/blocks/src/page-block/edgeless/components/component-toolbar/change-note-button.ts index de36e96f95d4..0bbca3a47718 100644 --- a/packages/blocks/src/page-block/edgeless/components/component-toolbar/change-note-button.ts +++ b/packages/blocks/src/page-block/edgeless/components/component-toolbar/change-note-button.ts @@ -91,6 +91,7 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) { @query('edgeless-tool-icon-button') private _colorSelectorButton!: HTMLDivElement; + @query('edgeless-color-panel') private _colorSelector!: HTMLDivElement; From 829cc4b49d3e19eec75b589f6d0603446cbae208 Mon Sep 17 00:00:00 2001 From: regischen Date: Tue, 31 Oct 2023 09:58:06 +0800 Subject: [PATCH 03/10] test: fix --- .../components/block-portal/edgeless-block-portal.ts | 6 +++++- tests/edgeless/auto-complete.spec.ts | 7 +++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/blocks/src/page-block/edgeless/components/block-portal/edgeless-block-portal.ts b/packages/blocks/src/page-block/edgeless/components/block-portal/edgeless-block-portal.ts index 7651f90d4403..2d361535747e 100644 --- a/packages/blocks/src/page-block/edgeless/components/block-portal/edgeless-block-portal.ts +++ b/packages/blocks/src/page-block/edgeless/components/block-portal/edgeless-block-portal.ts @@ -192,7 +192,11 @@ export class EdgelessBlockPortalContainer extends WithDisposable( _disposables.add( edgeless.selectionManager.slots.updated.on(() => { const { elements } = edgeless.selectionManager; - if (elements.length === 1 && isNoteBlock(elements[0])) { + if ( + !edgeless.selectionManager.editing && + elements.length === 1 && + isNoteBlock(elements[0]) + ) { this._showAutoConnect = true; } else { this._showAutoConnect = false; diff --git a/tests/edgeless/auto-complete.spec.ts b/tests/edgeless/auto-complete.spec.ts index a7076a5c4d52..d46a9515074f 100644 --- a/tests/edgeless/auto-complete.spec.ts +++ b/tests/edgeless/auto-complete.spec.ts @@ -49,11 +49,10 @@ test.describe('auto-complete', () => { await page.mouse.click(300, 50); await page.mouse.click(150, 120); const rect = await getEdgelessSelectedRectModel(page); - await clickView(page, [rect[0] + rect[2] / 2, rect[1] + rect[3] + 10]); - + await clickView(page, [rect[0] + rect[2] + 10, rect[1] + rect[3] / 2]); const newRect = await getEdgelessSelectedRectModel(page); - expect(rect[0]).toEqual(newRect[0]); - expect(rect[1]).not.toEqual(newRect[1]); + expect(rect[0]).not.toEqual(newRect[0]); + expect(rect[1]).toEqual(newRect[1]); expect(rect[2]).toEqual(newRect[2]); expect(rect[3]).toEqual(newRect[3]); }); From 89957b2fcb8e4a76687f6c6181472725648296b7 Mon Sep 17 00:00:00 2001 From: regischen Date: Tue, 31 Oct 2023 10:27:08 +0800 Subject: [PATCH 04/10] test: fix --- packages/blocks/src/_common/icons/edgeless.ts | 13 ++ .../edgeless-auto-connect-line.ts | 23 ++- .../edgeless-auto-connect-sequence.ts | 173 +++++++++++++++--- .../block-portal/edgeless-block-portal.ts | 14 +- tests/edgeless/note.spec.ts | 79 +------- tests/utils/asserts.ts | 7 + 6 files changed, 202 insertions(+), 107 deletions(-) diff --git a/packages/blocks/src/_common/icons/edgeless.ts b/packages/blocks/src/_common/icons/edgeless.ts index 3937f47e0865..c36ee39f36bb 100644 --- a/packages/blocks/src/_common/icons/edgeless.ts +++ b/packages/blocks/src/_common/icons/edgeless.ts @@ -2560,3 +2560,16 @@ export const ConnectorIcon = html` /> `; + +export const AutoConnectLeftIcon = svg` + + + +`; + +export const AutoConnectRightIcon = svg` + + + + +`; diff --git a/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts b/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts index 6435b28d3667..ebda5334980d 100644 --- a/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts +++ b/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts @@ -62,6 +62,7 @@ export class EdgelessAutoConnectLine extends WithDisposable(LitElement) { ); points.push([start, end]); } + const expand = 20; return repeat( points, @@ -71,10 +72,9 @@ export class EdgelessAutoConnectLine extends WithDisposable(LitElement) { const height = Math.abs(start[1] - end[1]); const style = styleMap({ position: 'absolute', - transform: `translate(${Math.min(start[0], end[0])}px, ${Math.min( - start[1], - end[1] - )}px)`, + transform: `translate(${Math.min(start[0], end[0]) - expand / 2}px, ${ + Math.min(start[1], end[1]) - expand / 2 + }px)`, }); const lineStart = [0, 0]; const lineEnd = [width, height]; @@ -94,11 +94,20 @@ export class EdgelessAutoConnectLine extends WithDisposable(LitElement) { lineEnd[1] = height; } - const newstart = Vec.pointOffset(lineStart, lineEnd, 16); - const newend = Vec.pointOffset(lineEnd, lineStart, 16); + const newWidth = width + expand; + const newHeight = height + expand; + + const newstart = Vec.add(Vec.pointOffset(lineStart, lineEnd, 16), [ + expand / 2, + expand / 2, + ]); + const newend = Vec.add(Vec.pointOffset(lineEnd, lineStart, 16), [ + expand / 2, + expand / 2, + ]); return svg` - + { this.requestUpdate(); @@ -58,6 +95,94 @@ export class EdgelessAutoConnectSequence extends WithDisposable(LitElement) { } }) ); + + _disposables.add( + edgeless.selectionManager.slots.updated.on(() => { + const { elements } = edgeless.selectionManager; + if (!(elements.length === 1 && isNoteBlock(elements[0]))) { + this._index = -1; + } + }) + ); + + requestAnimationFrame(() => { + if (surface.edgeless.dispatcher) { + this._disposables.add( + surface.edgeless.dispatcher.add('click', ctx => { + const event = ctx.get('pointerState'); + const { raw } = event; + const target = raw.target as HTMLElement; + if (!target) return false; + if (target.closest('.edgeless-auto-connect-sequence')) { + const ele = target.closest( + '.edgeless-auto-connect-sequence' + ) as Element; + const index = Number(ele.getAttribute('index')); + this._index = index === this._index ? -1 : index; + return true; + } else if (target.closest('.edgeless-auto-connect-next-button')) { + this._next(); + return true; + } else if ( + target.closest('.edgeless-auto-connect-previous-button') + ) { + this._previous(); + return true; + } + return false; + }) + ); + } + }); + } + + override connectedCallback(): void { + super.connectedCallback(); + this.style.position = 'absolute'; + this.style.top = '0'; + this.style.left = '0'; + this.style.zIndex = '1'; + } + + private _next() { + const { notes } = this; + if (this._index >= notes.length - 1) return; + this._index = this._index + 1; + const bound = Bound.deserialize(notes[this._index].xywh); + this.surface.viewport.setViewportByBound(bound, [80, 80, 80, 80], true); + } + + private _previous() { + const { notes } = this; + if (this._index <= 0) return; + this._index = this._index - 1; + const bound = Bound.deserialize(notes[this._index].xywh); + this.surface.viewport.setViewportByBound(bound, [80, 80, 80, 80], true); + } + + private _navigator(notes: NoteBlockModel[]) { + const { viewport } = this.surface; + const { zoom } = viewport; + const classname = `navigator ${this._index >= 0 ? 'show' : 'hidden'}`; + const note = notes[this._index]; + const bound = Bound.deserialize(note.xywh); + const [left, right] = viewport.toViewCoord(bound.x, bound.y); + const [width, height] = [bound.w * zoom, bound.h * zoom]; + const navigatorStyle = styleMap({ + position: 'absolute', + transform: `translate(${left + width / 2 - 26}px, ${ + right + height + 16 + }px)`, + }); + return html`
+
+ ${AutoConnectLeftIcon} +
+ +
+ ${AutoConnectRightIcon} +
+
`; } protected override render() { @@ -65,9 +190,9 @@ export class EdgelessAutoConnectSequence extends WithDisposable(LitElement) { const { viewport } = this.surface; const { zoom } = viewport; - const notes = this.surface.getblocks(NOTE).filter(note => !note.hidden); + const { notes } = this; - return repeat( + return html`${repeat( notes, note => note.id, (note, index) => { @@ -80,14 +205,20 @@ export class EdgelessAutoConnectSequence extends WithDisposable(LitElement) { right + height - 14 }px)`, }); - return html` -
+
${index + 1}
`; } - ); + )} + ${this._index >= 0 && this._index < notes.length + ? this._navigator(notes) + : nothing} `; } } diff --git a/packages/blocks/src/page-block/edgeless/components/block-portal/edgeless-block-portal.ts b/packages/blocks/src/page-block/edgeless/components/block-portal/edgeless-block-portal.ts index 2d361535747e..72bdf5ee2b72 100644 --- a/packages/blocks/src/page-block/edgeless/components/block-portal/edgeless-block-portal.ts +++ b/packages/blocks/src/page-block/edgeless/components/block-portal/edgeless-block-portal.ts @@ -28,10 +28,12 @@ import type { EdgelessPageBlockComponent } from '../../edgeless-page-block.js'; import { NoteResizeObserver } from '../../utils/note-resize-observer.js'; import { getBackgroundGrid, isNoteBlock } from '../../utils/query.js'; +const { NOTE, IMAGE, FRAME } = EdgelessBlockType; + const portalMap = { - [EdgelessBlockType.FRAME]: 'edgeless-block-portal-frame', - [EdgelessBlockType.NOTE]: 'edgeless-block-portal-note', - [EdgelessBlockType.IMAGE]: 'edgeless-block-portal-image', + [FRAME]: 'edgeless-block-portal-frame', + [NOTE]: 'edgeless-block-portal-note', + [IMAGE]: 'edgeless-block-portal-image', }; @customElement('edgeless-block-portal-container') @@ -210,11 +212,12 @@ export class EdgelessBlockPortalContainer extends WithDisposable( const { surface } = edgeless; if (!surface) return nothing; - const notes = surface.getblocks(EdgelessBlockType.NOTE); - const images = surface.getblocks(EdgelessBlockType.IMAGE); + const notes = surface.getblocks(NOTE); + const images = surface.getblocks(IMAGE); const blocks = [...notes, ...images].sort(surface.compare); const { readonly } = this.edgeless.page; + const showedNotes = surface.getblocks(NOTE).filter(note => !note.hidden); return html`
diff --git a/tests/edgeless/note.spec.ts b/tests/edgeless/note.spec.ts index 940ea184aa02..a4858f30de1f 100644 --- a/tests/edgeless/note.spec.ts +++ b/tests/edgeless/note.spec.ts @@ -51,6 +51,7 @@ import { assertEdgelessNoteBackground, assertEdgelessSelectedRect, assertNativeSelectionRangeCount, + assertNoteSequence, assertNoteXYWH, assertRectEqual, assertRectExist, @@ -729,76 +730,6 @@ test('continuous undo and redo (note block add operation) should work', async ({ expect(count).toBe(4); }); -test('manage note index and hidden status', async ({ page }) => { - await enterPlaygroundRoom(page); - await initEmptyEdgelessState(page); - await switchEditorMode(page); - await initThreeNotes(page); - - // one note comes from `initEmptyEdgelessState` - assertBlockCount(page, 'note', 4); - await waitNextFrame(page); - await page.mouse.click(10, 100); - - // select note-2 - await selectNoteInEdgeless(page, '4'); - expect(await page.locator('.note-status').innerText()).toBe('2'); - - // select note-3 - await selectNoteInEdgeless(page, '6'); - expect(await page.locator('.note-status').innerText()).toBe('3'); - - // select note-4 - await selectNoteInEdgeless(page, '8'); - expect(await page.locator('.note-status').innerText()).toBe('4'); - - // hide note-4 - await page.locator('.note-status-button').click(); - expect(await page.locator('.note-status.hidden').count()).toBe(1); - // reappear note-4 - await page.locator('.note-status-button').click(); - // index of note-4 still be 4 - expect(await page.locator('.note-status').innerText()).toBe('4'); - - // select note-3 and hide - await selectNoteInEdgeless(page, '6'); - await page.locator('.note-status-button').click(); - expect(await page.locator('.note-status.hidden').count()).toBe(1); - - // index of note-2 still 2 - await selectNoteInEdgeless(page, '4'); - expect(await page.locator('.note-status').innerText()).toBe('2'); - - // index of note-4 will be 3 - await selectNoteInEdgeless(page, '8'); - expect(await page.locator('.note-status').innerText()).toBe('3'); - - // switch to editor mode, note-3 will be hidden - await switchEditorMode(page); - expect(await page.locator('affine-note[data-block-id="6"]').count()).toBe(0); - - // switch to edgeless mode, note-3 will be visible - await switchEditorMode(page); - expect(await page.locator('affine-note[data-block-id="6"]').count()).toBe(1); - - // select note-3 and reappear - await selectNoteInEdgeless(page, '6'); - await waitNextFrame(page); - await page.locator('.note-status-button').click(); - - // index of note-2 still 2 - await selectNoteInEdgeless(page, '4'); - expect(await page.locator('.note-status').innerText()).toBe('2'); - - // index of note-3 will be 4 - await selectNoteInEdgeless(page, '6'); - expect(await page.locator('.note-status').innerText()).toBe('4'); - - // index of note-4 will be 3 - await selectNoteInEdgeless(page, '8'); - expect(await page.locator('.note-status').innerText()).toBe('3'); -}); - test('when no visible note block, clicking in page mode will auto add a new note block', async ({ page, }) => { @@ -807,13 +738,13 @@ test('when no visible note block, clicking in page mode will auto add a new note await switchEditorMode(page); assertBlockCount(page, 'note', 1); - + await page.pause(); // select note await selectNoteInEdgeless(page, '2'); - expect(await page.locator('.note-status').innerText()).toBe('1'); - expect(await page.locator('affine-note').count()).toBe(1); + await assertNoteSequence(page, '1'); + await assertBlockCount(page, 'note', 1); // hide note - await page.locator('.note-status-button').click(); + await page.locator('edgeless-change-note-button').click(); await switchEditorMode(page); let note = await page.evaluate(() => { diff --git a/tests/utils/asserts.ts b/tests/utils/asserts.ts index a4128b32af02..88ea9ce8a1c1 100644 --- a/tests/utils/asserts.ts +++ b/tests/utils/asserts.ts @@ -962,3 +962,10 @@ export async function assertNotHasClass(locator: Locator, className: string) { (await locator.getAttribute('class'))?.split(' ').includes(className) ).toEqual(false); } + +export async function assertNoteSequence(page: Page, expected: string) { + const actual = await page + .locator('.edgeless-auto-connect-sequence') + .innerText(); + expect(expected).toBe(actual); +} From 11f4ed7c2ea0e89e76e5a333ef28295aab86b034 Mon Sep 17 00:00:00 2001 From: regischen Date: Tue, 31 Oct 2023 10:30:27 +0800 Subject: [PATCH 05/10] fix: test --- tests/edgeless/note.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/edgeless/note.spec.ts b/tests/edgeless/note.spec.ts index a4858f30de1f..84ac4670cd56 100644 --- a/tests/edgeless/note.spec.ts +++ b/tests/edgeless/note.spec.ts @@ -738,7 +738,6 @@ test('when no visible note block, clicking in page mode will auto add a new note await switchEditorMode(page); assertBlockCount(page, 'note', 1); - await page.pause(); // select note await selectNoteInEdgeless(page, '2'); await assertNoteSequence(page, '1'); From 19e1e329864330225e7fd0369334ad45c6240f1a Mon Sep 17 00:00:00 2001 From: regischen Date: Tue, 31 Oct 2023 15:47:19 +0800 Subject: [PATCH 06/10] test: add --- .../edgeless-auto-connect-sequence.ts | 14 ++++++- tests/edgeless/auto-connect.spec.ts | 37 +++++++++++++++++++ tests/utils/actions/edgeless.ts | 5 ++- 3 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 tests/edgeless/auto-connect.spec.ts diff --git a/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-sequence.ts b/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-sequence.ts index 4ffe3c68b5e9..e274f7732562 100644 --- a/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-sequence.ts +++ b/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-sequence.ts @@ -148,7 +148,12 @@ export class EdgelessAutoConnectSequence extends WithDisposable( const { notes } = this; if (this._index >= notes.length - 1) return; this._index = this._index + 1; - const bound = Bound.deserialize(notes[this._index].xywh); + const note = notes[this._index]; + const bound = Bound.deserialize(note.xywh); + this.surface.edgeless.selectionManager.setSelection({ + elements: [note.id], + editing: false, + }); this.surface.viewport.setViewportByBound(bound, [80, 80, 80, 80], true); } @@ -156,7 +161,12 @@ export class EdgelessAutoConnectSequence extends WithDisposable( const { notes } = this; if (this._index <= 0) return; this._index = this._index - 1; - const bound = Bound.deserialize(notes[this._index].xywh); + const note = notes[this._index]; + const bound = Bound.deserialize(note.xywh); + this.surface.edgeless.selectionManager.setSelection({ + elements: [note.id], + editing: false, + }); this.surface.viewport.setViewportByBound(bound, [80, 80, 80, 80], true); } diff --git a/tests/edgeless/auto-connect.spec.ts b/tests/edgeless/auto-connect.spec.ts new file mode 100644 index 000000000000..20f87c3b544f --- /dev/null +++ b/tests/edgeless/auto-connect.spec.ts @@ -0,0 +1,37 @@ +import { type Page } from '@playwright/test'; + +import { + addNote, + edgelessCommonSetup, + getSelectedBound, + selectNoteInEdgeless, +} from '../utils/actions/edgeless.js'; +import { assertSelectedBound } from '../utils/asserts.js'; +import { test } from '../utils/playwright.js'; + +test.describe('auto-connect', () => { + async function init(page: Page) { + await edgelessCommonSetup(page); + } + test('navigator', async ({ page }) => { + await init(page); + const id1 = await addNote(page, 'page1', 100, 100); + await addNote(page, 'page2', 200, 300); + await addNote(page, 'page3', 300, 500); + await page.mouse.click(200, 50); + await selectNoteInEdgeless(page, id1); + const bound = await getSelectedBound(page, 0); + await page.locator('.edgeless-auto-connect-sequence').nth(0).click(); + await assertSelectedBound(page, bound); + + await page.locator('.edgeless-auto-connect-next-button').click(); + bound[0] += 100; + bound[1] += 200; + await assertSelectedBound(page, bound); + + await page.locator('.edgeless-auto-connect-next-button').click(); + bound[0] += 100; + bound[1] += 200; + await assertSelectedBound(page, bound); + }); +}); diff --git a/tests/utils/actions/edgeless.ts b/tests/utils/actions/edgeless.ts index 52b860e6063f..d5ef732112a4 100644 --- a/tests/utils/actions/edgeless.ts +++ b/tests/utils/actions/edgeless.ts @@ -1117,7 +1117,10 @@ export async function getConnectorPath(page: Page, index = 0) { ); } -export async function getSelectedBound(page: Page, index = 0) { +export async function getSelectedBound( + page: Page, + index = 0 +): Promise<[number, number, number, number]> { return await page.evaluate( ([index]) => { const container = document.querySelector('affine-edgeless-page'); From 544833771a55e6b1f53b9c94e5bf2a1726c3fb26 Mon Sep 17 00:00:00 2001 From: Yifeng Wang Date: Wed, 1 Nov 2023 15:30:35 +0800 Subject: [PATCH 07/10] style: naming --- .../auto-connect/edgeless-auto-connect-sequence.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-sequence.ts b/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-sequence.ts index e274f7732562..5f015891af2d 100644 --- a/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-sequence.ts +++ b/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-sequence.ts @@ -121,12 +121,12 @@ export class EdgelessAutoConnectSequence extends WithDisposable( this._index = index === this._index ? -1 : index; return true; } else if (target.closest('.edgeless-auto-connect-next-button')) { - this._next(); + this._navigateToNext(); return true; } else if ( target.closest('.edgeless-auto-connect-previous-button') ) { - this._previous(); + this._navigateToPrev(); return true; } return false; @@ -144,7 +144,7 @@ export class EdgelessAutoConnectSequence extends WithDisposable( this.style.zIndex = '1'; } - private _next() { + private _navigateToNext() { const { notes } = this; if (this._index >= notes.length - 1) return; this._index = this._index + 1; @@ -157,7 +157,7 @@ export class EdgelessAutoConnectSequence extends WithDisposable( this.surface.viewport.setViewportByBound(bound, [80, 80, 80, 80], true); } - private _previous() { + private _navigateToPrev() { const { notes } = this; if (this._index <= 0) return; this._index = this._index - 1; @@ -170,7 +170,7 @@ export class EdgelessAutoConnectSequence extends WithDisposable( this.surface.viewport.setViewportByBound(bound, [80, 80, 80, 80], true); } - private _navigator(notes: NoteBlockModel[]) { + private _NavigatorComponent(notes: NoteBlockModel[]) { const { viewport } = this.surface; const { zoom } = viewport; const classname = `navigator ${this._index >= 0 ? 'show' : 'hidden'}`; @@ -227,7 +227,7 @@ export class EdgelessAutoConnectSequence extends WithDisposable( } )} ${this._index >= 0 && this._index < notes.length - ? this._navigator(notes) + ? this._NavigatorComponent(notes) : nothing} `; } } From 1c78466b48db49f3c2ccd882a6de8074c7c31500 Mon Sep 17 00:00:00 2001 From: Yifeng Wang Date: Wed, 1 Nov 2023 15:41:10 +0800 Subject: [PATCH 08/10] style: naming --- .../auto-connect/edgeless-auto-connect-line.ts | 14 +++++++------- .../block-portal/edgeless-block-portal.ts | 6 +++--- .../edgeless/components/note-status/index.ts | 2 +- .../page-block/edgeless/edgeless-page-block.ts | 4 ++-- .../src/page-block/edgeless/frame-manager.ts | 2 +- .../blocks/src/surface-block/surface-block.ts | 16 ++++++++-------- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts b/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts index ebda5334980d..6ec606e583c0 100644 --- a/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts +++ b/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts @@ -48,7 +48,7 @@ export class EdgelessAutoConnectLine extends WithDisposable(LitElement) { if (!this.show) return nothing; const { viewport } = this.surface; - const notes = this.surface.getblocks(NOTE).filter(note => !note.hidden); + const notes = this.surface.getBlocks(NOTE).filter(note => !note.hidden); const points: [IVec, IVec][] = []; for (let i = 1; i < notes.length; i++) { const last = notes[i - 1]; @@ -97,11 +97,11 @@ export class EdgelessAutoConnectLine extends WithDisposable(LitElement) { const newWidth = width + expand; const newHeight = height + expand; - const newstart = Vec.add(Vec.pointOffset(lineStart, lineEnd, 16), [ + const newStart = Vec.add(Vec.pointOffset(lineStart, lineEnd, 16), [ expand / 2, expand / 2, ]); - const newend = Vec.add(Vec.pointOffset(lineEnd, lineStart, 16), [ + const newEnd = Vec.add(Vec.pointOffset(lineEnd, lineStart, 16), [ expand / 2, expand / 2, ]); @@ -122,10 +122,10 @@ export class EdgelessAutoConnectLine extends WithDisposable(LitElement) { !note.hidden); + const showedNotes = surface.getBlocks(NOTE).filter(note => !note.hidden); return html`
b.id === noteId); + const noteBlock = this.surface.getBlocks(NOTE).find(b => b.id === noteId); assertExists(noteBlock); requestAnimationFrame(() => { @@ -517,7 +517,7 @@ export class EdgelessPageBlockComponent extends BlockElement< const bounds = []; Object.values(EdgelessBlockType).forEach(edgelessBlock => { - this.surface.getblocks(edgelessBlock).forEach(block => { + this.surface.getBlocks(edgelessBlock).forEach(block => { bounds.push(Bound.deserialize(block.xywh)); }); }); diff --git a/packages/blocks/src/page-block/edgeless/frame-manager.ts b/packages/blocks/src/page-block/edgeless/frame-manager.ts index d1d42bfcfaf8..c40eef624b37 100644 --- a/packages/blocks/src/page-block/edgeless/frame-manager.ts +++ b/packages/blocks/src/page-block/edgeless/frame-manager.ts @@ -42,7 +42,7 @@ export class EdgelessFrameManager { } get frames() { - return this._edgeless.surface.getblocks(EdgelessBlockType.FRAME); + return this._edgeless.surface.getBlocks(EdgelessBlockType.FRAME); } selectFrame(eles: Selectable[]) { diff --git a/packages/blocks/src/surface-block/surface-block.ts b/packages/blocks/src/surface-block/surface-block.ts index fdb9bf08cf00..85dab574bd26 100644 --- a/packages/blocks/src/surface-block/surface-block.ts +++ b/packages/blocks/src/surface-block/surface-block.ts @@ -184,7 +184,7 @@ export class SurfaceBlockComponent extends BlockElement { return this.root.mode === 'edgeless'; } - getblocks(flavour: T) { + getBlocks(flavour: T) { let parent: BaseBlockModel = this.model; if (flavour === EdgelessBlockType.NOTE) { parent = this.edgeless.model; @@ -195,7 +195,7 @@ export class SurfaceBlockComponent extends BlockElement { } getSortedBlocks(flavour: T) { - return this.getblocks(flavour).sort(this.compare); + return this.getBlocks(flavour).sort(this.compare); } getGroupParent(element: id | EdgelessElement) { @@ -214,18 +214,18 @@ export class SurfaceBlockComponent extends BlockElement { get blocks() { return [ - ...this.getblocks(EdgelessBlockType.FRAME), - ...this.getblocks(EdgelessBlockType.NOTE), - ...this.getblocks(EdgelessBlockType.IMAGE), + ...this.getBlocks(EdgelessBlockType.FRAME), + ...this.getBlocks(EdgelessBlockType.NOTE), + ...this.getBlocks(EdgelessBlockType.IMAGE), ]; } get sortedBlocks() { return [ - ...this.getblocks(EdgelessBlockType.FRAME).sort(this.compare), + ...this.getBlocks(EdgelessBlockType.FRAME).sort(this.compare), ...[ - ...this.getblocks(EdgelessBlockType.NOTE), - ...this.getblocks(EdgelessBlockType.IMAGE), + ...this.getBlocks(EdgelessBlockType.NOTE), + ...this.getBlocks(EdgelessBlockType.IMAGE), ].sort(this.compare), ]; } From da26dd66169124d29b4aeb4dbf76d5a747252727 Mon Sep 17 00:00:00 2001 From: Yifeng Wang Date: Wed, 1 Nov 2023 15:49:15 +0800 Subject: [PATCH 09/10] refactor: component naming --- ...ct-sequence.ts => edgeless-index-label.ts} | 22 ++++++------------- .../block-portal/edgeless-block-portal.ts | 6 ++--- tests/edgeless/auto-connect.spec.ts | 2 +- tests/utils/asserts.ts | 4 +--- 4 files changed, 12 insertions(+), 22 deletions(-) rename packages/blocks/src/page-block/edgeless/components/auto-connect/{edgeless-auto-connect-sequence.ts => edgeless-index-label.ts} (91%) diff --git a/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-sequence.ts b/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-index-label.ts similarity index 91% rename from packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-sequence.ts rename to packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-index-label.ts index 5f015891af2d..7ffe24035dad 100644 --- a/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-sequence.ts +++ b/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-index-label.ts @@ -13,12 +13,10 @@ import { Bound } from '../../../../surface-block/index.js'; import type { SurfaceBlockComponent } from '../../../../surface-block/surface-block.js'; import { isNoteBlock } from '../../utils/query.js'; -@customElement('edgeless-auto-connect-sequence') -export class EdgelessAutoConnectSequence extends WithDisposable( - ShadowlessElement -) { +@customElement('edgeless-index-label') +export class EdgelessIndexLabel extends WithDisposable(ShadowlessElement) { static override styles = css` - .edgeless-auto-connect-sequence { + .edgeless-index-label { font-size: 15px; text-align: center; height: 24px; @@ -113,10 +111,8 @@ export class EdgelessAutoConnectSequence extends WithDisposable( const { raw } = event; const target = raw.target as HTMLElement; if (!target) return false; - if (target.closest('.edgeless-auto-connect-sequence')) { - const ele = target.closest( - '.edgeless-auto-connect-sequence' - ) as Element; + if (target.closest('.edgeless-index-label')) { + const ele = target.closest('.edgeless-index-label') as Element; const index = Number(ele.getAttribute('index')); this._index = index === this._index ? -1 : index; return true; @@ -216,11 +212,7 @@ export class EdgelessAutoConnectSequence extends WithDisposable( }px)`, }); return html` -
+
${index + 1}
`; @@ -234,6 +226,6 @@ export class EdgelessAutoConnectSequence extends WithDisposable( declare global { interface HTMLElementTagNameMap { - 'edgeless-auto-connect-sequence': EdgelessAutoConnectSequence; + 'edgeless-index-label': EdgelessIndexLabel; } } diff --git a/packages/blocks/src/page-block/edgeless/components/block-portal/edgeless-block-portal.ts b/packages/blocks/src/page-block/edgeless/components/block-portal/edgeless-block-portal.ts index 5be494326271..103bca3e4e32 100644 --- a/packages/blocks/src/page-block/edgeless/components/block-portal/edgeless-block-portal.ts +++ b/packages/blocks/src/page-block/edgeless/components/block-portal/edgeless-block-portal.ts @@ -6,7 +6,7 @@ import '../rects/edgeless-selected-rect.js'; import '../rects/edgeless-hover-rect.js'; import '../rects/edgeless-dragging-area-rect.js'; import '../note-status/index.js'; -import '../../components/auto-connect/edgeless-auto-connect-sequence.js'; +import '../../components/auto-connect/edgeless-index-label.js'; import '../../components/auto-connect/edgeless-auto-connect-line.js'; import { assertExists, throttle } from '@blocksuite/global/utils'; @@ -249,11 +249,11 @@ export class EdgelessBlockPortalContainer extends WithDisposable( .edgeless=${edgeless} > - + > `; } diff --git a/tests/edgeless/auto-connect.spec.ts b/tests/edgeless/auto-connect.spec.ts index 20f87c3b544f..7c45464cbd7d 100644 --- a/tests/edgeless/auto-connect.spec.ts +++ b/tests/edgeless/auto-connect.spec.ts @@ -21,7 +21,7 @@ test.describe('auto-connect', () => { await page.mouse.click(200, 50); await selectNoteInEdgeless(page, id1); const bound = await getSelectedBound(page, 0); - await page.locator('.edgeless-auto-connect-sequence').nth(0).click(); + await page.locator('.edgeless-index-label').nth(0).click(); await assertSelectedBound(page, bound); await page.locator('.edgeless-auto-connect-next-button').click(); diff --git a/tests/utils/asserts.ts b/tests/utils/asserts.ts index 65e0a7fd2ef0..8f9f889c862c 100644 --- a/tests/utils/asserts.ts +++ b/tests/utils/asserts.ts @@ -965,8 +965,6 @@ export async function assertNotHasClass(locator: Locator, className: string) { } export async function assertNoteSequence(page: Page, expected: string) { - const actual = await page - .locator('.edgeless-auto-connect-sequence') - .innerText(); + const actual = await page.locator('.edgeless-index-label').innerText(); expect(expected).toBe(actual); } From 6a7a38441accf4e82dde27eccea2c7463ff7e5de Mon Sep 17 00:00:00 2001 From: Yifeng Wang Date: Wed, 1 Nov 2023 15:56:02 +0800 Subject: [PATCH 10/10] style: naming --- .../edgeless-auto-connect-line.ts | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts b/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts index 6ec606e583c0..61be31d243ac 100644 --- a/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts +++ b/packages/blocks/src/page-block/edgeless/components/auto-connect/edgeless-auto-connect-line.ts @@ -9,6 +9,7 @@ import { Bound, type IVec, Vec } from '../../../../surface-block/index.js'; import type { SurfaceBlockComponent } from '../../../../surface-block/surface-block.js'; import { isNoteBlock } from '../../utils/query.js'; +const EXPAND_OFFSET = 20; const { NOTE } = EdgelessBlockType; @customElement('edgeless-auto-connect-line') @@ -62,7 +63,6 @@ export class EdgelessAutoConnectLine extends WithDisposable(LitElement) { ); points.push([start, end]); } - const expand = 20; return repeat( points, @@ -72,9 +72,9 @@ export class EdgelessAutoConnectLine extends WithDisposable(LitElement) { const height = Math.abs(start[1] - end[1]); const style = styleMap({ position: 'absolute', - transform: `translate(${Math.min(start[0], end[0]) - expand / 2}px, ${ - Math.min(start[1], end[1]) - expand / 2 - }px)`, + transform: `translate(${ + Math.min(start[0], end[0]) - EXPAND_OFFSET / 2 + }px, ${Math.min(start[1], end[1]) - EXPAND_OFFSET / 2}px)`, }); const lineStart = [0, 0]; const lineEnd = [width, height]; @@ -94,16 +94,16 @@ export class EdgelessAutoConnectLine extends WithDisposable(LitElement) { lineEnd[1] = height; } - const newWidth = width + expand; - const newHeight = height + expand; + const newWidth = width + EXPAND_OFFSET; + const newHeight = height + EXPAND_OFFSET; const newStart = Vec.add(Vec.pointOffset(lineStart, lineEnd, 16), [ - expand / 2, - expand / 2, + EXPAND_OFFSET / 2, + EXPAND_OFFSET / 2, ]); const newEnd = Vec.add(Vec.pointOffset(lineEnd, lineStart, 16), [ - expand / 2, - expand / 2, + EXPAND_OFFSET / 2, + EXPAND_OFFSET / 2, ]); return svg`