Skip to content

Commit 1cdfdf1

Browse files
committed
[#118] feat: useManager에 서버 동기화 로직 구현
1 parent 4510344 commit 1cdfdf1

File tree

1 file changed

+102
-78
lines changed

1 file changed

+102
-78
lines changed

frontend/src/hooks/useManager.tsx

+102-78
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,29 @@ import { Block, BlockType, BlockFamily, FamilyFunc, BlockMap } from '@/schemes';
22
import { useFamily } from '@/hooks';
33
import { focusState, blockRefState } from '@/stores';
44
import { useSetRecoilState } from 'recoil';
5+
import {
6+
createBlock,
7+
updateBlock,
8+
moveBlock,
9+
deletePageCascade,
10+
} from '@utils/blockApis';
511

612
interface ManagerFunc {
7-
insertNewChild: (option?: any, insertIndex?: number) => Block;
8-
insertNewSibling: (option?: any, insertIndex?: number) => Block;
9-
insertSibling: (id: string, inserIndex?: number) => Block;
10-
setBlock: (id: string, option?: any) => Block;
13+
insertNewChild: (option?: any, insertIndex?: number) => Promise<Block>;
14+
insertNewSibling: (option?: any, insertIndex?: number) => Promise<Block>;
15+
insertSibling: (id: string, inserIndex?: number) => Promise<Block>;
16+
setBlock: (id: string, option?: any) => Promise<Block>;
1117
startTransaction: () => void;
1218
commitTransaction: () => void;
13-
pullIn: () => Block;
14-
pullOut: () => Block;
15-
deleteBlock: () => string[];
19+
pullIn: () => Promise<Block>;
20+
pullOut: () => Promise<Block>;
21+
deleteBlock: () => Promise<void>;
1622
setFocus: (targetBlock: Block) => number;
17-
setCaretOffset: (offset?: number) => void;
23+
setCaretOffset: (
24+
offset?: number,
25+
isBlur?: boolean,
26+
isCaret?: boolean,
27+
) => void;
1828
}
1929

2030
const useManger = (
@@ -42,102 +52,103 @@ const useManger = (
4252
const startTransaction = () => {
4353
transaction = { ...blockMap };
4454
};
55+
4556
const commitTransaction = () => {
4657
familyFunc.setBlockMap(transaction);
4758
};
4859

49-
const setBlock = (id: string, option: any = {}) => {
50-
transaction[id] = {
60+
const setBlock = async (id: string, option: any = {}) => {
61+
const { block: updatedBlock } = await updateBlock({
5162
...transaction[id],
5263
...option,
64+
});
65+
return setUpdatedBlock(updatedBlock.id, updatedBlock);
66+
};
67+
68+
const setUpdatedBlock = async (id: string, option: any = {}) => {
69+
transaction = {
70+
...transaction,
71+
[id]: {
72+
...transaction[id],
73+
...option,
74+
},
5375
};
5476
return transaction[id];
5577
};
5678

57-
const insertNewChild = (option: any = {}, insertIndex = 0): Block => {
58-
const id = `${block.id}${children.length + 1}_${Date.now()}`;
59-
const newBlock: Block = {
60-
id,
61-
type: BlockType.TEXT,
62-
value: '',
63-
childIdList: [],
64-
parentId: block?.id ?? null,
65-
pageId: page.id,
66-
...option,
67-
};
68-
setBlock(id, newBlock);
69-
const copyChildIdList = [...childrenIdList];
70-
copyChildIdList.splice(insertIndex, 0, id);
71-
setBlock(block.id, {
72-
childIdList: copyChildIdList,
79+
const insertNewChild = async (
80+
option: any = {},
81+
insertIndex = 0,
82+
): Promise<Block> => {
83+
const { block: updatedBlock, parent: updatedParent } = await createBlock({
84+
parentBlockId: block.id,
85+
index: insertIndex,
86+
block: option,
7387
});
74-
return newBlock;
88+
setUpdatedBlock(updatedBlock.id, updatedBlock);
89+
setUpdatedBlock(updatedParent.id, updatedParent);
90+
return updatedBlock;
7591
};
7692

77-
const insertSibling = (id: string, insertIndex: number = 0) => {
78-
const copySiblingsIdList = transaction[parent.id].childIdList;
79-
copySiblingsIdList.splice(insertIndex, 0, id);
80-
setBlock(parent.id, {
81-
childrenIdList: copySiblingsIdList,
82-
});
83-
setBlock(id, {
84-
parentId: parent.id,
93+
const insertSibling = async (
94+
id: string,
95+
insertIndex: number = 0,
96+
): Promise<Block> => {
97+
const { block: updatedBlock, from, to } = await moveBlock({
98+
blockId: id,
99+
toId: parent.id,
100+
index: insertIndex,
85101
});
86-
return transaction[id];
102+
setUpdatedBlock(updatedBlock.id, updatedBlock);
103+
setUpdatedBlock(from.id, from);
104+
setUpdatedBlock(to.id, to);
105+
return updatedBlock;
87106
};
88107

89-
const insertNewSibling = (
108+
const insertNewSibling = async (
90109
option: any = {},
91110
insertIndex = blockIndex + 1,
92-
): Block => {
93-
const id = `${parent?.id ?? ''}${siblings.length + 1}_${Date.now()}`;
94-
const newBlock: Block = {
95-
id,
96-
type: BlockType.TEXT,
97-
value: '',
98-
childIdList: [],
99-
parentId: parent?.id ?? null,
100-
pageId: page.id,
101-
...option,
102-
};
103-
transaction[id] = newBlock;
104-
const copySiblingsIdList = [...siblingsIdList];
105-
copySiblingsIdList.splice(insertIndex, 0, id);
106-
setBlock(parent.id, {
107-
childIdList: copySiblingsIdList,
111+
): Promise<Block> => {
112+
const { block: updatedBlock, parent: updatedParent } = await createBlock({
113+
parentBlockId: parent.id,
114+
index: insertIndex,
115+
block: option,
108116
});
109-
return newBlock;
117+
setUpdatedBlock(updatedBlock.id, updatedBlock);
118+
setUpdatedBlock(updatedParent.id, updatedParent);
119+
return updatedBlock;
110120
};
111121

112-
const deleteBlock = () => {
113-
const filteredSiblingsIdList = siblingsIdList.filter(
114-
(id) => id !== block.id,
115-
);
116-
setBlock(parent.id, {
117-
childIdList: filteredSiblingsIdList,
118-
});
119-
return [...transaction[block.id].childIdList];
122+
const deleteBlock = async () => {
123+
const { parent: updatedBlock } = await deletePageCascade(block.id);
124+
setUpdatedBlock(updatedBlock.id, updatedBlock);
120125
};
121126

122-
const pullIn = () => {
127+
const pullIn = async () => {
123128
if (blockIndex) {
124-
const targetSibling = siblings[blockIndex - 1];
125-
setBlock(siblingsIdList[blockIndex - 1], {
126-
childIdList: [...targetSibling.childIdList, block.id],
129+
const { block: updatedBlock, from, to } = await moveBlock({
130+
blockId: block.id,
131+
toId: siblingsIdList[blockIndex - 1],
127132
});
128-
deleteBlock();
129-
setBlock(block.id, { parentId: siblingsIdList[blockIndex - 1] });
133+
setUpdatedBlock(updatedBlock.id, updatedBlock);
134+
setUpdatedBlock(from.id, from);
135+
setUpdatedBlock(to.id, to);
136+
return updatedBlock;
130137
}
131138
return block;
132139
};
133140

134-
const pullOut = () => {
141+
const pullOut = async () => {
135142
if (grandParent && grandParent.type !== BlockType.GRID) {
136-
deleteBlock();
137-
const copyParentsIdList = [...parentsIdList];
138-
copyParentsIdList.splice(parentIndex + 1, 0, block.id);
139-
setBlock(block.id, { parentId: grandParent.id });
140-
setBlock(grandParent.id, { childIdList: copyParentsIdList });
143+
const { block: updatedBlock, from, to } = await moveBlock({
144+
blockId: block.id,
145+
toId: grandParent.id,
146+
index: parentIndex + 1,
147+
});
148+
setUpdatedBlock(updatedBlock.id, updatedBlock);
149+
setUpdatedBlock(from.id, from);
150+
setUpdatedBlock(to.id, to);
151+
return updatedBlock;
141152
}
142153
return block;
143154
};
@@ -157,12 +168,25 @@ const useManger = (
157168

158169
const setCaretOffset = (
159170
offset: number = window.getSelection().focusOffset,
171+
isBlur: boolean = true,
172+
isCaret: boolean = true,
160173
) => {
161174
const sel = window.getSelection();
162-
const { focusNode: node } = sel;
163-
const { length } = node as any;
164-
!(node instanceof HTMLElement) &&
165-
sel.collapse(node, offset > length ? length : offset);
175+
const { focusNode: beforeNode } = sel;
176+
if (isBlur) {
177+
beforeNode.parentElement.blur();
178+
}
179+
setTimeout(() => {
180+
const { focusNode: afterNode } = window.getSelection();
181+
const length = (afterNode as any).length && afterNode.textContent.length;
182+
if (length && isCaret)
183+
sel.collapse(beforeNode, offset > length ? length : offset);
184+
});
185+
// else {
186+
// const { focusNode: afterNode } = window.getSelection();
187+
// const length = (afterNode as any).length && afterNode.textContent.length;
188+
// if (length) sel.collapse(beforeNode, offset > length ? length : offset);
189+
// }
166190
};
167191

168192
return [

0 commit comments

Comments
 (0)