diff --git a/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-link-input-popup.ts b/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-link-input-popup.ts index 1287457b8b..356616d4ea 100644 --- a/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-link-input-popup.ts +++ b/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/components/embed-iframe-link-input-popup.ts @@ -102,7 +102,7 @@ export class EmbedIframeLinkInputPopup extends EmbedIframeLinkInputBase { outline: none; } .link-input::placeholder { - color: var(--affine-placeholder-color); + color: ${unsafeCSSVarV2('text/placeholder')}; } } diff --git a/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/configs/toolbar.ts b/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/configs/toolbar.ts index c5e078b944..162531230f 100644 --- a/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/configs/toolbar.ts +++ b/blocksuite/affine/blocks/block-embed/src/embed-iframe-block/configs/toolbar.ts @@ -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, + 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, + 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; diff --git a/packages/frontend/core/src/blocksuite/extensions/editor-config/toolbar/index.ts b/packages/frontend/core/src/blocksuite/extensions/editor-config/toolbar/index.ts index 7892395dc7..c11779ebcc 100644 --- a/packages/frontend/core/src/blocksuite/extensions/editor-config/toolbar/index.ts +++ b/packages/frontend/core/src/blocksuite/extensions/editor-config/toolbar/index.ts @@ -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', - }); - }, - }, ], }, ],