mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-08 12:45:55 +08:00
1d865f16fe
#### PR Dependency Tree * **PR #13098** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for comments on graphical elements, allowing users to comment on both blocks and graphical elements within surfaces. * Enhanced comment previews to include graphical elements in selection summaries. * Improved editor navigation to focus on commented graphical elements in addition to blocks and inline texts. * **Bug Fixes** * Updated comment highlighting and management to consistently use the new comment manager across all block and element types. * **Refactor** * Renamed and extended the comment manager to handle both block and element comments. * Streamlined toolbar configurations by removing outdated comment button entries and adding a consolidated comment button in the root toolbar. * **Tests** * Disabled the mock comment provider integration in the test editor environment to refine testing setup. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
166 lines
4.0 KiB
TypeScript
166 lines
4.0 KiB
TypeScript
import { ImageBlockModel } from '@blocksuite/affine-model';
|
|
import {
|
|
ActionPlacement,
|
|
type ToolbarModuleConfig,
|
|
ToolbarModuleExtension,
|
|
} from '@blocksuite/affine-shared/services';
|
|
import {
|
|
BookmarkIcon,
|
|
CaptionIcon,
|
|
CopyIcon,
|
|
DeleteIcon,
|
|
DownloadIcon,
|
|
DuplicateIcon,
|
|
} from '@blocksuite/icons/lit';
|
|
import { BlockFlavourIdentifier } from '@blocksuite/std';
|
|
import type { ExtensionType } from '@blocksuite/store';
|
|
|
|
import { ImageBlockComponent } from '../image-block';
|
|
import { ImageEdgelessBlockComponent } from '../image-edgeless-block';
|
|
import { duplicate } from '../utils';
|
|
|
|
const trackBaseProps = {
|
|
category: 'image',
|
|
type: 'card view',
|
|
};
|
|
|
|
const builtinToolbarConfig = {
|
|
actions: [
|
|
{
|
|
id: 'a.download',
|
|
tooltip: 'Download',
|
|
icon: DownloadIcon(),
|
|
run(ctx) {
|
|
const block = ctx.getCurrentBlockByType(ImageBlockComponent);
|
|
block?.download();
|
|
},
|
|
},
|
|
{
|
|
id: 'b.caption',
|
|
tooltip: 'Caption',
|
|
icon: CaptionIcon(),
|
|
run(ctx) {
|
|
const block = ctx.getCurrentBlockByType(ImageBlockComponent);
|
|
block?.captionEditor?.show();
|
|
|
|
ctx.track('OpenedCaptionEditor', {
|
|
...trackBaseProps,
|
|
control: 'add caption',
|
|
});
|
|
},
|
|
},
|
|
{
|
|
placement: ActionPlacement.More,
|
|
id: 'a.clipboard',
|
|
actions: [
|
|
{
|
|
id: 'a.copy',
|
|
label: 'Copy',
|
|
icon: CopyIcon(),
|
|
run(ctx) {
|
|
const block = ctx.getCurrentBlockByType(ImageBlockComponent);
|
|
block?.copy();
|
|
},
|
|
},
|
|
{
|
|
id: 'b.duplicate',
|
|
label: 'Duplicate',
|
|
icon: DuplicateIcon(),
|
|
run(ctx) {
|
|
const block = ctx.getCurrentBlockByType(ImageBlockComponent);
|
|
if (!block) return;
|
|
|
|
duplicate(block);
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
placement: ActionPlacement.More,
|
|
id: 'b.conversions',
|
|
actions: [
|
|
{
|
|
id: 'a.turn-into-card-view',
|
|
label: 'Turn into card view',
|
|
icon: BookmarkIcon(),
|
|
when(ctx) {
|
|
const supported =
|
|
ctx.store.schema.flavourSchemaMap.has('affine:attachment');
|
|
if (!supported) return false;
|
|
|
|
const block = ctx.getCurrentBlockByType(ImageBlockComponent);
|
|
return Boolean(block?.blobUrl);
|
|
},
|
|
run(ctx) {
|
|
const block = ctx.getCurrentBlockByType(ImageBlockComponent);
|
|
block?.convertToCardView();
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
placement: ActionPlacement.More,
|
|
id: 'c.delete',
|
|
label: 'Delete',
|
|
icon: DeleteIcon(),
|
|
variant: 'destructive',
|
|
run(ctx) {
|
|
const block = ctx.getCurrentBlockByType(ImageBlockComponent);
|
|
if (!block) return;
|
|
|
|
ctx.store.deleteBlock(block.model);
|
|
},
|
|
},
|
|
],
|
|
|
|
placement: 'inner',
|
|
} as const satisfies ToolbarModuleConfig;
|
|
|
|
const builtinSurfaceToolbarConfig = {
|
|
actions: [
|
|
{
|
|
id: 'a.download',
|
|
tooltip: 'Download',
|
|
icon: DownloadIcon(),
|
|
run(ctx) {
|
|
const block = ctx.getCurrentBlockByType(ImageEdgelessBlockComponent);
|
|
block?.download();
|
|
},
|
|
},
|
|
{
|
|
id: 'b.caption',
|
|
tooltip: 'Caption',
|
|
icon: CaptionIcon(),
|
|
run(ctx) {
|
|
const block = ctx.getCurrentBlockByType(ImageEdgelessBlockComponent);
|
|
block?.captionEditor?.show();
|
|
|
|
ctx.track('OpenedCaptionEditor', {
|
|
...trackBaseProps,
|
|
control: 'add caption',
|
|
});
|
|
},
|
|
},
|
|
],
|
|
|
|
when: ctx => ctx.getSurfaceModelsByType(ImageBlockModel).length === 1,
|
|
} as const satisfies ToolbarModuleConfig;
|
|
|
|
export const createBuiltinToolbarConfigExtension = (
|
|
flavour: string
|
|
): ExtensionType[] => {
|
|
const name = flavour.split(':').pop();
|
|
|
|
return [
|
|
ToolbarModuleExtension({
|
|
id: BlockFlavourIdentifier(flavour),
|
|
config: builtinToolbarConfig,
|
|
}),
|
|
|
|
ToolbarModuleExtension({
|
|
id: BlockFlavourIdentifier(`affine:surface:${name}`),
|
|
config: builtinSurfaceToolbarConfig,
|
|
}),
|
|
];
|
|
};
|