mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-18 02:26:21 +08:00
feat(editor): update embed iframe toolbar config (#11221)
part of [BS-2843](https://linear.app/affine-design/issue/BS-2843/iframe-embed-block-占位态)
This commit is contained in:
+1
-1
@@ -102,7 +102,7 @@ export class EmbedIframeLinkInputPopup extends EmbedIframeLinkInputBase {
|
||||
outline: none;
|
||||
}
|
||||
.link-input::placeholder {
|
||||
color: var(--affine-placeholder-color);
|
||||
color: ${unsafeCSSVarV2('text/placeholder')};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,30 +24,77 @@ import {
|
||||
CopyIcon,
|
||||
DeleteIcon,
|
||||
DuplicateIcon,
|
||||
LinkedPageIcon,
|
||||
OpenInNewIcon,
|
||||
ResetIcon,
|
||||
} from '@blocksuite/icons/lit';
|
||||
import { type ExtensionType, Slice, Text } from '@blocksuite/store';
|
||||
import {
|
||||
type ExtensionType,
|
||||
Slice,
|
||||
Text,
|
||||
toDraftModel,
|
||||
} from '@blocksuite/store';
|
||||
import { computed, signal } from '@preact/signals-core';
|
||||
import { html } from 'lit';
|
||||
import { keyed } from 'lit/directives/keyed.js';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import {
|
||||
convertSelectedBlocksToLinkedDoc,
|
||||
getTitleFromSelectedModels,
|
||||
notifyDocCreated,
|
||||
promptDocTitle,
|
||||
} from '../../common/render-linked-doc';
|
||||
import { EmbedIframeBlockComponent } from '../embed-iframe-block';
|
||||
|
||||
const trackBaseProps = {
|
||||
category: 'embed iframe block',
|
||||
};
|
||||
|
||||
const showWhenUrlExists = (ctx: ToolbarContext) => {
|
||||
const model = ctx.getCurrentModelByType(EmbedIframeBlockModel);
|
||||
if (!model) return false;
|
||||
|
||||
return !!model.props.url;
|
||||
};
|
||||
|
||||
const openLinkAction = (id: string): ToolbarAction => {
|
||||
return {
|
||||
id,
|
||||
when: showWhenUrlExists,
|
||||
tooltip: 'Original',
|
||||
icon: OpenInNewIcon(),
|
||||
run(ctx) {
|
||||
const component = ctx.getCurrentBlockByType(EmbedIframeBlockComponent);
|
||||
component?.open();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const captionAction = (id: string): ToolbarAction => {
|
||||
return {
|
||||
id,
|
||||
when: showWhenUrlExists,
|
||||
tooltip: 'Caption',
|
||||
icon: CaptionIcon(),
|
||||
run(ctx) {
|
||||
const component = ctx.getCurrentBlockByType(EmbedIframeBlockComponent);
|
||||
component?.captionEditor?.show();
|
||||
|
||||
ctx.track('OpenedCaptionEditor', {
|
||||
...trackBaseProps,
|
||||
control: 'add caption',
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const builtinToolbarConfig = {
|
||||
actions: [
|
||||
openLinkAction('a.open-link'),
|
||||
{
|
||||
id: 'b.conversions',
|
||||
when: (ctx: ToolbarContext) => {
|
||||
const model = ctx.getCurrentModelByType(EmbedIframeBlockModel);
|
||||
if (!model) return false;
|
||||
|
||||
return !!model.props.url;
|
||||
},
|
||||
id: 'c.conversions',
|
||||
when: showWhenUrlExists,
|
||||
actions: [
|
||||
{
|
||||
id: 'inline',
|
||||
@@ -155,24 +202,48 @@ export const builtinToolbarConfig = {
|
||||
)}`;
|
||||
},
|
||||
} satisfies ToolbarActionGroup<ToolbarAction>,
|
||||
captionAction('d.caption'),
|
||||
{
|
||||
id: 'c.caption',
|
||||
when: (ctx: ToolbarContext) => {
|
||||
const model = ctx.getCurrentModelByType(EmbedIframeBlockModel);
|
||||
if (!model) return false;
|
||||
|
||||
return !!model.props.url;
|
||||
},
|
||||
tooltip: 'Caption',
|
||||
icon: CaptionIcon(),
|
||||
id: 'e.convert-to-linked-doc',
|
||||
tooltip: 'Create Linked Doc',
|
||||
icon: LinkedPageIcon(),
|
||||
run(ctx) {
|
||||
const component = ctx.getCurrentBlockByType(EmbedIframeBlockComponent);
|
||||
component?.captionEditor?.show();
|
||||
const model = ctx.getCurrentModelByType(EmbedIframeBlockModel);
|
||||
if (!model) return;
|
||||
|
||||
ctx.track('OpenedCaptionEditor', {
|
||||
...trackBaseProps,
|
||||
control: 'add caption',
|
||||
});
|
||||
const { store, std, selection, track } = ctx;
|
||||
selection.clear();
|
||||
|
||||
const draftedModels = [model].map(toDraftModel);
|
||||
const autofill = getTitleFromSelectedModels(draftedModels);
|
||||
promptDocTitle(std, autofill)
|
||||
.then(async title => {
|
||||
if (title === null) return;
|
||||
await convertSelectedBlocksToLinkedDoc(
|
||||
std,
|
||||
store,
|
||||
draftedModels,
|
||||
title
|
||||
);
|
||||
notifyDocCreated(std, store);
|
||||
|
||||
track('DocCreated', {
|
||||
segment: 'doc',
|
||||
page: 'doc editor',
|
||||
module: 'toolbar',
|
||||
control: 'create linked doc',
|
||||
type: 'embed-linked-doc',
|
||||
});
|
||||
|
||||
track('LinkedDocCreated', {
|
||||
segment: 'doc',
|
||||
page: 'doc editor',
|
||||
module: 'toolbar',
|
||||
control: 'create linked doc',
|
||||
type: 'embed-linked-doc',
|
||||
});
|
||||
})
|
||||
.catch(console.error);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -243,14 +314,10 @@ export const builtinToolbarConfig = {
|
||||
|
||||
export const builtinSurfaceToolbarConfig = {
|
||||
actions: [
|
||||
openLinkAction('a.open-link'),
|
||||
{
|
||||
id: 'b.conversions',
|
||||
when: (ctx: ToolbarContext) => {
|
||||
const model = ctx.getCurrentModelByType(EmbedIframeBlockModel);
|
||||
if (!model) return false;
|
||||
|
||||
return !!model.props.url;
|
||||
},
|
||||
id: 'c.conversions',
|
||||
when: showWhenUrlExists,
|
||||
actions: [
|
||||
{
|
||||
id: 'card',
|
||||
@@ -324,28 +391,9 @@ export const builtinSurfaceToolbarConfig = {
|
||||
)}`;
|
||||
},
|
||||
} satisfies ToolbarActionGroup<ToolbarAction>,
|
||||
captionAction('d.caption'),
|
||||
{
|
||||
id: 'c.caption',
|
||||
when: (ctx: ToolbarContext) => {
|
||||
const model = ctx.getCurrentModelByType(EmbedIframeBlockModel);
|
||||
if (!model) return false;
|
||||
|
||||
return !!model.props.url;
|
||||
},
|
||||
tooltip: 'Caption',
|
||||
icon: CaptionIcon(),
|
||||
run(ctx) {
|
||||
const component = ctx.getCurrentBlockByType(EmbedIframeBlockComponent);
|
||||
component?.captionEditor?.show();
|
||||
|
||||
ctx.track('OpenedCaptionEditor', {
|
||||
...trackBaseProps,
|
||||
control: 'add caption',
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'd.scale',
|
||||
id: 'e.scale',
|
||||
content(ctx) {
|
||||
const model = ctx.getCurrentModelByType(EmbedIframeBlockModel);
|
||||
if (!model) return null;
|
||||
|
||||
@@ -877,11 +877,11 @@ const embedIframeToolbarConfig = {
|
||||
},
|
||||
actions: [
|
||||
{
|
||||
id: 'a.copy-link-and-edit',
|
||||
id: 'b.copy-link',
|
||||
actions: [
|
||||
{
|
||||
id: 'copy-link',
|
||||
tooltip: 'Copy link',
|
||||
tooltip: 'Copy original link',
|
||||
icon: CopyIcon(),
|
||||
run(ctx) {
|
||||
const model = ctx.getCurrentBlockByType(
|
||||
@@ -895,52 +895,14 @@ const embedIframeToolbarConfig = {
|
||||
toast(ctx.host, 'Copied link to clipboard');
|
||||
|
||||
ctx.track('CopiedLink', {
|
||||
category: matchModels(model, [BookmarkBlockModel])
|
||||
? 'bookmark'
|
||||
category: matchModels(model, [EmbedIframeBlockModel])
|
||||
? 'embed iframe block'
|
||||
: 'link',
|
||||
type: 'card view',
|
||||
control: 'copy link',
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'edit',
|
||||
tooltip: 'Edit',
|
||||
icon: EditIcon(),
|
||||
run(ctx) {
|
||||
const component = ctx.getCurrentBlockByType(
|
||||
EmbedIframeBlockComponent
|
||||
);
|
||||
if (!component) return;
|
||||
|
||||
ctx.hide();
|
||||
|
||||
const model = component.model;
|
||||
const abortController = new AbortController();
|
||||
abortController.signal.onabort = () => ctx.show();
|
||||
|
||||
toggleEmbedCardEditModal(
|
||||
ctx.host,
|
||||
model,
|
||||
'card',
|
||||
undefined,
|
||||
undefined,
|
||||
(_std, _component, props) => {
|
||||
ctx.store.updateBlock(model, props);
|
||||
component.requestUpdate();
|
||||
},
|
||||
abortController
|
||||
);
|
||||
|
||||
ctx.track('OpenedAliasPopup', {
|
||||
category: matchModels(model, [BookmarkBlockModel])
|
||||
? 'bookmark'
|
||||
: 'link',
|
||||
type: 'card view',
|
||||
control: 'edit',
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user