refactor(editor): move file drop manager to components (#9264)

This commit is contained in:
Saul-Mirone
2024-12-24 02:20:03 +00:00
parent 74a168222c
commit b29cb5945a
16 changed files with 321 additions and 261 deletions
@@ -1,3 +1,4 @@
import { FileDropConfigExtension } from '@blocksuite/affine-components/drag-indicator';
import { ImageBlockSchema } from '@blocksuite/affine-model';
import {
DragHandleConfigExtension,
@@ -13,64 +14,60 @@ import {
import { BlockService } from '@blocksuite/block-std';
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
import {
FileDropManager,
type FileDropOptions,
} from '../_common/components/file-drop-manager.js';
import { setImageProxyMiddlewareURL } from '../_common/transformers/middlewares.js';
import { addImages } from '../root-block/edgeless/utils/common.js';
import type { ImageBlockComponent } from './image-block.js';
import { ImageEdgelessBlockComponent } from './image-edgeless-block.js';
import { addSiblingImageBlock } from './utils.js';
// bytes.parse('2GB')
const maxFileSize = 2147483648;
export class ImageBlockService extends BlockService {
static override readonly flavour = ImageBlockSchema.model.flavour;
static setImageProxyURL = setImageProxyMiddlewareURL;
private readonly _fileDropOptions: FileDropOptions = {
flavour: this.flavour,
onDrop: async ({ files, targetModel, place, point }) => {
const imageFiles = files.filter(file => file.type.startsWith('image/'));
if (!imageFiles.length) return false;
if (targetModel && !matchFlavours(targetModel, ['affine:surface'])) {
addSiblingImageBlock(
this.host,
imageFiles,
this.maxFileSize,
targetModel,
place
);
} else if (isInsideEdgelessEditor(this.host)) {
const gfx = this.std.get(GfxControllerIdentifier);
point = gfx.viewport.toViewCoordFromClientCoord(point);
await addImages(this.std, files, point);
this.std.getOptional(TelemetryProvider)?.track('CanvasElementAdded', {
control: 'canvas:drop',
page: 'whiteboard editor',
module: 'toolbar',
segment: 'toolbar',
type: 'image',
});
}
return true;
},
};
fileDropManager!: FileDropManager;
maxFileSize = 10 * 1000 * 1000; // 10MB (default)
override mounted(): void {
super.mounted();
this.fileDropManager = new FileDropManager(this, this._fileDropOptions);
}
maxFileSize = maxFileSize;
}
export const ImageDropOption = FileDropConfigExtension({
flavour: ImageBlockSchema.model.flavour,
onDrop: ({ files, targetModel, place, point, std }) => {
const imageFiles = files.filter(file => file.type.startsWith('image/'));
if (!imageFiles.length) return false;
if (targetModel && !matchFlavours(targetModel, ['affine:surface'])) {
addSiblingImageBlock(
std.host,
imageFiles,
// TODO: use max file size from service
maxFileSize,
targetModel,
place
);
return true;
}
if (isInsideEdgelessEditor(std.host)) {
const gfx = std.get(GfxControllerIdentifier);
point = gfx.viewport.toViewCoordFromClientCoord(point);
addImages(std, files, point).catch(console.error);
std.getOptional(TelemetryProvider)?.track('CanvasElementAdded', {
control: 'canvas:drop',
page: 'whiteboard editor',
module: 'toolbar',
segment: 'toolbar',
type: 'image',
});
return true;
}
return false;
},
});
export const ImageDragHandleOption = DragHandleConfigExtension({
flavour: ImageBlockSchema.model.flavour,
edgeless: true,
@@ -10,7 +10,11 @@ import { literal } from 'lit/static-html.js';
import { ImageBlockAdapterExtensions } from './adapters/extension.js';
import { commands } from './commands/index.js';
import { ImageBlockService, ImageDragHandleOption } from './image-service.js';
import {
ImageBlockService,
ImageDragHandleOption,
ImageDropOption,
} from './image-service.js';
export const ImageBlockSpec: ExtensionType[] = [
FlavourExtension('affine:image'),
@@ -29,6 +33,7 @@ export const ImageBlockSpec: ExtensionType[] = [
imageToolbar: literal`affine-image-toolbar-widget`,
}),
ImageDragHandleOption,
ImageDropOption,
ImageSelectionExtension,
ImageBlockAdapterExtensions,
].flat();