import { addAttachments } from '@blocksuite/affine-block-attachment'; import { insertLinkByQuickSearchCommand } from '@blocksuite/affine-block-bookmark'; import { addImages, LoadedImageIcon } from '@blocksuite/affine-block-image'; import { AttachmentIcon, LinkIcon } from '@blocksuite/affine-components/icons'; import { MAX_IMAGE_WIDTH } from '@blocksuite/affine-model'; import { TelemetryProvider } from '@blocksuite/affine-shared/services'; import type { NoteChildrenFlavour } from '@blocksuite/affine-shared/types'; import { getImageFilesFromLocal, openFileOrFiles, } from '@blocksuite/affine-shared/utils'; import { EdgelessToolbarToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar'; import type { GfxToolsFullOptionValue } from '@blocksuite/block-std/gfx'; import { effect } from '@preact/signals-core'; import { css, html, LitElement } from 'lit'; import { property, state } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; import type { NoteToolOption } from '../note-tool.js'; import { NOTE_MENU_ITEMS } from './note-menu-config.js'; export class EdgelessNoteMenu extends EdgelessToolbarToolMixin(LitElement) { static override styles = css` :host { position: absolute; display: flex; z-index: -1; } .menu-content { display: flex; align-items: center; justify-content: center; } .button-group-container { display: flex; justify-content: center; align-items: center; gap: 14px; fill: var(--affine-icon-color); } .button-group-container svg { width: 20px; height: 20px; } .divider { width: 1px; height: 24px; background: var(--affine-border-color); transform: scaleX(0.5); margin: 0 14px; } `; override type: GfxToolsFullOptionValue['type'] = 'affine:note'; private async _addImages() { this._imageLoading = true; const imageFiles = await getImageFilesFromLocal(); const ids = await addImages(this.edgeless.std, imageFiles, { maxWidth: MAX_IMAGE_WIDTH, }); this._imageLoading = false; // @ts-expect-error FIXME: resolve after gfx tool refactor this.gfx.tool.setTool('default'); this.gfx.selection.set({ elements: ids }); } private _onHandleLinkButtonClick() { const [_, { insertedLinkType }] = this.edgeless.service.std.command.exec( insertLinkByQuickSearchCommand ); insertedLinkType ?.then(type => { const flavour = type?.flavour; if (!flavour) return; this.edgeless.std .getOptional(TelemetryProvider) ?.track('CanvasElementAdded', { control: 'toolbar:general', page: 'whiteboard editor', module: 'toolbar', type: flavour.split(':')[1], }); }) .catch(console.error); } override disconnectedCallback() { super.disconnectedCallback(); } override firstUpdated() { this.disposables.add( effect(() => { const tool = this.gfx.tool.currentToolOption$.value; if (tool?.type !== 'affine:note') return; this.childFlavour = tool.childFlavour; this.childType = tool.childType; this.tip = tool.tip; }) ); } override render() { const { childType } = this; return html` `; } @state() private accessor _imageLoading = false; @property({ attribute: false }) accessor childFlavour!: NoteChildrenFlavour; @property({ attribute: false }) accessor childType!: string | null; @property({ attribute: false }) accessor onChange!: ( props: Partial<{ childFlavour: NoteToolOption['childFlavour']; childType: string | null; tip: string; }> ) => void; @property({ attribute: false }) accessor tip!: string; }