|
@@ -4,12 +4,209 @@ import {
|
|
|
DocumentVersionPB,
|
|
|
OpenDocumentPayloadPB,
|
|
|
} from '../../services/backend/events/flowy-document';
|
|
|
-import { Block, BlockType } from '../interfaces';
|
|
|
+import { BlockInterface, BlockType } from '../interfaces';
|
|
|
import { useParams } from 'react-router-dom';
|
|
|
+import { getBlockEditor, createBlockEditor } from '../block_editor';
|
|
|
|
|
|
+const loadBlockData = async (id: string): Promise<Record<string, BlockInterface>> => {
|
|
|
+ return {
|
|
|
+ [id]: {
|
|
|
+ id: id,
|
|
|
+ type: BlockType.PageBlock,
|
|
|
+ data: { title: 'Document Title' },
|
|
|
+ next: null,
|
|
|
+ firstChild: "L1-1",
|
|
|
+ },
|
|
|
+ "L1-1": {
|
|
|
+ id: "L1-1",
|
|
|
+ type: BlockType.HeadingBlock,
|
|
|
+ data: { level: 1, content: [{ text: 'Heading 1' }] },
|
|
|
+ next: "L1-2",
|
|
|
+ firstChild: null,
|
|
|
+ },
|
|
|
+ "L1-2": {
|
|
|
+ id: "L1-2",
|
|
|
+ type: BlockType.HeadingBlock,
|
|
|
+ data: { level: 2, content: [{ text: 'Heading 2' }] },
|
|
|
+ next: "L1-3",
|
|
|
+ firstChild: null,
|
|
|
+ },
|
|
|
+ "L1-3": {
|
|
|
+ id: "L1-3",
|
|
|
+ type: BlockType.HeadingBlock,
|
|
|
+ data: { level: 3, content: [{ text: 'Heading 3' }] },
|
|
|
+ next: "L1-4",
|
|
|
+ firstChild: null,
|
|
|
+ },
|
|
|
+ "L1-4": {
|
|
|
+ id: "L1-4",
|
|
|
+ type: BlockType.TextBlock,
|
|
|
+ data: { content: [
|
|
|
+ {
|
|
|
+ text:
|
|
|
+ 'This example shows how you can make a hovering menu appear above your content, which you can use to make text ',
|
|
|
+ },
|
|
|
+ { text: 'bold', bold: true },
|
|
|
+ { text: ', ' },
|
|
|
+ { text: 'italic', italic: true },
|
|
|
+ { text: ', or anything else you might want to do!' },
|
|
|
+ ] },
|
|
|
+ next: "L1-5",
|
|
|
+ firstChild: null,
|
|
|
+ },
|
|
|
+ "L1-5": {
|
|
|
+ id: "L1-5",
|
|
|
+ type: BlockType.TextBlock,
|
|
|
+ data: { content: [
|
|
|
+ { text: 'Try it out yourself! Just ' },
|
|
|
+ { text: 'select any piece of text and the menu will appear', bold: true },
|
|
|
+ { text: '.' },
|
|
|
+ ] },
|
|
|
+ next: "L1-6",
|
|
|
+ firstChild: "L1-5-1",
|
|
|
+ },
|
|
|
+ "L1-5-1": {
|
|
|
+ id: "L1-5-1",
|
|
|
+ type: BlockType.TextBlock,
|
|
|
+ data: { content: [
|
|
|
+ { text: 'Try it out yourself! Just ' },
|
|
|
+ ] },
|
|
|
+ next: "L1-5-2",
|
|
|
+ firstChild: null,
|
|
|
+ },
|
|
|
+ "L1-5-2": {
|
|
|
+ id: "L1-5-2",
|
|
|
+ type: BlockType.TextBlock,
|
|
|
+ data: { content: [
|
|
|
+ { text: 'Try it out yourself! Just ' },
|
|
|
+ ] },
|
|
|
+ next: null,
|
|
|
+ firstChild: null,
|
|
|
+ },
|
|
|
+ "L1-6": {
|
|
|
+ id: "L1-6",
|
|
|
+ type: BlockType.ListBlock,
|
|
|
+ data: { type: 'bulleted', content: [
|
|
|
+ {
|
|
|
+ text:
|
|
|
+ "Since it's rich text, you can do things like turn a selection of text ",
|
|
|
+ },
|
|
|
+ { text: 'bold', bold: true },
|
|
|
+ {
|
|
|
+ text:
|
|
|
+ ', or add a semantically rendered block quote in the middle of the page, like this:',
|
|
|
+ },
|
|
|
+ ] },
|
|
|
+ next: "L1-7",
|
|
|
+ firstChild: "L1-6-1",
|
|
|
+ },
|
|
|
+ "L1-6-1": {
|
|
|
+ id: "L1-6-1",
|
|
|
+ type: BlockType.ListBlock,
|
|
|
+ data: { type: 'numbered', content: [
|
|
|
+ {
|
|
|
+ text:
|
|
|
+ "Since it's rich text, you can do things like turn a selection of text ",
|
|
|
+ },
|
|
|
+
|
|
|
+ ] },
|
|
|
+
|
|
|
+ next: "L1-6-2",
|
|
|
+ firstChild: null,
|
|
|
+ },
|
|
|
+ "L1-6-2": {
|
|
|
+ id: "L1-6-2",
|
|
|
+ type: BlockType.ListBlock,
|
|
|
+ data: { type: 'numbered', content: [
|
|
|
+ {
|
|
|
+ text:
|
|
|
+ "Since it's rich text, you can do things like turn a selection of text ",
|
|
|
+ },
|
|
|
+
|
|
|
+ ] },
|
|
|
+
|
|
|
+ next: "L1-6-3",
|
|
|
+ firstChild: null,
|
|
|
+ },
|
|
|
+
|
|
|
+ "L1-6-3": {
|
|
|
+ id: "L1-6-3",
|
|
|
+ type: BlockType.TextBlock,
|
|
|
+ data: { content: [{ text: 'A wise quote.' }] },
|
|
|
+ next: null,
|
|
|
+ firstChild: null,
|
|
|
+ },
|
|
|
+
|
|
|
+ "L1-7": {
|
|
|
+ id: "L1-7",
|
|
|
+ type: BlockType.ListBlock,
|
|
|
+ data: { type: 'column' },
|
|
|
+
|
|
|
+ next: "L1-8",
|
|
|
+ firstChild: "L1-7-1",
|
|
|
+ },
|
|
|
+ "L1-7-1": {
|
|
|
+ id: "L1-7-1",
|
|
|
+ type: BlockType.ColumnBlock,
|
|
|
+ data: { ratio: '0.33' },
|
|
|
+ next: "L1-7-2",
|
|
|
+ firstChild: "L1-7-1-1",
|
|
|
+ },
|
|
|
+ "L1-7-1-1": {
|
|
|
+ id: "L1-7-1-1",
|
|
|
+ type: BlockType.TextBlock,
|
|
|
+ data: { content: [
|
|
|
+ { text: 'Try it out yourself! Just ' },
|
|
|
+ ] },
|
|
|
+ next: null,
|
|
|
+ firstChild: null,
|
|
|
+ },
|
|
|
+ "L1-7-2": {
|
|
|
+ id: "L1-7-2",
|
|
|
+ type: BlockType.ColumnBlock,
|
|
|
+ data: { ratio: '0.33' },
|
|
|
+ next: "L1-7-3",
|
|
|
+ firstChild: "L1-7-2-1",
|
|
|
+ },
|
|
|
+ "L1-7-2-1": {
|
|
|
+ id: "L1-7-2-1",
|
|
|
+ type: BlockType.TextBlock,
|
|
|
+ data: { content: [
|
|
|
+ { text: 'Try it out yourself! Just ' },
|
|
|
+ ] },
|
|
|
+ next: "L1-7-2-2",
|
|
|
+ firstChild: null,
|
|
|
+ },
|
|
|
+ "L1-7-2-2": {
|
|
|
+ id: "L1-7-2-2",
|
|
|
+ type: BlockType.TextBlock,
|
|
|
+ data: { content: [
|
|
|
+ { text: 'Try it out yourself! Just ' },
|
|
|
+ ] },
|
|
|
+ next: null,
|
|
|
+ firstChild: null,
|
|
|
+ },
|
|
|
+ "L1-7-3": {
|
|
|
+ id: "L1-7-3",
|
|
|
+ type: BlockType.ColumnBlock,
|
|
|
+ data: { ratio: '0.33' },
|
|
|
+ next: null,
|
|
|
+ firstChild: "L1-7-3-1",
|
|
|
+ },
|
|
|
+ "L1-7-3-1": {
|
|
|
+ id: "L1-7-3-1",
|
|
|
+ type: BlockType.TextBlock,
|
|
|
+ data: { content: [
|
|
|
+ { text: 'Try it out yourself! Just ' },
|
|
|
+ ] },
|
|
|
+ next: null,
|
|
|
+ firstChild: null,
|
|
|
+ },
|
|
|
+ }
|
|
|
+}
|
|
|
export const useDocument = () => {
|
|
|
const params = useParams();
|
|
|
- const [blocksMap, setBlocksMap] = useState<Record<string, Block>>();
|
|
|
+ const [blockId, setBlockId] = useState<string>();
|
|
|
const loadDocument = async (id: string): Promise<any> => {
|
|
|
const getDocumentResult = await DocumentEventGetDocument(
|
|
|
OpenDocumentPayloadPB.fromObject({
|
|
@@ -26,148 +223,24 @@ export const useDocument = () => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- const loadBlockData = async (blockId: string): Promise<Record<string, Block>> => {
|
|
|
- return {
|
|
|
- [blockId]: {
|
|
|
- id: blockId,
|
|
|
- type: BlockType.PageBlock,
|
|
|
- data: { title: 'Document Title' },
|
|
|
- parent: null,
|
|
|
- next: null,
|
|
|
- prev: null,
|
|
|
- firstChild: "A",
|
|
|
- lastChild: "E"
|
|
|
- },
|
|
|
- "A": {
|
|
|
- id: "A",
|
|
|
- type: BlockType.HeadingBlock,
|
|
|
- data: { level: 1, text: 'A Heading-1' },
|
|
|
- parent: blockId,
|
|
|
- prev: null,
|
|
|
- next: "B",
|
|
|
- firstChild: null,
|
|
|
- lastChild: null,
|
|
|
- },
|
|
|
- "B": {
|
|
|
- id: "B",
|
|
|
- type: BlockType.TextBlock,
|
|
|
- data: { text: 'Hello', attr: '' },
|
|
|
- parent: blockId,
|
|
|
- prev: "A",
|
|
|
- next: "C",
|
|
|
- firstChild: null,
|
|
|
- lastChild: null,
|
|
|
- },
|
|
|
- "C": {
|
|
|
- id: "C",
|
|
|
- type: BlockType.TextBlock,
|
|
|
- data: { text: 'block c' },
|
|
|
- prev: null,
|
|
|
- parent: blockId,
|
|
|
- next: "D",
|
|
|
- firstChild: "F",
|
|
|
- lastChild: null,
|
|
|
- },
|
|
|
- "D": {
|
|
|
- id: "D",
|
|
|
- type: BlockType.ListBlock,
|
|
|
- data: { type: 'number_list', text: 'D List' },
|
|
|
- prev: "C",
|
|
|
- parent: blockId,
|
|
|
- next: null,
|
|
|
- firstChild: "G",
|
|
|
- lastChild: "H",
|
|
|
- },
|
|
|
- "E": {
|
|
|
- id: "E",
|
|
|
- type: BlockType.TextBlock,
|
|
|
- data: { text: 'World', attr: '' },
|
|
|
- prev: "D",
|
|
|
- parent: blockId,
|
|
|
- next: null,
|
|
|
- firstChild: null,
|
|
|
- lastChild: null,
|
|
|
- },
|
|
|
- "F": {
|
|
|
- id: "F",
|
|
|
- type: BlockType.TextBlock,
|
|
|
- data: { text: 'Heading', attr: '' },
|
|
|
- prev: null,
|
|
|
- parent: "C",
|
|
|
- next: null,
|
|
|
- firstChild: null,
|
|
|
- lastChild: null,
|
|
|
- },
|
|
|
- "G": {
|
|
|
- id: "G",
|
|
|
- type: BlockType.TextBlock,
|
|
|
- data: { text: 'Item 1', attr: '' },
|
|
|
- prev: null,
|
|
|
- parent: "D",
|
|
|
- next: "H",
|
|
|
- firstChild: null,
|
|
|
- lastChild: null,
|
|
|
- },
|
|
|
- "H": {
|
|
|
- id: "H",
|
|
|
- type: BlockType.TextBlock,
|
|
|
- data: { text: 'Item 2', attr: '' },
|
|
|
- prev: "G",
|
|
|
- parent: "D",
|
|
|
- next: "I",
|
|
|
- firstChild: null,
|
|
|
- lastChild: null,
|
|
|
- },
|
|
|
- "I": {
|
|
|
- id: "I",
|
|
|
- type: BlockType.HeadingBlock,
|
|
|
- data: { level: 2, text: 'B Heading-1' },
|
|
|
- parent: blockId,
|
|
|
- prev: "H",
|
|
|
- next: 'L',
|
|
|
- firstChild: null,
|
|
|
- lastChild: null,
|
|
|
- },
|
|
|
- "L": {
|
|
|
- id: "L",
|
|
|
- type: BlockType.TextBlock,
|
|
|
- data: { text: '456' },
|
|
|
- parent: blockId,
|
|
|
- prev: "I",
|
|
|
- next: 'J',
|
|
|
- firstChild: null,
|
|
|
- lastChild: null,
|
|
|
- },
|
|
|
- "J": {
|
|
|
- id: "J",
|
|
|
- type: BlockType.HeadingBlock,
|
|
|
- data: { level: 3, text: 'C Heading-1' },
|
|
|
- parent: blockId,
|
|
|
- prev: "L",
|
|
|
- next: "K",
|
|
|
- firstChild: null,
|
|
|
- lastChild: null,
|
|
|
- },
|
|
|
- "K": {
|
|
|
- id: "K",
|
|
|
- type: BlockType.TextBlock,
|
|
|
- data: { text: '123' },
|
|
|
- parent: blockId,
|
|
|
- prev: "J",
|
|
|
- next: null,
|
|
|
- firstChild: null,
|
|
|
- lastChild: null,
|
|
|
- },
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
useEffect(() => {
|
|
|
void (async () => {
|
|
|
if (!params?.id) return;
|
|
|
const data = await loadBlockData(params.id);
|
|
|
- console.log(data);
|
|
|
- setBlocksMap(data);
|
|
|
+ console.log('==== enter ====', params?.id, data);
|
|
|
+
|
|
|
+ const blockEditor = getBlockEditor();
|
|
|
+ if (blockEditor) {
|
|
|
+ blockEditor.changeDoc(params?.id, data);
|
|
|
+ } else {
|
|
|
+ createBlockEditor(params?.id, data);
|
|
|
+ }
|
|
|
+
|
|
|
+ setBlockId(params.id)
|
|
|
})();
|
|
|
- }, [params]);
|
|
|
- return { blocksMap, blockId: params.id };
|
|
|
+ return () => {
|
|
|
+ console.log('==== leave ====', params?.id)
|
|
|
+ }
|
|
|
+ }, [params.id]);
|
|
|
+ return { blockId };
|
|
|
};
|