|
@@ -1,22 +1,12 @@
|
|
-import { BlockType, TextDelta } from "@/appflowy_app/interfaces/document";
|
|
|
|
-import { PayloadAction, createSlice } from "@reduxjs/toolkit";
|
|
|
|
-import { RegionGrid } from "./region_grid";
|
|
|
|
-
|
|
|
|
-export interface Node {
|
|
|
|
- id: string;
|
|
|
|
- type: BlockType;
|
|
|
|
- data: {
|
|
|
|
- text?: string;
|
|
|
|
- style?: Record<string, any>
|
|
|
|
- };
|
|
|
|
- parent: string | null;
|
|
|
|
- children: string;
|
|
|
|
-}
|
|
|
|
|
|
+import { BlockType, NestedBlock, TextDelta } from '@/appflowy_app/interfaces/document';
|
|
|
|
+import { PayloadAction, createSlice } from '@reduxjs/toolkit';
|
|
|
|
+import { RegionGrid } from './region_grid';
|
|
|
|
+
|
|
|
|
+export type Node = NestedBlock;
|
|
|
|
|
|
export interface NodeState {
|
|
export interface NodeState {
|
|
nodes: Record<string, Node>;
|
|
nodes: Record<string, Node>;
|
|
children: Record<string, string[]>;
|
|
children: Record<string, string[]>;
|
|
- delta: Record<string, TextDelta[]>;
|
|
|
|
selections: string[];
|
|
selections: string[];
|
|
}
|
|
}
|
|
|
|
|
|
@@ -25,7 +15,6 @@ const regionGrid = new RegionGrid(50);
|
|
const initialState: NodeState = {
|
|
const initialState: NodeState = {
|
|
nodes: {},
|
|
nodes: {},
|
|
children: {},
|
|
children: {},
|
|
- delta: {},
|
|
|
|
selections: [],
|
|
selections: [],
|
|
};
|
|
};
|
|
|
|
|
|
@@ -33,46 +22,56 @@ export const documentSlice = createSlice({
|
|
name: 'document',
|
|
name: 'document',
|
|
initialState: initialState,
|
|
initialState: initialState,
|
|
reducers: {
|
|
reducers: {
|
|
- clear: (state, action: PayloadAction) => {
|
|
|
|
|
|
+ clear: () => {
|
|
return initialState;
|
|
return initialState;
|
|
},
|
|
},
|
|
|
|
|
|
- createTree: (state, action: PayloadAction<{
|
|
|
|
- nodes: Record<string, Node>;
|
|
|
|
- children: Record<string, string[]>;
|
|
|
|
- delta: Record<string, TextDelta[]>;
|
|
|
|
- }>) => {
|
|
|
|
- const { nodes, children, delta } = action.payload;
|
|
|
|
|
|
+ create: (
|
|
|
|
+ state,
|
|
|
|
+ action: PayloadAction<{
|
|
|
|
+ nodes: Record<string, Node>;
|
|
|
|
+ children: Record<string, string[]>;
|
|
|
|
+ }>
|
|
|
|
+ ) => {
|
|
|
|
+ const { nodes, children } = action.payload;
|
|
state.nodes = nodes;
|
|
state.nodes = nodes;
|
|
state.children = children;
|
|
state.children = children;
|
|
- state.delta = delta;
|
|
|
|
},
|
|
},
|
|
|
|
|
|
updateSelections: (state, action: PayloadAction<string[]>) => {
|
|
updateSelections: (state, action: PayloadAction<string[]>) => {
|
|
state.selections = action.payload;
|
|
state.selections = action.payload;
|
|
},
|
|
},
|
|
|
|
|
|
- changeSelectionByIntersectRect: (state, action: PayloadAction<{
|
|
|
|
- startX: number;
|
|
|
|
- startY: number;
|
|
|
|
- endX: number;
|
|
|
|
- endY: number
|
|
|
|
- }>) => {
|
|
|
|
|
|
+ setSelectionByRect: (
|
|
|
|
+ state,
|
|
|
|
+ action: PayloadAction<{
|
|
|
|
+ startX: number;
|
|
|
|
+ startY: number;
|
|
|
|
+ endX: number;
|
|
|
|
+ endY: number;
|
|
|
|
+ }>
|
|
|
|
+ ) => {
|
|
const { startX, startY, endX, endY } = action.payload;
|
|
const { startX, startY, endX, endY } = action.payload;
|
|
const blocks = regionGrid.getIntersectBlocks(startX, startY, endX, endY);
|
|
const blocks = regionGrid.getIntersectBlocks(startX, startY, endX, endY);
|
|
- state.selections = blocks.map(block => block.id);
|
|
|
|
|
|
+ state.selections = blocks.map((block) => block.id);
|
|
},
|
|
},
|
|
|
|
|
|
- updateNodePosition: (state, action: PayloadAction<{id: string; rect: {
|
|
|
|
- x: number;
|
|
|
|
- y: number;
|
|
|
|
- width: number;
|
|
|
|
- height: number;
|
|
|
|
- }}>) => {
|
|
|
|
|
|
+ updateNodePosition: (
|
|
|
|
+ state,
|
|
|
|
+ action: PayloadAction<{
|
|
|
|
+ id: string;
|
|
|
|
+ rect: {
|
|
|
|
+ x: number;
|
|
|
|
+ y: number;
|
|
|
|
+ width: number;
|
|
|
|
+ height: number;
|
|
|
|
+ };
|
|
|
|
+ }>
|
|
|
|
+ ) => {
|
|
const { id, rect } = action.payload;
|
|
const { id, rect } = action.payload;
|
|
const position = {
|
|
const position = {
|
|
id,
|
|
id,
|
|
- ...rect
|
|
|
|
|
|
+ ...rect,
|
|
};
|
|
};
|
|
regionGrid.updateBlock(id, position);
|
|
regionGrid.updateBlock(id, position);
|
|
},
|
|
},
|
|
@@ -81,13 +80,13 @@ export const documentSlice = createSlice({
|
|
state.nodes[action.payload.id] = action.payload;
|
|
state.nodes[action.payload.id] = action.payload;
|
|
},
|
|
},
|
|
|
|
|
|
- addChild: (state, action: PayloadAction<{ parentId: string, childId: string, prevId: string }>) => {
|
|
|
|
|
|
+ addChild: (state, action: PayloadAction<{ parentId: string; childId: string; prevId: string }>) => {
|
|
const { parentId, childId, prevId } = action.payload;
|
|
const { parentId, childId, prevId } = action.payload;
|
|
const parentChildrenId = state.nodes[parentId].children;
|
|
const parentChildrenId = state.nodes[parentId].children;
|
|
const children = state.children[parentChildrenId];
|
|
const children = state.children[parentChildrenId];
|
|
const prevIndex = children.indexOf(prevId);
|
|
const prevIndex = children.indexOf(prevId);
|
|
if (prevIndex === -1) {
|
|
if (prevIndex === -1) {
|
|
- children.push(childId)
|
|
|
|
|
|
+ children.push(childId);
|
|
} else {
|
|
} else {
|
|
children.splice(prevIndex + 1, 0, childId);
|
|
children.splice(prevIndex + 1, 0, childId);
|
|
}
|
|
}
|
|
@@ -98,32 +97,28 @@ export const documentSlice = createSlice({
|
|
state.children[id] = childIds;
|
|
state.children[id] = childIds;
|
|
},
|
|
},
|
|
|
|
|
|
- updateDelta: (state, action: PayloadAction<{ id: string; delta: TextDelta[] }>) => {
|
|
|
|
- const { id, delta } = action.payload;
|
|
|
|
- state.delta[id] = delta;
|
|
|
|
- },
|
|
|
|
-
|
|
|
|
- updateNode: (state, action: PayloadAction<{id: string; type?: BlockType; data?: any }>) => {
|
|
|
|
|
|
+ updateNode: (state, action: PayloadAction<{ id: string; data: any }>) => {
|
|
state.nodes[action.payload.id] = {
|
|
state.nodes[action.payload.id] = {
|
|
...state.nodes[action.payload.id],
|
|
...state.nodes[action.payload.id],
|
|
- ...action.payload
|
|
|
|
- }
|
|
|
|
|
|
+ ...action.payload,
|
|
|
|
+ };
|
|
},
|
|
},
|
|
|
|
|
|
removeNode: (state, action: PayloadAction<string>) => {
|
|
removeNode: (state, action: PayloadAction<string>) => {
|
|
const { children, data, parent } = state.nodes[action.payload];
|
|
const { children, data, parent } = state.nodes[action.payload];
|
|
|
|
+ // remove from parent
|
|
if (parent) {
|
|
if (parent) {
|
|
const index = state.children[state.nodes[parent].children].indexOf(action.payload);
|
|
const index = state.children[state.nodes[parent].children].indexOf(action.payload);
|
|
if (index > -1) {
|
|
if (index > -1) {
|
|
state.children[state.nodes[parent].children].splice(index, 1);
|
|
state.children[state.nodes[parent].children].splice(index, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ // remove children
|
|
if (children) {
|
|
if (children) {
|
|
delete state.children[children];
|
|
delete state.children[children];
|
|
}
|
|
}
|
|
- if (data && data.text) {
|
|
|
|
- delete state.delta[data.text];
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ // remove node
|
|
delete state.nodes[action.payload];
|
|
delete state.nodes[action.payload];
|
|
},
|
|
},
|
|
},
|
|
},
|