feat(core): extract edgeless selected images (#13420)

> CLOSE AF-2782

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added support for extracting image files from selected elements in
edgeless editor mode, allowing users to retrieve image files alongside
canvas snapshots.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
德布劳外 · 贾贵
2025-08-05 18:43:18 +08:00
committed by GitHub
parent 46acf9aa4f
commit 6ffa60c501
2 changed files with 20 additions and 1 deletions

View File

@@ -34,6 +34,7 @@ import { Doc as YDoc } from 'yjs';
import { getStoreManager } from '../../manager/store';
import type { ChatContextValue } from '../components/ai-chat-content';
import { isAttachment } from './attachment';
import { isImage } from './image';
import {
getSelectedAttachments,
getSelectedImagesAsBlobs,
@@ -63,6 +64,7 @@ async function extractEdgelessSelected(
let snapshot: DocSnapshot | null = null;
let markdown = '';
const attachments: ChatContextValue['attachments'] = [];
const images: File[] = [];
if (selectedElements.length) {
const transformer = host.store.getTransformer();
@@ -103,6 +105,14 @@ async function extractEdgelessSelected(
if (name && sourceId) {
attachments.push({ name, sourceId });
}
} else if (isImage(element)) {
const { sourceId } = element.props;
if (sourceId) {
const blob = await host.store.blobSync.get(sourceId);
if (blob) {
images.push(new File([blob], sourceId));
}
}
} else if (element instanceof GfxPrimitiveElementModel) {
needSnapshot = true;
const props = getElementProps(element, new Map());
@@ -130,7 +140,7 @@ async function extractEdgelessSelected(
if (!blob) return null;
return {
images: [new File([blob], 'selected.png')],
images: [new File([blob], 'selected.png'), ...images],
snapshot: snapshot ? JSON.stringify(snapshot) : null,
combinedElementsMarkdown: markdown.length ? markdown : null,
attachments,

View File

@@ -1,4 +1,7 @@
import { ImageBlockModel } from '@blocksuite/affine/model';
import { FetchUtils } from '@blocksuite/affine/shared/adapters';
import type { BlockModel } from '@blocksuite/affine/store';
import type { GfxModel } from '@blocksuite/std/gfx';
export async function fetchImageToFile(
url: string,
@@ -107,3 +110,9 @@ export function canvasToBlob(
export function randomSeed(min = 0, max = Date.now()) {
return Math.round(Math.random() * (max - min)) + min;
}
export function isImage(
model: GfxModel | BlockModel
): model is ImageBlockModel {
return model instanceof ImageBlockModel;
}