From 41499c1cd6bac0e370247279fd5b0771fd05b8a3 Mon Sep 17 00:00:00 2001 From: Saul-Mirone Date: Sat, 5 Apr 2025 12:59:48 +0000 Subject: [PATCH] refactor(editor): merge implementation of createTemplateJob (#11474) --- .../toolbar/template/template-panel.ts | 7 +- .../src/edgeless/edgeless-root-service.ts | 47 ------------- .../blocks/block-root/src/edgeless/index.ts | 1 + .../src/edgeless/services/template.ts | 67 ++++++++++++++++++- .../ai/actions/edgeless-response.ts | 4 +- .../blocksuite/ai/actions/page-response.ts | 4 +- .../core/src/blocksuite/ai/slides/index.ts | 4 +- .../src/blocksuite/ai/utils/template-job.ts | 41 ------------ 8 files changed, 77 insertions(+), 98 deletions(-) delete mode 100644 packages/frontend/core/src/blocksuite/ai/utils/template-job.ts diff --git a/blocksuite/affine/blocks/block-root/src/edgeless/components/toolbar/template/template-panel.ts b/blocksuite/affine/blocks/block-root/src/edgeless/components/toolbar/template/template-panel.ts index b5b5ee7c6b..bdb6f5c122 100644 --- a/blocksuite/affine/blocks/block-root/src/edgeless/components/toolbar/template/template-panel.ts +++ b/blocksuite/affine/blocks/block-root/src/edgeless/components/toolbar/template/template-panel.ts @@ -23,6 +23,7 @@ import { styleMap } from 'lit/directives/style-map.js'; import { unsafeSVG } from 'lit/directives/unsafe-svg.js'; import { EdgelessRootService } from '../../../edgeless-root-service.js'; +import { createTemplateJob } from '../../../services/template.js'; import { builtInTemplates } from './builtin-templates.js'; import { defaultPreview, Triangle } from './cards.js'; import type { Template } from './template-type.js'; @@ -287,7 +288,11 @@ export class EdgelessTemplatePanel extends WithDisposable(LitElement) { x: bound.x + bound.w / 2, y: bound.y + bound.h / 2, }; - const templateJob = this.service.createTemplateJob(template.type, center); + const templateJob = createTemplateJob( + this.edgeless.std, + template.type, + center + ); try { const { assets } = template; diff --git a/blocksuite/affine/blocks/block-root/src/edgeless/edgeless-root-service.ts b/blocksuite/affine/blocks/block-root/src/edgeless/edgeless-root-service.ts index 69d8ec4fab..913c400c5c 100644 --- a/blocksuite/affine/blocks/block-root/src/edgeless/edgeless-root-service.ts +++ b/blocksuite/affine/blocks/block-root/src/edgeless/edgeless-root-service.ts @@ -11,7 +11,6 @@ import { RootBlockSchema, } from '@blocksuite/affine-model'; import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions'; -import { Bound, getCommonBound } from '@blocksuite/global/gfx'; import type { BlockStdScope } from '@blocksuite/std'; import type { GfxController, @@ -33,12 +32,6 @@ import clamp from 'lodash-es/clamp'; import { RootService } from '../root-service.js'; import { TemplateJob } from './services/template.js'; -import { - createInsertPlaceMiddleware, - createRegenerateIndexMiddleware, - createStickerMiddleware, - replaceIdMiddleware, -} from './services/template-middlewares.js'; import { getCursorMode } from './utils/query.js'; export class EdgelessRootService extends RootService implements SurfaceContext { @@ -160,46 +153,6 @@ export class EdgelessRootService extends RootService implements SurfaceContext { ); } - createTemplateJob( - type: 'template' | 'sticker', - center?: { x: number; y: number } - ) { - const middlewares: ((job: TemplateJob) => void)[] = []; - - if (type === 'template') { - const bounds = [...this.blocks, ...this.elements].map(i => - Bound.deserialize(i.xywh) - ); - const currentContentBound = getCommonBound(bounds); - - if (currentContentBound) { - currentContentBound.x += - currentContentBound.w + 20 / this.viewport.zoom; - middlewares.push(createInsertPlaceMiddleware(currentContentBound)); - } - - const idxGenerator = this.layer.createIndexGenerator(); - - middlewares.push(createRegenerateIndexMiddleware(() => idxGenerator())); - } - - if (type === 'sticker') { - middlewares.push( - createStickerMiddleware(center || this.viewport.center, () => - this.layer.generateIndex() - ) - ); - } - - middlewares.push(replaceIdMiddleware); - - return TemplateJob.create({ - model: this.surface, - type, - middlewares, - }); - } - generateIndex() { return this.layer.generateIndex(); } diff --git a/blocksuite/affine/blocks/block-root/src/edgeless/index.ts b/blocksuite/affine/blocks/block-root/src/edgeless/index.ts index 75a41f94aa..5bd476ffce 100644 --- a/blocksuite/affine/blocks/block-root/src/edgeless/index.ts +++ b/blocksuite/affine/blocks/block-root/src/edgeless/index.ts @@ -6,6 +6,7 @@ export * from './edgeless-root-block.js'; export { EdgelessRootPreviewBlockComponent } from './edgeless-root-preview-block.js'; export { EdgelessRootService } from './edgeless-root-service.js'; export * from './gfx-tool'; +export * from './services/template.js'; export * from './utils/clipboard-utils.js'; export { sortEdgelessElements } from './utils/clone-utils.js'; export { isCanvasElement } from './utils/query.js'; diff --git a/blocksuite/affine/blocks/block-root/src/edgeless/services/template.ts b/blocksuite/affine/blocks/block-root/src/edgeless/services/template.ts index c93da1e63b..6332895e5e 100644 --- a/blocksuite/affine/blocks/block-root/src/edgeless/services/template.ts +++ b/blocksuite/affine/blocks/block-root/src/edgeless/services/template.ts @@ -1,10 +1,14 @@ -import type { - SurfaceBlockModel, - SurfaceBlockTransformer, +import { + getSurfaceBlock, + type SurfaceBlockModel, + type SurfaceBlockTransformer, } from '@blocksuite/affine-block-surface'; import type { ConnectorElementModel } from '@blocksuite/affine-model'; +import { BlockSuiteError } from '@blocksuite/global/exceptions'; import { Bound, getCommonBound } from '@blocksuite/global/gfx'; import { assertType } from '@blocksuite/global/utils'; +import type { BlockStdScope } from '@blocksuite/std'; +import { GfxControllerIdentifier } from '@blocksuite/std/gfx'; import { type BlockModel, type BlockSnapshot, @@ -15,6 +19,13 @@ import { } from '@blocksuite/store'; import { Subject } from 'rxjs'; import type * as Y from 'yjs'; + +import { + createInsertPlaceMiddleware, + createRegenerateIndexMiddleware, + createStickerMiddleware, + replaceIdMiddleware, +} from './template-middlewares'; /** * Those block contains other block's id * should defer the loading @@ -369,3 +380,53 @@ export class TemplateJob { iterate(this._template.blocks, this._template); } } + +export function createTemplateJob( + std: BlockStdScope, + type: 'template' | 'sticker', + center?: { x: number; y: number } +) { + const surface = getSurfaceBlock(std.store); + if (!surface) { + throw new BlockSuiteError( + BlockSuiteError.ErrorCode.NoSurfaceModelError, + 'This doc is missing surface block in edgeless.' + ); + } + + const gfx = std.get(GfxControllerIdentifier); + const middlewares: ((job: TemplateJob) => void)[] = []; + const { layer, viewport } = gfx; + const blocks = layer.blocks; + const elements = layer.canvasElements; + + if (type === 'template') { + const bounds = [...blocks, ...elements].map(i => Bound.deserialize(i.xywh)); + const currentContentBound = getCommonBound(bounds); + + if (currentContentBound) { + currentContentBound.x += currentContentBound.w + 20 / viewport.zoom; + middlewares.push(createInsertPlaceMiddleware(currentContentBound)); + } + + const idxGenerator = layer.createIndexGenerator(); + + middlewares.push(createRegenerateIndexMiddleware(() => idxGenerator())); + } + + if (type === 'sticker') { + middlewares.push( + createStickerMiddleware(center || viewport.center, () => + layer.generateIndex() + ) + ); + } + + middlewares.push(replaceIdMiddleware); + + return TemplateJob.create({ + model: surface, + type, + middlewares, + }); +} diff --git a/packages/frontend/core/src/blocksuite/ai/actions/edgeless-response.ts b/packages/frontend/core/src/blocksuite/ai/actions/edgeless-response.ts index c94b4ccbe3..e8d5820017 100644 --- a/packages/frontend/core/src/blocksuite/ai/actions/edgeless-response.ts +++ b/packages/frontend/core/src/blocksuite/ai/actions/edgeless-response.ts @@ -1,4 +1,5 @@ import { addImages } from '@blocksuite/affine/blocks/image'; +import { createTemplateJob } from '@blocksuite/affine/blocks/root'; import { getSurfaceBlock } from '@blocksuite/affine/blocks/surface'; import { LightLoadingIcon } from '@blocksuite/affine/components/icons'; import { addTree } from '@blocksuite/affine/gfx/mindmap'; @@ -46,7 +47,6 @@ import { getEdgelessRootFromEditor, getSurfaceElementFromEditor, } from '../utils/selection-utils'; -import { createTemplateJob } from '../utils/template-job'; import type { AffineAIPanelWidget } from '../widgets/ai-panel/ai-panel'; import type { EdgelessCopilotWidget } from '../widgets/edgeless-copilot'; import { EXCLUDING_INSERT_ACTIONS, generatingStages } from './consts'; @@ -514,7 +514,7 @@ async function responseToCreateSlides(host: EditorHost, ctx: AIContext) { for (let i = 0; i < contents.length; i++) { const image = images[i] || []; const content = contents[i]; - const job = createTemplateJob(host); + const job = createTemplateJob(host.std, 'template'); const imagePromises = image.map(async ({ id, url }) => { const response = await fetch(url); diff --git a/packages/frontend/core/src/blocksuite/ai/actions/page-response.ts b/packages/frontend/core/src/blocksuite/ai/actions/page-response.ts index 886afb5655..1383c61644 100644 --- a/packages/frontend/core/src/blocksuite/ai/actions/page-response.ts +++ b/packages/frontend/core/src/blocksuite/ai/actions/page-response.ts @@ -1,4 +1,5 @@ import { uploadBlobForImage } from '@blocksuite/affine/blocks/image'; +import { createTemplateJob } from '@blocksuite/affine/blocks/root'; import { getSurfaceBlock, SurfaceBlockModel, @@ -25,7 +26,6 @@ import { insertAbove, insertBelow, replace } from '../utils/editor-actions'; import { preprocessHtml } from '../utils/html'; import { fetchImageToFile } from '../utils/image'; import { getSelections } from '../utils/selection-utils'; -import { createTemplateJob } from '../utils/template-job'; const PADDING = 100; @@ -138,7 +138,7 @@ async function responseToCreateSlides( for (let i = 0; i < contents.length; i++) { const image = images[i]; const content = contents[i]; - const job = createTemplateJob(host); + const job = createTemplateJob(host.std, 'template'); await Promise.all( image.map(({ id, url }) => fetch(url) diff --git a/packages/frontend/core/src/blocksuite/ai/slides/index.ts b/packages/frontend/core/src/blocksuite/ai/slides/index.ts index c1ae39c1b8..94063f44a7 100644 --- a/packages/frontend/core/src/blocksuite/ai/slides/index.ts +++ b/packages/frontend/core/src/blocksuite/ai/slides/index.ts @@ -1,10 +1,10 @@ +import { createTemplateJob } from '@blocksuite/affine/blocks/root'; import type { EditorHost } from '@blocksuite/affine/std'; import { GfxControllerIdentifier } from '@blocksuite/affine/std/gfx'; import type { BlockSnapshot } from '@blocksuite/affine/store'; import { markdownToSnapshot } from '../../utils'; import { getSurfaceElementFromEditor } from '../utils/selection-utils'; -import { createTemplateJob } from '../utils/template-job'; import { basicTheme, type PPTDoc, @@ -36,7 +36,7 @@ export const PPTBuilder = (host: EditorHost) => { }; docs.push(doc); - const job = createTemplateJob(host); + const job = createTemplateJob(host.std, 'template'); const { images, content } = await basicTheme(doc); contents.push(content); allImages.push(images); diff --git a/packages/frontend/core/src/blocksuite/ai/utils/template-job.ts b/packages/frontend/core/src/blocksuite/ai/utils/template-job.ts deleted file mode 100644 index 189a51e3fd..0000000000 --- a/packages/frontend/core/src/blocksuite/ai/utils/template-job.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { - TemplateJob, - TemplateMiddlewares, -} from '@blocksuite/affine/blocks/root'; -import { getSurfaceBlock } from '@blocksuite/affine/blocks/surface'; -import { Bound, getCommonBound } from '@blocksuite/affine/global/gfx'; -import type { EditorHost } from '@blocksuite/affine/std'; -import { GfxController, LayerManager } from '@blocksuite/affine/std/gfx'; - -export function createTemplateJob(host: EditorHost) { - const surface = getSurfaceBlock(host.doc); - if (!surface) { - throw new Error('surface is not found'); - } - - const middlewares: ((job: TemplateJob) => void)[] = []; - const layer = new LayerManager(host.std.get(GfxController)); - const bounds = [...layer.blocks, ...layer.canvasElements].map(i => - Bound.deserialize(i.xywh) - ); - const currentContentBound = getCommonBound(bounds); - - if (currentContentBound) { - currentContentBound.x += currentContentBound.w + 100; - middlewares.push( - TemplateMiddlewares.createInsertPlaceMiddleware(currentContentBound) - ); - } - - const idxGenerator = layer.createIndexGenerator(); - middlewares.push( - TemplateMiddlewares.createRegenerateIndexMiddleware(() => idxGenerator()) - ); - middlewares.push(TemplateMiddlewares.replaceIdMiddleware); - - return TemplateJob.create({ - model: surface, - type: 'template', - middlewares, - }); -}