1+ /* eslint-disable no-continue */
12import { useCallback } from 'react' ;
23import { DraggingPosition , TreeItem } from '../types' ;
34import { useGetGetParentOfLinearItem } from './useGetParentOfLinearItem' ;
@@ -9,54 +10,96 @@ export const useGetViableDragPositions = () => {
910 const getParentOfLinearItem = useGetGetParentOfLinearItem ( ) ;
1011 const canDropAt = useCanDropAt ( ) ;
1112
13+ const isDescendant = useCallback (
14+ ( treeId : string , itemLinearIndex : number , potentialParents : TreeItem [ ] ) => {
15+ // based on DraggingPositionEvaluation.isDescendant()
16+ const { parent, parentLinearIndex } = getParentOfLinearItem (
17+ itemLinearIndex ,
18+ treeId
19+ ) ;
20+ if ( potentialParents . some ( p => p . index === parent . item ) ) return true ;
21+ if ( parent . depth === 0 ) return false ;
22+ return isDescendant ( treeId , parentLinearIndex , potentialParents ) ;
23+ } ,
24+ [ getParentOfLinearItem ]
25+ ) ;
26+
1227 return useCallback (
1328 ( treeId : string , draggingItems : TreeItem [ ] ) => {
1429 const linearItems = environment . linearItems [ treeId ] ;
15- return linearItems
16- . map < DraggingPosition [ ] > ( ( { item, depth } , linearIndex ) => {
17- const { parent } = getParentOfLinearItem ( linearIndex , treeId ) ;
18- const childIndex =
19- environment . items [ parent . item ] . children ! . indexOf ( item ) ;
30+ const targets : DraggingPosition [ ] = [ ] ;
31+ let skipUntilDepthIsLowerThan = - 1 ;
32+
33+ for (
34+ let linearIndex = 0 ;
35+ linearIndex < linearItems . length ;
36+ // eslint-disable-next-line no-plusplus
37+ linearIndex ++
38+ ) {
39+ const { item, depth } = linearItems [ linearIndex ] ;
40+
41+ if (
42+ skipUntilDepthIsLowerThan !== - 1 &&
43+ depth > skipUntilDepthIsLowerThan
44+ ) {
45+ continue ;
46+ } else {
47+ skipUntilDepthIsLowerThan = - 1 ;
48+ }
49+
50+ const { parent } = getParentOfLinearItem ( linearIndex , treeId ) ;
51+ const childIndex =
52+ environment . items [ parent . item ] . children ! . indexOf ( item ) ;
53+
54+ if ( isDescendant ( treeId , linearIndex , draggingItems ) ) {
55+ skipUntilDepthIsLowerThan = depth + 1 ;
56+ continue ;
57+ }
58+
59+ const itemPosition : DraggingPosition = {
60+ targetType : 'item' ,
61+ parentItem : parent . item ,
62+ targetItem : item ,
63+ linearIndex,
64+ depth,
65+ treeId,
66+ } ;
2067
21- const itemPosition : DraggingPosition = {
22- targetType : 'item' ,
23- parentItem : parent . item ,
24- targetItem : item ,
25- linearIndex,
26- depth,
27- treeId,
28- } ;
68+ const topPosition : DraggingPosition = {
69+ targetType : 'between-items' ,
70+ parentItem : parent . item ,
71+ linePosition : 'top' ,
72+ childIndex,
73+ depth,
74+ treeId,
75+ linearIndex,
76+ } ;
2977
30- const topPosition : DraggingPosition = {
31- targetType : 'between-items' ,
32- parentItem : parent . item ,
33- linePosition : 'top ' ,
34- childIndex ,
35- depth ,
36- treeId ,
37- linearIndex ,
38- } ;
78+ const bottomPosition : DraggingPosition = {
79+ targetType : 'between-items' ,
80+ parentItem : parent . item ,
81+ linePosition : 'bottom ' ,
82+ linearIndex : linearIndex + 1 ,
83+ childIndex : childIndex + 1 ,
84+ depth ,
85+ treeId ,
86+ } ;
3987
40- const bottomPosition : DraggingPosition = {
41- targetType : 'between-items' ,
42- parentItem : parent . item ,
43- linePosition : 'bottom' ,
44- linearIndex : linearIndex + 1 ,
45- childIndex : childIndex + 1 ,
46- depth,
47- treeId,
48- } ;
88+ const skipTopPosition =
89+ depth === ( linearItems [ linearIndex - 1 ] ?. depth ?? - 1 ) ;
4990
50- const skipTopPosition =
51- depth === ( linearItems [ linearIndex - 1 ] ?. depth ?? - 1 ) ;
91+ if ( ! skipTopPosition && canDropAt ( topPosition , draggingItems ) ) {
92+ targets . push ( topPosition ) ;
93+ }
94+ if ( canDropAt ( itemPosition , draggingItems ) ) {
95+ targets . push ( itemPosition ) ;
96+ }
97+ if ( canDropAt ( bottomPosition , draggingItems ) ) {
98+ targets . push ( bottomPosition ) ;
99+ }
100+ }
52101
53- if ( skipTopPosition ) {
54- return [ itemPosition , bottomPosition ] ;
55- }
56- return [ topPosition , itemPosition , bottomPosition ] ;
57- } )
58- . reduce ( ( a , b ) => [ ...a , ...b ] , [ ] )
59- . filter ( position => canDropAt ( position , draggingItems ) ) ;
102+ return targets ;
60103 } ,
61104 [
62105 canDropAt ,
0 commit comments