refactor(editor): remove legacy service watcher (#10455)

The main changes in this PR involve replacing the deprecated `BlockServiceWatcher` with the new `LifeCycleWatcher` across multiple files. Here's a detailed breakdown:

1. **Core Architectural Change:**
   - Removed `BlockServiceWatcher` class completely (deleted file)
   - Migrated to `LifeCycleWatcher` as the new standard for watching component lifecycle events

2. **Key Changes in Implementation:**
   - Changed from using `blockService.specSlots` events to using `view.viewUpdated` events
   - Replaced `flavour` static property with `key` static property
   - Updated event handling to use more specific payload type checking

3. **Major File Changes:**
   - Modified multiple block components:
     - Embed synced doc block
     - Frame preview
     - Edgeless root spec
     - AI-related components (code, image, paragraph, etc.)
     - Quick search service
     - Edgeless clipboard

4. **Pattern of Changes:**
   The migration follows a consistent pattern:
   ```typescript
   // Old pattern
   class SomeWatcher extends BlockServiceWatcher {
     static override readonly flavour = 'some:flavour';
     mounted() {
       this.blockService.specSlots.viewConnected.on(...)
     }
   }

   // New pattern
   class SomeWatcher extends LifeCycleWatcher {
     static override key = 'some-watcher';
     mounted() {
       const { view } = this.std;
       view.viewUpdated.on(payload => {
         if (payload.type !== 'block' || payload.method !== 'add') return;
         // Handle event
       });
     }
   }
   ```

5. **Benefits:**
   - More explicit and type-safe event handling
   - Cleaner architecture by removing deprecated code
   - More consistent approach to lifecycle management
   - Better separation of concerns

This appears to be a significant architectural improvement that modernizes the codebase by removing deprecated patterns and standardizing on a more robust lifecycle management system.
This commit is contained in:
Saul-Mirone
2025-02-26 15:15:45 +00:00
parent fd6d96a38e
commit 2c79d7229f
13 changed files with 208 additions and 245 deletions

View File

@@ -26,9 +26,9 @@ import {
} from '@blocksuite/affine-shared/utils'; } from '@blocksuite/affine-shared/utils';
import { import {
BlockSelection, BlockSelection,
BlockServiceWatcher,
BlockStdScope, BlockStdScope,
type EditorHost, type EditorHost,
LifeCycleWatcher,
} from '@blocksuite/block-std'; } from '@blocksuite/block-std';
import { import {
GfxControllerIdentifier, GfxControllerIdentifier,
@@ -124,27 +124,31 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
this.std.getOptional(EditorSettingProvider) ?? this.std.getOptional(EditorSettingProvider) ??
signal(GeneralSettingSchema.parse({})); signal(GeneralSettingSchema.parse({}));
class EmbedSyncedDocWatcher extends BlockServiceWatcher { class EmbedSyncedDocWatcher extends LifeCycleWatcher {
static override readonly flavour = 'affine:embed-synced-doc'; static override key = 'embed-synced-doc-watcher';
override mounted() { override mounted(): void {
const disposableGroup = this.blockService.disposables; const { view } = this.std;
const slots = this.blockService.specSlots; view.viewUpdated.on(payload => {
disposableGroup.add( if (
slots.viewConnected.on(({ component }) => { payload.type !== 'block' ||
const nextComponent = component as EmbedSyncedDocBlockComponent; payload.view.model.flavour !== 'affine:embed-synced-doc'
) {
return;
}
const nextComponent = payload.view as EmbedSyncedDocBlockComponent;
if (payload.method === 'add') {
nextComponent.depth = nextDepth; nextComponent.depth = nextDepth;
currentDisposables.add(() => { currentDisposables.add(() => {
nextComponent.depth = 0; nextComponent.depth = 0;
}); });
}) return;
); }
disposableGroup.add( if (payload.method === 'delete') {
slots.viewDisconnected.on(({ component }) => {
const nextComponent = component as EmbedSyncedDocBlockComponent;
nextComponent.depth = 0; nextComponent.depth = 0;
}) return;
); }
});
} }
} }

View File

@@ -1,9 +1,9 @@
import type { FrameBlockModel } from '@blocksuite/affine-model'; import type { FrameBlockModel } from '@blocksuite/affine-model';
import { SpecProvider } from '@blocksuite/affine-shared/utils'; import { SpecProvider } from '@blocksuite/affine-shared/utils';
import { import {
BlockServiceWatcher,
BlockStdScope, BlockStdScope,
type EditorHost, type EditorHost,
LifeCycleWatcher,
ShadowlessElement, ShadowlessElement,
} from '@blocksuite/block-std'; } from '@blocksuite/block-std';
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx'; import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
@@ -117,22 +117,26 @@ export class FramePreview extends WithDisposable(ShadowlessElement) {
private _initSpec() { private _initSpec() {
const refreshViewport = this._refreshViewport.bind(this); const refreshViewport = this._refreshViewport.bind(this);
class FramePreviewWatcher extends BlockServiceWatcher { class FramePreviewWatcher extends LifeCycleWatcher {
static override readonly flavour = 'affine:page'; static override key = 'frame-preview-watcher';
override mounted() { override mounted() {
const blockService = this.blockService; const { view } = this.std;
blockService.disposables.add( view.viewUpdated.on(payload => {
blockService.specSlots.viewConnected.on(({ component }) => { if (
payload.type !== 'block' ||
payload.method !== 'add' ||
payload.view.model.flavour !== 'affine:page'
) {
return;
}
const edgelessBlock = const edgelessBlock =
component as EdgelessRootPreviewBlockComponent; payload.view as EdgelessRootPreviewBlockComponent;
edgelessBlock.editorViewportSelector = 'frame-preview-viewport'; edgelessBlock.editorViewportSelector = 'frame-preview-viewport';
edgelessBlock.service.viewport.sizeUpdated.once(() => { edgelessBlock.service.viewport.sizeUpdated.once(() => {
refreshViewport(); refreshViewport();
}); });
}) });
);
} }
} }
this._previewSpec.extend([FramePreviewWatcher]); this._previewSpec.extend([FramePreviewWatcher]);

View File

@@ -2,11 +2,14 @@ import { autoConnectWidget } from '@blocksuite/affine-widget-edgeless-auto-conne
import { frameTitleWidget } from '@blocksuite/affine-widget-frame-title'; import { frameTitleWidget } from '@blocksuite/affine-widget-frame-title';
import { edgelessRemoteSelectionWidget } from '@blocksuite/affine-widget-remote-selection'; import { edgelessRemoteSelectionWidget } from '@blocksuite/affine-widget-remote-selection';
import { import {
BlockServiceWatcher,
BlockViewExtension, BlockViewExtension,
LifeCycleWatcher,
WidgetViewExtension, WidgetViewExtension,
} from '@blocksuite/block-std'; } from '@blocksuite/block-std';
import { ToolController } from '@blocksuite/block-std/gfx'; import {
GfxControllerIdentifier,
ToolController,
} from '@blocksuite/block-std/gfx';
import type { ExtensionType } from '@blocksuite/store'; import type { ExtensionType } from '@blocksuite/store';
import { literal, unsafeStatic } from 'lit/static-html.js'; import { literal, unsafeStatic } from 'lit/static-html.js';
@@ -56,17 +59,12 @@ export const edgelessToolbarWidget = WidgetViewExtension(
literal`${unsafeStatic(EDGELESS_TOOLBAR_WIDGET)}` literal`${unsafeStatic(EDGELESS_TOOLBAR_WIDGET)}`
); );
class EdgelessLocker extends BlockServiceWatcher { class EdgelessLocker extends LifeCycleWatcher {
static override readonly flavour = 'affine:page'; static override key = 'edgeless-locker';
override mounted() { override mounted() {
const service = this.blockService; const { viewport } = this.std.get(GfxControllerIdentifier);
service.disposables.add( viewport.locked = true;
service.specSlots.viewConnected.on(({ service }) => {
// Does not allow the user to move and zoom.
(service as EdgelessRootService).locked = true;
})
);
} }
} }

View File

@@ -5,5 +5,4 @@ export * from './flavour.js';
export * from './keymap.js'; export * from './keymap.js';
export * from './lifecycle-watcher.js'; export * from './lifecycle-watcher.js';
export * from './service.js'; export * from './service.js';
export * from './service-watcher.js';
export * from './widget-view-map.js'; export * from './widget-view-map.js';

View File

@@ -1,47 +0,0 @@
import type { Container } from '@blocksuite/global/di';
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
import {
BlockServiceIdentifier,
LifeCycleWatcherIdentifier,
StdIdentifier,
} from '../identifier.js';
import type { BlockStdScope } from '../scope/index.js';
import { LifeCycleWatcher } from './lifecycle-watcher.js';
import type { BlockService } from './service.js';
const idMap = new Map<string, number>();
/**
* @deprecated
* BlockServiceWatcher is deprecated. You should reconsider where to put your feature.
*
* BlockServiceWatcher is a legacy extension that is used to watch the slots registered on block service.
* However, we recommend using the new extension system.
*/
export abstract class BlockServiceWatcher extends LifeCycleWatcher {
static flavour: string;
constructor(
std: BlockStdScope,
readonly blockService: BlockService
) {
super(std);
}
static override setup(di: Container) {
if (!this.flavour) {
throw new BlockSuiteError(
ErrorCode.ValueNotExists,
'Flavour is not defined in the BlockServiceWatcher'
);
}
const id = idMap.get(this.flavour) ?? 0;
idMap.set(this.flavour, id + 1);
di.addImpl(
LifeCycleWatcherIdentifier(`${this.flavour}-watcher-${id}`),
this,
[StdIdentifier, BlockServiceIdentifier(this.flavour)]
);
}
}

View File

@@ -1,4 +1,4 @@
import { BlockServiceWatcher } from '@blocksuite/affine/block-std'; import { LifeCycleWatcher } from '@blocksuite/affine/block-std';
import { import {
AffineCodeToolbarWidget, AffineCodeToolbarWidget,
CodeBlockSpec, CodeBlockSpec,
@@ -7,15 +7,19 @@ import type { ExtensionType } from '@blocksuite/affine/store';
import { setupCodeToolbarAIEntry } from '../entries/code-toolbar/setup-code-toolbar'; import { setupCodeToolbarAIEntry } from '../entries/code-toolbar/setup-code-toolbar';
class AICodeBlockWatcher extends BlockServiceWatcher { class AICodeBlockWatcher extends LifeCycleWatcher {
static override readonly flavour = 'affine:code'; static override key = 'ai-code-block-watcher';
override mounted() { override mounted() {
super.mounted(); super.mounted();
const service = this.blockService; const { view } = this.std;
service.specSlots.widgetConnected.on(view => { view.viewUpdated.on(payload => {
if (view.component instanceof AffineCodeToolbarWidget) { if (payload.type !== 'widget' || payload.method !== 'add') {
setupCodeToolbarAIEntry(view.component); return;
}
const component = payload.view;
if (component instanceof AffineCodeToolbarWidget) {
setupCodeToolbarAIEntry(component);
} }
}); });
} }

View File

@@ -1,4 +1,4 @@
import { BlockServiceWatcher } from '@blocksuite/affine/block-std'; import { LifeCycleWatcher } from '@blocksuite/affine/block-std';
import { import {
AffineFormatBarWidget, AffineFormatBarWidget,
AffineSlashMenuWidget, AffineSlashMenuWidget,
@@ -39,32 +39,37 @@ export function createAIEdgelessRootBlockSpec(
} }
function getAIEdgelessRootWatcher(framework: FrameworkProvider) { function getAIEdgelessRootWatcher(framework: FrameworkProvider) {
class AIEdgelessRootWatcher extends BlockServiceWatcher { class AIEdgelessRootWatcher extends LifeCycleWatcher {
static override readonly flavour = 'affine:page'; static override key = 'ai-edgeless-root-watcher';
override mounted() { override mounted() {
super.mounted(); super.mounted();
this.blockService.specSlots.widgetConnected.on(view => { const { view } = this.std;
if (view.component instanceof AffineAIPanelWidget) { view.viewUpdated.on(payload => {
view.component.style.width = '430px'; if (payload.type !== 'widget' || payload.method !== 'add') {
view.component.config = buildAIPanelConfig(view.component, framework); return;
setupSpaceAIEntry(view.component); }
const component = payload.view;
if (component instanceof AffineAIPanelWidget) {
component.style.width = '430px';
component.config = buildAIPanelConfig(component, framework);
setupSpaceAIEntry(component);
} }
if (view.component instanceof EdgelessCopilotWidget) { if (component instanceof EdgelessCopilotWidget) {
setupEdgelessCopilot(view.component); setupEdgelessCopilot(component);
} }
if (view.component instanceof EdgelessElementToolbarWidget) { if (component instanceof EdgelessElementToolbarWidget) {
setupEdgelessElementToolbarAIEntry(view.component); setupEdgelessElementToolbarAIEntry(component);
} }
if (view.component instanceof AffineFormatBarWidget) { if (component instanceof AffineFormatBarWidget) {
setupFormatBarAIEntry(view.component); setupFormatBarAIEntry(component);
} }
if (view.component instanceof AffineSlashMenuWidget) { if (component instanceof AffineSlashMenuWidget) {
setupSlashMenuAIEntry(view.component); setupSlashMenuAIEntry(component);
} }
}); });
} }

View File

@@ -1,4 +1,4 @@
import { BlockServiceWatcher } from '@blocksuite/affine/block-std'; import { LifeCycleWatcher } from '@blocksuite/affine/block-std';
import { import {
AffineImageToolbarWidget, AffineImageToolbarWidget,
ImageBlockSpec, ImageBlockSpec,
@@ -7,14 +7,19 @@ import type { ExtensionType } from '@blocksuite/affine/store';
import { setupImageToolbarAIEntry } from '../entries/image-toolbar/setup-image-toolbar'; import { setupImageToolbarAIEntry } from '../entries/image-toolbar/setup-image-toolbar';
class AIImageBlockWatcher extends BlockServiceWatcher { class AIImageBlockWatcher extends LifeCycleWatcher {
static override readonly flavour = 'affine:image'; static override key = 'ai-image-block-watcher';
override mounted() { override mounted() {
super.mounted(); super.mounted();
this.blockService.specSlots.widgetConnected.on(view => { const { view } = this.std;
if (view.component instanceof AffineImageToolbarWidget) { view.viewUpdated.on(payload => {
setupImageToolbarAIEntry(view.component); if (payload.type !== 'widget' || payload.method !== 'add') {
return;
}
const component = payload.view;
if (component instanceof AffineImageToolbarWidget) {
setupImageToolbarAIEntry(component);
} }
}); });
} }

View File

@@ -1,4 +1,4 @@
import { BlockServiceWatcher } from '@blocksuite/affine/block-std'; import { LifeCycleWatcher } from '@blocksuite/affine/block-std';
import { import {
AffineFormatBarWidget, AffineFormatBarWidget,
AffineSlashMenuWidget, AffineSlashMenuWidget,
@@ -17,24 +17,29 @@ import {
} from '../widgets/ai-panel/ai-panel'; } from '../widgets/ai-panel/ai-panel';
function getAIPageRootWatcher(framework: FrameworkProvider) { function getAIPageRootWatcher(framework: FrameworkProvider) {
class AIPageRootWatcher extends BlockServiceWatcher { class AIPageRootWatcher extends LifeCycleWatcher {
static override readonly flavour = 'affine:page'; static override key = 'ai-page-root-watcher';
override mounted() { override mounted() {
super.mounted(); super.mounted();
this.blockService.specSlots.widgetConnected.on(view => { const { view } = this.std;
if (view.component instanceof AffineAIPanelWidget) { view.viewUpdated.on(payload => {
view.component.style.width = '630px'; if (payload.type !== 'widget' || payload.method !== 'add') {
view.component.config = buildAIPanelConfig(view.component, framework); return;
setupSpaceAIEntry(view.component); }
const component = payload.view;
if (component instanceof AffineAIPanelWidget) {
component.style.width = '630px';
component.config = buildAIPanelConfig(component, framework);
setupSpaceAIEntry(component);
} }
if (view.component instanceof AffineFormatBarWidget) { if (component instanceof AffineFormatBarWidget) {
setupFormatBarAIEntry(view.component); setupFormatBarAIEntry(component);
} }
if (view.component instanceof AffineSlashMenuWidget) { if (component instanceof AffineSlashMenuWidget) {
setupSlashMenuAIEntry(view.component); setupSlashMenuAIEntry(component);
} }
}); });
} }

View File

@@ -1,18 +1,16 @@
import { BlockServiceWatcher } from '@blocksuite/affine/block-std'; import { LifeCycleWatcher } from '@blocksuite/affine/block-std';
import { import {
ParagraphBlockService, ParagraphBlockService,
ParagraphBlockSpec, ParagraphBlockSpec,
} from '@blocksuite/affine/blocks'; } from '@blocksuite/affine/blocks';
import { assertInstanceOf } from '@blocksuite/affine/global/utils';
import type { ExtensionType } from '@blocksuite/affine/store'; import type { ExtensionType } from '@blocksuite/affine/store';
class AIParagraphBlockWatcher extends BlockServiceWatcher { class AIParagraphBlockWatcher extends LifeCycleWatcher {
static override readonly flavour = 'affine:paragraph'; static override key = 'ai-paragraph-block-watcher';
override mounted() { override mounted() {
super.mounted(); super.mounted();
const service = this.blockService; const service = this.std.get(ParagraphBlockService);
assertInstanceOf(service, ParagraphBlockService);
service.placeholderGenerator = model => { service.placeholderGenerator = model => {
if (model.type === 'text') { if (model.type === 'text') {
return "Type '/' for commands, 'space' for AI"; return "Type '/' for commands, 'space' for AI";

View File

@@ -1,27 +1,26 @@
import { AIChatBlockSchema } from '@affine/core/blocksuite/ai/blocks'; import { AIChatBlockSchema } from '@affine/core/blocksuite/ai/blocks';
import { BlockServiceWatcher } from '@blocksuite/affine/block-std'; import { LifeCycleWatcher } from '@blocksuite/affine/block-std';
import { EdgelessRootBlockComponent } from '@blocksuite/affine/blocks'; import { EdgelessRootBlockComponent } from '@blocksuite/affine/blocks';
import type { BlockSnapshot } from '@blocksuite/affine/store'; import type { BlockSnapshot } from '@blocksuite/affine/store';
export class EdgelessClipboardWatcher extends BlockServiceWatcher { export class EdgelessClipboardWatcher extends LifeCycleWatcher {
static override readonly flavour = 'affine:page'; static override key = 'edgeless-clipboard-watcher';
override mounted() { override mounted() {
super.mounted(); super.mounted();
this.blockService.disposables.add( const { view } = this.std;
this.blockService.specSlots.viewConnected.on(view => { view.viewUpdated.on(payload => {
const { component } = view; if (payload.type !== 'block' || payload.method !== 'add') {
if (component instanceof EdgelessRootBlockComponent) { return;
}
const component = payload.view;
if (!(component instanceof EdgelessRootBlockComponent)) {
return;
}
const AIChatBlockFlavour = AIChatBlockSchema.model.flavour; const AIChatBlockFlavour = AIChatBlockSchema.model.flavour;
const createFunc = (block: BlockSnapshot) => { const createFunc = (block: BlockSnapshot) => {
const { const { xywh, scale, messages, sessionId, rootDocId, rootWorkspaceId } =
xywh, block.props;
scale,
messages,
sessionId,
rootDocId,
rootWorkspaceId,
} = block.props;
const blockId = component.service.crud.addBlock( const blockId = component.service.crud.addBlock(
AIChatBlockFlavour, AIChatBlockFlavour,
{ {
@@ -40,8 +39,6 @@ export class EdgelessClipboardWatcher extends BlockServiceWatcher {
AIChatBlockFlavour, AIChatBlockFlavour,
createFunc createFunc
); );
} });
})
);
} }
} }

View File

@@ -10,10 +10,7 @@ import {
import { ExternalLinksQuickSearchSession } from '@affine/core/modules/quicksearch/impls/external-links'; import { ExternalLinksQuickSearchSession } from '@affine/core/modules/quicksearch/impls/external-links';
import { JournalsQuickSearchSession } from '@affine/core/modules/quicksearch/impls/journals'; import { JournalsQuickSearchSession } from '@affine/core/modules/quicksearch/impls/journals';
import { track } from '@affine/track'; import { track } from '@affine/track';
import { import { LifeCycleWatcher } from '@blocksuite/affine/block-std';
BlockServiceWatcher,
type WidgetComponent,
} from '@blocksuite/affine/block-std';
import type { QuickSearchResult } from '@blocksuite/affine/blocks'; import type { QuickSearchResult } from '@blocksuite/affine/blocks';
import { import {
AffineSlashMenuWidget, AffineSlashMenuWidget,
@@ -123,9 +120,17 @@ export function patchQuickSearchService(framework: FrameworkProvider) {
}, },
}); });
const SlashMenuQuickSearchExtension = patchSpecService( class SlashMenuQuickSearchExtension extends LifeCycleWatcher {
'affine:page', static override key = 'slash-menu-quick-search-extension';
(component: WidgetComponent) => {
override mounted() {
super.mounted();
const { view } = this.std;
view.viewUpdated.on(payload => {
if (payload.type !== 'widget' || payload.method !== 'add') {
return;
}
const component = payload.view;
if (component instanceof AffineSlashMenuWidget) { if (component instanceof AffineSlashMenuWidget) {
component.config.items.forEach(item => { component.config.items.forEach(item => {
if ( if (
@@ -134,7 +139,9 @@ export function patchQuickSearchService(framework: FrameworkProvider) {
) { ) {
item.action = async ({ rootComponent }) => { item.action = async ({ rootComponent }) => {
const [success, { insertedLinkType }] = const [success, { insertedLinkType }] =
rootComponent.std.command.exec(insertLinkByQuickSearchCommand); rootComponent.std.command.exec(
insertLinkByQuickSearchCommand
);
if (!success) return; if (!success) return;
@@ -160,28 +167,9 @@ export function patchQuickSearchService(framework: FrameworkProvider) {
} }
}); });
} }
});
} }
); }
return [QuickSearch, SlashMenuQuickSearchExtension]; return [QuickSearch, SlashMenuQuickSearchExtension];
} }
function patchSpecService(
flavour: string,
onWidgetConnected?: (component: WidgetComponent) => void
) {
class TempServiceWatcher extends BlockServiceWatcher {
static override readonly flavour = flavour;
override mounted() {
super.mounted();
const disposableGroup = this.blockService.disposables;
if (onWidgetConnected) {
disposableGroup.add(
this.blockService.specSlots.widgetConnected.on(({ component }) => {
onWidgetConnected(component);
})
);
}
}
}
return TempServiceWatcher;
}

View File

@@ -2,16 +2,14 @@ import { Skeleton } from '@affine/component';
import type { EditorSettingSchema } from '@affine/core/modules/editor-setting'; import type { EditorSettingSchema } from '@affine/core/modules/editor-setting';
import { EditorSettingService } from '@affine/core/modules/editor-setting'; import { EditorSettingService } from '@affine/core/modules/editor-setting';
import type { EditorHost } from '@blocksuite/affine/block-std'; import type { EditorHost } from '@blocksuite/affine/block-std';
import { import { BlockStdScope } from '@blocksuite/affine/block-std';
BlockServiceIdentifier,
BlockStdScope,
} from '@blocksuite/affine/block-std';
import { import {
GfxControllerIdentifier, GfxControllerIdentifier,
type GfxPrimitiveElementModel, type GfxPrimitiveElementModel,
} from '@blocksuite/affine/block-std/gfx'; } from '@blocksuite/affine/block-std/gfx';
import { import {
EdgelessCRUDIdentifier, EdgelessCRUDIdentifier,
type EdgelessRootPreviewBlockComponent,
SpecProvider, SpecProvider,
} from '@blocksuite/affine/blocks'; } from '@blocksuite/affine/blocks';
import { Bound } from '@blocksuite/affine/global/utils'; import { Bound } from '@blocksuite/affine/global/utils';
@@ -93,14 +91,18 @@ export const EdgelessSnapshot = (props: Props) => {
} }
// refresh viewport // refresh viewport
const edgelessService = editorHost.std.get(
BlockServiceIdentifier('affine:page')
);
const gfx = editorHost.std.get(GfxControllerIdentifier); const gfx = editorHost.std.get(GfxControllerIdentifier);
edgelessService.specSlots.viewConnected.once(({ component }) => { const disposable = editorHost.std.view.viewUpdated.on(payload => {
const edgelessBlock = component as any; if (
payload.type !== 'block' ||
payload.method !== 'add' ||
payload.view.model.flavour !== 'affine:page'
) {
return;
}
const component = payload.view as EdgelessRootPreviewBlockComponent;
doc.readonly = false; doc.readonly = false;
edgelessBlock.editorViewportSelector = 'ref-viewport'; component.editorViewportSelector = 'ref-viewport';
const frame = getFrameBlock(doc); const frame = getFrameBlock(doc);
if (frame && docName !== 'frame') { if (frame && docName !== 'frame') {
// docName with value 'frame' shouldn't be deleted, it is a part of frame settings // docName with value 'frame' shouldn't be deleted, it is a part of frame settings
@@ -110,6 +112,7 @@ export const EdgelessSnapshot = (props: Props) => {
const bound = boundMap.get(docName); const bound = boundMap.get(docName);
bound && gfx.viewport.setViewportByBound(bound); bound && gfx.viewport.setViewportByBound(bound);
doc.readonly = true; doc.readonly = true;
disposable.dispose();
}); });
// append to dom node // append to dom node