refactor(editor): edgeless external embed card toolbar config extension (#10712)
This commit is contained in:
@@ -1,18 +1,29 @@
|
|||||||
|
import { reassociateConnectorsCommand } from '@blocksuite/affine-block-surface';
|
||||||
import { toast } from '@blocksuite/affine-components/toast';
|
import { toast } from '@blocksuite/affine-components/toast';
|
||||||
import {
|
import {
|
||||||
BookmarkStyles,
|
BookmarkStyles,
|
||||||
|
type EmbedCardStyle,
|
||||||
EmbedGithubModel,
|
EmbedGithubModel,
|
||||||
|
EmbedGithubStyles,
|
||||||
isExternalEmbedModel,
|
isExternalEmbedModel,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
|
import {
|
||||||
|
EMBED_CARD_HEIGHT,
|
||||||
|
EMBED_CARD_WIDTH,
|
||||||
|
} from '@blocksuite/affine-shared/consts';
|
||||||
import {
|
import {
|
||||||
ActionPlacement,
|
ActionPlacement,
|
||||||
EmbedOptionProvider,
|
EmbedOptionProvider,
|
||||||
|
type LinkEventType,
|
||||||
type ToolbarAction,
|
type ToolbarAction,
|
||||||
type ToolbarActionGroup,
|
type ToolbarActionGroup,
|
||||||
|
type ToolbarContext,
|
||||||
type ToolbarModuleConfig,
|
type ToolbarModuleConfig,
|
||||||
|
ToolbarModuleExtension,
|
||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
import { getBlockProps } from '@blocksuite/affine-shared/utils';
|
import { getBlockProps } from '@blocksuite/affine-shared/utils';
|
||||||
import { BlockSelection } from '@blocksuite/block-std';
|
import { BlockFlavourIdentifier, BlockSelection } from '@blocksuite/block-std';
|
||||||
|
import { Bound } from '@blocksuite/global/gfx';
|
||||||
import {
|
import {
|
||||||
CaptionIcon,
|
CaptionIcon,
|
||||||
CopyIcon,
|
CopyIcon,
|
||||||
@@ -20,8 +31,8 @@ import {
|
|||||||
DuplicateIcon,
|
DuplicateIcon,
|
||||||
ResetIcon,
|
ResetIcon,
|
||||||
} from '@blocksuite/icons/lit';
|
} from '@blocksuite/icons/lit';
|
||||||
import { Slice, Text } from '@blocksuite/store';
|
import { type ExtensionType, Slice, Text } from '@blocksuite/store';
|
||||||
import { signal } from '@preact/signals-core';
|
import { computed, signal } from '@preact/signals-core';
|
||||||
import { html } from 'lit';
|
import { html } from 'lit';
|
||||||
import { keyed } from 'lit/directives/keyed.js';
|
import { keyed } from 'lit/directives/keyed.js';
|
||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
@@ -32,15 +43,46 @@ import type { EmbedLoomBlockComponent } from '../embed-loom-block';
|
|||||||
import type { EmbedYoutubeBlockComponent } from '../embed-youtube-block';
|
import type { EmbedYoutubeBlockComponent } from '../embed-youtube-block';
|
||||||
|
|
||||||
const trackBaseProps = {
|
const trackBaseProps = {
|
||||||
segment: 'doc',
|
|
||||||
page: 'doc editor',
|
|
||||||
module: 'toolbar',
|
|
||||||
category: 'link',
|
category: 'link',
|
||||||
type: 'card view',
|
type: 'card view',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const previewAction = {
|
||||||
|
id: 'a.preview',
|
||||||
|
content(ctx) {
|
||||||
|
const model = ctx.getCurrentModel();
|
||||||
|
if (!model || !isExternalEmbedModel(model)) return null;
|
||||||
|
|
||||||
|
const { url } = model.props;
|
||||||
|
const options = ctx.std.get(EmbedOptionProvider).getEmbedBlockOptions(url);
|
||||||
|
|
||||||
|
if (options?.viewType !== 'card') return null;
|
||||||
|
|
||||||
|
return html`<affine-link-preview .url=${url}></affine-link-preview>`;
|
||||||
|
},
|
||||||
|
} satisfies ToolbarAction;
|
||||||
|
|
||||||
|
const createOnToggleFn =
|
||||||
|
(
|
||||||
|
ctx: ToolbarContext,
|
||||||
|
name: Extract<
|
||||||
|
LinkEventType,
|
||||||
|
| 'OpenedViewSelector'
|
||||||
|
| 'OpenedCardStyleSelector'
|
||||||
|
| 'OpenedCardScaleSelector'
|
||||||
|
>,
|
||||||
|
control: 'switch view' | 'switch card style' | 'switch card scale'
|
||||||
|
) =>
|
||||||
|
(e: CustomEvent<boolean>) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
const opened = e.detail;
|
||||||
|
if (!opened) return;
|
||||||
|
|
||||||
|
ctx.track(name, { ...trackBaseProps, control });
|
||||||
|
};
|
||||||
|
|
||||||
// External embed blocks
|
// External embed blocks
|
||||||
export function createBuiltinToolbarConfigForExternal(
|
function createBuiltinToolbarConfigForExternal(
|
||||||
klass:
|
klass:
|
||||||
| typeof EmbedGithubBlockComponent
|
| typeof EmbedGithubBlockComponent
|
||||||
| typeof EmbedFigmaBlockComponent
|
| typeof EmbedFigmaBlockComponent
|
||||||
@@ -49,22 +91,7 @@ export function createBuiltinToolbarConfigForExternal(
|
|||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
previewAction,
|
||||||
id: 'a.preview',
|
|
||||||
content(ctx) {
|
|
||||||
const model = ctx.getCurrentBlockByType(klass)?.model;
|
|
||||||
if (!model || !isExternalEmbedModel(model)) return null;
|
|
||||||
|
|
||||||
const { url } = model.props;
|
|
||||||
const options = ctx.std
|
|
||||||
.get(EmbedOptionProvider)
|
|
||||||
.getEmbedBlockOptions(url);
|
|
||||||
|
|
||||||
if (options?.viewType !== 'card') return null;
|
|
||||||
|
|
||||||
return html`<affine-link-preview .url=${url}></affine-link-preview>`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'b.conversions',
|
id: 'b.conversions',
|
||||||
actions: [
|
actions: [
|
||||||
@@ -72,7 +99,7 @@ export function createBuiltinToolbarConfigForExternal(
|
|||||||
id: 'inline',
|
id: 'inline',
|
||||||
label: 'Inline view',
|
label: 'Inline view',
|
||||||
run(ctx) {
|
run(ctx) {
|
||||||
const model = ctx.getCurrentBlockByType(klass)?.model;
|
const model = ctx.getCurrentModel();
|
||||||
if (!model || !isExternalEmbedModel(model)) return;
|
if (!model || !isExternalEmbedModel(model)) return;
|
||||||
|
|
||||||
const { title, caption, url: link } = model.props;
|
const { title, caption, url: link } = model.props;
|
||||||
@@ -105,7 +132,7 @@ export function createBuiltinToolbarConfigForExternal(
|
|||||||
id: 'card',
|
id: 'card',
|
||||||
label: 'Card view',
|
label: 'Card view',
|
||||||
disabled(ctx) {
|
disabled(ctx) {
|
||||||
const model = ctx.getCurrentBlockByType(klass)?.model;
|
const model = ctx.getCurrentModel();
|
||||||
if (!model || !isExternalEmbedModel(model)) return true;
|
if (!model || !isExternalEmbedModel(model)) return true;
|
||||||
|
|
||||||
const { url } = model.props;
|
const { url } = model.props;
|
||||||
@@ -116,7 +143,7 @@ export function createBuiltinToolbarConfigForExternal(
|
|||||||
return options?.viewType === 'card';
|
return options?.viewType === 'card';
|
||||||
},
|
},
|
||||||
run(ctx) {
|
run(ctx) {
|
||||||
const model = ctx.getCurrentBlockByType(klass)?.model;
|
const model = ctx.getCurrentModel();
|
||||||
if (!model || !isExternalEmbedModel(model)) return;
|
if (!model || !isExternalEmbedModel(model)) return;
|
||||||
|
|
||||||
const { url, caption } = model.props;
|
const { url, caption } = model.props;
|
||||||
@@ -165,7 +192,7 @@ export function createBuiltinToolbarConfigForExternal(
|
|||||||
id: 'embed',
|
id: 'embed',
|
||||||
label: 'Embed view',
|
label: 'Embed view',
|
||||||
disabled(ctx) {
|
disabled(ctx) {
|
||||||
const model = ctx.getCurrentBlockByType(klass)?.model;
|
const model = ctx.getCurrentModel();
|
||||||
if (!model || !isExternalEmbedModel(model)) return false;
|
if (!model || !isExternalEmbedModel(model)) return false;
|
||||||
|
|
||||||
const { url } = model.props;
|
const { url } = model.props;
|
||||||
@@ -176,7 +203,7 @@ export function createBuiltinToolbarConfigForExternal(
|
|||||||
return options?.viewType === 'embed';
|
return options?.viewType === 'embed';
|
||||||
},
|
},
|
||||||
when(ctx) {
|
when(ctx) {
|
||||||
const model = ctx.getCurrentBlockByType(klass)?.model;
|
const model = ctx.getCurrentModel();
|
||||||
if (!model || !isExternalEmbedModel(model)) return false;
|
if (!model || !isExternalEmbedModel(model)) return false;
|
||||||
|
|
||||||
const { url } = model.props;
|
const { url } = model.props;
|
||||||
@@ -187,7 +214,7 @@ export function createBuiltinToolbarConfigForExternal(
|
|||||||
return options?.viewType === 'embed';
|
return options?.viewType === 'embed';
|
||||||
},
|
},
|
||||||
run(ctx) {
|
run(ctx) {
|
||||||
const model = ctx.getCurrentBlockByType(klass)?.model;
|
const model = ctx.getCurrentModel();
|
||||||
if (!model || !isExternalEmbedModel(model)) return;
|
if (!model || !isExternalEmbedModel(model)) return;
|
||||||
|
|
||||||
const { url, caption } = model.props;
|
const { url, caption } = model.props;
|
||||||
@@ -231,7 +258,7 @@ export function createBuiltinToolbarConfigForExternal(
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
content(ctx) {
|
content(ctx) {
|
||||||
const model = ctx.getCurrentBlockByType(klass)?.model;
|
const model = ctx.getCurrentModel();
|
||||||
if (!model || !isExternalEmbedModel(model)) return null;
|
if (!model || !isExternalEmbedModel(model)) return null;
|
||||||
|
|
||||||
const { url } = model.props;
|
const { url } = model.props;
|
||||||
@@ -242,15 +269,11 @@ export function createBuiltinToolbarConfigForExternal(
|
|||||||
const viewType$ = signal(
|
const viewType$ = signal(
|
||||||
`${viewType === 'card' ? 'Card' : 'Embed'} view`
|
`${viewType === 'card' ? 'Card' : 'Embed'} view`
|
||||||
);
|
);
|
||||||
const onToggle = (e: CustomEvent<boolean>) => {
|
const onToggle = createOnToggleFn(
|
||||||
const opened = e.detail;
|
ctx,
|
||||||
if (!opened) return;
|
'OpenedViewSelector',
|
||||||
|
'switch view'
|
||||||
ctx.track('OpenedViewSelector', {
|
);
|
||||||
...trackBaseProps,
|
|
||||||
control: 'switch view',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return html`${keyed(
|
return html`${keyed(
|
||||||
model,
|
model,
|
||||||
@@ -275,6 +298,9 @@ export function createBuiltinToolbarConfigForExternal(
|
|||||||
label: 'Small horizontal style',
|
label: 'Small horizontal style',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
when(ctx) {
|
||||||
|
return Boolean(ctx.getCurrentModelByType(EmbedGithubModel));
|
||||||
|
},
|
||||||
content(ctx) {
|
content(ctx) {
|
||||||
const model = ctx.getCurrentModelByType(EmbedGithubModel);
|
const model = ctx.getCurrentModelByType(EmbedGithubModel);
|
||||||
if (!model) return null;
|
if (!model) return null;
|
||||||
@@ -291,16 +317,11 @@ export function createBuiltinToolbarConfigForExternal(
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
})) satisfies ToolbarAction[];
|
})) satisfies ToolbarAction[];
|
||||||
|
const onToggle = createOnToggleFn(
|
||||||
const onToggle = (e: CustomEvent<boolean>) => {
|
ctx,
|
||||||
const opened = e.detail;
|
'OpenedCardStyleSelector',
|
||||||
if (!opened) return;
|
'switch card style'
|
||||||
|
);
|
||||||
ctx.track('OpenedCardStyleSelector', {
|
|
||||||
...trackBaseProps,
|
|
||||||
control: 'switch card style',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return html`${keyed(
|
return html`${keyed(
|
||||||
model,
|
model,
|
||||||
@@ -393,3 +414,264 @@ export function createBuiltinToolbarConfigForExternal(
|
|||||||
],
|
],
|
||||||
} as const satisfies ToolbarModuleConfig;
|
} as const satisfies ToolbarModuleConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const createBuiltinSurfaceToolbarConfigForExternal = (
|
||||||
|
klass:
|
||||||
|
| typeof EmbedGithubBlockComponent
|
||||||
|
| typeof EmbedFigmaBlockComponent
|
||||||
|
| typeof EmbedLoomBlockComponent
|
||||||
|
| typeof EmbedYoutubeBlockComponent
|
||||||
|
) => {
|
||||||
|
return {
|
||||||
|
actions: [
|
||||||
|
previewAction,
|
||||||
|
{
|
||||||
|
id: 'b.conversions',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
id: 'card',
|
||||||
|
label: 'Card view',
|
||||||
|
run(ctx) {
|
||||||
|
const model = ctx.getCurrentBlockByType(klass)?.model;
|
||||||
|
if (!model || !isExternalEmbedModel(model)) return;
|
||||||
|
|
||||||
|
const { id: oldId, xywh, parent } = model;
|
||||||
|
const { url, caption } = model.props;
|
||||||
|
|
||||||
|
let { style } = model.props;
|
||||||
|
let flavour = 'affine:bookmark';
|
||||||
|
|
||||||
|
if (!BookmarkStyles.includes(style)) {
|
||||||
|
style = BookmarkStyles[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const bounds = Bound.deserialize(xywh);
|
||||||
|
bounds.w = EMBED_CARD_WIDTH[style];
|
||||||
|
bounds.h = EMBED_CARD_HEIGHT[style];
|
||||||
|
|
||||||
|
const newId = ctx.store.addBlock(
|
||||||
|
flavour,
|
||||||
|
{ url, caption, style, xywh: bounds.serialize() },
|
||||||
|
parent
|
||||||
|
);
|
||||||
|
|
||||||
|
ctx.command.exec(reassociateConnectorsCommand, { oldId, newId });
|
||||||
|
|
||||||
|
ctx.store.deleteBlock(model);
|
||||||
|
|
||||||
|
// Selects new block
|
||||||
|
ctx.gfx.selection.set({ editing: false, elements: [newId] });
|
||||||
|
|
||||||
|
ctx.track('SelectedView', {
|
||||||
|
...trackBaseProps,
|
||||||
|
control: 'select view',
|
||||||
|
type: 'card view',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'embed',
|
||||||
|
label: 'Embed view',
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
when(ctx) {
|
||||||
|
const model = ctx.getCurrentBlockByType(klass)?.model;
|
||||||
|
if (!model || !isExternalEmbedModel(model)) return false;
|
||||||
|
|
||||||
|
const { url } = model.props;
|
||||||
|
const options = ctx.std
|
||||||
|
.get(EmbedOptionProvider)
|
||||||
|
.getEmbedBlockOptions(url);
|
||||||
|
|
||||||
|
return options?.viewType === 'embed';
|
||||||
|
},
|
||||||
|
content(ctx) {
|
||||||
|
const model = ctx.getCurrentBlockByType(klass)?.model;
|
||||||
|
if (!model || !isExternalEmbedModel(model)) return null;
|
||||||
|
|
||||||
|
const { url } = model.props;
|
||||||
|
const viewType =
|
||||||
|
ctx.std.get(EmbedOptionProvider).getEmbedBlockOptions(url)
|
||||||
|
?.viewType ?? 'card';
|
||||||
|
const actions = this.actions.map(action => ({ ...action }));
|
||||||
|
const viewType$ = signal(
|
||||||
|
`${viewType === 'card' ? 'Card' : 'Embed'} view`
|
||||||
|
);
|
||||||
|
const onToggle = createOnToggleFn(
|
||||||
|
ctx,
|
||||||
|
'OpenedViewSelector',
|
||||||
|
'switch view'
|
||||||
|
);
|
||||||
|
|
||||||
|
return html`${keyed(
|
||||||
|
model,
|
||||||
|
html`<affine-view-dropdown-menu
|
||||||
|
@toggle=${onToggle}
|
||||||
|
.actions=${actions}
|
||||||
|
.context=${ctx}
|
||||||
|
.viewType$=${viewType$}
|
||||||
|
></affine-view-dropdown-menu>`
|
||||||
|
)}`;
|
||||||
|
},
|
||||||
|
} satisfies ToolbarActionGroup<ToolbarAction>,
|
||||||
|
{
|
||||||
|
id: 'c.style',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
id: 'horizontal',
|
||||||
|
label: 'Large horizontal style',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'list',
|
||||||
|
label: 'Small horizontal style',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'vertical',
|
||||||
|
label: 'Large vertical style',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'cube',
|
||||||
|
label: 'Small vertical style',
|
||||||
|
},
|
||||||
|
].filter(action =>
|
||||||
|
EmbedGithubStyles.includes(action.id as EmbedCardStyle)
|
||||||
|
),
|
||||||
|
when(ctx) {
|
||||||
|
return Boolean(ctx.getCurrentModelByType(EmbedGithubModel));
|
||||||
|
},
|
||||||
|
content(ctx) {
|
||||||
|
const model = ctx.getCurrentBlockByType(klass)?.model;
|
||||||
|
if (!model) return null;
|
||||||
|
|
||||||
|
const actions = this.actions.map(action => ({
|
||||||
|
...action,
|
||||||
|
run: ({ store }) => {
|
||||||
|
const style = action.id as EmbedCardStyle;
|
||||||
|
const bounds = Bound.deserialize(model.xywh);
|
||||||
|
bounds.w = EMBED_CARD_WIDTH[style];
|
||||||
|
bounds.h = EMBED_CARD_HEIGHT[style];
|
||||||
|
const xywh = bounds.serialize();
|
||||||
|
|
||||||
|
store.updateBlock(model, { style, xywh });
|
||||||
|
|
||||||
|
ctx.track('SelectedCardStyle', {
|
||||||
|
...trackBaseProps,
|
||||||
|
control: 'select card style',
|
||||||
|
type: style,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
})) satisfies ToolbarAction[];
|
||||||
|
const style$ = model.props.style$;
|
||||||
|
const onToggle = createOnToggleFn(
|
||||||
|
ctx,
|
||||||
|
'OpenedCardStyleSelector',
|
||||||
|
'switch card style'
|
||||||
|
);
|
||||||
|
|
||||||
|
return html`${keyed(
|
||||||
|
model,
|
||||||
|
html`<affine-card-style-dropdown-menu
|
||||||
|
@toggle=${onToggle}
|
||||||
|
.actions=${actions}
|
||||||
|
.context=${ctx}
|
||||||
|
.style$=${style$}
|
||||||
|
></affine-card-style-dropdown-menu>`
|
||||||
|
)}`;
|
||||||
|
},
|
||||||
|
} satisfies ToolbarActionGroup<ToolbarAction>,
|
||||||
|
{
|
||||||
|
id: 'd.caption',
|
||||||
|
tooltip: 'Caption',
|
||||||
|
icon: CaptionIcon(),
|
||||||
|
run(ctx) {
|
||||||
|
const block = ctx.getCurrentBlockByType(klass);
|
||||||
|
block?.captionEditor?.show();
|
||||||
|
|
||||||
|
ctx.track('OpenedCaptionEditor', {
|
||||||
|
...trackBaseProps,
|
||||||
|
control: 'add caption',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'e.scale',
|
||||||
|
content(ctx) {
|
||||||
|
const model = ctx.getCurrentBlockByType(klass)?.model;
|
||||||
|
if (!model) return null;
|
||||||
|
|
||||||
|
const scale$ = computed(() => {
|
||||||
|
const {
|
||||||
|
xywh$: { value: xywh },
|
||||||
|
} = model;
|
||||||
|
const {
|
||||||
|
style$: { value: style },
|
||||||
|
} = model.props;
|
||||||
|
const bounds = Bound.deserialize(xywh);
|
||||||
|
const height = EMBED_CARD_HEIGHT[style];
|
||||||
|
return Math.round(100 * (bounds.h / height));
|
||||||
|
});
|
||||||
|
const onSelect = (e: CustomEvent<number>) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
const scale = e.detail / 100;
|
||||||
|
|
||||||
|
const bounds = Bound.deserialize(model.xywh);
|
||||||
|
const style = model.props.style;
|
||||||
|
bounds.h = EMBED_CARD_HEIGHT[style] * scale;
|
||||||
|
bounds.w = EMBED_CARD_WIDTH[style] * scale;
|
||||||
|
const xywh = bounds.serialize();
|
||||||
|
|
||||||
|
ctx.store.updateBlock(model, { xywh });
|
||||||
|
|
||||||
|
ctx.track('SelectedCardScale', {
|
||||||
|
...trackBaseProps,
|
||||||
|
control: 'select card scale',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const onToggle = createOnToggleFn(
|
||||||
|
ctx,
|
||||||
|
'OpenedCardScaleSelector',
|
||||||
|
'switch card scale'
|
||||||
|
);
|
||||||
|
const format = (value: number) => `${value}%`;
|
||||||
|
|
||||||
|
return html`${keyed(
|
||||||
|
model,
|
||||||
|
html`<affine-size-dropdown-menu
|
||||||
|
@select=${onSelect}
|
||||||
|
@toggle=${onToggle}
|
||||||
|
.format=${format}
|
||||||
|
.size$=${scale$}
|
||||||
|
></affine-size-dropdown-menu>`
|
||||||
|
)}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
when: ctx => ctx.getSurfaceBlocksByType(klass).length === 1,
|
||||||
|
} as const satisfies ToolbarModuleConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createBuiltinToolbarConfigExtension = (
|
||||||
|
flavour: string,
|
||||||
|
klass:
|
||||||
|
| typeof EmbedGithubBlockComponent
|
||||||
|
| typeof EmbedFigmaBlockComponent
|
||||||
|
| typeof EmbedLoomBlockComponent
|
||||||
|
| typeof EmbedYoutubeBlockComponent
|
||||||
|
): ExtensionType[] => {
|
||||||
|
const name = flavour.split(':').pop();
|
||||||
|
|
||||||
|
return [
|
||||||
|
ToolbarModuleExtension({
|
||||||
|
id: BlockFlavourIdentifier(flavour),
|
||||||
|
config: createBuiltinToolbarConfigForExternal(klass),
|
||||||
|
}),
|
||||||
|
|
||||||
|
ToolbarModuleExtension({
|
||||||
|
id: BlockFlavourIdentifier(`affine:surface:${name}`),
|
||||||
|
config: createBuiltinSurfaceToolbarConfigForExternal(klass),
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
import { EmbedFigmaBlockSchema } from '@blocksuite/affine-model';
|
import { EmbedFigmaBlockSchema } from '@blocksuite/affine-model';
|
||||||
import { ToolbarModuleExtension } from '@blocksuite/affine-shared/services';
|
|
||||||
import { SlashMenuConfigExtension } from '@blocksuite/affine-widget-slash-menu';
|
import { SlashMenuConfigExtension } from '@blocksuite/affine-widget-slash-menu';
|
||||||
import {
|
import { BlockViewExtension, FlavourExtension } from '@blocksuite/block-std';
|
||||||
BlockServiceIdentifier,
|
|
||||||
BlockViewExtension,
|
|
||||||
FlavourExtension,
|
|
||||||
} from '@blocksuite/block-std';
|
|
||||||
import type { ExtensionType } from '@blocksuite/store';
|
import type { ExtensionType } from '@blocksuite/store';
|
||||||
import { literal } from 'lit/static-html.js';
|
import { literal } from 'lit/static-html.js';
|
||||||
|
|
||||||
import { createBuiltinToolbarConfigForExternal } from '../configs/toolbar';
|
import { createBuiltinToolbarConfigExtension } from '../configs/toolbar';
|
||||||
import { EmbedFigmaBlockAdapterExtensions } from './adapters/extension';
|
import { EmbedFigmaBlockAdapterExtensions } from './adapters/extension';
|
||||||
import { embedFigmaSlashMenuConfig } from './configs/slash-menu';
|
import { embedFigmaSlashMenuConfig } from './configs/slash-menu';
|
||||||
import { EmbedFigmaBlockComponent } from './embed-figma-block';
|
import { EmbedFigmaBlockComponent } from './embed-figma-block';
|
||||||
@@ -26,9 +21,6 @@ export const EmbedFigmaBlockSpec: ExtensionType[] = [
|
|||||||
}),
|
}),
|
||||||
EmbedFigmaBlockAdapterExtensions,
|
EmbedFigmaBlockAdapterExtensions,
|
||||||
EmbedFigmaBlockOptionConfig,
|
EmbedFigmaBlockOptionConfig,
|
||||||
ToolbarModuleExtension({
|
createBuiltinToolbarConfigExtension(flavour, EmbedFigmaBlockComponent),
|
||||||
id: BlockServiceIdentifier(flavour),
|
|
||||||
config: createBuiltinToolbarConfigForExternal(EmbedFigmaBlockComponent),
|
|
||||||
}),
|
|
||||||
SlashMenuConfigExtension(flavour, embedFigmaSlashMenuConfig),
|
SlashMenuConfigExtension(flavour, embedFigmaSlashMenuConfig),
|
||||||
].flat();
|
].flat();
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
import { EmbedGithubBlockSchema } from '@blocksuite/affine-model';
|
import { EmbedGithubBlockSchema } from '@blocksuite/affine-model';
|
||||||
import { ToolbarModuleExtension } from '@blocksuite/affine-shared/services';
|
|
||||||
import { SlashMenuConfigExtension } from '@blocksuite/affine-widget-slash-menu';
|
import { SlashMenuConfigExtension } from '@blocksuite/affine-widget-slash-menu';
|
||||||
import {
|
import { BlockViewExtension, FlavourExtension } from '@blocksuite/block-std';
|
||||||
BlockServiceIdentifier,
|
|
||||||
BlockViewExtension,
|
|
||||||
FlavourExtension,
|
|
||||||
} from '@blocksuite/block-std';
|
|
||||||
import type { ExtensionType } from '@blocksuite/store';
|
import type { ExtensionType } from '@blocksuite/store';
|
||||||
import { literal } from 'lit/static-html.js';
|
import { literal } from 'lit/static-html.js';
|
||||||
|
|
||||||
import { createBuiltinToolbarConfigForExternal } from '../configs/toolbar';
|
import { createBuiltinToolbarConfigExtension } from '../configs/toolbar';
|
||||||
import { EmbedGithubBlockAdapterExtensions } from './adapters/extension';
|
import { EmbedGithubBlockAdapterExtensions } from './adapters/extension';
|
||||||
import { embedGithubSlashMenuConfig } from './configs/slash-menu';
|
import { embedGithubSlashMenuConfig } from './configs/slash-menu';
|
||||||
import { EmbedGithubBlockComponent } from './embed-github-block';
|
import { EmbedGithubBlockComponent } from './embed-github-block';
|
||||||
@@ -30,9 +25,6 @@ export const EmbedGithubBlockSpec: ExtensionType[] = [
|
|||||||
}),
|
}),
|
||||||
EmbedGithubBlockAdapterExtensions,
|
EmbedGithubBlockAdapterExtensions,
|
||||||
EmbedGithubBlockOptionConfig,
|
EmbedGithubBlockOptionConfig,
|
||||||
ToolbarModuleExtension({
|
createBuiltinToolbarConfigExtension(flavour, EmbedGithubBlockComponent),
|
||||||
id: BlockServiceIdentifier(flavour),
|
|
||||||
config: createBuiltinToolbarConfigForExternal(EmbedGithubBlockComponent),
|
|
||||||
}),
|
|
||||||
SlashMenuConfigExtension(flavour, embedGithubSlashMenuConfig),
|
SlashMenuConfigExtension(flavour, embedGithubSlashMenuConfig),
|
||||||
].flat();
|
].flat();
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
import { EmbedLoomBlockSchema } from '@blocksuite/affine-model';
|
import { EmbedLoomBlockSchema } from '@blocksuite/affine-model';
|
||||||
import { ToolbarModuleExtension } from '@blocksuite/affine-shared/services';
|
|
||||||
import { SlashMenuConfigExtension } from '@blocksuite/affine-widget-slash-menu';
|
import { SlashMenuConfigExtension } from '@blocksuite/affine-widget-slash-menu';
|
||||||
import {
|
import { BlockViewExtension, FlavourExtension } from '@blocksuite/block-std';
|
||||||
BlockServiceIdentifier,
|
|
||||||
BlockViewExtension,
|
|
||||||
FlavourExtension,
|
|
||||||
} from '@blocksuite/block-std';
|
|
||||||
import type { ExtensionType } from '@blocksuite/store';
|
import type { ExtensionType } from '@blocksuite/store';
|
||||||
import { literal } from 'lit/static-html.js';
|
import { literal } from 'lit/static-html.js';
|
||||||
|
|
||||||
import { createBuiltinToolbarConfigForExternal } from '../configs/toolbar';
|
import { createBuiltinToolbarConfigExtension } from '../configs/toolbar';
|
||||||
import { EmbedLoomBlockAdapterExtensions } from './adapters/extension';
|
import { EmbedLoomBlockAdapterExtensions } from './adapters/extension';
|
||||||
import { embedLoomSlashMenuConfig } from './configs/slash-menu';
|
import { embedLoomSlashMenuConfig } from './configs/slash-menu';
|
||||||
import { EmbedLoomBlockComponent } from './embed-loom-block';
|
import { EmbedLoomBlockComponent } from './embed-loom-block';
|
||||||
@@ -30,9 +25,6 @@ export const EmbedLoomBlockSpec: ExtensionType[] = [
|
|||||||
}),
|
}),
|
||||||
EmbedLoomBlockAdapterExtensions,
|
EmbedLoomBlockAdapterExtensions,
|
||||||
EmbedLoomBlockOptionConfig,
|
EmbedLoomBlockOptionConfig,
|
||||||
ToolbarModuleExtension({
|
createBuiltinToolbarConfigExtension(flavour, EmbedLoomBlockComponent),
|
||||||
id: BlockServiceIdentifier(flavour),
|
|
||||||
config: createBuiltinToolbarConfigForExternal(EmbedLoomBlockComponent),
|
|
||||||
}),
|
|
||||||
SlashMenuConfigExtension(flavour, embedLoomSlashMenuConfig),
|
SlashMenuConfigExtension(flavour, embedLoomSlashMenuConfig),
|
||||||
].flat();
|
].flat();
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
import { EmbedYoutubeBlockSchema } from '@blocksuite/affine-model';
|
import { EmbedYoutubeBlockSchema } from '@blocksuite/affine-model';
|
||||||
import { ToolbarModuleExtension } from '@blocksuite/affine-shared/services';
|
|
||||||
import { SlashMenuConfigExtension } from '@blocksuite/affine-widget-slash-menu';
|
import { SlashMenuConfigExtension } from '@blocksuite/affine-widget-slash-menu';
|
||||||
import {
|
import { BlockViewExtension, FlavourExtension } from '@blocksuite/block-std';
|
||||||
BlockServiceIdentifier,
|
|
||||||
BlockViewExtension,
|
|
||||||
FlavourExtension,
|
|
||||||
} from '@blocksuite/block-std';
|
|
||||||
import type { ExtensionType } from '@blocksuite/store';
|
import type { ExtensionType } from '@blocksuite/store';
|
||||||
import { literal } from 'lit/static-html.js';
|
import { literal } from 'lit/static-html.js';
|
||||||
|
|
||||||
import { createBuiltinToolbarConfigForExternal } from '../configs/toolbar';
|
import { createBuiltinToolbarConfigExtension } from '../configs/toolbar';
|
||||||
import { EmbedYoutubeBlockAdapterExtensions } from './adapters/extension';
|
import { EmbedYoutubeBlockAdapterExtensions } from './adapters/extension';
|
||||||
import { embedYoutubeSlashMenuConfig } from './configs/slash-menu';
|
import { embedYoutubeSlashMenuConfig } from './configs/slash-menu';
|
||||||
import { EmbedYoutubeBlockComponent } from './embed-youtube-block';
|
import { EmbedYoutubeBlockComponent } from './embed-youtube-block';
|
||||||
@@ -30,9 +25,6 @@ export const EmbedYoutubeBlockSpec: ExtensionType[] = [
|
|||||||
}),
|
}),
|
||||||
EmbedYoutubeBlockAdapterExtensions,
|
EmbedYoutubeBlockAdapterExtensions,
|
||||||
EmbedYoutubeBlockOptionConfig,
|
EmbedYoutubeBlockOptionConfig,
|
||||||
ToolbarModuleExtension({
|
createBuiltinToolbarConfigExtension(flavour, EmbedYoutubeBlockComponent),
|
||||||
id: BlockServiceIdentifier(flavour),
|
|
||||||
config: createBuiltinToolbarConfigForExternal(EmbedYoutubeBlockComponent),
|
|
||||||
}),
|
|
||||||
SlashMenuConfigExtension('affine:embed-youtube', embedYoutubeSlashMenuConfig),
|
SlashMenuConfigExtension('affine:embed-youtube', embedYoutubeSlashMenuConfig),
|
||||||
].flat();
|
].flat();
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
import type { ToolbarModuleConfig } from '@blocksuite/affine-shared/services';
|
|
||||||
|
|
||||||
export const builtinEmbedToolbarConfig = {
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
id: 'a.test',
|
|
||||||
label: 'Embed',
|
|
||||||
run() {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
} as const satisfies ToolbarModuleConfig;
|
|
||||||
@@ -4,7 +4,6 @@ import type { ExtensionType } from '@blocksuite/store';
|
|||||||
|
|
||||||
import { builtinBrushToolbarConfig } from './brush';
|
import { builtinBrushToolbarConfig } from './brush';
|
||||||
import { builtinConnectorToolbarConfig } from './connector';
|
import { builtinConnectorToolbarConfig } from './connector';
|
||||||
import { builtinEmbedToolbarConfig } from './embed';
|
|
||||||
import { builtinFrameToolbarConfig } from './frame';
|
import { builtinFrameToolbarConfig } from './frame';
|
||||||
import { builtinGroupToolbarConfig } from './group';
|
import { builtinGroupToolbarConfig } from './group';
|
||||||
import { builtinImageToolbarConfig } from './image';
|
import { builtinImageToolbarConfig } from './image';
|
||||||
@@ -30,11 +29,6 @@ export const EdgelessElementToolbarExtension: ExtensionType[] = [
|
|||||||
config: builtinConnectorToolbarConfig,
|
config: builtinConnectorToolbarConfig,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
ToolbarModuleExtension({
|
|
||||||
id: BlockFlavourIdentifier('affine:surface:embed'),
|
|
||||||
config: builtinEmbedToolbarConfig,
|
|
||||||
}),
|
|
||||||
|
|
||||||
ToolbarModuleExtension({
|
ToolbarModuleExtension({
|
||||||
id: BlockFlavourIdentifier('affine:surface:frame'),
|
id: BlockFlavourIdentifier('affine:surface:frame'),
|
||||||
config: builtinFrameToolbarConfig,
|
config: builtinFrameToolbarConfig,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import type { GfxModel } from '@blocksuite/block-std/gfx';
|
||||||
import type { BlockModel } from '@blocksuite/store';
|
import type { BlockModel } from '@blocksuite/store';
|
||||||
|
|
||||||
import { EmbedFigmaModel } from './figma';
|
import { EmbedFigmaModel } from './figma';
|
||||||
@@ -34,7 +35,7 @@ export type LinkableEmbedModel = EmbedCardModel | EmbedIframeBlockModel;
|
|||||||
export type BuiltInEmbedModel = EmbedCardModel | EmbedHtmlModel;
|
export type BuiltInEmbedModel = EmbedCardModel | EmbedHtmlModel;
|
||||||
|
|
||||||
export function isExternalEmbedModel(
|
export function isExternalEmbedModel(
|
||||||
model: BlockModel
|
model: GfxModel | BlockModel
|
||||||
): model is InstanceType<ExternalEmbedModel> {
|
): model is InstanceType<ExternalEmbedModel> {
|
||||||
return (
|
return (
|
||||||
model instanceof EmbedFigmaModel ||
|
model instanceof EmbedFigmaModel ||
|
||||||
@@ -45,7 +46,7 @@ export function isExternalEmbedModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isInternalEmbedModel(
|
export function isInternalEmbedModel(
|
||||||
model: BlockModel
|
model: GfxModel | BlockModel
|
||||||
): model is InstanceType<InternalEmbedModel> {
|
): model is InstanceType<InternalEmbedModel> {
|
||||||
return (
|
return (
|
||||||
model instanceof EmbedLinkedDocModel || model instanceof EmbedSyncedDocModel
|
model instanceof EmbedLinkedDocModel || model instanceof EmbedSyncedDocModel
|
||||||
|
|||||||
@@ -128,8 +128,8 @@ abstract class ToolbarContextBase {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getSurfaceModelsByType<M extends abstract new (...args: any) => any>(
|
getSurfaceModelsByType<T extends abstract new (...args: any) => any>(
|
||||||
klass: M
|
klass: T
|
||||||
) {
|
) {
|
||||||
if (this.hasSelectedSurfaceModels) {
|
if (this.hasSelectedSurfaceModels) {
|
||||||
const elements = this.elementsMap$.peek().get(this.flavour$.peek());
|
const elements = this.elementsMap$.peek().get(this.flavour$.peek());
|
||||||
@@ -140,6 +140,20 @@ abstract class ToolbarContextBase {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSurfaceBlocksByType<T extends abstract new (...args: any) => any>(
|
||||||
|
klass: T
|
||||||
|
) {
|
||||||
|
if (this.hasSelectedSurfaceModels) {
|
||||||
|
const elements = this.elementsMap$.peek().get(this.flavour$.peek());
|
||||||
|
if (elements?.length) {
|
||||||
|
return elements
|
||||||
|
.map(model => this.gfx.view.get(model.id))
|
||||||
|
.filter(block => block && this.matchBlock(block, klass));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
getCurrentBlockBy<T extends SelectionConstructor>(type: T) {
|
getCurrentBlockBy<T extends SelectionConstructor>(type: T) {
|
||||||
const selection = this.selection.find(type);
|
const selection = this.selection.find(type);
|
||||||
if (!selection) return null;
|
if (!selection) return null;
|
||||||
@@ -160,17 +174,17 @@ abstract class ToolbarContextBase {
|
|||||||
: this.getCurrentBlockBy(BlockSelection);
|
: this.getCurrentBlockBy(BlockSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentBlockByType<K extends abstract new (...args: any) => any>(
|
getCurrentBlockByType<T extends abstract new (...args: any) => any>(
|
||||||
klass: K
|
klass: T
|
||||||
) {
|
) {
|
||||||
const block = this.getCurrentBlock();
|
const block = this.getCurrentBlock();
|
||||||
return this.matchBlock(block, klass) ? block : null;
|
return this.matchBlock(block, klass) ? block : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
matchBlock<K extends abstract new (...args: any) => any>(
|
matchBlock<T extends abstract new (...args: any) => any>(
|
||||||
component: GfxElementModelView | BlockComponent | null,
|
component: GfxElementModelView | BlockComponent | null,
|
||||||
klass: K
|
klass: T
|
||||||
): component is InstanceType<K> {
|
): component is InstanceType<T> {
|
||||||
return component instanceof klass;
|
return component instanceof klass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,23 +198,23 @@ abstract class ToolbarContextBase {
|
|||||||
return this.store.getBlock(selection.blockId)?.model ?? null;
|
return this.store.getBlock(selection.blockId)?.model ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentModel() {
|
getCurrentModel(): GfxModel | BlockModel | null {
|
||||||
return this.hasSelectedSurfaceModels
|
return this.hasSelectedSurfaceModels
|
||||||
? this.getCurrentModelBy(SurfaceSelection)
|
? this.getCurrentModelBy(SurfaceSelection)
|
||||||
: this.getCurrentModelBy(BlockSelection);
|
: this.getCurrentModelBy(BlockSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentModelByType<M extends abstract new (...args: any) => any>(
|
getCurrentModelByType<T extends abstract new (...args: any) => any>(
|
||||||
klass: M
|
klass: T
|
||||||
) {
|
) {
|
||||||
const model = this.getCurrentModel();
|
const model = this.getCurrentModel();
|
||||||
return this.matchModel(model, klass) ? model : null;
|
return this.matchModel(model, klass) ? model : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
matchModel<K extends abstract new (...args: any) => any>(
|
matchModel<T extends abstract new (...args: any) => any>(
|
||||||
model: GfxModel | BlockModel | null,
|
model: GfxModel | BlockModel | null,
|
||||||
klass: K
|
klass: T
|
||||||
): model is InstanceType<K> {
|
): model is InstanceType<T> {
|
||||||
return model instanceof klass;
|
return model instanceof klass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -397,15 +397,16 @@ export class AffineToolbarWidget extends WidgetComponent {
|
|||||||
// `card view` or `embed view`
|
// `card view` or `embed view`
|
||||||
disposables.add(
|
disposables.add(
|
||||||
std.view.viewUpdated.subscribe(record => {
|
std.view.viewUpdated.subscribe(record => {
|
||||||
if (record.type !== 'block') return;
|
const hasAddedBlock =
|
||||||
if (!flags.isBlock()) return;
|
record.type === 'block' && record.method === 'add';
|
||||||
|
if (!hasAddedBlock) return;
|
||||||
|
|
||||||
|
if (flags.isBlock()) {
|
||||||
const blockIds = std.selection
|
const blockIds = std.selection
|
||||||
.filter$(BlockSelection)
|
.filter$(BlockSelection)
|
||||||
.peek()
|
.peek()
|
||||||
.map(s => s.blockId);
|
.map(s => s.blockId);
|
||||||
|
if (blockIds.includes(record.id)) {
|
||||||
if (record.method === 'add' && blockIds.includes(record.id)) {
|
|
||||||
batch(() => {
|
batch(() => {
|
||||||
this.setReferenceElementWithBlocks(
|
this.setReferenceElementWithBlocks(
|
||||||
blockIds
|
blockIds
|
||||||
@@ -414,6 +415,12 @@ export class AffineToolbarWidget extends WidgetComponent {
|
|||||||
);
|
);
|
||||||
flags.refresh(Flag.Block);
|
flags.refresh(Flag.Block);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags.isSurface()) {
|
||||||
|
flags.refresh(Flag.Surface);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -425,7 +425,6 @@ function createExternalLinkableToolbarConfig(
|
|||||||
toast(ctx.host, 'Copied link to clipboard');
|
toast(ctx.host, 'Copied link to clipboard');
|
||||||
|
|
||||||
ctx.track('CopiedLink', {
|
ctx.track('CopiedLink', {
|
||||||
module: 'toolbar',
|
|
||||||
category: matchModels(model, [BookmarkBlockModel])
|
category: matchModels(model, [BookmarkBlockModel])
|
||||||
? 'bookmark'
|
? 'bookmark'
|
||||||
: 'link',
|
: 'link',
|
||||||
@@ -462,7 +461,6 @@ function createExternalLinkableToolbarConfig(
|
|||||||
);
|
);
|
||||||
|
|
||||||
ctx.track('OpenedAliasPopup', {
|
ctx.track('OpenedAliasPopup', {
|
||||||
module: 'toolbar',
|
|
||||||
category: matchModels(model, [BookmarkBlockModel])
|
category: matchModels(model, [BookmarkBlockModel])
|
||||||
? 'bookmark'
|
? 'bookmark'
|
||||||
: 'link',
|
: 'link',
|
||||||
@@ -600,9 +598,6 @@ const embedLinkedDocToolbarConfig = {
|
|||||||
toast(ctx.host, 'Copied link to clipboard');
|
toast(ctx.host, 'Copied link to clipboard');
|
||||||
|
|
||||||
ctx.track('CopiedLink', {
|
ctx.track('CopiedLink', {
|
||||||
segment: 'doc',
|
|
||||||
page: 'doc editor',
|
|
||||||
module: 'toolbar',
|
|
||||||
category: 'linked doc',
|
category: 'linked doc',
|
||||||
type: 'card view',
|
type: 'card view',
|
||||||
control: 'copy link',
|
control: 'copy link',
|
||||||
@@ -648,9 +643,6 @@ const embedLinkedDocToolbarConfig = {
|
|||||||
);
|
);
|
||||||
|
|
||||||
ctx.track('OpenedAliasPopup', {
|
ctx.track('OpenedAliasPopup', {
|
||||||
segment: 'doc',
|
|
||||||
page: 'doc editor',
|
|
||||||
module: 'toolbar',
|
|
||||||
category: 'linked doc',
|
category: 'linked doc',
|
||||||
type: 'embed view',
|
type: 'embed view',
|
||||||
control: 'edit',
|
control: 'edit',
|
||||||
@@ -689,9 +681,6 @@ const embedSyncedDocToolbarConfig = {
|
|||||||
toast(ctx.host, 'Copied link to clipboard');
|
toast(ctx.host, 'Copied link to clipboard');
|
||||||
|
|
||||||
ctx.track('CopiedLink', {
|
ctx.track('CopiedLink', {
|
||||||
segment: 'doc',
|
|
||||||
page: 'doc editor',
|
|
||||||
module: 'toolbar',
|
|
||||||
category: 'linked doc',
|
category: 'linked doc',
|
||||||
type: 'embed view',
|
type: 'embed view',
|
||||||
control: 'copy link',
|
control: 'copy link',
|
||||||
@@ -730,9 +719,6 @@ const embedSyncedDocToolbarConfig = {
|
|||||||
);
|
);
|
||||||
|
|
||||||
ctx.track('OpenedAliasPopup', {
|
ctx.track('OpenedAliasPopup', {
|
||||||
segment: 'doc',
|
|
||||||
page: 'doc editor',
|
|
||||||
module: 'toolbar',
|
|
||||||
category: 'linked doc',
|
category: 'linked doc',
|
||||||
type: 'embed view',
|
type: 'embed view',
|
||||||
control: 'edit',
|
control: 'edit',
|
||||||
@@ -846,9 +832,6 @@ const inlineReferenceToolbarConfig = {
|
|||||||
toast(ctx.host, 'Copied link to clipboard');
|
toast(ctx.host, 'Copied link to clipboard');
|
||||||
|
|
||||||
ctx.track('CopiedLink', {
|
ctx.track('CopiedLink', {
|
||||||
segment: 'doc',
|
|
||||||
page: 'doc editor',
|
|
||||||
module: 'toolbar',
|
|
||||||
category: 'linked doc',
|
category: 'linked doc',
|
||||||
type: 'inline view',
|
type: 'inline view',
|
||||||
control: 'copy link',
|
control: 'copy link',
|
||||||
@@ -882,9 +865,6 @@ const inlineReferenceToolbarConfig = {
|
|||||||
abortController.signal.onabort = () => popover.remove();
|
abortController.signal.onabort = () => popover.remove();
|
||||||
|
|
||||||
ctx.track('OpenedAliasPopup', {
|
ctx.track('OpenedAliasPopup', {
|
||||||
segment: 'doc',
|
|
||||||
page: 'doc editor',
|
|
||||||
module: 'toolbar',
|
|
||||||
category: 'linked doc',
|
category: 'linked doc',
|
||||||
type: 'inline view',
|
type: 'inline view',
|
||||||
control: 'edit',
|
control: 'edit',
|
||||||
@@ -992,21 +972,41 @@ export const createCustomToolbarExtension = (
|
|||||||
config: createExternalLinkableToolbarConfig(EmbedFigmaBlockComponent),
|
config: createExternalLinkableToolbarConfig(EmbedFigmaBlockComponent),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
ToolbarModuleExtension({
|
||||||
|
id: BlockFlavourIdentifier('custom:affine:surface:embed-figma'),
|
||||||
|
config: createExternalLinkableToolbarConfig(BookmarkBlockComponent),
|
||||||
|
}),
|
||||||
|
|
||||||
ToolbarModuleExtension({
|
ToolbarModuleExtension({
|
||||||
id: BlockFlavourIdentifier('custom:affine:embed-github'),
|
id: BlockFlavourIdentifier('custom:affine:embed-github'),
|
||||||
config: createExternalLinkableToolbarConfig(EmbedGithubBlockComponent),
|
config: createExternalLinkableToolbarConfig(EmbedGithubBlockComponent),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
ToolbarModuleExtension({
|
||||||
|
id: BlockFlavourIdentifier('custom:affine:surface:embed-github'),
|
||||||
|
config: createExternalLinkableToolbarConfig(BookmarkBlockComponent),
|
||||||
|
}),
|
||||||
|
|
||||||
ToolbarModuleExtension({
|
ToolbarModuleExtension({
|
||||||
id: BlockFlavourIdentifier('custom:affine:embed-loom'),
|
id: BlockFlavourIdentifier('custom:affine:embed-loom'),
|
||||||
config: createExternalLinkableToolbarConfig(EmbedLoomBlockComponent),
|
config: createExternalLinkableToolbarConfig(EmbedLoomBlockComponent),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
ToolbarModuleExtension({
|
||||||
|
id: BlockFlavourIdentifier('custom:affine:surface:embed-loom'),
|
||||||
|
config: createExternalLinkableToolbarConfig(BookmarkBlockComponent),
|
||||||
|
}),
|
||||||
|
|
||||||
ToolbarModuleExtension({
|
ToolbarModuleExtension({
|
||||||
id: BlockFlavourIdentifier('custom:affine:embed-youtube'),
|
id: BlockFlavourIdentifier('custom:affine:embed-youtube'),
|
||||||
config: createExternalLinkableToolbarConfig(EmbedYoutubeBlockComponent),
|
config: createExternalLinkableToolbarConfig(EmbedYoutubeBlockComponent),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
ToolbarModuleExtension({
|
||||||
|
id: BlockFlavourIdentifier('custom:affine:surface:embed-youtube'),
|
||||||
|
config: createExternalLinkableToolbarConfig(BookmarkBlockComponent),
|
||||||
|
}),
|
||||||
|
|
||||||
ToolbarModuleExtension({
|
ToolbarModuleExtension({
|
||||||
id: BlockFlavourIdentifier('custom:affine:embed-linked-doc'),
|
id: BlockFlavourIdentifier('custom:affine:embed-linked-doc'),
|
||||||
config: embedLinkedDocToolbarConfig,
|
config: embedLinkedDocToolbarConfig,
|
||||||
|
|||||||
Reference in New Issue
Block a user