mirror of
https://github.com/toeverything/AFFiNE.git
synced 2025-01-05 14:24:38 +03:00
fix: can not copy from white board and paste in editor
This commit is contained in:
parent
8ccc997062
commit
3c8b04d91a
@ -5,7 +5,10 @@ import { getSession } from '@toeverything/components/board-sessions';
|
|||||||
import { deepCopy, TldrawApp } from '@toeverything/components/board-state';
|
import { deepCopy, TldrawApp } from '@toeverything/components/board-state';
|
||||||
import { tools } from '@toeverything/components/board-tools';
|
import { tools } from '@toeverything/components/board-tools';
|
||||||
import { TDShapeType } from '@toeverything/components/board-types';
|
import { TDShapeType } from '@toeverything/components/board-types';
|
||||||
import { RecastBlockProvider } from '@toeverything/components/editor-core';
|
import {
|
||||||
|
RecastBlockProvider,
|
||||||
|
getClipDataOfBlocksById,
|
||||||
|
} from '@toeverything/components/editor-core';
|
||||||
import { services } from '@toeverything/datasource/db-service';
|
import { services } from '@toeverything/datasource/db-service';
|
||||||
import { AsyncBlock, BlockEditor } from '@toeverything/framework/virgo';
|
import { AsyncBlock, BlockEditor } from '@toeverything/framework/virgo';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
@ -16,7 +19,11 @@ interface AffineBoardProps {
|
|||||||
rootBlockId: string;
|
rootBlockId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AffineBoard = ({ workspace, rootBlockId }: AffineBoardProps) => {
|
const AffineBoard = ({
|
||||||
|
workspace,
|
||||||
|
rootBlockId,
|
||||||
|
editor,
|
||||||
|
}: AffineBoardProps & { editor: BlockEditor }) => {
|
||||||
const [app, set_app] = useState<TldrawApp>();
|
const [app, set_app] = useState<TldrawApp>();
|
||||||
|
|
||||||
const [document] = useState(() => {
|
const [document] = useState(() => {
|
||||||
@ -62,6 +69,14 @@ const AffineBoard = ({ workspace, rootBlockId }: AffineBoardProps) => {
|
|||||||
onMount(app) {
|
onMount(app) {
|
||||||
set_app(app);
|
set_app(app);
|
||||||
},
|
},
|
||||||
|
async onCopy(e, groupIds) {
|
||||||
|
const [mimeType, data] = await getClipDataOfBlocksById(
|
||||||
|
editor,
|
||||||
|
groupIds
|
||||||
|
);
|
||||||
|
|
||||||
|
e.clipboardData?.setData(mimeType, data);
|
||||||
|
},
|
||||||
onChangePage(app, shapes, bindings, assets) {
|
onChangePage(app, shapes, bindings, assets) {
|
||||||
Promise.all(
|
Promise.all(
|
||||||
Object.entries(shapes).map(async ([id, shape]) => {
|
Object.entries(shapes).map(async ([id, shape]) => {
|
||||||
@ -130,7 +145,11 @@ export const AffineBoardWitchContext = ({
|
|||||||
}, [editor, rootBlockId]);
|
}, [editor, rootBlockId]);
|
||||||
return page ? (
|
return page ? (
|
||||||
<RecastBlockProvider block={page}>
|
<RecastBlockProvider block={page}>
|
||||||
<AffineBoard workspace={workspace} rootBlockId={rootBlockId} />
|
<AffineBoard
|
||||||
|
workspace={workspace}
|
||||||
|
rootBlockId={rootBlockId}
|
||||||
|
editor={editor}
|
||||||
|
/>
|
||||||
</RecastBlockProvider>
|
</RecastBlockProvider>
|
||||||
) : null;
|
) : null;
|
||||||
};
|
};
|
||||||
|
@ -171,6 +171,10 @@ interface TDCallbacks {
|
|||||||
* (optional) A callback to run when the user exports their page or selection.
|
* (optional) A callback to run when the user exports their page or selection.
|
||||||
*/
|
*/
|
||||||
onExport?: (app: TldrawApp, info: TDExport) => Promise<void>;
|
onExport?: (app: TldrawApp, info: TDExport) => Promise<void>;
|
||||||
|
/**
|
||||||
|
* (optional) A callback to run when the shape is copied.
|
||||||
|
*/
|
||||||
|
onCopy?: (e: ClipboardEvent, ids: string[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TldrawAppCtorProps {
|
export interface TldrawAppCtorProps {
|
||||||
@ -1898,12 +1902,14 @@ export class TldrawApp extends StateManager<TDSnapshot> {
|
|||||||
/**
|
/**
|
||||||
* Copy one or more shapes to the clipboard.
|
* Copy one or more shapes to the clipboard.
|
||||||
* @param ids The ids of the shapes to copy.
|
* @param ids The ids of the shapes to copy.
|
||||||
|
* @param pageId
|
||||||
|
* @param e
|
||||||
*/
|
*/
|
||||||
copy = (
|
copy = async (
|
||||||
ids = this.selectedIds,
|
ids = this.selectedIds,
|
||||||
pageId = this.currentPageId,
|
pageId = this.currentPageId,
|
||||||
e?: ClipboardEvent
|
e?: ClipboardEvent
|
||||||
): this => {
|
) => {
|
||||||
e?.preventDefault();
|
e?.preventDefault();
|
||||||
|
|
||||||
this.clipboard = this.get_clipboard(ids, pageId);
|
this.clipboard = this.get_clipboard(ids, pageId);
|
||||||
@ -1919,17 +1925,24 @@ export class TldrawApp extends StateManager<TDSnapshot> {
|
|||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
e.clipboardData?.setData('text/html', tldrawString);
|
e.clipboardData?.setData('text/html', tldrawString);
|
||||||
|
await this.callbacks.onCopy?.(e, this.selectedIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (navigator.clipboard && window.ClipboardItem) {
|
/**
|
||||||
navigator.clipboard.write([
|
* Reasons for not using Clipboard API for now:
|
||||||
new ClipboardItem({
|
* 1. The `clipboardData.setData` method temporarily satisfies the need for replication functionality
|
||||||
'text/html': new Blob([tldrawString], {
|
* 2. Clipboard API requires the user to agree to access(https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API)
|
||||||
type: 'text/html',
|
*
|
||||||
}),
|
* **/
|
||||||
}),
|
// if (navigator.clipboard && window.ClipboardItem) {
|
||||||
]);
|
// navigator.clipboard.write([
|
||||||
}
|
// new ClipboardItem({
|
||||||
|
// 'text/html': new Blob([tldrawString], {
|
||||||
|
// type: 'text/html',
|
||||||
|
// }),
|
||||||
|
// }),
|
||||||
|
// ]);
|
||||||
|
// }
|
||||||
|
|
||||||
this.pasteInfo.offset = [0, 0];
|
this.pasteInfo.offset = [0, 0];
|
||||||
this.pasteInfo.center = [0, 0];
|
this.pasteInfo.center = [0, 0];
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { Editor } from '../editor';
|
import { Editor } from '../editor';
|
||||||
|
import { ClipBlockInfo, OFFICE_CLIPBOARD_MIMETYPE } from './types';
|
||||||
|
import { Clip } from './clip';
|
||||||
|
|
||||||
export const shouldHandlerContinue = (event: Event, editor: Editor) => {
|
export const shouldHandlerContinue = (event: Event, editor: Editor) => {
|
||||||
const filterNodes = ['INPUT', 'SELECT', 'TEXTAREA'];
|
const filterNodes = ['INPUT', 'SELECT', 'TEXTAREA'];
|
||||||
@ -12,3 +14,38 @@ export const shouldHandlerContinue = (event: Event, editor: Editor) => {
|
|||||||
|
|
||||||
return editor.selectionManager.currentSelectInfo.type !== 'None';
|
return editor.selectionManager.currentSelectInfo.type !== 'None';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getClipInfoOfBlockById = async (
|
||||||
|
editor: Editor,
|
||||||
|
blockId: string
|
||||||
|
) => {
|
||||||
|
const block = await editor.getBlockById(blockId);
|
||||||
|
const blockView = editor.getView(block.type);
|
||||||
|
const blockInfo: ClipBlockInfo = {
|
||||||
|
type: block.type,
|
||||||
|
properties: blockView.getSelProperties(block, {}),
|
||||||
|
children: [] as ClipBlockInfo[],
|
||||||
|
};
|
||||||
|
const children = await block?.children();
|
||||||
|
|
||||||
|
for (let i = 0; i < children.length; i++) {
|
||||||
|
const childInfo = await getClipInfoOfBlockById(editor, children[i].id);
|
||||||
|
blockInfo.children.push(childInfo);
|
||||||
|
}
|
||||||
|
return blockInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getClipDataOfBlocksById = async (
|
||||||
|
editor: Editor,
|
||||||
|
blockIds: string[]
|
||||||
|
) => {
|
||||||
|
const clipInfos = await Promise.all(
|
||||||
|
blockIds.map(blockId => getClipInfoOfBlockById(editor, blockId))
|
||||||
|
);
|
||||||
|
return [
|
||||||
|
OFFICE_CLIPBOARD_MIMETYPE.DOCS_DOCUMENT_SLICE_CLIP_WRAPPED,
|
||||||
|
JSON.stringify({
|
||||||
|
data: clipInfos,
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
};
|
||||||
|
@ -10,3 +10,4 @@ export { BlockDropPlacement, HookType, GroupDirection } from './types';
|
|||||||
export type { Plugin, PluginCreator, PluginHooks, Virgo } from './types';
|
export type { Plugin, PluginCreator, PluginHooks, Virgo } from './types';
|
||||||
export { BaseView, getTextHtml, getTextProperties } from './views/base-view';
|
export { BaseView, getTextHtml, getTextProperties } from './views/base-view';
|
||||||
export type { ChildrenView, CreateView } from './views/base-view';
|
export type { ChildrenView, CreateView } from './views/base-view';
|
||||||
|
export { getClipDataOfBlocksById } from './clipboard/utils';
|
||||||
|
Loading…
Reference in New Issue
Block a user