Files
AFFiNE-Mirror/blocksuite/affine/blocks/embed/src/embed-iframe-block/commands/insert-embed-iframe-with-url.ts
Saul-Mirone 1f45cc5dec refactor(editor): unify directories naming (#11516)
**Directory Structure Changes**

- Renamed multiple block-related directories by removing the "block-" prefix:
  - `block-attachment` → `attachment`
  - `block-bookmark` → `bookmark`
  - `block-callout` → `callout`
  - `block-code` → `code`
  - `block-data-view` → `data-view`
  - `block-database` → `database`
  - `block-divider` → `divider`
  - `block-edgeless-text` → `edgeless-text`
  - `block-embed` → `embed`
2025-04-07 12:34:40 +00:00

110 lines
3.4 KiB
TypeScript

import {
EdgelessCRUDIdentifier,
SurfaceBlockComponent,
} from '@blocksuite/affine-block-surface';
import { EmbedIframeService } from '@blocksuite/affine-shared/services';
import { Bound, Vec } from '@blocksuite/global/gfx';
import {
BlockSelection,
type Command,
SurfaceSelection,
TextSelection,
} from '@blocksuite/std';
import { GfxControllerIdentifier } from '@blocksuite/std/gfx';
import {
EMBED_IFRAME_DEFAULT_HEIGHT_IN_SURFACE,
EMBED_IFRAME_DEFAULT_WIDTH_IN_SURFACE,
} from '../consts';
export const insertEmbedIframeWithUrlCommand: Command<
{ url: string },
{ blockId: string; flavour: string }
> = (ctx, next) => {
const { url, std } = ctx;
const embedIframeService = std.get(EmbedIframeService);
if (!embedIframeService || !embedIframeService.canEmbed(url)) {
return;
}
const config = embedIframeService.getConfig(url);
if (!config) {
return;
}
const { host } = std;
const selectionManager = host.selection;
let selectedBlockId: string | undefined;
const textSelection = selectionManager.find(TextSelection);
const blockSelection = selectionManager.find(BlockSelection);
const surfaceSelection = selectionManager.find(SurfaceSelection);
if (textSelection) {
selectedBlockId = textSelection.blockId;
} else if (blockSelection) {
selectedBlockId = blockSelection.blockId;
} else if (surfaceSelection && surfaceSelection.editing) {
selectedBlockId = surfaceSelection.blockId;
}
const flavour = 'affine:embed-iframe';
const props: Record<string, unknown> = { url };
// When there is a selected block, it means that the selection is in note or edgeless text
// we should insert the embed iframe block after the selected block and only need the url prop
let newBlockId: string | undefined;
if (selectedBlockId) {
const block = host.view.getBlock(selectedBlockId);
if (!block) return;
const parent = host.doc.getParent(block.model);
if (!parent) return;
const index = parent.children.indexOf(block.model);
newBlockId = host.doc.addBlock(flavour, props, parent, index + 1);
} else {
// When there is no selected block and in edgeless mode
// We should insert the embed iframe block to surface
// It means that not only the url prop but also the xywh prop is needed
const rootId = std.store.root?.id;
if (!rootId) return;
const edgelessRoot = std.view.getBlock(rootId);
if (!edgelessRoot) return;
const gfx = std.get(GfxControllerIdentifier);
const crud = std.get(EdgelessCRUDIdentifier);
gfx.viewport.smoothZoom(1);
const surfaceBlock = gfx.surfaceComponent;
if (!(surfaceBlock instanceof SurfaceBlockComponent)) return;
const options = config.options;
const { widthInSurface, heightInSurface } = options ?? {};
const width = widthInSurface ?? EMBED_IFRAME_DEFAULT_WIDTH_IN_SURFACE;
const height = heightInSurface ?? EMBED_IFRAME_DEFAULT_HEIGHT_IN_SURFACE;
const center = Vec.toVec(surfaceBlock.renderer.viewport.center);
const xywh = Bound.fromCenter(center, width, height).serialize();
newBlockId = crud.addBlock(
flavour,
{
...props,
xywh,
},
surfaceBlock.model
);
gfx.tool.setTool(
// @ts-expect-error FIXME: resolve after gfx tool refactor
'default'
);
gfx.selection.set({
elements: [newBlockId],
editing: false,
});
}
if (!newBlockId) {
return;
}
next({ blockId: newBlockId, flavour });
};