8
8
*/
9
9
10
10
import * as React from 'react' ;
11
- import { useEffect , useMemo , useRef } from 'react' ;
11
+ import { useEffect , useMemo , useRef , useState } from 'react' ;
12
12
import AutoSizer from 'react-virtualized-auto-sizer' ;
13
13
import { FixedSizeList } from 'react-window' ;
14
14
import SnapshotCommitListItem from './SnapshotCommitListItem' ;
@@ -72,6 +72,12 @@ type ListProps = {|
72
72
width : number ,
73
73
| } ;
74
74
75
+ type DragStartCommit = {
76
+ dragStartCommitIndex : number ,
77
+ rectLeft : number ,
78
+ width : number ,
79
+ } ;
80
+
75
81
function List ( {
76
82
commitDurations,
77
83
selectedCommitIndex,
@@ -105,6 +111,87 @@ function List({
105
111
[ commitDurations ] ,
106
112
) ;
107
113
114
+ const maxCommitIndex = filteredCommitIndices . length - 1 ;
115
+
116
+ const [ state , setState ] = useState ( {
117
+ dragCommitStarted : false ,
118
+ dragStartCommit : null ,
119
+ modifiedIframes : null ,
120
+ } ) ;
121
+
122
+ const startCommitDrag = ( newDragStartCommit : DragStartCommit ) => {
123
+ const element = divRef . current ;
124
+ if ( element !== null ) {
125
+ const iframes = element . ownerDocument . querySelectorAll ( 'iframe' ) ;
126
+ if ( iframes . length > 0 ) {
127
+ const modifiedIframesMap = new Map ( ) ;
128
+ for ( let i = 0 ; i < iframes . length ; i ++ ) {
129
+ if ( iframes [ i ] . style . pointerEvents !== 'none' ) {
130
+ modifiedIframesMap . set ( iframes [ i ] , iframes [ i ] . style . pointerEvents ) ;
131
+ iframes [ i ] . style . pointerEvents = 'none' ;
132
+ }
133
+ }
134
+ setState ( {
135
+ dragCommitStarted : true ,
136
+ dragStartCommit : newDragStartCommit ,
137
+ modifiedIframes : modifiedIframesMap ,
138
+ } ) ;
139
+ }
140
+ }
141
+ } ;
142
+
143
+ const handleDragCommit = ( e : any ) => {
144
+ const { dragCommitStarted, dragStartCommit, modifiedIframes} = state ;
145
+ if ( dragCommitStarted === false || dragStartCommit === null ) return ;
146
+ if ( e . buttons === 0 ) {
147
+ if ( modifiedIframes !== null ) {
148
+ modifiedIframes . forEach ( ( value , iframe ) => {
149
+ iframe . style . pointerEvents = value ;
150
+ } ) ;
151
+ }
152
+ setState ( {
153
+ dragCommitStarted : false ,
154
+ dragStartCommit : null ,
155
+ modifiedIframes : null ,
156
+ } ) ;
157
+ return ;
158
+ }
159
+
160
+ let newCommitIndex = dragStartCommit . dragStartCommitIndex ;
161
+ let newCommitRectLeft = dragStartCommit . rectLeft ;
162
+
163
+ if ( e . pageX < dragStartCommit . rectLeft ) {
164
+ while ( e . pageX < newCommitRectLeft ) {
165
+ newCommitRectLeft = newCommitRectLeft - 1 - dragStartCommit . width ;
166
+ newCommitIndex -= 1 ;
167
+ }
168
+ } else {
169
+ let newCommitRectRight = newCommitRectLeft + dragStartCommit . width ;
170
+ while ( e . pageX > newCommitRectRight ) {
171
+ newCommitRectRight = newCommitRectRight + 1 + dragStartCommit . width ;
172
+ newCommitIndex += 1 ;
173
+ }
174
+ }
175
+
176
+ if ( newCommitIndex < 0 ) {
177
+ newCommitIndex = 0 ;
178
+ } else if ( newCommitIndex > maxCommitIndex ) {
179
+ newCommitIndex = maxCommitIndex ;
180
+ }
181
+ selectCommitIndex ( newCommitIndex ) ;
182
+ } ;
183
+
184
+ useEffect ( ( ) => {
185
+ const element = divRef . current ;
186
+ if ( element !== null ) {
187
+ const ownerDocument = element . ownerDocument ;
188
+ ownerDocument . addEventListener ( 'mousemove' , handleDragCommit ) ;
189
+ return ( ) => {
190
+ ownerDocument . removeEventListener ( 'mousemove' , handleDragCommit ) ;
191
+ } ;
192
+ }
193
+ } , [ state ] ) ;
194
+
108
195
// Pass required contextual data down to the ListItem renderer.
109
196
const itemData = useMemo < ItemData > (
110
197
( ) => ( {
@@ -115,6 +202,7 @@ function List({
115
202
selectedCommitIndex,
116
203
selectedFilteredCommitIndex,
117
204
selectCommitIndex,
205
+ startCommitDrag,
118
206
} ) ,
119
207
[
120
208
commitDurations ,
@@ -124,6 +212,7 @@ function List({
124
212
selectedCommitIndex ,
125
213
selectedFilteredCommitIndex ,
126
214
selectCommitIndex ,
215
+ startCommitDrag ,
127
216
] ,
128
217
) ;
129
218
0 commit comments