refactor(editor): move frame related component to frame panel (#10735)

This commit is contained in:
Saul-Mirone
2025-03-10 05:45:18 +00:00
parent 6b0639facd
commit 36cf973372
13 changed files with 64 additions and 54 deletions

View File

@@ -1,6 +1,7 @@
import {
EditPropsStore,
ThemeProvider,
ViewportElementProvider,
} from '@blocksuite/affine-shared/services';
import { Bound } from '@blocksuite/global/gfx';
import {
@@ -240,7 +241,8 @@ export class EdgelessDraggableElementController<T>
// Cannot get edgeless.host.getBoundingClientRect().width in Safari (Always 0)
const edgelessRect = edgeless.host.getBoundingClientRect();
if (edgelessRect.width === 0) {
edgelessRect.width = edgeless.viewport.clientWidth;
const { viewport } = edgeless.std.get(ViewportElementProvider);
edgelessRect.width = viewport.clientWidth;
}
this.info = {

View File

@@ -6,6 +6,7 @@ import type {
import {
EditPropsStore,
ThemeProvider,
ViewportElementProvider,
} from '@blocksuite/affine-shared/services';
import type { GfxToolsFullOptionValue } from '@blocksuite/block-std/gfx';
import type { Bound } from '@blocksuite/global/gfx';
@@ -309,7 +310,8 @@ export class EdgelessMindmapToolButton extends EdgelessToolbarToolMixin(
this.setEdgelessTool({ type: 'empty' });
const icon = this.mindmapElement;
const { x, y } = service.gfx.tool.lastMousePos$.peek();
const { left, top } = this.edgeless.viewport;
const { viewport } = this.edgeless.std.get(ViewportElementProvider);
const { left, top } = viewport;
const clientPos = { x: x + left, y: y + top };
this.draggableController.clickToDrag(icon, clientPos);
},

View File

@@ -11,6 +11,7 @@ import {
EditPropsStore,
TelemetryProvider,
ThemeProvider,
ViewportElementProvider,
} from '@blocksuite/affine-shared/services';
import { SignalWatcher } from '@blocksuite/global/lit';
import { css, html, LitElement, nothing } from 'lit';
@@ -253,7 +254,8 @@ export class EdgelessToolbarShapeDraggable extends EdgelessToolbarToolMixin(
return;
}
const { x, y } = service.gfx.tool.lastMousePos$.peek();
const { left, top } = this.edgeless.viewport;
const { viewport } = this.edgeless.std.get(ViewportElementProvider);
const { left, top } = viewport;
const clientPos = { x: x + left, y: y + top };
this.draggableController.clickToDrag(el, clientPos);
},

View File

@@ -22,7 +22,6 @@ import {
ThemeProvider,
ViewportElementProvider,
} from '@blocksuite/affine-shared/services';
import type { Viewport } from '@blocksuite/affine-shared/types';
import {
isTouchPadPinchEvent,
matchModels,
@@ -158,14 +157,6 @@ export class EdgelessRootBlockComponent extends BlockComponent<
) as SurfaceBlockModel;
}
/**
* Don't confuse with `gfx.viewport` which is edgeless-only concept.
* This refers to the wrapper element of the EditorHost.
*/
get viewport(): Viewport {
return this.std.get(ViewportElementProvider).viewport;
}
get viewportElement(): HTMLElement {
return this.std.get(ViewportElementProvider).viewportElement;
}

View File

@@ -1,4 +1,5 @@
import {
EdgelessCRUDIdentifier,
getBgGridGap,
type SurfaceBlockComponent,
type SurfaceBlockModel,
@@ -16,7 +17,10 @@ import {
type GfxBlockComponent,
SurfaceSelection,
} from '@blocksuite/block-std';
import type { GfxViewportElement } from '@blocksuite/block-std/gfx';
import {
GfxControllerIdentifier,
type GfxViewportElement,
} from '@blocksuite/block-std/gfx';
import { css, html } from 'lit';
import { query, state } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js';
@@ -87,6 +91,10 @@ export class EdgelessRootPreviewBlockComponent extends BlockComponent<
return this.service?.uiEventDispatcher;
}
private get _gfx() {
return this.std.get(GfxControllerIdentifier);
}
get surfaceBlockModel() {
return this.model.children.find(
child => child.flavour === 'affine:surface'
@@ -118,7 +126,7 @@ export class EdgelessRootPreviewBlockComponent extends BlockComponent<
});
this._disposables.add(
this.service.layer.slots.layerUpdated.on(() => updateLayers())
this._gfx.layer.slots.layerUpdated.on(() => updateLayers())
);
}
@@ -127,7 +135,7 @@ export class EdgelessRootPreviewBlockComponent extends BlockComponent<
const onPixelRatioChange = () => {
if (media) {
this.service.viewport.onResize();
this._gfx.viewport.onResize();
media.removeEventListener('change', onPixelRatioChange);
}
@@ -144,13 +152,8 @@ export class EdgelessRootPreviewBlockComponent extends BlockComponent<
private _initResizeEffect() {
const resizeObserver = new ResizeObserver((_: ResizeObserverEntry[]) => {
// FIXME: find a better way to get rid of empty check
if (!this.service || !this.service.selection || !this.service.viewport) {
console.error('Service is not ready');
return;
}
this.service.selection.set(this.service.selection.surfaceSelections);
this.service.viewport.onResize();
this._gfx.selection.set(this._gfx.selection.surfaceSelections);
this._gfx.viewport.onResize();
});
try {
@@ -177,6 +180,10 @@ export class EdgelessRootPreviewBlockComponent extends BlockComponent<
return editorSetting?.peek().edgelessDisableScheduleUpdate ?? false;
}
private get _crud() {
return this.std.get(EdgelessCRUDIdentifier);
}
override connectedCallback() {
super.connectedCallback();
@@ -186,7 +193,7 @@ export class EdgelessRootPreviewBlockComponent extends BlockComponent<
);
if (!surface) return;
const el = this.service.crud.getElementById(surface.elements[0]);
const el = this._crud.getElementById(surface.elements[0]);
if (isCanvasElement(el)) {
return true;
}
@@ -212,7 +219,7 @@ export class EdgelessRootPreviewBlockComponent extends BlockComponent<
this._initLayerUpdateEffect();
this._disposables.add(
this.service.viewport.viewportUpdated.on(() => {
this._gfx.viewport.viewportUpdated.on(() => {
this._refreshLayerViewport();
})
);
@@ -229,10 +236,10 @@ export class EdgelessRootPreviewBlockComponent extends BlockComponent<
<div class="edgeless-background edgeless-container" style=${background}>
<gfx-viewport
.enableChildrenSchedule=${!this._disableScheduleUpdate}
.viewport=${this.service.viewport}
.viewport=${this._gfx.viewport}
.getModelsInViewport=${() => {
const blocks = this.service.gfx.grid.search(
this.service.viewport.viewportBounds,
const blocks = this._gfx.grid.search(
this._gfx.viewport.viewportBounds,
{
useSet: true,
filter: ['block'],

View File

@@ -15,10 +15,10 @@ import type { ExtensionType } from '@blocksuite/store';
import { literal, unsafeStatic } from 'lit/static-html.js';
import { CommonSpecs } from '../common-specs/index.js';
import { edgelessNavigatorBgWidget } from '../widgets/edgeless-navigator-bg/index.js';
import { AFFINE_EDGELESS_ZOOM_TOOLBAR_WIDGET } from '../widgets/edgeless-zoom-toolbar/index.js';
import { EDGELESS_ELEMENT_TOOLBAR_WIDGET } from '../widgets/element-toolbar/index.js';
import { NOTE_SLICER_WIDGET } from './components/note-slicer/index.js';
import { EDGELESS_NAVIGATOR_BLACK_BACKGROUND_WIDGET } from './components/presentation/edgeless-navigator-black-background.js';
import { EDGELESS_DRAGGING_AREA_WIDGET } from './components/rects/edgeless-dragging-area-rect.js';
import { EDGELESS_SELECTED_RECT_WIDGET } from './components/rects/edgeless-selected-rect.js';
import { EDGELESS_TOOLBAR_WIDGET } from './components/toolbar/edgeless-toolbar.js';
@@ -44,11 +44,6 @@ export const noteSlicerWidget = WidgetViewExtension(
NOTE_SLICER_WIDGET,
literal`${unsafeStatic(NOTE_SLICER_WIDGET)}`
);
export const edgelessNavigatorBlackBackgroundWidget = WidgetViewExtension(
'affine:page',
EDGELESS_NAVIGATOR_BLACK_BACKGROUND_WIDGET,
literal`${unsafeStatic(EDGELESS_NAVIGATOR_BLACK_BACKGROUND_WIDGET)}`
);
export const edgelessSelectedRectWidget = WidgetViewExtension(
'affine:page',
EDGELESS_SELECTED_RECT_WIDGET,
@@ -86,7 +81,7 @@ export const EdgelessRootBlockSpec: ExtensionType[] = [
autoConnectWidget,
edgelessDraggingAreaWidget,
noteSlicerWidget,
edgelessNavigatorBlackBackgroundWidget,
edgelessNavigatorBgWidget,
edgelessSelectedRectWidget,
edgelessToolbarWidget,
];

View File

@@ -1,4 +1,3 @@
export { FramePreview } from './components/frame/frame-preview.js';
export { EdgelessTemplatePanel } from './components/toolbar/template/template-panel.js';
export * from './components/toolbar/template/template-type.js';
export * from './edgeless-root-block.js';

View File

@@ -24,10 +24,6 @@ import { EdgelessShapePanel } from './edgeless/components/panel/shape-panel.js';
import { EdgelessShapeStylePanel } from './edgeless/components/panel/shape-style-panel.js';
import { EdgelessSizePanel } from './edgeless/components/panel/size-panel.js';
import { StrokeStylePanel } from './edgeless/components/panel/stroke-style-panel.js';
import {
EDGELESS_NAVIGATOR_BLACK_BACKGROUND_WIDGET,
EdgelessNavigatorBlackBackgroundWidget,
} from './edgeless/components/presentation/edgeless-navigator-black-background.js';
import {
EDGELESS_DRAGGING_AREA_WIDGET,
EdgelessDraggingAreaRectWidget,
@@ -80,10 +76,13 @@ import {
EDGELESS_TOOLBAR_WIDGET,
EdgelessRootBlockComponent,
EdgelessRootPreviewBlockComponent,
FramePreview,
PageRootBlockComponent,
PreviewRootBlockComponent,
} from './index.js';
import {
EDGELESS_NAVIGATOR_BLACK_BACKGROUND_WIDGET,
EdgelessNavigatorBlackBackgroundWidget,
} from './widgets/edgeless-navigator-bg/index.js';
import {
AFFINE_EDGELESS_ZOOM_TOOLBAR_WIDGET,
AffineEdgelessZoomToolbarWidget,
@@ -268,7 +267,6 @@ function registerMiscComponents() {
// Loading and preview components
customElements.define('loader-element', Loader);
customElements.define('frame-preview', FramePreview);
customElements.define('affine-template-loading', AffineTemplateLoading);
// Toolbar and UI components
@@ -327,7 +325,6 @@ declare global {
'edgeless-tool-icon-button': EdgelessToolIconButton;
'edgeless-toolbar-button': EdgelessToolbarButton;
'edgeless-connector-handle': EdgelessConnectorHandle;
'frame-preview': FramePreview;
'note-slicer': NoteSlicer;
'edgeless-align-panel': EdgelessAlignPanel;
'card-style-panel': CardStylePanel;

View File

@@ -1,20 +1,17 @@
import { EdgelessLegacySlotIdentifier } from '@blocksuite/affine-block-surface';
import type { FrameBlockModel, RootBlockModel } from '@blocksuite/affine-model';
import { EditPropsStore } from '@blocksuite/affine-shared/services';
import { WidgetComponent } from '@blocksuite/block-std';
import { WidgetComponent, WidgetViewExtension } from '@blocksuite/block-std';
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
import { Bound } from '@blocksuite/global/gfx';
import { effect } from '@preact/signals-core';
import { css, html, nothing } from 'lit';
import { state } from 'lit/decorators.js';
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
import { literal, unsafeStatic } from 'lit/static-html.js';
export const EDGELESS_NAVIGATOR_BLACK_BACKGROUND_WIDGET =
'edgeless-navigator-black-background';
export class EdgelessNavigatorBlackBackgroundWidget extends WidgetComponent<
RootBlockModel,
EdgelessRootBlockComponent
> {
export class EdgelessNavigatorBlackBackgroundWidget extends WidgetComponent<RootBlockModel> {
static override styles = css`
.edgeless-navigator-black-background {
background-color: black;
@@ -31,6 +28,10 @@ export class EdgelessNavigatorBlackBackgroundWidget extends WidgetComponent<
return this.std.get(GfxControllerIdentifier);
}
private get _slots() {
return this.std.get(EdgelessLegacySlotIdentifier);
}
private _tryLoadBlackBackground() {
const value = this.std
.get(EditPropsStore)
@@ -39,15 +40,15 @@ export class EdgelessNavigatorBlackBackgroundWidget extends WidgetComponent<
}
override firstUpdated() {
const { _disposables, gfx, block } = this;
const { _disposables, gfx } = this;
_disposables.add(
block.slots.navigatorFrameChanged.on(frame => {
this._slots.navigatorFrameChanged.on(frame => {
this.frame = frame;
})
);
_disposables.add(
block.slots.navigatorSettingUpdated.on(({ blackBackground }) => {
this._slots.navigatorSettingUpdated.on(({ blackBackground }) => {
if (blackBackground !== undefined) {
this.std
.get(EditPropsStore)
@@ -57,7 +58,7 @@ export class EdgelessNavigatorBlackBackgroundWidget extends WidgetComponent<
this.show =
blackBackground &&
block.gfx.tool.currentToolOption$.peek().type === 'frameNavigator';
this.gfx.tool.currentToolOption$.peek().type === 'frameNavigator';
}
})
);
@@ -75,7 +76,7 @@ export class EdgelessNavigatorBlackBackgroundWidget extends WidgetComponent<
);
_disposables.add(
block.slots.fullScreenToggled.on(
this._slots.fullScreenToggled.on(
() =>
setTimeout(() => {
this.requestUpdate();
@@ -114,3 +115,9 @@ export class EdgelessNavigatorBlackBackgroundWidget extends WidgetComponent<
@state()
private accessor show = false;
}
export const edgelessNavigatorBgWidget = WidgetViewExtension(
'affine:page',
EDGELESS_NAVIGATOR_BLACK_BACKGROUND_WIDGET,
literal`${unsafeStatic(EDGELESS_NAVIGATOR_BLACK_BACKGROUND_WIDGET)}`
);

View File

@@ -28,7 +28,9 @@
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.12",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
"minimatch": "^10.0.1",
"zod": "^3.23.8"
},

View File

@@ -55,6 +55,8 @@ const styles = css`
}
`;
export const AFFINE_FRAME_PREVIEW = 'frame-preview';
export class FramePreview extends WithDisposable(ShadowlessElement) {
static override styles = styles;

View File

@@ -11,6 +11,7 @@ import {
AFFINE_FRAME_TITLE_EDITOR,
FrameCardTitleEditor,
} from './card/frame-card-title-editor';
import { AFFINE_FRAME_PREVIEW, FramePreview } from './card/frame-preview';
import { AFFINE_FRAME_PANEL, FramePanel } from './frame-panel';
import {
AFFINE_FRAME_PANEL_HEADER,
@@ -29,4 +30,5 @@ export function effects() {
customElements.define(AFFINE_FRAME_PANEL_BODY, FramePanelBody);
customElements.define(AFFINE_FRAME_PANEL_HEADER, FramePanelHeader);
customElements.define(AFFINE_FRAMES_SETTING_MENU, FramesSettingMenu);
customElements.define(AFFINE_FRAME_PREVIEW, FramePreview);
}