mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-24 05:48:59 +08:00
init: the first public commit for AFFiNE
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Tldraw } from '@toeverything/components/board-draw';
|
||||
import { tools } from '@toeverything/components/board-tools';
|
||||
import { getSession } from '@toeverything/components/board-sessions';
|
||||
import * as commands from '@toeverything/components/board-commands';
|
||||
import { TldrawApp, deepCopy } from '@toeverything/components/board-state';
|
||||
import { TDShapeType } from '@toeverything/components/board-types';
|
||||
import { services } from '@toeverything/datasource/db-service';
|
||||
import { useShapes } from './hooks';
|
||||
import { RecastBlockProvider } from '@toeverything/components/editor-core';
|
||||
import { createEditor } from '@toeverything/components/affine-editor';
|
||||
import { AsyncBlock, BlockEditor } from '@toeverything/framework/virgo';
|
||||
|
||||
interface AffineBoardProps {
|
||||
workspace: string;
|
||||
rootBlockId: string;
|
||||
}
|
||||
|
||||
const AffineBoard = ({ workspace, rootBlockId }: AffineBoardProps) => {
|
||||
const [app, set_app] = useState<TldrawApp>();
|
||||
|
||||
const [document] = useState(() => {
|
||||
return {
|
||||
...deepCopy(TldrawApp.default_document),
|
||||
id: workspace,
|
||||
pages: {
|
||||
[rootBlockId]: {
|
||||
id: rootBlockId,
|
||||
name: `Page ${rootBlockId}`,
|
||||
childIndex: 1,
|
||||
shapes: {},
|
||||
bindings: {},
|
||||
},
|
||||
},
|
||||
pageStates: {
|
||||
[rootBlockId]: {
|
||||
id: rootBlockId,
|
||||
camera: {
|
||||
point: [0, 0],
|
||||
zoom: 1,
|
||||
},
|
||||
selectedIds: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const shapes = useShapes(workspace, rootBlockId);
|
||||
useEffect(() => {
|
||||
if (app) {
|
||||
app.replacePageContent(shapes || {}, {}, {});
|
||||
}
|
||||
}, [app, shapes]);
|
||||
|
||||
return (
|
||||
<Tldraw
|
||||
document={document}
|
||||
commands={commands}
|
||||
tools={tools}
|
||||
getSession={getSession}
|
||||
callbacks={{
|
||||
onMount(app) {
|
||||
set_app(app);
|
||||
},
|
||||
onChangePage(app, shapes, bindings, assets) {
|
||||
Promise.all(
|
||||
Object.entries(shapes).map(async ([id, shape]) => {
|
||||
if (shape === undefined) {
|
||||
return services.api.editorBlock.delete({
|
||||
workspace: workspace,
|
||||
id,
|
||||
});
|
||||
} else {
|
||||
let block = (
|
||||
await services.api.editorBlock.get({
|
||||
workspace: workspace,
|
||||
ids: [shape.affineId],
|
||||
})
|
||||
)?.[0];
|
||||
if (!block) {
|
||||
block =
|
||||
await services.api.editorBlock.create({
|
||||
workspace: workspace,
|
||||
parentId:
|
||||
app.appState.currentPageId,
|
||||
type:
|
||||
shape.type ===
|
||||
TDShapeType.Editor
|
||||
? 'group'
|
||||
: 'shape',
|
||||
});
|
||||
}
|
||||
shape.affineId = block.id;
|
||||
return services.api.editorBlock.update({
|
||||
workspace: shape.workspace,
|
||||
id: block.id,
|
||||
properties: {
|
||||
shapeProps: {
|
||||
value: JSON.stringify(shape),
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const AffineBoardWitchContext = ({
|
||||
workspace,
|
||||
rootBlockId,
|
||||
}: AffineBoardProps) => {
|
||||
const [editor, set_editor] = useState<BlockEditor>();
|
||||
useEffect(() => {
|
||||
const inner_editor = createEditor(workspace, true);
|
||||
set_editor(inner_editor);
|
||||
return () => {
|
||||
inner_editor.dispose();
|
||||
};
|
||||
}, [workspace]);
|
||||
|
||||
const [page, set_page] = useState<AsyncBlock>();
|
||||
useEffect(() => {
|
||||
editor?.getBlockById(rootBlockId).then(block => {
|
||||
set_page(block);
|
||||
});
|
||||
}, [editor, rootBlockId]);
|
||||
return page ? (
|
||||
<RecastBlockProvider block={page}>
|
||||
<AffineBoard workspace={workspace} rootBlockId={rootBlockId} />
|
||||
</RecastBlockProvider>
|
||||
) : null;
|
||||
};
|
||||
Reference in New Issue
Block a user