Skip to content

Commit

Permalink
refactor(edgeless): change surface selection to multi-instance (#5852)
Browse files Browse the repository at this point in the history
  • Loading branch information
doouding authored Dec 26, 2023
1 parent 685898e commit 8b72dc1
Show file tree
Hide file tree
Showing 34 changed files with 261 additions and 188 deletions.
12 changes: 8 additions & 4 deletions packages/block-std/src/selection/variants/surface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ export class SurfaceSelection extends BaseSelection {
readonly elements: string[];
readonly editing: boolean;

constructor(elements: string[], editing: boolean) {
super({ path: [] });
constructor(path: string[], elements: string[], editing: boolean) {
super({ path });

this.elements = elements;
this.editing = editing;
}
Expand All @@ -40,17 +41,20 @@ export class SurfaceSelection extends BaseSelection {
override toJSON(): Record<string, unknown> {
return {
type: 'surface',
path: this.path,
elements: this.elements,
blockId: this.blockId,
editing: this.editing,
};
}

static override fromJSON(
json: Record<string, unknown> | { elements: string[]; editing: boolean }
json:
| Record<string, unknown>
| { path: string[]; elements: string[]; editing: boolean }
): SurfaceSelection {
SurfaceSelectionSchema.parse(json);
return new SurfaceSelection(
json.path as string[],
json.elements as string[],
json.editing as boolean
);
Expand Down
2 changes: 1 addition & 1 deletion packages/blocks/src/_common/mind-map/draw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export function drawMindMap(
) {
const { shapeIds, connectorIds } = drawAllNode(mindMap, surfaceElement);
const { edgeless } = surfaceElement;
edgeless.selectionManager.setSelection({
edgeless.selectionManager.set({
elements: [...shapeIds, ...connectorIds],
editing: false,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ export class EdgelessAutoCompletePanel extends WithDisposable(LitElement) {
});

mountShapeTextEditor(surface.pickById(id) as ShapeElement, this.edgeless);
edgeless.selectionManager.setSelection({
edgeless.selectionManager.set({
elements: [id],
editing: true,
});
Expand Down Expand Up @@ -331,7 +331,7 @@ export class EdgelessAutoCompletePanel extends WithDisposable(LitElement) {
surface.updateElement<CanvasElementType.CONNECTOR>(this.connector.id, {
target: { id, position },
});
this.edgeless.selectionManager.setSelection({
this.edgeless.selectionManager.set({
elements: [id],
editing: true,
});
Expand Down Expand Up @@ -366,7 +366,7 @@ export class EdgelessAutoCompletePanel extends WithDisposable(LitElement) {
surface.updateElement<CanvasElementType.CONNECTOR>(this.connector.id, {
target: { id, position },
});
edgeless.selectionManager.setSelection({
edgeless.selectionManager.set({
elements: [frame.id],
editing: false,
});
Expand All @@ -384,7 +384,7 @@ export class EdgelessAutoCompletePanel extends WithDisposable(LitElement) {
surface.updateElement<CanvasElementType.CONNECTOR>(this.connector.id, {
target: { id, position },
});
this.edgeless.selectionManager.setSelection({
this.edgeless.selectionManager.set({
elements: [id],
editing: false,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ export class EdgelessAutoComplete extends WithDisposable(LitElement) {
});
}

this.edgeless.selectionManager.setSelection({
this.edgeless.selectionManager.set({
elements: [id],
editing: true,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ export class EdgelessIndexLabel extends WithDisposable(ShadowlessElement) {
this._index = this._index + 1;
const element = elements[this._index];
const bound = Bound.deserialize(element.xywh);
this.surface.edgeless.selectionManager.setSelection({
this.surface.edgeless.selectionManager.set({
elements: [element.id],
editing: false,
});
Expand All @@ -208,7 +208,7 @@ export class EdgelessIndexLabel extends WithDisposable(ShadowlessElement) {
this._index = this._index - 1;
const element = elements[this._index];
const bound = Bound.deserialize(element.xywh);
this.surface.edgeless.selectionManager.setSelection({
this.surface.edgeless.selectionManager.set({
elements: [element.id],
editing: false,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,10 @@ export class EdgelessBlockPortalContainer extends WithDisposable(
);

_disposables.add(
edgeless.selectionManager.slots.updated.on(e => {
if (e.elements.length === 0 || e.editing) {
edgeless.selectionManager.slots.updated.on(() => {
const selection = edgeless.selectionManager;

if (selection.selectedIds.length === 0 || selection.editing) {
this._toolbarVisible = false;
} else {
this._toolbarVisible = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,11 @@ export class EdgeelssFrameTitle extends WithDisposable(ShadowlessElement) {
);

_disposables.add(
edgeless.selectionManager.slots.updated.on(({ editing, elements }) => {
if (elements[0] === this.frame.id && editing) {
edgeless.selectionManager.slots.updated.on(() => {
if (
edgeless.selectionManager.selectedIds[0] === this.frame.id &&
edgeless.selectionManager.editing
) {
this._editing = true;
} else {
this._editing = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,10 @@ export class EdgelessNoteMask extends WithDisposable(ShadowlessElement) {

override render() {
const selected =
this.edgeless.selectionManager.state.editing &&
this.edgeless.selectionManager.state.elements.includes(this.model.id);
this.edgeless.selectionManager.has(this.model.id) &&
this.edgeless.selectionManager.selections.some(
sel => sel.elements.includes(this.model.id) && sel.editing
);

const style = {
position: 'absolute',
Expand Down Expand Up @@ -107,8 +109,8 @@ export class EdgelessBlockPortalNote extends EdgelessPortalBase<NoteBlockModel>
private _handleEditingTransition() {
const selection = this.surface.edgeless.selectionManager;
this._disposables.add(
selection.slots.updated.on(({ elements, editing }) => {
if (elements.includes(this.model.id) && editing) {
selection.slots.updated.on(selections => {
if (selection.has(this.model.id) && selections?.[0].editing) {
this._editing = true;
} else {
this._editing = false;
Expand Down Expand Up @@ -148,10 +150,7 @@ export class EdgelessBlockPortalNote extends EdgelessPortalBase<NoteBlockModel>
}

private _hovered() {
if (
!this._isHover &&
this.edgeless.selectionManager.isSelected(this.model.id)
) {
if (!this._isHover && this.edgeless.selectionManager.has(this.model.id)) {
this._isHover = true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ export class EdgelessComponentToolbar extends WithDisposable(LitElement) {

private _updateOnSelectedChange = (element: string | { id: string }) => {
const id = typeof element === 'string' ? element : element.id;
if (this.selection.isSelected(id)) {
if (this.selection.has(id)) {
this.requestUpdate();
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ export class EdgelessMoreButton extends WithDisposable(LitElement) {
this.page.captureSync();
deleteElements(this.surface, this.selection.elements);

this.selection.setSelection({
this.selection.set({
elements: [],
editing: false,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,7 @@ export class EdgelessSelectedRect extends WithDisposable(LitElement) {

const id = typeof element === 'string' ? element : element.id;

if (this._resizeManager.bounds.has(id) || this.selection.isSelected(id))
if (this._resizeManager.bounds.has(id) || this.selection.has(id))
this._updateSelectedRect();
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export class EdgelessFrameTitleEditor extends WithDisposable(
private _unmount() {
// dispose in advance to avoid execute `this.remove()` twice
this.disposables.dispose();
this.edgeless.selectionManager.setSelection({
this.edgeless.selectionManager.set({
elements: [],
editing: false,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export class EdgelessGroupTitleEditor extends WithDisposable(
// dispose in advance to avoid execute `this.remove()` twice
this.disposables.dispose();
this.group.showTitle = true;
this.edgeless.selectionManager.setSelection({
this.edgeless.selectionManager.set({
elements: [this.group.id],
editing: false,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
);
this.richText.style.minHeight = `${containerHeight}px`;
}
this.edgeless.selectionManager.setSelection({
this.edgeless.selectionManager.set({
elements: [this.element.id],
editing: true,
});
Expand Down Expand Up @@ -138,7 +138,7 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
this.element.textDisplay = true;

this.remove();
this.edgeless.selectionManager.setSelection({
this.edgeless.selectionManager.set({
elements: [],
editing: false,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ export class EdgelessTextEditor extends WithDisposable(ShadowlessElement) {
deleteElements(edgeless.surface, [element]);
}

edgeless.selectionManager.setSelection({
edgeless.selectionManager.set({
elements: [],
editing: false,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export class EdgelessFrameMenu extends WithDisposable(LitElement) {
const frame = edgeless.surface.pickById(id);
assertExists(frame);
edgeless.tools.setEdgelessTool({ type: 'default' });
edgeless.selectionManager.setSelection({
edgeless.selectionManager.set({
elements: [frame.id],
editing: false,
});
Expand Down
34 changes: 19 additions & 15 deletions packages/blocks/src/page-block/edgeless/controllers/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,11 @@ export class EdgelessClipboardController extends PageClipboard {
this.host.handleEvent(
'copy',
ctx => {
const surfaceSelection = this.selectionManager.state;
const elements = surfaceSelection.elements;
if (elements.length === 0) return false;
const { selections, selectedIds } = this.selectionManager;

this._onCopy(ctx, surfaceSelection).catch(console.error);
if (selectedIds.length === 0) return false;

this._onCopy(ctx, selections).catch(console.error);
return;
},
{ global: true }
Expand Down Expand Up @@ -147,7 +147,7 @@ export class EdgelessClipboardController extends PageClipboard {

private _onCopy = async (
_context: UIEventStateContext,
surfaceSelection: SurfaceSelection
surfaceSelection: SurfaceSelection[]
) => {
const event = _context.get('clipboardState').raw;
event.preventDefault();
Expand All @@ -156,8 +156,9 @@ export class EdgelessClipboardController extends PageClipboard {
this.surface,
this.selectionManager.elements
);

// when note active, handle copy like page mode
if (surfaceSelection.editing) {
if (surfaceSelection[0] && surfaceSelection[0].editing) {
// use build-in copy handler in rich-text when copy in surface text element
if (isCanvasElementWithText(elements[0])) return;
this.onPageCopy(_context);
Expand Down Expand Up @@ -185,8 +186,9 @@ export class EdgelessClipboardController extends PageClipboard {
const event = _context.get('clipboardState').raw;
event.preventDefault();

const { state, elements } = this.selectionManager;
if (state.editing) {
const { selections, elements } = this.selectionManager;

if (selections[0]?.editing) {
// use build-in paste handler in rich-text when paste in surface text element
if (isCanvasElementWithText(elements[0])) return;
this.onPagePaste(_context);
Expand Down Expand Up @@ -227,7 +229,7 @@ export class EdgelessClipboardController extends PageClipboard {
},
this.surface.model.id
);
this.selectionManager.setSelection({
this.selectionManager.set({
editing: false,
elements: [id],
});
Expand All @@ -241,14 +243,16 @@ export class EdgelessClipboardController extends PageClipboard {
};

private _onCut = (_context: UIEventStateContext) => {
const { state, elements } = this.selectionManager;
if (state.elements.length === 0) return;
const { selections, elements } = this.selectionManager;

if (elements.length === 0) return;

const event = _context.get('clipboardState').event;
event.preventDefault();

this._onCopy(_context, state).catch(console.error);
if (state.editing) {
this._onCopy(_context, selections).catch(console.error);

if (selections[0]?.editing) {
// use build-in cut handler in rich-text when cut in surface text element
if (isCanvasElementWithText(elements[0])) return;
this.onPageCut(_context);
Expand All @@ -259,7 +263,7 @@ export class EdgelessClipboardController extends PageClipboard {
deleteElements(this.surface, elements);
});

this.selectionManager.setSelection({
this.selectionManager.set({
editing: false,
elements: [],
});
Expand Down Expand Up @@ -441,7 +445,7 @@ export class EdgelessClipboardController extends PageClipboard {
}),
];

this.selectionManager.setSelection({
this.selectionManager.set({
editing: false,
elements: newSelected,
});
Expand Down
Loading

1 comment on commit 8b72dc1

@vercel
Copy link

@vercel vercel bot commented on 8b72dc1 Dec 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

blocksuite – ./packages/playground

blocksuite-git-master-toeverything.vercel.app
try-blocksuite.vercel.app
blocksuite-toeverything.vercel.app

Please sign in to comment.