feat(editor): replace slot with rxjs subject (#10768)

This commit is contained in:
Mirone
2025-03-12 11:29:24 +09:00
committed by GitHub
parent 19f978d9aa
commit cd63e0ed8b
302 changed files with 1405 additions and 1251 deletions
+3 -2
View File
@@ -53,7 +53,8 @@
"@blocksuite/global": "workspace:*",
"@blocksuite/inline": "workspace:*",
"@blocksuite/store": "workspace:*",
"@blocksuite/sync": "workspace:*"
"@blocksuite/sync": "workspace:*",
"rxjs": "^7.8.1"
},
"exports": {
".": "./src/index.ts",
@@ -67,7 +68,7 @@
"./global/di": "./src/global/di.ts",
"./global/types": "./src/global/types.ts",
"./global/gfx": "./src/global/gfx.ts",
"./global/slot": "./src/global/slot.ts",
"./global/disposable": "./src/global/disposable.ts",
"./global/lit": "./src/global/lit.ts",
"./store": "./src/store/index.ts",
"./store/test": "./src/store/test.ts",
@@ -0,0 +1 @@
export * from '@blocksuite/global/disposable';
-1
View File
@@ -1 +0,0 @@
export * from '@blocksuite/global/slot';
@@ -31,6 +31,7 @@
"file-type": "^20.0.0",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"rxjs": "^7.8.1",
"zod": "^3.23.8"
},
"exports": {
@@ -112,7 +112,7 @@ export class AttachmentBlockComponent extends CaptionedBlockComponent<Attachment
});
}
this.model.propsUpdated.on(({ key }) => {
this.model.propsUpdated.subscribe(({ key }) => {
if (key === 'sourceId') {
// Reset the blob url when the sourceId is changed
if (this.blobUrl) {
@@ -22,14 +22,14 @@ export class AttachmentEdgelessBlockComponent extends toGfxBlockComponent(
super.connectedCallback();
this._disposables.add(
this.slots.elementResizeStart.on(() => {
this.slots.elementResizeStart.subscribe(() => {
this._isResizing = true;
this._showOverlay = true;
})
);
this._disposables.add(
this.slots.elementResizeEnd.on(() => {
this.slots.elementResizeEnd.subscribe(() => {
this._isResizing = false;
this._showOverlay =
this._isResizing || this._isDragging || !this.selected$.peek();
@@ -28,6 +28,7 @@
"@toeverything/theme": "^1.1.12",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"rxjs": "^7.8.1",
"yjs": "^13.6.23",
"zod": "^3.23.8"
},
@@ -62,7 +62,7 @@ export class BookmarkBlockComponent extends CaptionedBlockComponent<BookmarkBloc
}
this.disposables.add(
this.model.propsUpdated.on(({ key }) => {
this.model.propsUpdated.subscribe(({ key }) => {
if (key === 'url') {
this.refreshData();
}
@@ -41,7 +41,7 @@ export class BookmarkCard extends WithDisposable(ShadowlessElement) {
super.connectedCallback();
this.disposables.add(
this.bookmark.model.propsUpdated.on(() => {
this.bookmark.model.propsUpdated.subscribe(() => {
this.requestUpdate();
})
);
@@ -32,6 +32,7 @@
"emoji-mart": "^5.6.0",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"rxjs": "^7.8.1",
"zod": "^3.23.8"
},
"exports": {
@@ -30,6 +30,7 @@
"@types/mdast": "^4.0.4",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"rxjs": "^7.8.1",
"shiki": "^3.0.0",
"zod": "^3.23.8"
},
@@ -14,7 +14,7 @@ import {
Clipboard,
type UIEventHandler,
} from '@blocksuite/block-std';
import { DisposableGroup } from '@blocksuite/global/slot';
import { DisposableGroup } from '@blocksuite/global/disposable';
export class CodeClipboardController {
private _clipboard!: Clipboard;
@@ -31,6 +31,7 @@
"@types/mdast": "^4.0.4",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"rxjs": "^7.8.1",
"zod": "^3.23.8"
},
"exports": {
@@ -1,5 +1,5 @@
import type { PropertyMetaConfig } from '@blocksuite/data-view';
import type { Disposable } from '@blocksuite/global/slot';
import type { DisposableMember } from '@blocksuite/global/disposable';
import type { Block, BlockModel } from '@blocksuite/store';
type PropertyMeta<
@@ -14,7 +14,7 @@ type PropertyMeta<
setColumnData?: (block: T, data: ColumnData) => void;
get: (block: T) => Value;
set?: (block: T, value: Value) => void;
updated: (block: T, callback: () => void) => Disposable;
updated: (block: T, callback: () => void) => DisposableMember;
};
export type BlockMeta<T extends BlockModel = BlockModel> = {
selector: (block: Block) => boolean;
@@ -39,7 +39,7 @@ todoMeta.addProperty({
block.checked = value ?? false;
},
updated: (block, callback) => {
return block.propsUpdated.on(({ key }) => {
return block.propsUpdated.subscribe(({ key }) => {
if (key === 'checked') {
callback();
}
@@ -53,7 +53,7 @@ todoMeta.addProperty({
metaConfig: propertyPresets.textPropertyConfig,
get: block => block.doc.meta?.title ?? '',
updated: (block, callback) => {
return block.doc.workspace.slots.docListUpdated.on(() => {
return block.doc.workspace.slots.docListUpdated.subscribe(() => {
callback();
});
},
@@ -11,8 +11,8 @@ import type { EditorHost } from '@blocksuite/block-std';
import { DataSourceBase, type PropertyMetaConfig } from '@blocksuite/data-view';
import { propertyPresets } from '@blocksuite/data-view/property-presets';
import { BlockSuiteError } from '@blocksuite/global/exceptions';
import { Slot } from '@blocksuite/global/slot';
import type { Block, Store } from '@blocksuite/store';
import { Subject } from 'rxjs';
import type { BlockMeta } from './block-meta/base.js';
import { blockMetaMap } from './block-meta/index.js';
@@ -37,7 +37,7 @@ export class BlockQueryDataSource extends DataSourceBase {
docDisposeMap = new Map<string, () => void>();
slots = {
update: new Slot(),
update: new Subject(),
};
private get blocks() {
@@ -83,13 +83,13 @@ export class BlockQueryDataSource extends DataSourceBase {
this.workspace.docs.forEach(doc => {
this.listenToDoc(doc.getStore());
});
this.workspace.slots.docCreated.on(id => {
this.workspace.slots.docCreated.subscribe(id => {
const doc = this.workspace.getDoc(id);
if (doc) {
this.listenToDoc(doc);
}
});
this.workspace.slots.docRemoved.on(id => {
this.workspace.slots.docRemoved.subscribe(id => {
this.docDisposeMap.get(id)?.();
});
}
@@ -149,7 +149,7 @@ export class BlockQueryDataSource extends DataSourceBase {
listenToDoc(doc: Store) {
this.docDisposeMap.set(
doc.id,
doc.slots.blockUpdated.on(v => {
doc.slots.blockUpdated.subscribe(v => {
if (v.type === 'add') {
const blockById = doc.getBlock(v.id);
if (blockById && this.meta.selector(blockById)) {
@@ -158,8 +158,8 @@ export class BlockQueryDataSource extends DataSourceBase {
} else if (v.type === 'delete') {
this.blockMap.delete(v.id);
}
this.slots.update.emit();
}).dispose
this.slots.update.next(undefined);
}).unsubscribe
);
}
@@ -34,6 +34,7 @@
"date-fns": "^4.0.0",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"rxjs": "^7.8.1",
"yjs": "^13.6.21",
"zod": "^3.23.8"
},
@@ -81,7 +81,7 @@ export class LinkCell extends BaseCellRenderer<string> {
return;
}
std.getOptional(RefNodeSlotsProvider)?.docLinkClicked.emit({
std.getOptional(RefNodeSlotsProvider)?.docLinkClicked.next({
pageId: this.docId$.value,
host: std.host,
});
@@ -339,8 +339,10 @@ export class RichTextCell extends BaseCellRenderer<Text> {
effect(() => {
const editor = this.inlineEditor$.value;
if (editor) {
const disposable = editor.slots.keydown.on(this._handleKeyDown);
return () => disposable.dispose();
const disposable = editor.slots.keydown.subscribe(
this._handleKeyDown
);
return () => disposable.unsubscribe();
}
return;
})
@@ -27,6 +27,7 @@
"@types/mdast": "^4.0.4",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"rxjs": "^7.8.1",
"zod": "^3.23.8"
},
"exports": {
@@ -29,6 +29,7 @@
"@toeverything/theme": "^1.1.12",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"rxjs": "^7.8.1",
"zod": "^3.23.8"
},
"exports": {
@@ -54,7 +54,7 @@ export const insertEdgelessTextCommand: Command<
elements: [textId],
editing: true,
});
const disposable = selection.slots.updated.on(() => {
const disposable = selection.slots.updated.subscribe(() => {
const editing = selection.editing;
const id = selection.selectedIds[0];
if (!editing || id !== textId) {
@@ -63,7 +63,7 @@ export const insertEdgelessTextCommand: Command<
textBlock.model.hasMaxWidth = true;
}
disposable.dispose();
disposable.unsubscribe();
}
});
@@ -91,7 +91,8 @@ export const insertEdgelessTextCommand: Command<
signal: abortController.signal,
}
);
paragraph.model.deleted.once(() => {
const subscription = paragraph.model.deleted.subscribe(() => {
subscription.unsubscribe();
abortController.abort();
});
edgelessText.addEventListener(
@@ -92,7 +92,7 @@ export class EdgelessTextBlockComponent extends GfxBlockComponent<EdgelessTextBl
super.connectedCallback();
this.disposables.add(
this.model.propsUpdated.on(({ key }) => {
this.model.propsUpdated.subscribe(({ key }) => {
this.updateComplete
.then(() => {
const command = this.std.command;
@@ -137,7 +137,7 @@ export class EdgelessTextBlockComponent extends GfxBlockComponent<EdgelessTextBl
const edgelessSelection = this.gfx.selection;
disposables.add(
edgelessSelection.slots.updated.on(() => {
edgelessSelection.slots.updated.subscribe(() => {
if (edgelessSelection.has(this.model.id) && edgelessSelection.editing) {
this._editing = true;
} else {
@@ -32,6 +32,7 @@
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
"minimatch": "^10.0.1",
"rxjs": "^7.8.1",
"yjs": "^13.6.21",
"zod": "^3.23.8"
},
@@ -341,7 +341,7 @@ export function notifyDocCreated(std: BlockStdScope, doc: Store) {
const clear = () => {
doc.history.off('stack-item-added', addHandler);
doc.history.off('stack-item-popped', popHandler);
disposable.dispose();
disposable.unsubscribe();
};
const closeNotify = () => {
abortController.abort();
@@ -353,7 +353,7 @@ export function notifyDocCreated(std: BlockStdScope, doc: Store) {
const popHandler = doc.history.on('stack-item-popped', closeNotify);
const disposable = std
.get(EditorLifeCycleExtension)
.slots.unmounted.on(closeNotify);
.slots.unmounted.subscribe(closeNotify);
notification.notify({
title: 'Linked doc created',
@@ -54,14 +54,14 @@ export function toEdgelessEmbedBlock<
super.connectedCallback();
this._disposables.add(
this.edgelessSlots.elementResizeStart.on(() => {
this.edgelessSlots.elementResizeStart.subscribe(() => {
this._isResizing = true;
this._showOverlay = true;
})
);
this._disposables.add(
this.edgelessSlots.elementResizeEnd.on(() => {
this.edgelessSlots.elementResizeEnd.subscribe(() => {
this._isResizing = false;
this._showOverlay =
this._isResizing || this._isDragging || !this.selected$.peek();
@@ -62,7 +62,7 @@ export class EmbedFigmaBlockComponent extends EmbedBlockComponent<EmbedFigmaMode
}
this.disposables.add(
this.model.propsUpdated.on(({ key }) => {
this.model.propsUpdated.subscribe(({ key }) => {
if (key === 'url') {
this.refreshData();
}
@@ -102,7 +102,7 @@ export class EmbedGithubBlockComponent extends EmbedBlockComponent<
});
this.disposables.add(
this.model.propsUpdated.on(({ key }) => {
this.model.propsUpdated.subscribe(({ key }) => {
if (key === 'url') {
this.refreshData();
}
@@ -73,12 +73,17 @@ const linkedDocSlashMenuConfig: SlashMenuConfig = {
insertContent(std.host, model, triggerKey);
const inlineEditor = getInlineEditorByModel(std.host, model);
// Wait for range to be updated
inlineEditor?.slots.inlineRangeSync.once(() => {
// TODO(@L-Sun): make linked-doc-widget as extension
// @ts-expect-error same as above
linkedDocWidget.show({ addTriggerKey: true });
});
if (inlineEditor) {
// Wait for range to be updated
const subscription = inlineEditor.slots.inlineRangeSync.subscribe(
() => {
// TODO(@L-Sun): make linked-doc-widget as extension
subscription.unsubscribe();
// @ts-expect-error same as above
linkedDocWidget.show({ addTriggerKey: true });
}
);
}
},
},
],
@@ -87,7 +87,8 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
if (!this.isError && !linkedDoc.root) {
await new Promise<void>(resolve => {
linkedDoc.slots.rootAdded.once(() => {
const subscription = linkedDoc.slots.rootAdded.subscribe(() => {
subscription.unsubscribe();
resolve();
});
});
@@ -203,7 +204,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
openMode?: OpenDocMode;
event?: MouseEvent;
} = {}) => {
this.std.getOptional(RefNodeSlotsProvider)?.docLinkClicked.emit({
this.std.getOptional(RefNodeSlotsProvider)?.docLinkClicked.next({
...this.referenceInfo$.peek(),
openMode,
event,
@@ -285,7 +286,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
const linkedDoc = this.linkedDoc;
if (linkedDoc) {
this.disposables.add(
linkedDoc.workspace.slots.docListUpdated.on(() => {
linkedDoc.workspace.slots.docListUpdated.subscribe(() => {
this._load().catch(e => {
console.error(e);
this.isError = true;
@@ -295,7 +296,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
// Should throttle the blockUpdated event to avoid too many re-renders
// Because the blockUpdated event is triggered too frequently at some cases
this.disposables.add(
linkedDoc.slots.blockUpdated.on(
linkedDoc.slots.blockUpdated.subscribe(
throttle(payload => {
if (
payload.type === 'update' &&
@@ -318,7 +319,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
this._setDocUpdatedAt();
this.disposables.add(
this.doc.workspace.slots.docListUpdated.on(() => {
this.doc.workspace.slots.docListUpdated.subscribe(() => {
this._setDocUpdatedAt();
})
);
@@ -337,7 +338,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
}
this.disposables.add(
this.model.propsUpdated.on(({ key }) => {
this.model.propsUpdated.subscribe(({ key }) => {
if (key === 'style') {
this._cardStyle = this.model.style;
}
@@ -82,7 +82,7 @@ export class EmbedLoomBlockComponent extends EmbedBlockComponent<
}
this.disposables.add(
this.model.propsUpdated.on(({ key }) => {
this.model.propsUpdated.subscribe(({ key }) => {
this.requestUpdate();
if (key === 'url') {
this.refreshData();
@@ -99,20 +99,21 @@ export class EmbedSyncedDocCard extends WithDisposable(ShadowlessElement) {
if (syncedDoc.root) {
renderLinkedDocInCard(this);
} else {
syncedDoc.slots.rootAdded.once(() => {
const subscription = syncedDoc.slots.rootAdded.subscribe(() => {
subscription.unsubscribe();
renderLinkedDocInCard(this);
});
}
this.disposables.add(
syncedDoc.workspace.slots.docListUpdated.on(() => {
syncedDoc.workspace.slots.docListUpdated.subscribe(() => {
renderLinkedDocInCard(this);
})
);
// Should throttle the blockUpdated event to avoid too many re-renders
// Because the blockUpdated event is triggered too frequently at some cases
this.disposables.add(
syncedDoc.slots.blockUpdated.on(
syncedDoc.slots.blockUpdated.subscribe(
throttle(payload => {
if (this._dragging) {
return;
@@ -129,7 +129,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
override mounted(): void {
const { view } = this.std;
view.viewUpdated.on(payload => {
view.viewUpdated.subscribe(payload => {
if (
payload.type !== 'block' ||
payload.view.model.flavour !== 'affine:embed-synced-doc'
@@ -355,7 +355,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
this.std
.getOptional(RefNodeSlotsProvider)
?.docLinkClicked.emit({ ...event, pageId, host: this.host });
?.docLinkClicked.next({ ...event, pageId, host: this.host });
};
refreshData = () => {
@@ -464,7 +464,10 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
if (!this._error && !syncedDoc.root) {
await new Promise<void>(resolve => {
syncedDoc.slots.rootAdded.once(() => resolve());
const subscription = syncedDoc.slots.rootAdded.subscribe(() => {
subscription.unsubscribe();
resolve();
});
});
}
@@ -504,7 +507,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
this.contentEditable = 'false';
this.disposables.add(
this.model.propsUpdated.on(({ key }) => {
this.model.propsUpdated.subscribe(({ key }) => {
if (key === 'pageId' || key === 'style') {
this._load().catch(e => {
console.error(e);
@@ -516,7 +519,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
this._setDocUpdatedAt();
this.disposables.add(
this.doc.workspace.slots.docListUpdated.on(() => {
this.doc.workspace.slots.docListUpdated.subscribe(() => {
this._setDocUpdatedAt();
})
);
@@ -535,7 +538,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
this.syncedDoc &&
this.disposables.add(
this.syncedDoc.slots.blockUpdated.on(() => {
this.syncedDoc.slots.blockUpdated.subscribe(() => {
this._isEmptySyncedDoc = isEmptyDoc(this.syncedDoc, this.editorMode);
})
);
@@ -85,7 +85,7 @@ export class EmbedYoutubeBlockComponent extends EmbedBlockComponent<
}
this.disposables.add(
this.model.propsUpdated.on(({ key }) => {
this.model.propsUpdated.subscribe(({ key }) => {
this.requestUpdate();
if (key === 'url') {
this.refreshData();
@@ -28,6 +28,7 @@
"@types/mdast": "^4.0.4",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"rxjs": "^7.8.1",
"yjs": "^13.6.21",
"zod": "^3.23.8"
},
@@ -12,14 +12,14 @@ export class FrameBlockComponent extends GfxBlockComponent<FrameBlockModel> {
super.connectedCallback();
this._disposables.add(
this.doc.slots.blockUpdated.on(({ type, id }) => {
this.doc.slots.blockUpdated.subscribe(({ type, id }) => {
if (id === this.model.id && type === 'update') {
this.requestUpdate();
}
})
);
this._disposables.add(
this.gfx.viewport.viewportUpdated.on(() => {
this.gfx.viewport.viewportUpdated.subscribe(() => {
this.requestUpdate();
})
);
@@ -13,6 +13,7 @@ import {
isGfxGroupCompatibleModel,
renderableInEdgeless,
} from '@blocksuite/block-std/gfx';
import { DisposableGroup } from '@blocksuite/global/disposable';
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
import {
Bound,
@@ -20,7 +21,6 @@ import {
type IVec,
type SerializedXYWH,
} from '@blocksuite/global/gfx';
import { DisposableGroup } from '@blocksuite/global/slot';
import { type BlockModel, Text } from '@blocksuite/store';
import * as Y from 'yjs';
@@ -98,11 +98,12 @@ export class FrameOverlay extends Overlay {
if (highlightOutline) this._frame = frame;
if (highlightElementsInBound) this._innerElements = innerElements;
this._disposable.add(
frame.deleted.once(() => {
this.clear();
})
);
const subscription = frame.deleted.subscribe(() => {
subscription.unsubscribe();
this.clear();
});
this._disposable.add(subscription);
this._renderer?.refresh();
}
@@ -223,7 +224,7 @@ export class EdgelessFrameManager extends GfxExtension {
const { surface: surfaceModel, doc } = this.gfx;
this._disposable.add(
surfaceModel.elementAdded.on(({ id, local }) => {
surfaceModel.elementAdded.subscribe(({ id, local }) => {
const element = surfaceModel.getElementById(id);
if (element && local) {
const frame = this.getFrameFromPoint(element.elementBound.center);
@@ -249,7 +250,7 @@ export class EdgelessFrameManager extends GfxExtension {
);
this._disposable.add(
doc.slots.blockUpdated.on(payload => {
doc.slots.blockUpdated.subscribe(payload => {
if (
payload.type === 'add' &&
payload.model instanceof GfxBlockElementModel &&
@@ -31,6 +31,7 @@
"file-type": "^20.0.0",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"rxjs": "^7.8.1",
"zod": "^3.23.8"
},
"exports": {
@@ -191,7 +191,7 @@ export class ImageBlockPageComponent extends WithDisposable(ShadowlessElement) {
private _handleSelection() {
const selection = this._host.selection;
this._disposables.add(
selection.slots.changed.on(selList => {
selection.slots.changed.subscribe(selList => {
this._isSelected = selList.some(
sel => sel.blockId === this.block.blockId && sel.is(ImageSelection)
);
@@ -199,7 +199,7 @@ export class ImageBlockPageComponent extends WithDisposable(ShadowlessElement) {
);
this._disposables.add(
this._model.propsUpdated.on(() => {
this._model.propsUpdated.subscribe(() => {
this.requestUpdate();
})
);
@@ -60,7 +60,7 @@ export class ImageBlockComponent extends CaptionedBlockComponent<ImageBlockModel
this.refreshData();
this.contentEditable = 'false';
this._disposables.add(
this.model.propsUpdated.on(({ key }) => {
this.model.propsUpdated.subscribe(({ key }) => {
if (key === 'sourceId') {
this.refreshData();
}
@@ -62,7 +62,7 @@ export class ImageEdgelessBlockComponent extends GfxBlockComponent<ImageBlockMod
this.refreshData();
this.contentEditable = 'false';
this.disposables.add(
this.model.propsUpdated.on(({ key }) => {
this.model.propsUpdated.subscribe(({ key }) => {
if (key === 'sourceId') {
this.refreshData();
}
@@ -34,6 +34,7 @@
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"remark-math": "^6.0.0",
"rxjs": "^7.8.1",
"zod": "^3.23.8"
},
"exports": {
@@ -29,6 +29,7 @@
"@types/mdast": "^4.0.4",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"rxjs": "^7.8.1",
"zod": "^3.23.8"
},
"devDependencies": {
@@ -33,6 +33,7 @@
"@vanilla-extract/css": "^1.17.0",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"rxjs": "^7.8.1",
"zod": "^3.23.8"
},
"exports": {
@@ -126,7 +126,7 @@ export class EdgelessNoteBlockComponent extends toGfxBlockComponent(
this._editing = selection.has(this.model.id) && selection.editing;
this._disposables.add(
selection.slots.updated.on(() => {
selection.slots.updated.subscribe(() => {
if (selection.has(this.model.id) && selection.editing) {
this._editing = true;
} else {
@@ -147,7 +147,7 @@ export class EdgelessNoteBlockComponent extends toGfxBlockComponent(
const selection = this.gfx.selection;
_disposables.add(
this.edgelessSlots.elementResizeStart.on(() => {
this.edgelessSlots.elementResizeStart.subscribe(() => {
if (selection.selectedElements.includes(this.model)) {
this._isResizing = true;
}
@@ -155,7 +155,7 @@ export class EdgelessNoteBlockComponent extends toGfxBlockComponent(
);
_disposables.add(
this.edgelessSlots.elementResizeEnd.on(() => {
this.edgelessSlots.elementResizeEnd.subscribe(() => {
this._isResizing = false;
})
);
@@ -28,6 +28,7 @@
"@types/mdast": "^4.0.4",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"rxjs": "^7.8.1",
"zod": "^3.23.8"
},
"exports": {
@@ -60,6 +60,7 @@
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
"minimatch": "^10.0.1",
"rxjs": "^7.8.1",
"simple-xml-to-json": "^1.2.2",
"yjs": "^13.6.21",
"zod": "^3.23.8"
@@ -15,7 +15,7 @@ import {
retainFirstModelCommand,
} from '@blocksuite/affine-shared/commands';
import type { UIEventHandler } from '@blocksuite/block-std';
import { DisposableGroup } from '@blocksuite/global/slot';
import { DisposableGroup } from '@blocksuite/global/disposable';
import type { BlockSnapshot, Store } from '@blocksuite/store';
import { ReadOnlyClipboard } from './readonly-clipboard';
@@ -14,7 +14,7 @@ import {
getSelectedModelsCommand,
} from '@blocksuite/affine-shared/commands';
import type { BlockComponent, UIEventHandler } from '@blocksuite/block-std';
import { DisposableGroup } from '@blocksuite/global/slot';
import { DisposableGroup } from '@blocksuite/global/disposable';
import { ClipboardAdapter } from './adapter.js';
@@ -48,6 +48,7 @@ import {
type SerializedElement,
SortOrder,
} from '@blocksuite/block-std/gfx';
import { DisposableGroup } from '@blocksuite/global/disposable';
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
import {
Bound,
@@ -57,7 +58,6 @@ import {
type SerializedXYWH,
Vec,
} from '@blocksuite/global/gfx';
import { DisposableGroup } from '@blocksuite/global/slot';
import { assertType } from '@blocksuite/global/utils';
import {
type BlockSnapshot,
@@ -568,7 +568,7 @@ export class EdgelessAutoCompletePanel extends WithDisposable(LitElement) {
override firstUpdated() {
this.disposables.add(
this.edgeless.service.viewport.viewportUpdated.on(() =>
this.edgeless.service.viewport.viewportUpdated.subscribe(() =>
this.requestUpdate()
)
);
@@ -25,10 +25,10 @@ import {
import { handleNativeRangeAtPoint } from '@blocksuite/affine-shared/utils';
import { type BlockStdScope, stdContext } from '@blocksuite/block-std';
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
import { DisposableGroup } from '@blocksuite/global/disposable';
import type { Bound, IVec } from '@blocksuite/global/gfx';
import { Vec } from '@blocksuite/global/gfx';
import { WithDisposable } from '@blocksuite/global/lit';
import { DisposableGroup } from '@blocksuite/global/slot';
import {
ArrowUpBigIcon,
PlusIcon,
@@ -670,7 +670,7 @@ export class EdgelessAutoComplete extends WithDisposable(LitElement) {
const { _disposables, edgeless } = this;
_disposables.add(
this.gfx.selection.slots.updated.on(() => {
this.gfx.selection.slots.updated.subscribe(() => {
this._autoCompleteOverlay.linePoints = [];
this._autoCompleteOverlay.renderShape = null;
})
@@ -9,9 +9,9 @@ import {
stdContext,
} from '@blocksuite/block-std';
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
import { DisposableGroup } from '@blocksuite/global/disposable';
import { Vec } from '@blocksuite/global/gfx';
import { WithDisposable } from '@blocksuite/global/lit';
import { DisposableGroup } from '@blocksuite/global/slot';
import type { Store } from '@blocksuite/store';
import { consume } from '@lit/context';
import { css, html, LitElement } from 'lit';
@@ -63,11 +63,11 @@ export class EdgelessConnectorHandle extends WithDisposable(LitElement) {
const edgeless = this.edgeless;
this._disposables.addFromEvent(this._startHandler, 'pointerdown', e => {
edgeless.slots.elementResizeStart.emit();
edgeless.slots.elementResizeStart.next();
this._capPointerDown(e, 'source');
});
this._disposables.addFromEvent(this._endHandler, 'pointerdown', e => {
edgeless.slots.elementResizeStart.emit();
edgeless.slots.elementResizeStart.next();
this._capPointerDown(e, 'target');
});
this._disposables.add(() => {
@@ -96,7 +96,7 @@ export class EdgelessConnectorHandle extends WithDisposable(LitElement) {
_disposables.dispose();
this._disposables = new DisposableGroup();
this._bindEvent();
edgeless.slots.elementResizeEnd.emit();
edgeless.slots.elementResizeEnd.next();
});
}
@@ -105,7 +105,7 @@ export class EdgelessConnectorHandle extends WithDisposable(LitElement) {
const { viewport } = edgeless.service;
this._lastZoom = viewport.zoom;
edgeless.service.viewport.viewportUpdated.on(() => {
edgeless.service.viewport.viewportUpdated.subscribe(() => {
if (viewport.zoom !== this._lastZoom) {
this._lastZoom = viewport.zoom;
this.requestUpdate();
@@ -10,8 +10,8 @@ import { TelemetryProvider } from '@blocksuite/affine-shared/services';
import { getRectByBlockComponent } from '@blocksuite/affine-shared/utils';
import { WidgetComponent } from '@blocksuite/block-std';
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
import { DisposableGroup } from '@blocksuite/global/disposable';
import { deserializeXYWH, Point, serializeXYWH } from '@blocksuite/global/gfx';
import { DisposableGroup } from '@blocksuite/global/slot';
import { ScissorsIcon } from '@blocksuite/icons/lit';
import { css, html, nothing, type PropertyValues } from 'lit';
import { state } from 'lit/decorators.js';
@@ -267,13 +267,13 @@ export class NoteSlicer extends WidgetComponent<
this._updateDivingLineAndBlockIds();
disposables.add(
block.slots.elementResizeStart.on(() => {
block.slots.elementResizeStart.subscribe(() => {
this._isResizing = true;
})
);
disposables.add(
block.slots.elementResizeEnd.on(() => {
block.slots.elementResizeEnd.subscribe(() => {
this._isResizing = false;
})
);
@@ -289,14 +289,14 @@ export class NoteSlicer extends WidgetComponent<
);
disposables.add(
gfx.viewport.viewportUpdated.on(() => {
gfx.viewport.viewportUpdated.subscribe(() => {
this._hidden = true;
this.requestUpdate();
})
);
disposables.add(
gfx.selection.slots.updated.on(() => {
gfx.selection.slots.updated.subscribe(() => {
this._enableNoteSlicer = false;
this._updateSlicedNote();
@@ -307,7 +307,7 @@ export class NoteSlicer extends WidgetComponent<
);
disposables.add(
block.slots.toggleNoteSlicer.on(() => {
block.slots.toggleNoteSlicer.subscribe(() => {
this._enableNoteSlicer = !this._enableNoteSlicer;
if (this.selectedRectEle && this._enableNoteSlicer) {
@@ -411,7 +411,7 @@ export class NoteSlicer extends WidgetComponent<
if (this._anchorNote) {
this._noteDisposables = new DisposableGroup();
this._noteDisposables.add(
this._anchorNote.propsUpdated.on(({ key }) => {
this._anchorNote.propsUpdated.subscribe(({ key }) => {
if (key === 'children' || key === 'xywh') {
this.requestUpdate();
}
@@ -1,8 +1,8 @@
import { ShapeStyle } from '@blocksuite/affine-model';
import { Slot } from '@blocksuite/global/slot';
import { css, html, LitElement } from 'lit';
import { property } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import { Subject } from 'rxjs';
import type { ShapeTool } from '../../gfx-tool/shape-tool.js';
import { ShapeComponentConfig } from '../toolbar/shape/shape-menu-config.js';
@@ -18,16 +18,16 @@ export class EdgelessShapePanel extends LitElement {
`;
slots = {
select: new Slot<ShapeTool['activatedOption']['shapeName']>(),
select: new Subject<ShapeTool['activatedOption']['shapeName']>(),
};
private _onSelect(value: ShapeTool['activatedOption']['shapeName']) {
this.selectedShape = value;
this.slots.select.emit(value);
this.slots.select.next(value);
}
override disconnectedCallback(): void {
this.slots.select.dispose();
this.slots.select.complete();
super.disconnectedCallback();
}
@@ -55,13 +55,13 @@ import {
deserializeXYWH,
normalizeDegAngle,
} from '@blocksuite/global/gfx';
import { type Disposable, Slot } from '@blocksuite/global/slot';
import { assertType } from '@blocksuite/global/utils';
import { css, html, nothing } from 'lit';
import { state } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { styleMap } from 'lit/directives/style-map.js';
import clamp from 'lodash-es/clamp';
import { Subject, type Subscription } from 'rxjs';
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
import {
@@ -447,13 +447,13 @@ export class EdgelessSelectedRectWidget extends WidgetComponent<
private _dragEndCallback: (() => void)[] = [];
private readonly _initSelectedSlot = () => {
this._propDisposables.forEach(disposable => disposable.dispose());
this._propDisposables.forEach(disposable => disposable.unsubscribe());
this._propDisposables = [];
this.selection.selectedElements.forEach(element => {
if ('flavour' in element) {
this._propDisposables.push(
element.propsUpdated.on(() => {
element.propsUpdated.subscribe(() => {
this._updateOnElementChange(element.id);
})
);
@@ -462,7 +462,7 @@ export class EdgelessSelectedRectWidget extends WidgetComponent<
};
private readonly _onDragEnd = () => {
this.slots.dragEnd.emit();
this.slots.dragEnd.next();
this.doc.transact(() => {
this._dragEndCallback.forEach(cb => cb());
@@ -478,7 +478,7 @@ export class EdgelessSelectedRectWidget extends WidgetComponent<
this._scaleDirection = undefined;
this._updateMode();
this.block.slots.elementResizeEnd.emit();
this.block.slots.elementResizeEnd.next();
this.frameOverlay.clear();
};
@@ -494,7 +494,7 @@ export class EdgelessSelectedRectWidget extends WidgetComponent<
>,
direction: HandleDirection
) => {
this.slots.dragMove.emit();
this.slots.dragMove.next();
const { gfx } = this;
@@ -557,7 +557,7 @@ export class EdgelessSelectedRectWidget extends WidgetComponent<
};
private readonly _onDragRotate = (center: IPoint, delta: number) => {
this.slots.dragRotate.emit();
this.slots.dragRotate.next();
const { selection } = this;
const m = new DOMMatrix()
@@ -602,12 +602,12 @@ export class EdgelessSelectedRectWidget extends WidgetComponent<
};
private readonly _onDragStart = () => {
this.slots.dragStart.emit();
this.slots.dragStart.next();
const rotation = this._resizeManager.rotation;
this._dragEndCallback = [];
this.block.slots.elementResizeStart.emit();
this.block.slots.elementResizeStart.next();
this.selection.selectedElements.forEach(el => {
el.stash('xywh');
@@ -644,7 +644,7 @@ export class EdgelessSelectedRectWidget extends WidgetComponent<
this._updateResizeManagerState(true);
};
private _propDisposables: Disposable[] = [];
private _propDisposables: Subscription[] = [];
private readonly _resizeManager: HandleResizeManager;
@@ -836,10 +836,10 @@ export class EdgelessSelectedRectWidget extends WidgetComponent<
}, this);
readonly slots = {
dragStart: new Slot(),
dragMove: new Slot(),
dragRotate: new Slot(),
dragEnd: new Slot(),
dragStart: new Subject<void>(),
dragMove: new Subject<void>(),
dragRotate: new Subject<void>(),
dragEnd: new Subject<void>(),
};
get dragDirection() {
@@ -1307,39 +1307,41 @@ export class EdgelessSelectedRectWidget extends WidgetComponent<
_disposables.add(
// viewport zooming / scrolling
gfx.viewport.viewportUpdated.on(this._updateOnViewportChange)
gfx.viewport.viewportUpdated.subscribe(this._updateOnViewportChange)
);
if (gfx.surface) {
_disposables.add(
gfx.surface.elementAdded.on(this._updateOnElementChange)
gfx.surface.elementAdded.subscribe(this._updateOnElementChange)
);
_disposables.add(
gfx.surface.elementRemoved.on(this._updateOnElementChange)
gfx.surface.elementRemoved.subscribe(this._updateOnElementChange)
);
_disposables.add(
gfx.surface.elementUpdated.on(this._updateOnElementChange)
gfx.surface.elementUpdated.subscribe(this._updateOnElementChange)
);
}
_disposables.add(
this.doc.slots.blockUpdated.on(this._updateOnElementChange)
);
_disposables.add(selection.slots.updated.on(this._updateOnSelectionChange));
_disposables.add(
block.slots.readonlyUpdated.on(() => this.requestUpdate())
this.doc.slots.blockUpdated.subscribe(this._updateOnElementChange)
);
_disposables.add(
block.slots.elementResizeStart.on(() => (this._isResizing = true))
selection.slots.updated.subscribe(this._updateOnSelectionChange)
);
_disposables.add(
block.slots.readonlyUpdated.subscribe(() => this.requestUpdate())
);
_disposables.add(
block.slots.elementResizeStart.subscribe(() => (this._isResizing = true))
);
_disposables.add(
block.slots.elementResizeEnd.on(() => (this._isResizing = false))
block.slots.elementResizeEnd.subscribe(() => (this._isResizing = false))
);
_disposables.add(() => {
this._propDisposables.forEach(disposable => disposable.dispose());
this._propDisposables.forEach(disposable => disposable.unsubscribe());
});
this.block.handleEvent(
@@ -127,7 +127,7 @@ export class EdgelessConnectorLabelEditor extends WithDisposable(
if (!this.inlineEditor) return;
this.inlineEditor.selectAll();
this.inlineEditor.slots.renderComplete.on(() => {
this.inlineEditor.slots.renderComplete.subscribe(() => {
this.requestUpdate();
});
@@ -153,13 +153,13 @@ export class EdgelessConnectorLabelEditor extends WithDisposable(
);
this.disposables.add(
edgeless.service.surface.elementUpdated.on(({ id }) => {
edgeless.service.surface.elementUpdated.subscribe(({ id }) => {
if (id === connector.id) this.requestUpdate();
})
);
this.disposables.add(
edgeless.service.viewport.viewportUpdated.on(() => {
edgeless.service.viewport.viewportUpdated.subscribe(() => {
this.requestUpdate();
})
);
@@ -69,7 +69,7 @@ export class EdgelessFrameTitleEditor extends WithDisposable(
this.inlineEditor.selectAll();
this.inlineEditor.slots.renderComplete.on(() => {
this.inlineEditor.slots.renderComplete.subscribe(() => {
this.requestUpdate();
});
@@ -87,7 +87,7 @@ export class EdgelessFrameTitleEditor extends WithDisposable(
})
);
this.disposables.add(
this.edgeless.service.viewport.viewportUpdated.on(() => {
this.edgeless.service.viewport.viewportUpdated.subscribe(() => {
this.requestUpdate();
})
);
@@ -54,7 +54,7 @@ export class EdgelessGroupTitleEditor extends WithDisposable(
this.group.showTitle = false;
this.inlineEditor.slots.renderComplete.on(() => {
this.inlineEditor.slots.renderComplete.subscribe(() => {
this.requestUpdate();
});
@@ -72,7 +72,7 @@ export class EdgelessGroupTitleEditor extends WithDisposable(
})
);
this.disposables.add(
this.edgeless.service.viewport.viewportUpdated.on(() => {
this.edgeless.service.viewport.viewportUpdated.subscribe(() => {
this.requestUpdate();
})
);
@@ -178,7 +178,7 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
this.element.textDisplay = false;
this.disposables.add(
this.edgeless.service.viewport.viewportUpdated.on(() => {
this.edgeless.service.viewport.viewportUpdated.subscribe(() => {
this.requestUpdate();
this.updateComplete
.then(() => {
@@ -208,7 +208,7 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
}
this.disposables.add(
this.inlineEditor.slots.renderComplete.on(() => {
this.inlineEditor.slots.renderComplete.subscribe(() => {
this._updateElementWH();
})
);
@@ -386,7 +386,7 @@ export class EdgelessDraggableElementController<T>
hostConnected() {
this.host.disposables.add(
this.options.service.viewport.viewportUpdated.on(({ zoom }) => {
this.options.service.viewport.viewportUpdated.subscribe(({ zoom }) => {
this._updateOverlayScale(zoom);
})
);
@@ -121,7 +121,7 @@ export class EdgelessSlideMenu extends WithDisposable(LitElement) {
this._toggleSlideButton();
});
this._disposables.add(
this.toolbarSlots.resize.on(() => this._toggleSlideButton())
this.toolbarSlots.resize.subscribe(() => this._toggleSlideButton())
);
}
@@ -1,11 +1,11 @@
import type { ColorScheme } from '@blocksuite/affine-model';
import type { Slot } from '@blocksuite/global/slot';
import { createContext } from '@lit/context';
import type { Subject } from 'rxjs';
import type { EdgelessToolbarWidget } from './edgeless-toolbar.js';
export interface EdgelessToolbarSlots {
resize: Slot<{ w: number; h: number }>;
resize: Subject<{ w: number; h: number }>;
}
export const edgelessToolbarSlotsContext = createContext<EdgelessToolbarSlots>(
@@ -16,7 +16,6 @@ import {
import { stopPropagation } from '@blocksuite/affine-shared/utils';
import { WidgetComponent } from '@blocksuite/block-std';
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
import { Slot } from '@blocksuite/global/slot';
import {
ArrowLeftSmallIcon,
ArrowRightSmallIcon,
@@ -30,6 +29,7 @@ import { css, html, nothing, unsafeCSS } from 'lit';
import { query, state } from 'lit/decorators.js';
import { cache } from 'lit/directives/cache.js';
import debounce from 'lodash-es/debounce';
import { Subject } from 'rxjs';
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
import type { MenuPopper } from './common/create-popper.js';
@@ -238,7 +238,7 @@ export class EdgelessToolbarWidget extends WidgetComponent<
({ w }: { w: number }) => {
if (!this.isConnected) return;
this.slots.resize.emit({ w, h: TOOLBAR_HEIGHT });
this.slots.resize.next({ w, h: TOOLBAR_HEIGHT });
this.containerWidth = w;
if (this._denseSeniorTools) {
@@ -273,7 +273,7 @@ export class EdgelessToolbarWidget extends WidgetComponent<
private readonly _slotsProvider = new ContextProvider(this, {
context: edgelessToolbarSlotsContext,
initialValue: { resize: new Slot() } satisfies EdgelessToolbarSlots,
initialValue: { resize: new Subject() } satisfies EdgelessToolbarSlots,
});
private readonly _themeProvider = new ContextProvider(this, {
@@ -605,22 +605,22 @@ export class EdgelessToolbarWidget extends WidgetComponent<
const { _disposables, block, gfx } = this;
_disposables.add(
gfx.viewport.viewportUpdated.on(() => this.requestUpdate())
gfx.viewport.viewportUpdated.subscribe(() => this.requestUpdate())
);
_disposables.add(
block.slots.readonlyUpdated.on(() => {
block.slots.readonlyUpdated.subscribe(() => {
this.requestUpdate();
})
);
_disposables.add(
block.slots.toolbarLocked.on(disabled => {
block.slots.toolbarLocked.subscribe(disabled => {
this.toggleAttribute('disabled', disabled);
})
);
// This state from `editPropsStore` is not reactive,
// if the value is updated outside of this component, it will not be reflected.
_disposables.add(
this.std.get(EditPropsStore).slots.storageUpdated.on(({ key }) => {
this.std.get(EditPropsStore).slots.storageUpdated.subscribe(({ key }) => {
if (key === 'presentHideToolbar') {
this.requestUpdate();
}
@@ -1,7 +1,7 @@
import { EdgelessCRUDIdentifier } from '@blocksuite/affine-block-surface';
import { generateKeyBetweenV2 } from '@blocksuite/block-std/gfx';
import { DisposableGroup } from '@blocksuite/global/disposable';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit';
import { DisposableGroup } from '@blocksuite/global/slot';
import { css, html, LitElement, nothing } from 'lit';
import { property, query, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
@@ -73,7 +73,7 @@ export class EdgelessNavigatorSettingButton extends WithDisposable(LitElement) {
private readonly _onBlackBackgroundChange = (checked: boolean) => {
this.blackBackground = checked;
this.edgeless.slots.navigatorSettingUpdated.emit({
this.edgeless.slots.navigatorSettingUpdated.next({
blackBackground: this.blackBackground,
});
};
@@ -134,7 +134,7 @@ export class EdgelessNavigatorSettingButton extends WithDisposable(LitElement) {
<div class="text">Black background</div>
<toggle-switch
.on=${this.blackBackground}
.subscribe=${this.blackBackground}
.onChange=${this._onBlackBackgroundChange}
>
</toggle-switch>
@@ -144,7 +144,7 @@ export class EdgelessNavigatorSettingButton extends WithDisposable(LitElement) {
<div class="text">Hide toolbar</div>
<toggle-switch
.on=${this.hideToolbar}
.subscribe=${this.hideToolbar}
.onChange=${(checked: boolean) => {
this.onHideToolbarChange && this.onHideToolbarChange(checked);
}}
@@ -197,7 +197,7 @@ export class PresentationToolbar extends EdgelessToolbarToolMixin(
}
viewport.setViewportByBound(bound, [0, 0, 0, 0], false);
this.edgeless.slots.navigatorFrameChanged.emit(
this.edgeless.slots.navigatorFrameChanged.next(
this._frames[this._currentFrameIndex]
);
}
@@ -278,7 +278,7 @@ export class PresentationToolbar extends EdgelessToolbarToolMixin(
this._bindHotKey();
_disposables.add(
edgeless.slots.navigatorSettingUpdated.on(({ fillScreen }) => {
edgeless.slots.navigatorSettingUpdated.subscribe(({ fillScreen }) => {
if (fillScreen !== undefined) {
this._navigatorMode = fillScreen ? 'fill' : 'fit';
}
@@ -307,7 +307,7 @@ export class PresentationToolbar extends EdgelessToolbarToolMixin(
}
setTimeout(() => this._moveToCurrentFrame(), 400);
this.edgeless.slots.fullScreenToggled.emit();
this.edgeless.slots.fullScreenToggled.next();
});
this._navigatorMode =
@@ -3,7 +3,7 @@ import {
once,
requestConnectedFrame,
} from '@blocksuite/affine-shared/utils';
import { DisposableGroup } from '@blocksuite/global/slot';
import { DisposableGroup } from '@blocksuite/global/disposable';
import { css, html, LitElement } from 'lit';
import { query } from 'lit/decorators.js';
@@ -138,7 +138,7 @@ export class EdgelessPageKeyboardManager extends PageKeyboardManager {
NoteBlockModel,
])
) {
rootComponent.slots.toggleNoteSlicer.emit();
rootComponent.slots.toggleNoteSlicer.next();
}
},
f: () => {
@@ -173,7 +173,7 @@ export class EdgelessPageKeyboardManager extends PageKeyboardManager {
elements.length === 1 &&
isNoteBlock(elements[0])
) {
rootComponent.slots.toggleNoteSlicer.emit();
rootComponent.slots.toggleNoteSlicer.next();
}
},
'@': () => {
@@ -182,7 +182,7 @@ export class EdgelessRootBlockComponent extends BlockComponent<
});
this._disposables.add(
this.gfx.layer.slots.layerUpdated.on(() => updateLayers())
this.gfx.layer.slots.layerUpdated.subscribe(() => updateLayers())
);
}
@@ -426,7 +426,7 @@ export class EdgelessRootBlockComponent extends BlockComponent<
const dy = simulateHorizontalScroll ? 0 : e.deltaY / viewport.zoom;
viewport.applyDeltaCenter(dx, dy);
viewport.viewportMoved.emit([dx, dy]);
viewport.viewportMoved.next([dx, dy]);
e.stopPropagation();
}
})
@@ -520,14 +520,14 @@ export class EdgelessRootBlockComponent extends BlockComponent<
this.gfx.tool.setTool('default');
}
this.gfx.viewport.elementReady.emit(this.gfxViewportElm);
this.gfx.viewport.elementReady.next(this.gfxViewportElm);
requestConnectedFrame(() => {
this.requestUpdate();
}, this);
this._disposables.add(
this.gfx.viewport.viewportUpdated.on(() => {
this.gfx.viewport.viewportUpdated.subscribe(() => {
this._refreshLayerViewport();
})
);
@@ -126,7 +126,7 @@ export class EdgelessRootPreviewBlockComponent extends BlockComponent<
});
this._disposables.add(
this._gfx.layer.slots.layerUpdated.on(() => updateLayers())
this._gfx.layer.slots.layerUpdated.subscribe(() => updateLayers())
);
}
@@ -219,7 +219,7 @@ export class EdgelessRootPreviewBlockComponent extends BlockComponent<
this._initLayerUpdateEffect();
this._disposables.add(
this._gfx.viewport.viewportUpdated.on(() => {
this._gfx.viewport.viewportUpdated.subscribe(() => {
this._refreshLayerViewport();
})
);
@@ -152,7 +152,7 @@ export class EdgelessRootService extends RootService implements SurfaceContext {
effect(() => {
if (readonly !== doc.readonly) {
readonly = doc.readonly;
slots.readonlyUpdated.emit(readonly);
slots.readonlyUpdated.next(readonly);
}
})
);
@@ -42,9 +42,9 @@ import {
isGfxGroupCompatibleModel,
type PointTestOptions,
} from '@blocksuite/block-std/gfx';
import { DisposableGroup } from '@blocksuite/global/disposable';
import type { IVec } from '@blocksuite/global/gfx';
import { Bound, getCommonBoundWithRotation, Vec } from '@blocksuite/global/gfx';
import { DisposableGroup } from '@blocksuite/global/slot';
import { noop } from '@blocksuite/global/utils';
import { effect } from '@preact/signals-core';
import clamp from 'lodash-es/clamp';
@@ -598,7 +598,7 @@ export class DefaultTool extends BaseTool {
// If the viewport updates when dragging, should update the dragging area and selection
if (this.dragType === DefaultModeDragType.Selecting) {
this._disposables.add(
this.gfx.viewport.viewportUpdated.on(() => {
this.gfx.viewport.viewportUpdated.subscribe(() => {
if (
this.dragType === DefaultModeDragType.Selecting &&
this.controller.dragging$.peek() &&
@@ -613,7 +613,7 @@ export class DefaultTool extends BaseTool {
if (this.dragType === DefaultModeDragType.ContentMoving) {
this._disposables.add(
this.gfx.viewport.viewportMoved.on(delta => {
this.gfx.viewport.viewportMoved.subscribe(delta => {
if (
this.dragType === DefaultModeDragType.ContentMoving &&
this.controller.dragging$.peek() &&
@@ -69,7 +69,7 @@ export class NoteTool extends BaseTool<NoteToolOption> {
endY = startY + (endY > startY ? m : -m);
}
_draggingNoteOverlay.slots.draggingNoteUpdated.emit({
_draggingNoteOverlay.slots.draggingNoteUpdated.next({
xywh: [
Math.min(startX, endX),
Math.min(startY, endY),
@@ -9,7 +9,7 @@ import type { SlotBlockPayload, TemplateJob } from './template.js';
export const replaceIdMiddleware = (job: TemplateJob) => {
const regeneratedIdMap = new Map<string, string>();
job.slots.beforeInsert.on(payload => {
job.slots.beforeInsert.subscribe(payload => {
switch (payload.type) {
case 'block':
regenerateBlockId(payload.data);
@@ -134,7 +134,7 @@ export const createInsertPlaceMiddleware = (targetPlace: Bound) => {
y: number;
};
job.slots.beforeInsert.on(blockData => {
job.slots.beforeInsert.subscribe(blockData => {
if (blockData.type === 'template') {
templateBound = blockData.bound;
@@ -211,7 +211,7 @@ export const createStickerMiddleware = (
getIndex: () => string
) => {
return (job: TemplateJob) => {
job.slots.beforeInsert.on(blockData => {
job.slots.beforeInsert.subscribe(blockData => {
if (blockData.type === 'block') {
changeInserPosition(blockData.data.blockJson);
}
@@ -238,7 +238,7 @@ export const createRegenerateIndexMiddleware = (
generateIndex: () => string
) => {
return (job: TemplateJob) => {
job.slots.beforeInsert.on(blockData => {
job.slots.beforeInsert.subscribe(blockData => {
if (blockData.type === 'template') {
generateIndexMap();
}
@@ -4,7 +4,6 @@ import type {
} from '@blocksuite/affine-block-surface';
import type { ConnectorElementModel } from '@blocksuite/affine-model';
import { Bound, getCommonBound } from '@blocksuite/global/gfx';
import { Slot } from '@blocksuite/global/slot';
import { assertType } from '@blocksuite/global/utils';
import {
type BlockModel,
@@ -14,6 +13,7 @@ import {
type SnapshotNode,
type Transformer,
} from '@blocksuite/store';
import { Subject } from 'rxjs';
import type * as Y from 'yjs';
/**
* Those block contains other block's id
@@ -73,7 +73,7 @@ export class TemplateJob {
model: SurfaceBlockModel;
slots = {
beforeInsert: new Slot<
beforeInsert: new Subject<
| SlotBlockPayload
| {
type: 'template';
@@ -255,7 +255,7 @@ export class TemplateJob {
index,
};
this.slots.beforeInsert.emit({ type: 'block', data: slotData });
this.slots.beforeInsert.next({ type: 'block', data: slotData });
/**
* merge block should not be converted to model data
@@ -340,7 +340,7 @@ export class TemplateJob {
const templateBound = this._getTemplateBound();
this.slots.beforeInsert.emit({
this.slots.beforeInsert.next({
type: 'template',
template: template,
bound: templateBound,
@@ -12,11 +12,12 @@ import {
} from '@blocksuite/affine-model';
import { ThemeProvider } from '@blocksuite/affine-shared/services';
import type { GfxController, GfxToolsMap } from '@blocksuite/block-std/gfx';
import { DisposableGroup } from '@blocksuite/global/disposable';
import type { XYWH } from '@blocksuite/global/gfx';
import { Bound } from '@blocksuite/global/gfx';
import { DisposableGroup, Slot } from '@blocksuite/global/slot';
import { assertType, noop } from '@blocksuite/global/utils';
import { effect } from '@preact/signals-core';
import { Subject } from 'rxjs';
import type { ShapeTool } from '../gfx-tool/shape-tool.js';
import {
@@ -237,7 +238,7 @@ class ToolOverlay extends Overlay {
this.globalAlpha = 0;
this.gfx = gfx;
this.disposables.add(
this.gfx.viewport.viewportUpdated.on(() => {
this.gfx.viewport.viewportUpdated.subscribe(() => {
// when viewport is updated, we should keep the overlay in the same position
// to get last mouse position and convert it to model coordinates
const pos = this.gfx.tool.lastMousePos$.value;
@@ -444,7 +445,7 @@ export class DraggingNoteOverlay extends NoteOverlay {
height: number;
slots: {
draggingNoteUpdated: Slot<{ xywh: XYWH }>;
draggingNoteUpdated: Subject<{ xywh: XYWH }>;
};
width: number;
@@ -452,14 +453,14 @@ export class DraggingNoteOverlay extends NoteOverlay {
constructor(gfx: GfxController, background: Color) {
super(gfx, background);
this.slots = {
draggingNoteUpdated: new Slot<{
draggingNoteUpdated: new Subject<{
xywh: XYWH;
}>(),
};
this.width = 0;
this.height = 0;
this.disposables.add(
this.slots.draggingNoteUpdated.on(({ xywh }) => {
this.slots.draggingNoteUpdated.subscribe(({ xywh }) => {
[this.x, this.y, this.width, this.height] = xywh;
(this.gfx.surfaceComponent as SurfaceBlockComponent).refresh();
})
@@ -214,7 +214,7 @@ export class PageRootBlockComponent extends BlockComponent<
(entries: ResizeObserverEntry[]) => {
for (const { target } of entries) {
if (target === viewportElement) {
viewportService.emit(viewport);
viewportService.next(viewport);
break;
}
}
@@ -416,7 +416,7 @@ export class PageRootBlockComponent extends BlockComponent<
);
noteModels.forEach(note => {
this.disposables.add(
note.propsUpdated.on(({ key }) => {
note.propsUpdated.subscribe(({ key }) => {
if (key === 'displayMode') {
this.requestUpdate();
}
@@ -42,13 +42,13 @@ export class EdgelessNavigatorBlackBackgroundWidget extends WidgetComponent<Root
override firstUpdated() {
const { _disposables, gfx } = this;
_disposables.add(
this._slots.navigatorFrameChanged.on(frame => {
this._slots.navigatorFrameChanged.subscribe(frame => {
this.frame = frame;
})
);
_disposables.add(
this._slots.navigatorSettingUpdated.on(({ blackBackground }) => {
this._slots.navigatorSettingUpdated.subscribe(({ blackBackground }) => {
if (blackBackground !== undefined) {
this.std
.get(EditPropsStore)
@@ -76,7 +76,7 @@ export class EdgelessNavigatorBlackBackgroundWidget extends WidgetComponent<Root
);
_disposables.add(
this._slots.fullScreenToggled.on(
this._slots.fullScreenToggled.subscribe(
() =>
setTimeout(() => {
this.requestUpdate();
@@ -63,7 +63,7 @@ export class AffineEdgelessZoomToolbarWidget extends WidgetComponent<
const slots = std.get(EdgelessLegacySlotIdentifier);
disposables.add(
slots.navigatorSettingUpdated.on(({ hideToolbar }) => {
slots.navigatorSettingUpdated.subscribe(({ hideToolbar }) => {
if (hideToolbar !== undefined) {
this._hide = hideToolbar;
}
@@ -69,7 +69,7 @@ export class ZoomBarToggleButton extends WithDisposable(LitElement) {
override firstUpdated() {
const { disposables } = this;
disposables.add(
this.edgeless.slots.readonlyUpdated.on(() => {
this.edgeless.slots.readonlyUpdated.subscribe(() => {
this.requestUpdate();
})
);
@@ -130,12 +130,12 @@ export class EdgelessZoomToolbar extends WithDisposable(LitElement) {
override firstUpdated() {
const { disposables } = this;
disposables.add(
this.edgeless.service.viewport.viewportUpdated.on(() =>
this.edgeless.service.viewport.viewportUpdated.subscribe(() =>
this.requestUpdate()
)
);
disposables.add(
this.edgeless.slots.readonlyUpdated.on(() => {
this.edgeless.slots.readonlyUpdated.subscribe(() => {
this.requestUpdate();
})
);
@@ -304,7 +304,7 @@ export class EdgelessAlignButton extends WithDisposable(LitElement) {
override firstUpdated() {
this._disposables.add(
this.edgeless.service.selection.slots.updated.on(() =>
this.edgeless.service.selection.slots.updated.subscribe(() =>
this.requestUpdate()
)
);
@@ -159,7 +159,7 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
const surfaceService = this.edgeless.service;
if (!surfaceService) return;
this.edgeless.slots.toggleNoteSlicer.emit();
this.edgeless.slots.toggleNoteSlicer.next();
}
private _setCollapse() {
@@ -201,7 +201,7 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
const clear = () => {
this.doc.history.off('stack-item-added', addHandler);
this.doc.history.off('stack-item-popped', popHandler);
disposable.dispose();
disposable.unsubscribe();
};
const closeNotify = () => {
abortController.abort();
@@ -212,7 +212,7 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
const popHandler = this.doc.history.on('stack-item-popped', closeNotify);
const disposable = this.edgeless.std
.get(EditorLifeCycleExtension)
.slots.unmounted.on(closeNotify);
.slots.unmounted.subscribe(closeNotify);
const undo = () => {
this.doc.undo();
@@ -232,7 +232,7 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
const _disposables = this._disposables;
_disposables.add(
this._shapePanel.slots.select.on(shapeName => {
this._shapePanel.slots.select.subscribe(shapeName => {
this.edgeless.doc.captureSync();
this.elements.forEach(element => {
this.crud.updateElement(element.id, {
@@ -361,13 +361,13 @@ export class EdgelessElementToolbarWidget extends WidgetComponent<
this.moreGroups = getMoreMenuConfig(this.std).configure(this.moreGroups);
_disposables.add(
edgeless.service.viewport.viewportUpdated.on(() => {
edgeless.service.viewport.viewportUpdated.subscribe(() => {
this._recalculatePosition();
})
);
_disposables.add(
this.selection.slots.updated.on(() => {
this.selection.slots.updated.subscribe(() => {
if (
this.selection.selectedIds.length === 0 ||
this.selection.editing ||
@@ -383,18 +383,18 @@ export class EdgelessElementToolbarWidget extends WidgetComponent<
);
_disposables.add(
this.edgeless.service.surface.elementAdded.on(
this.edgeless.service.surface.elementAdded.subscribe(
this._updateOnSelectedChange
)
);
_disposables.add(
this.edgeless.service.surface.elementUpdated.on(
this.edgeless.service.surface.elementUpdated.subscribe(
this._updateOnSelectedChange
)
);
_disposables.add(
this.doc.slots.blockUpdated.on(this._updateOnSelectedChange)
this.doc.slots.blockUpdated.subscribe(this._updateOnSelectedChange)
);
_disposables.add(
@@ -410,19 +410,19 @@ export class EdgelessElementToolbarWidget extends WidgetComponent<
);
_disposables.add(
edgeless.slots.elementResizeStart.on(() => {
edgeless.slots.elementResizeStart.subscribe(() => {
this._dragging = true;
})
);
_disposables.add(
edgeless.slots.elementResizeEnd.on(() => {
edgeless.slots.elementResizeEnd.subscribe(() => {
this._dragging = false;
this._recalculatePosition();
})
);
_disposables.add(
edgeless.slots.readonlyUpdated.on(() => this.requestUpdate())
edgeless.slots.readonlyUpdated.subscribe(() => this.requestUpdate())
);
this.updateComplete
@@ -359,13 +359,18 @@ const pageToolGroup: KeyboardToolPanelGroup = {
const inlineEditor = getInlineEditorByModel(std.host, currentModel);
// Wait for range to be updated
inlineEditor?.slots.inlineRangeSync.once(() => {
linkedDocWidget.show({
mode: 'mobile',
addTriggerKey: true,
});
closeToolPanel();
});
if (inlineEditor) {
const subscription = inlineEditor.slots.inlineRangeSync.subscribe(
() => {
subscription.unsubscribe();
linkedDocWidget.show({
mode: 'mobile',
addTriggerKey: true,
});
closeToolPanel();
}
);
}
})
.run();
},
@@ -1,6 +1,6 @@
import { type VirtualKeyboardProvider } from '@blocksuite/affine-shared/services';
import type { BlockStdScope, ShadowlessElement } from '@blocksuite/block-std';
import { DisposableGroup } from '@blocksuite/global/slot';
import { DisposableGroup } from '@blocksuite/global/disposable';
import { effect, type Signal } from '@preact/signals-core';
import type { ReactiveController, ReactiveControllerHost } from 'lit';
@@ -199,7 +199,7 @@ export class AffineLinkedDocWidget extends WidgetComponent<
private _watchViewportChange() {
const gfx = this.std.get(GfxControllerIdentifier);
this.disposables.add(
gfx.viewport.viewportUpdated.on(() => {
gfx.viewport.viewportUpdated.subscribe(() => {
this._updateInputRects();
})
);
@@ -273,7 +273,7 @@ export class AffineLinkedDocWidget extends WidgetComponent<
});
}
const disposable = inlineEditor.slots.renderComplete.on(() => {
const disposable = inlineEditor.slots.renderComplete.subscribe(() => {
this._updateInputRects();
});
this._context = {
@@ -283,7 +283,7 @@ export class AffineLinkedDocWidget extends WidgetComponent<
triggerKey: primaryTriggerKey,
config: this.config,
close: () => {
disposable.dispose();
disposable.unsubscribe();
this._inputRects$.value = [];
this._mode$.value = 'none';
this._context = null;
@@ -183,9 +183,11 @@ export class LinkedDocPopover extends SignalWatcher(
if (isComposition) {
this._updateLinkedDocGroup().catch(console.error);
} else {
this.context.inlineEditor.slots.renderComplete.once(
this._updateLinkedDocGroup
);
const subscription =
this.context.inlineEditor.slots.renderComplete.subscribe(() => {
subscription.unsubscribe();
this._updateLinkedDocGroup().catch(console.error);
});
}
},
onPaste: () => {
@@ -201,9 +203,11 @@ export class LinkedDocPopover extends SignalWatcher(
if (curRange.index < this.context.startRange.index) {
this.context.close();
}
this.context.inlineEditor.slots.renderComplete.once(
this._updateLinkedDocGroup
);
const subscription =
this.context.inlineEditor.slots.renderComplete.subscribe(() => {
subscription.unsubscribe();
this._updateLinkedDocGroup().catch(console.error);
});
},
onMove: step => {
const itemLen = this._flattenActionList.length;
@@ -332,7 +336,9 @@ export class LinkedDocPopover extends SignalWatcher(
}
const gfx = this.context.std.get(GfxControllerIdentifier);
this.disposables.add(gfx.viewport.viewportUpdated.on(updatePosition));
this.disposables.add(
gfx.viewport.viewportUpdated.subscribe(updatePosition)
);
updatePosition();
}
@@ -196,20 +196,28 @@ export class AffineMobileLinkedDocMenu extends SignalWatcher(
if (isComposition) {
this._updateLinkedDocGroup().catch(console.error);
} else {
inlineEditor.slots.renderComplete.once(this._updateLinkedDocGroup);
const subscription = inlineEditor.slots.renderComplete.subscribe(
() => {
subscription.unsubscribe();
this._updateLinkedDocGroup().catch(console.error);
}
);
}
},
onDelete: () => {
inlineEditor.slots.renderComplete.once(() => {
const curRange = inlineEditor.getInlineRange();
const subscription = inlineEditor.slots.renderComplete.subscribe(
() => {
subscription.unsubscribe();
const curRange = inlineEditor.getInlineRange();
if (!this.context.startRange || !curRange) return;
if (!this.context.startRange || !curRange) return;
if (curRange.index < this.context.startRange.index) {
this.context.close();
if (curRange.index < this.context.startRange.index) {
this.context.close();
}
this._updateLinkedDocGroup().catch(console.error);
}
this._updateLinkedDocGroup().catch(console.error);
});
);
},
onConfirm: () => {
this._firstActionItem?.action()?.catch(console.error);
@@ -31,6 +31,7 @@
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
"nanoid": "^5.0.7",
"rxjs": "^7.8.1",
"zod": "^3.23.8"
},
"exports": {
@@ -30,7 +30,7 @@ export class SurfaceRefGenericBlockPortal extends WithDisposable(
override firstUpdated() {
this.disposables.add(
this.model.propsUpdated.on(() => this.requestUpdate())
this.model.propsUpdated.subscribe(() => this.requestUpdate())
);
}
@@ -62,7 +62,7 @@ export class SurfaceRefNotePortal extends WithDisposable(ShadowlessElement) {
override firstUpdated() {
this.disposables.add(
this.model.propsUpdated.on(() => this.requestUpdate())
this.model.propsUpdated.subscribe(() => this.requestUpdate())
);
}
@@ -36,13 +36,13 @@ import {
type GfxModel,
GfxPrimitiveElementModel,
} from '@blocksuite/block-std/gfx';
import { DisposableGroup } from '@blocksuite/global/disposable';
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
import {
Bound,
deserializeXYWH,
type SerializedXYWH,
} from '@blocksuite/global/gfx';
import { DisposableGroup } from '@blocksuite/global/slot';
import { DeleteIcon, EdgelessIcon, FrameIcon } from '@blocksuite/icons/lit';
import type { BaseSelection, Store } from '@blocksuite/store';
import { css, html, nothing, type TemplateResult } from 'lit';
@@ -376,7 +376,7 @@ export class SurfaceRefBlockComponent extends BlockComponent<SurfaceRefBlockMode
init();
this._disposables.add(
this.model.propsUpdated.on(payload => {
this.model.propsUpdated.subscribe(payload => {
if (
payload.key === 'reference' &&
this.model.reference !== this._referencedModel?.id
@@ -388,7 +388,7 @@ export class SurfaceRefBlockComponent extends BlockComponent<SurfaceRefBlockMode
if (surfaceModel && this._referencedModel instanceof SurfaceElementModel) {
this._disposables.add(
surfaceModel.elementRemoved.on(({ id }) => {
surfaceModel.elementRemoved.subscribe(({ id }) => {
if (this.model.reference === id) {
init();
}
@@ -398,7 +398,7 @@ export class SurfaceRefBlockComponent extends BlockComponent<SurfaceRefBlockMode
if (this._referencedModel instanceof GfxBlockElementModel) {
this._disposables.add(
this.doc.slots.blockUpdated.on(({ type, id }) => {
this.doc.slots.blockUpdated.subscribe(({ type, id }) => {
if (type === 'delete' && id === this.model.reference) {
init();
}
@@ -410,7 +410,7 @@ export class SurfaceRefBlockComponent extends BlockComponent<SurfaceRefBlockMode
private _initSelection() {
const selection = this.host.selection;
this._disposables.add(
selection.slots.changed.on(selList => {
selection.slots.changed.subscribe(selList => {
this._focused = selList.some(
sel => sel.blockId === this.blockId && sel.is(BlockSelection)
);
@@ -424,16 +424,16 @@ export class SurfaceRefBlockComponent extends BlockComponent<SurfaceRefBlockMode
static override readonly key = 'surfaceRefViewportInitializer';
override mounted() {
const disposable = this.std.view.viewUpdated.on(payload => {
const disposable = this.std.view.viewUpdated.subscribe(payload => {
if (payload.type !== 'block') return;
if (
payload.method === 'add' &&
matchModels(payload.view.model, [RootBlockModel])
) {
disposable.dispose();
disposable.unsubscribe();
queueMicrotask(() => refreshViewport());
const gfx = this.std.get(GfxControllerIdentifier);
gfx.viewport.sizeUpdated.on(() => {
gfx.viewport.sizeUpdated.subscribe(() => {
refreshViewport();
});
}
@@ -475,7 +475,7 @@ export class SurfaceRefBlockComponent extends BlockComponent<SurfaceRefBlockMode
);
} else if (referenceElement instanceof GfxPrimitiveElementModel) {
_disposable.add(
surfaceModel.elementUpdated.on(({ id, oldValues }) => {
surfaceModel.elementUpdated.subscribe(({ id, oldValues }) => {
if (
id === referenceId &&
oldValues.xywh !== referenceElement.xywh
@@ -31,6 +31,7 @@
"lodash-es": "^4.17.21",
"nanoid": "^5.0.7",
"pdf-lib": "^1.17.1",
"rxjs": "^7.8.1",
"yjs": "^13.6.21",
"zod": "^3.23.8"
},
@@ -1,40 +1,39 @@
import type { FrameBlockModel } from '@blocksuite/affine-model';
import { createIdentifier } from '@blocksuite/global/di';
import { Slot } from '@blocksuite/global/slot';
import type { ExtensionType } from '@blocksuite/store';
import { Subject } from 'rxjs';
export const EdgelessLegacySlotIdentifier = createIdentifier<{
readonlyUpdated: Slot<boolean>;
navigatorSettingUpdated: Slot<{
readonlyUpdated: Subject<boolean>;
navigatorSettingUpdated: Subject<{
hideToolbar?: boolean;
blackBackground?: boolean;
fillScreen?: boolean;
}>;
navigatorFrameChanged: Slot<FrameBlockModel>;
fullScreenToggled: Slot;
navigatorFrameChanged: Subject<FrameBlockModel>;
fullScreenToggled: Subject<void>;
elementResizeStart: Slot;
elementResizeEnd: Slot;
toggleNoteSlicer: Slot;
elementResizeStart: Subject<void>;
elementResizeEnd: Subject<void>;
toggleNoteSlicer: Subject<void>;
toolbarLocked: Slot<boolean>;
toolbarLocked: Subject<boolean>;
}>('AffineEdgelessLegacySlotService');
export const EdgelessLegacySlotExtension: ExtensionType = {
setup: di => {
di.addImpl(EdgelessLegacySlotIdentifier, () => ({
readonlyUpdated: new Slot<boolean>(),
navigatorSettingUpdated: new Slot<{
readonlyUpdated: new Subject<boolean>(),
navigatorSettingUpdated: new Subject<{
hideToolbar?: boolean;
blackBackground?: boolean;
fillScreen?: boolean;
}>(),
navigatorFrameChanged: new Slot<FrameBlockModel>(),
fullScreenToggled: new Slot(),
elementResizeStart: new Slot(),
elementResizeEnd: new Slot(),
toggleNoteSlicer: new Slot(),
toolbarLocked: new Slot<boolean>(),
navigatorFrameChanged: new Subject<FrameBlockModel>(),
fullScreenToggled: new Subject(),
elementResizeStart: new Subject(),
elementResizeEnd: new Subject(),
toggleNoteSlicer: new Subject(),
toolbarLocked: new Subject<boolean>(),
}));
},
};
@@ -6,10 +6,11 @@ import type {
SurfaceBlockModel,
Viewport,
} from '@blocksuite/block-std/gfx';
import { DisposableGroup } from '@blocksuite/global/disposable';
import type { IBound } from '@blocksuite/global/gfx';
import { getBoundWithRotation, intersects } from '@blocksuite/global/gfx';
import { DisposableGroup, Slot } from '@blocksuite/global/slot';
import last from 'lodash-es/last';
import { Subject } from 'rxjs';
import type { SurfaceElementModel } from '../element-model/base.js';
import { RoughCanvas } from '../utils/rough/canvas.js';
@@ -58,7 +59,7 @@ export class CanvasRenderer {
provider: Partial<EnvProvider>;
stackingCanvasUpdated = new Slot<{
stackingCanvasUpdated = new Subject<{
canvases: HTMLCanvasElement[];
added: HTMLCanvasElement[];
removed: HTMLCanvasElement[];
@@ -175,14 +176,14 @@ export class CanvasRenderer {
payload.removed = currentCanvases.slice(diff);
}
this.stackingCanvasUpdated.emit(payload);
this.stackingCanvasUpdated.next(payload);
}
this.refresh();
};
this._disposables.add(
this.layerManager.slots.layerUpdated.on(() => {
this.layerManager.slots.layerUpdated.subscribe(() => {
updateStackingCanvas();
})
);
@@ -194,13 +195,13 @@ export class CanvasRenderer {
let sizeUpdatedRafId: number | null = null;
this._disposables.add(
this.viewport.viewportUpdated.on(() => {
this.viewport.viewportUpdated.subscribe(() => {
this.refresh();
})
);
this._disposables.add(
this.viewport.sizeUpdated.on(() => {
this.viewport.sizeUpdated.subscribe(() => {
if (sizeUpdatedRafId) return;
sizeUpdatedRafId = requestConnectedFrame(() => {
sizeUpdatedRafId = null;
@@ -319,20 +320,24 @@ export class CanvasRenderer {
}
private _watchSurface(surfaceModel: SurfaceBlockModel) {
const slots = [
'elementAdded',
'elementRemoved',
'localElementAdded',
'localElementDeleted',
'localElementUpdated',
] as const;
slots.forEach(slotName => {
this._disposables.add(surfaceModel[slotName].on(() => this.refresh()));
});
this._disposables.add(
surfaceModel.elementAdded.subscribe(() => this.refresh())
);
this._disposables.add(
surfaceModel.elementRemoved.subscribe(() => this.refresh())
);
this._disposables.add(
surfaceModel.localElementAdded.subscribe(() => this.refresh())
);
this._disposables.add(
surfaceModel.localElementDeleted.subscribe(() => this.refresh())
);
this._disposables.add(
surfaceModel.localElementUpdated.subscribe(() => this.refresh())
);
this._disposables.add(
surfaceModel.elementUpdated.on(payload => {
surfaceModel.elementUpdated.subscribe(payload => {
// ignore externalXYWH update cause it's updated by the renderer
if (payload.props['externalXYWH']) return;
this.refresh();
@@ -7,9 +7,9 @@ import {
type Viewport,
} from '@blocksuite/block-std/gfx';
import { Bound } from '@blocksuite/global/gfx';
import type { Slot } from '@blocksuite/global/slot';
import { css, html } from 'lit';
import { query } from 'lit/decorators.js';
import type { Subject } from 'rxjs';
import { ConnectorElementModel } from './element-model/index.js';
import { CanvasRenderer } from './renderer/canvas-renderer.js';
@@ -28,7 +28,7 @@ export interface SurfaceContext {
selection: {
selectedIds: string[];
slots: {
updated: Slot<SurfaceSelection[]>;
updated: Subject<SurfaceSelection[]>;
};
};
}
@@ -191,7 +191,7 @@ export class SurfaceBlockComponent extends BlockComponent<
this._renderer.dispose();
});
this._disposables.add(
this._renderer.stackingCanvasUpdated.on(payload => {
this._renderer.stackingCanvasUpdated.subscribe(payload => {
if (payload.added.length) {
this._surfaceContainer.append(...payload.added);
}
@@ -204,7 +204,7 @@ export class SurfaceBlockComponent extends BlockComponent<
})
);
this._disposables.add(
gfx.selection.slots.updated.on(() => {
gfx.selection.slots.updated.subscribe(() => {
this._renderer.refresh();
})
);
@@ -4,7 +4,7 @@ import type {
} from '@blocksuite/affine-model';
import type { SurfaceBlockProps } from '@blocksuite/block-std/gfx';
import { SurfaceBlockModel as BaseSurfaceModel } from '@blocksuite/block-std/gfx';
import { DisposableGroup } from '@blocksuite/global/slot';
import { DisposableGroup } from '@blocksuite/global/disposable';
import { BlockSchemaExtension, defineBlockSchema } from '@blocksuite/store';
import * as Y from 'yjs';

Some files were not shown because too many files have changed in this diff Show More