@@ -2,19 +2,29 @@ import { Block, BlockType, BlockFamily, FamilyFunc, BlockMap } from '@/schemes';
2
2
import { useFamily } from '@/hooks' ;
3
3
import { focusState , blockRefState } from '@/stores' ;
4
4
import { useSetRecoilState } from 'recoil' ;
5
+ import {
6
+ createBlock ,
7
+ updateBlock ,
8
+ moveBlock ,
9
+ deletePageCascade ,
10
+ } from '@utils/blockApis' ;
5
11
6
12
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 > ;
11
17
startTransaction : ( ) => void ;
12
18
commitTransaction : ( ) => void ;
13
- pullIn : ( ) => Block ;
14
- pullOut : ( ) => Block ;
15
- deleteBlock : ( ) => string [ ] ;
19
+ pullIn : ( ) => Promise < Block > ;
20
+ pullOut : ( ) => Promise < Block > ;
21
+ deleteBlock : ( ) => Promise < void > ;
16
22
setFocus : ( targetBlock : Block ) => number ;
17
- setCaretOffset : ( offset ?: number ) => void ;
23
+ setCaretOffset : (
24
+ offset ?: number ,
25
+ isBlur ?: boolean ,
26
+ isCaret ?: boolean ,
27
+ ) => void ;
18
28
}
19
29
20
30
const useManger = (
@@ -42,102 +52,103 @@ const useManger = (
42
52
const startTransaction = ( ) => {
43
53
transaction = { ...blockMap } ;
44
54
} ;
55
+
45
56
const commitTransaction = ( ) => {
46
57
familyFunc . setBlockMap ( transaction ) ;
47
58
} ;
48
59
49
- const setBlock = ( id : string , option : any = { } ) => {
50
- transaction [ id ] = {
60
+ const setBlock = async ( id : string , option : any = { } ) => {
61
+ const { block : updatedBlock } = await updateBlock ( {
51
62
...transaction [ id ] ,
52
63
...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
+ } ,
53
75
} ;
54
76
return transaction [ id ] ;
55
77
} ;
56
78
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 ,
73
87
} ) ;
74
- return newBlock ;
88
+ setUpdatedBlock ( updatedBlock . id , updatedBlock ) ;
89
+ setUpdatedBlock ( updatedParent . id , updatedParent ) ;
90
+ return updatedBlock ;
75
91
} ;
76
92
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 ,
85
101
} ) ;
86
- return transaction [ id ] ;
102
+ setUpdatedBlock ( updatedBlock . id , updatedBlock ) ;
103
+ setUpdatedBlock ( from . id , from ) ;
104
+ setUpdatedBlock ( to . id , to ) ;
105
+ return updatedBlock ;
87
106
} ;
88
107
89
- const insertNewSibling = (
108
+ const insertNewSibling = async (
90
109
option : any = { } ,
91
110
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 ,
108
116
} ) ;
109
- return newBlock ;
117
+ setUpdatedBlock ( updatedBlock . id , updatedBlock ) ;
118
+ setUpdatedBlock ( updatedParent . id , updatedParent ) ;
119
+ return updatedBlock ;
110
120
} ;
111
121
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 ) ;
120
125
} ;
121
126
122
- const pullIn = ( ) => {
127
+ const pullIn = async ( ) => {
123
128
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 ] ,
127
132
} ) ;
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 ;
130
137
}
131
138
return block ;
132
139
} ;
133
140
134
- const pullOut = ( ) => {
141
+ const pullOut = async ( ) => {
135
142
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 ;
141
152
}
142
153
return block ;
143
154
} ;
@@ -157,12 +168,25 @@ const useManger = (
157
168
158
169
const setCaretOffset = (
159
170
offset : number = window . getSelection ( ) . focusOffset ,
171
+ isBlur : boolean = true ,
172
+ isCaret : boolean = true ,
160
173
) => {
161
174
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
+ // }
166
190
} ;
167
191
168
192
return [
0 commit comments