mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-27 02:42:25 +08:00
feat(editor): add edgeless media entry (#9949)
This commit is contained in:
@@ -264,7 +264,8 @@ export async function addSiblingAttachmentBlocks(
|
|||||||
export async function addAttachments(
|
export async function addAttachments(
|
||||||
std: BlockStdScope,
|
std: BlockStdScope,
|
||||||
files: File[],
|
files: File[],
|
||||||
point?: IVec
|
point?: IVec,
|
||||||
|
transformPoint?: boolean // determines whether we should use `toModelCoord` to convert the point
|
||||||
): Promise<string[]> {
|
): Promise<string[]> {
|
||||||
if (!files.length) return [];
|
if (!files.length) return [];
|
||||||
|
|
||||||
@@ -284,7 +285,14 @@ export async function addAttachments(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let { x, y } = gfx.viewport.center;
|
let { x, y } = gfx.viewport.center;
|
||||||
if (point) [x, y] = gfx.viewport.toModelCoord(...point);
|
if (point) {
|
||||||
|
let transform = transformPoint ?? true;
|
||||||
|
if (transform) {
|
||||||
|
[x, y] = gfx.viewport.toModelCoord(...point);
|
||||||
|
} else {
|
||||||
|
[x, y] = point;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const CARD_STACK_GAP = 32;
|
const CARD_STACK_GAP = 32;
|
||||||
|
|
||||||
|
|||||||
@@ -428,6 +428,7 @@ export async function addImages(
|
|||||||
options: {
|
options: {
|
||||||
point?: IVec;
|
point?: IVec;
|
||||||
maxWidth?: number;
|
maxWidth?: number;
|
||||||
|
transformPoint?: boolean; // determines whether we should use `toModelCoord` to convert the point
|
||||||
}
|
}
|
||||||
): Promise<string[]> {
|
): Promise<string[]> {
|
||||||
const imageFiles = [...files].filter(file => file.type.startsWith('image/'));
|
const imageFiles = [...files].filter(file => file.type.startsWith('image/'));
|
||||||
@@ -449,9 +450,15 @@ export async function addImages(
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const { point, maxWidth } = options;
|
const { point, maxWidth, transformPoint = true } = options;
|
||||||
let { x, y } = gfx.viewport.center;
|
let { x, y } = gfx.viewport.center;
|
||||||
if (point) [x, y] = gfx.viewport.toModelCoord(...point);
|
if (point) {
|
||||||
|
if (transformPoint) {
|
||||||
|
[x, y] = gfx.viewport.toModelCoord(...point);
|
||||||
|
} else {
|
||||||
|
[x, y] = point;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const dropInfos: { point: Point; blockId: string }[] = [];
|
const dropInfos: { point: Point; blockId: string }[] = [];
|
||||||
const IMAGE_STACK_GAP = 32;
|
const IMAGE_STACK_GAP = 32;
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
|
import { addAttachments } from '@blocksuite/affine-block-attachment';
|
||||||
import { insertEdgelessTextCommand } from '@blocksuite/affine-block-edgeless-text';
|
import { insertEdgelessTextCommand } from '@blocksuite/affine-block-edgeless-text';
|
||||||
|
import { addImages } from '@blocksuite/affine-block-image';
|
||||||
import { CanvasElementType } from '@blocksuite/affine-block-surface';
|
import { CanvasElementType } from '@blocksuite/affine-block-surface';
|
||||||
import { type MindmapStyle, TextElementModel } from '@blocksuite/affine-model';
|
import {
|
||||||
|
MAX_IMAGE_WIDTH,
|
||||||
|
type MindmapStyle,
|
||||||
|
TextElementModel,
|
||||||
|
} from '@blocksuite/affine-model';
|
||||||
import {
|
import {
|
||||||
FeatureFlagService,
|
FeatureFlagService,
|
||||||
TelemetryProvider,
|
TelemetryProvider,
|
||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
|
import { openFileOrFiles } from '@blocksuite/affine-shared/utils';
|
||||||
import { assertInstanceOf, Bound } from '@blocksuite/global/utils';
|
import { assertInstanceOf, Bound } from '@blocksuite/global/utils';
|
||||||
import type { TemplateResult } from 'lit';
|
import type { TemplateResult } from 'lit';
|
||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
@@ -19,7 +26,7 @@ export type ConfigStyle = Partial<Record<ConfigProperty, number | string>>;
|
|||||||
export type ToolConfig = Record<ConfigState, ConfigStyle>;
|
export type ToolConfig = Record<ConfigState, ConfigStyle>;
|
||||||
|
|
||||||
export type DraggableTool = {
|
export type DraggableTool = {
|
||||||
name: 'text' | 'mindmap';
|
name: 'text' | 'mindmap' | 'media';
|
||||||
icon: TemplateResult;
|
icon: TemplateResult;
|
||||||
config: ToolConfig;
|
config: ToolConfig;
|
||||||
standardWidth?: number;
|
standardWidth?: number;
|
||||||
@@ -27,7 +34,7 @@ export type DraggableTool = {
|
|||||||
bound: Bound,
|
bound: Bound,
|
||||||
edgelessService: EdgelessRootService,
|
edgelessService: EdgelessRootService,
|
||||||
edgeless: EdgelessRootBlockComponent
|
edgeless: EdgelessRootBlockComponent
|
||||||
) => string;
|
) => Promise<string | null>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const unitMap = { x: 'px', y: 'px', r: 'deg', s: '', z: '', o: '' };
|
const unitMap = { x: 'px', y: 'px', r: 'deg', s: '', z: '', o: '' };
|
||||||
@@ -38,15 +45,21 @@ export const textConfig: ToolConfig = {
|
|||||||
next: { x: -22, y: 64, r: 0 },
|
next: { x: -22, y: 64, r: 0 },
|
||||||
};
|
};
|
||||||
export const mindmapConfig: ToolConfig = {
|
export const mindmapConfig: ToolConfig = {
|
||||||
default: { x: 4, y: -4, s: 1, z: 1, r: -7 },
|
default: { x: 4, y: -4, s: 1, z: 2, r: -7 },
|
||||||
active: { x: 11, y: -14, r: 9, s: 1 },
|
active: { x: 11, y: -14, r: 9, s: 1 },
|
||||||
hover: { x: 11, y: -14, r: 9, s: 1.16, z: 3 },
|
hover: { x: 11, y: -14, r: 9, s: 1.16, z: 3 },
|
||||||
next: { y: 64, r: 0 },
|
next: { y: 64, r: 0 },
|
||||||
};
|
};
|
||||||
|
export const mediaConfig: ToolConfig = {
|
||||||
|
default: { x: -20, y: -8, r: -1, s: 0.92, z: 1 },
|
||||||
|
active: { x: -20, y: -14, r: -9, s: 1 },
|
||||||
|
hover: { x: -20, y: -14, r: -9, s: 1.16, z: 2 },
|
||||||
|
next: { y: 64, r: 0 },
|
||||||
|
};
|
||||||
|
|
||||||
export const getMindmapRender =
|
export const getMindmapRender =
|
||||||
(mindmapStyle: MindmapStyle): DraggableTool['render'] =>
|
(mindmapStyle: MindmapStyle): DraggableTool['render'] =>
|
||||||
(bound, edgelessService) => {
|
async (bound, edgelessService) => {
|
||||||
const [x, y, _, h] = bound.toXYWH();
|
const [x, y, _, h] = bound.toXYWH();
|
||||||
|
|
||||||
const rootW = 145;
|
const rootW = 145;
|
||||||
@@ -98,7 +111,8 @@ export const getMindmapRender =
|
|||||||
|
|
||||||
return mindmapId;
|
return mindmapId;
|
||||||
};
|
};
|
||||||
export const textRender: DraggableTool['render'] = (
|
|
||||||
|
export const textRender: DraggableTool['render'] = async (
|
||||||
bound,
|
bound,
|
||||||
service,
|
service,
|
||||||
edgeless
|
edgeless
|
||||||
@@ -143,6 +157,41 @@ export const textRender: DraggableTool['render'] = (
|
|||||||
return id;
|
return id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const mediaRender: DraggableTool['render'] = async (
|
||||||
|
bound,
|
||||||
|
_,
|
||||||
|
edgeless
|
||||||
|
) => {
|
||||||
|
let file: File | null = null;
|
||||||
|
try {
|
||||||
|
file = await openFileOrFiles();
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!file) return null;
|
||||||
|
|
||||||
|
// image
|
||||||
|
if (file.type.startsWith('image/')) {
|
||||||
|
const [id] = await addImages(edgeless.std, [file], {
|
||||||
|
point: [bound.x, bound.y],
|
||||||
|
maxWidth: MAX_IMAGE_WIDTH,
|
||||||
|
transformPoint: false,
|
||||||
|
});
|
||||||
|
if (id) return id;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// attachment
|
||||||
|
const [id] = await addAttachments(
|
||||||
|
edgeless.std,
|
||||||
|
[file],
|
||||||
|
[bound.x, bound.y],
|
||||||
|
false
|
||||||
|
);
|
||||||
|
return id;
|
||||||
|
};
|
||||||
|
|
||||||
const toolStyle2StyleObj = (state: ConfigState, style: ConfigStyle = {}) => {
|
const toolStyle2StyleObj = (state: ConfigState, style: ConfigStyle = {}) => {
|
||||||
const styleObj = {} as Record<string, string>;
|
const styleObj = {} as Record<string, string>;
|
||||||
for (const [key, value] of Object.entries(style)) {
|
for (const [key, value] of Object.entries(style)) {
|
||||||
|
|||||||
@@ -574,3 +574,25 @@ export const importMindMapIcon = svg`<svg width="64" height="48" viewBox="0 0 64
|
|||||||
<rect x="5.5" y="17.9183" width="17.3771" height="12.1639" rx="3" fill="black" fill-opacity="0.03" stroke="#929292" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="2 3"/>
|
<rect x="5.5" y="17.9183" width="17.3771" height="12.1639" rx="3" fill="black" fill-opacity="0.03" stroke="#929292" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="2 3"/>
|
||||||
</svg>
|
</svg>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const mindmapMenuMediaIcon = svg`<svg width="56" height="49" viewBox="0 0 56 49" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g filter="url(#filter0_d_215_65373)">
|
||||||
|
<path d="M4.51611 7.83333C4.51611 5.99238 6.01812 4.5 7.87095 4.5H48.129C49.9818 4.5 51.4838 5.99239 51.4838 7.83334V41.1667C51.4838 43.0076 49.9818 44.5 48.129 44.5H7.87095C6.01813 44.5 4.51611 43.0076 4.51611 41.1667V7.83333Z" fill="#F4F9FF"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.87096 2H48.129C51.3714 2 53.9999 4.61167 53.9999 7.83333V41.1667C53.9999 44.3883 51.3714 47 48.129 47H7.87096C4.62852 47 2 44.3883 2 41.1667V7.83333C2 4.61167 4.62852 2 7.87096 2ZM7.87096 4.5C6.01814 4.5 4.51613 5.99238 4.51613 7.83333V41.1667C4.51613 43.0076 6.01814 44.5 7.87096 44.5H48.129C49.9818 44.5 51.4838 43.0076 51.4838 41.1667V7.83333C51.4838 5.99238 49.9818 4.5 48.129 4.5H7.87096Z" fill="#3883FF"/>
|
||||||
|
<path d="M7.87095 44.5001H48.129C49.9818 44.5001 51.4838 43.0077 51.4838 41.1667V39.7435L35.8959 17.6424C33.3356 14.0123 28.3633 13.009 24.5807 15.3591L4.51611 27.8252V41.1667C4.51611 43.0077 6.01813 44.5001 7.87095 44.5001Z" fill="#3883FF"/>
|
||||||
|
<ellipse cx="5.03225" cy="5" rx="5.03225" ry="5" transform="matrix(-1 -8.76786e-08 -8.88135e-08 1 47.9972 7.41357)" fill="#3883FF"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d_215_65373" x="0" y="0" width="56" height="49" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset/>
|
||||||
|
<feGaussianBlur stdDeviation="1"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_215_65373"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_215_65373" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
`;
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import { getTooltipWithShortcut } from '../../utils.js';
|
|||||||
import { EdgelessDraggableElementController } from '../common/draggable/draggable-element.controller.js';
|
import { EdgelessDraggableElementController } from '../common/draggable/draggable-element.controller.js';
|
||||||
import { EdgelessToolbarToolMixin } from '../mixins/tool.mixin.js';
|
import { EdgelessToolbarToolMixin } from '../mixins/tool.mixin.js';
|
||||||
import { getMindMaps, type ToolbarMindmapItem } from './assets.js';
|
import { getMindMaps, type ToolbarMindmapItem } from './assets.js';
|
||||||
import { textRender } from './basket-elements.js';
|
import { mediaRender, textRender } from './basket-elements.js';
|
||||||
import { importMindMapIcon, textIcon } from './icons.js';
|
import { importMindMapIcon, mindmapMenuMediaIcon, textIcon } from './icons.js';
|
||||||
import { MindMapPlaceholder } from './mindmap-importing-placeholder.js';
|
import { MindMapPlaceholder } from './mindmap-importing-placeholder.js';
|
||||||
|
|
||||||
type TextItem = {
|
type TextItem = {
|
||||||
@@ -32,6 +32,12 @@ type TextItem = {
|
|||||||
render: typeof textRender;
|
render: typeof textRender;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type MediaItem = {
|
||||||
|
type: 'media';
|
||||||
|
icon: TemplateResult;
|
||||||
|
render: typeof mediaRender;
|
||||||
|
};
|
||||||
|
|
||||||
type ImportItem = {
|
type ImportItem = {
|
||||||
type: 'import';
|
type: 'import';
|
||||||
icon: TemplateResult;
|
icon: TemplateResult;
|
||||||
@@ -39,6 +45,12 @@ type ImportItem = {
|
|||||||
|
|
||||||
const textItem: TextItem = { type: 'text', icon: textIcon, render: textRender };
|
const textItem: TextItem = { type: 'text', icon: textIcon, render: textRender };
|
||||||
|
|
||||||
|
const mediaItem: MediaItem = {
|
||||||
|
type: 'media',
|
||||||
|
icon: mindmapMenuMediaIcon,
|
||||||
|
render: mediaRender,
|
||||||
|
};
|
||||||
|
|
||||||
export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
||||||
SignalWatcher(LitElement)
|
SignalWatcher(LitElement)
|
||||||
) {
|
) {
|
||||||
@@ -60,7 +72,8 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
|||||||
height: 48px;
|
height: 48px;
|
||||||
background: var(--affine-border-color);
|
background: var(--affine-border-color);
|
||||||
}
|
}
|
||||||
.text-item {
|
.text-item,
|
||||||
|
.media-item {
|
||||||
width: 60px;
|
width: 60px;
|
||||||
}
|
}
|
||||||
.mindmap-item {
|
.mindmap-item {
|
||||||
@@ -68,6 +81,7 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.text-item,
|
.text-item,
|
||||||
|
.media-item,
|
||||||
.mindmap-item {
|
.mindmap-item {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
@@ -77,6 +91,7 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.text-item > button,
|
.text-item > button,
|
||||||
|
.media-item > button,
|
||||||
.mindmap-item > button {
|
.mindmap-item > button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
@@ -86,11 +101,13 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
.text-item:hover,
|
.text-item:hover,
|
||||||
|
.media-item:hover,
|
||||||
.mindmap-item[data-is-active='true'],
|
.mindmap-item[data-is-active='true'],
|
||||||
.mindmap-item:hover {
|
.mindmap-item:hover {
|
||||||
background: var(--affine-hover-color);
|
background: var(--affine-hover-color);
|
||||||
}
|
}
|
||||||
.text-item > button.next,
|
.text-item > button.next,
|
||||||
|
.media-item > button.next,
|
||||||
.mindmap-item > button.next {
|
.mindmap-item > button.next {
|
||||||
transition: transform 0.3s ease-in-out;
|
transition: transform 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
@@ -103,7 +120,7 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
|||||||
});
|
});
|
||||||
|
|
||||||
draggableController!: EdgelessDraggableElementController<
|
draggableController!: EdgelessDraggableElementController<
|
||||||
ToolbarMindmapItem | TextItem | ImportItem
|
ToolbarMindmapItem | TextItem | ImportItem | MediaItem
|
||||||
>;
|
>;
|
||||||
|
|
||||||
override type = 'empty' as const;
|
override type = 'empty' as const;
|
||||||
@@ -215,21 +232,26 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
|||||||
},
|
},
|
||||||
onDrop: (element, bound) => {
|
onDrop: (element, bound) => {
|
||||||
if ('render' in element.data) {
|
if ('render' in element.data) {
|
||||||
const id = element.data.render(
|
element.data
|
||||||
bound,
|
.render(bound, this.edgeless.service, this.edgeless)
|
||||||
this.edgeless.service,
|
.then(id => {
|
||||||
this.edgeless
|
if (!id) return;
|
||||||
);
|
if (element.data.type === 'mindmap') {
|
||||||
if (element.data.type === 'mindmap') {
|
this.onActiveStyleChange?.(element.data.style);
|
||||||
this.onActiveStyleChange?.(element.data.style);
|
this.setEdgelessTool({ type: 'default' });
|
||||||
this.setEdgelessTool({ type: 'default' });
|
this.edgeless.gfx.selection.set({
|
||||||
this.edgeless.gfx.selection.set({ elements: [id], editing: false });
|
elements: [id],
|
||||||
} else if (element.data.type === 'text') {
|
editing: false,
|
||||||
this.setEdgelessTool({ type: 'default' });
|
});
|
||||||
}
|
} else if (
|
||||||
}
|
element.data.type === 'text' ||
|
||||||
|
element.data.type === 'media'
|
||||||
if (element.data.type === 'import') {
|
) {
|
||||||
|
this.setEdgelessTool({ type: 'default' });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(console.error);
|
||||||
|
} else if (element.data.type === 'import') {
|
||||||
this._onImportMindMap?.(bound);
|
this._onImportMindMap?.(bound);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -240,10 +262,40 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
|||||||
const { cancelled, draggingElement, dragOut } =
|
const { cancelled, draggingElement, dragOut } =
|
||||||
this.draggableController?.states || {};
|
this.draggableController?.states || {};
|
||||||
|
|
||||||
|
const isDraggingMedia = draggingElement?.data?.type === 'media';
|
||||||
const isDraggingText = draggingElement?.data?.type === 'text';
|
const isDraggingText = draggingElement?.data?.type === 'text';
|
||||||
const showNextText = dragOut && !cancelled;
|
const showNextText = dragOut && !cancelled;
|
||||||
return html`<edgeless-slide-menu .height=${'64px'}>
|
return html`<edgeless-slide-menu .height=${'64px'}>
|
||||||
<div class="text-and-mindmap">
|
<div class="text-and-mindmap">
|
||||||
|
<div class="media-item">
|
||||||
|
${isDraggingMedia
|
||||||
|
? html`<button
|
||||||
|
class="next"
|
||||||
|
style="transform: translateY(${showNextText ? 0 : 64}px)"
|
||||||
|
>
|
||||||
|
${mediaItem.icon}
|
||||||
|
</button>`
|
||||||
|
: nothing}
|
||||||
|
<button
|
||||||
|
style="opacity: ${isDraggingMedia ? 0 : 1}"
|
||||||
|
@mousedown=${(e: MouseEvent) =>
|
||||||
|
this.draggableController.onMouseDown(e, {
|
||||||
|
preview: mediaItem.icon,
|
||||||
|
data: mediaItem,
|
||||||
|
})}
|
||||||
|
@touchstart=${(e: TouchEvent) =>
|
||||||
|
this.draggableController.onTouchStart(e, {
|
||||||
|
preview: mediaItem.icon,
|
||||||
|
data: mediaItem,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
${mediaItem.icon}
|
||||||
|
</button>
|
||||||
|
<affine-tooltip tip-position="top" .offset=${12}>
|
||||||
|
${getTooltipWithShortcut('Add media')}
|
||||||
|
</affine-tooltip>
|
||||||
|
</div>
|
||||||
|
<div class="thin-divider"></div>
|
||||||
<div class="text-item">
|
<div class="text-item">
|
||||||
${isDraggingText
|
${isDraggingText
|
||||||
? html`<button
|
? html`<button
|
||||||
|
|||||||
@@ -23,12 +23,19 @@ import { getMindMaps } from './assets.js';
|
|||||||
import {
|
import {
|
||||||
type DraggableTool,
|
type DraggableTool,
|
||||||
getMindmapRender,
|
getMindmapRender,
|
||||||
|
mediaConfig,
|
||||||
|
mediaRender,
|
||||||
mindmapConfig,
|
mindmapConfig,
|
||||||
textConfig,
|
textConfig,
|
||||||
textRender,
|
textRender,
|
||||||
toolConfig2StyleObj,
|
toolConfig2StyleObj,
|
||||||
} from './basket-elements.js';
|
} from './basket-elements.js';
|
||||||
import { basketIconDark, basketIconLight, textIcon } from './icons.js';
|
import {
|
||||||
|
basketIconDark,
|
||||||
|
basketIconLight,
|
||||||
|
mindmapMenuMediaIcon,
|
||||||
|
textIcon,
|
||||||
|
} from './icons.js';
|
||||||
import { importMindmap } from './utils/import-mindmap.js';
|
import { importMindmap } from './utils/import-mindmap.js';
|
||||||
|
|
||||||
export class EdgelessMindmapToolButton extends EdgelessToolbarToolMixin(
|
export class EdgelessMindmapToolButton extends EdgelessToolbarToolMixin(
|
||||||
@@ -142,6 +149,13 @@ export class EdgelessMindmapToolButton extends EdgelessToolbarToolMixin(
|
|||||||
const mindmap =
|
const mindmap =
|
||||||
this.mindmaps.find(m => m.style === style) || this.mindmaps[0];
|
this.mindmaps.find(m => m.style === style) || this.mindmaps[0];
|
||||||
return [
|
return [
|
||||||
|
{
|
||||||
|
name: 'media',
|
||||||
|
icon: mindmapMenuMediaIcon,
|
||||||
|
config: mediaConfig,
|
||||||
|
standardWidth: 100,
|
||||||
|
render: mediaRender,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'text',
|
name: 'text',
|
||||||
icon: textIcon,
|
icon: textIcon,
|
||||||
@@ -244,14 +258,22 @@ export class EdgelessMindmapToolButton extends EdgelessToolbarToolMixin(
|
|||||||
this.readyToDrop = false;
|
this.readyToDrop = false;
|
||||||
},
|
},
|
||||||
onDrop: (el, bound) => {
|
onDrop: (el, bound) => {
|
||||||
const id = el.data.render(bound, this.edgeless.service, this.edgeless);
|
el.data
|
||||||
this.readyToDrop = false;
|
.render(bound, this.edgeless.service, this.edgeless)
|
||||||
if (el.data.name === 'mindmap') {
|
.then(id => {
|
||||||
this.setEdgelessTool({ type: 'default' });
|
if (!id) return;
|
||||||
this.edgeless.gfx.selection.set({ elements: [id], editing: false });
|
this.readyToDrop = false;
|
||||||
} else if (el.data.name === 'text') {
|
if (el.data.name === 'mindmap') {
|
||||||
this.setEdgelessTool({ type: 'default' });
|
this.setEdgelessTool({ type: 'default' });
|
||||||
}
|
this.edgeless.gfx.selection.set({
|
||||||
|
elements: [id],
|
||||||
|
editing: false,
|
||||||
|
});
|
||||||
|
} else if (el.data.name === 'text') {
|
||||||
|
this.setEdgelessTool({ type: 'default' });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(console.error);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user