88 */
99
1010import * as React from 'react' ;
11- import { useEffect , useMemo , useRef } from 'react' ;
11+ import { useEffect , useMemo , useRef , useState } from 'react' ;
1212import AutoSizer from 'react-virtualized-auto-sizer' ;
1313import { FixedSizeList } from 'react-window' ;
1414import SnapshotCommitListItem from './SnapshotCommitListItem' ;
@@ -24,6 +24,13 @@ export type ItemData = {|
2424 selectedCommitIndex : number | null ,
2525 selectedFilteredCommitIndex : number | null ,
2626 selectCommitIndex : ( index : number ) => void ,
27+ startCommitDrag : ( newDragStartCommit : DragStartCommit ) => void ,
28+ | } ;
29+
30+ type State = { |
31+ dragCommitStarted : boolean ,
32+ dragStartCommit : DragStartCommit | null ,
33+ modifiedIframes : Map < HTMLElement , string> | null ,
2734| } ;
2835
2936type Props = { |
@@ -72,6 +79,12 @@ type ListProps = {|
7279 width : number ,
7380| } ;
7481
82+ type DragStartCommit = {
83+ dragStartCommitIndex : number ,
84+ rectLeft : number ,
85+ width : number ,
86+ } ;
87+
7588function List ( {
7689 commitDurations,
7790 selectedCommitIndex,
@@ -105,6 +118,87 @@ function List({
105118 [ commitDurations ] ,
106119 ) ;
107120
121+ const maxCommitIndex = filteredCommitIndices . length - 1 ;
122+
123+ const [ state , setState ] = useState < State > ( {
124+ dragCommitStarted : false ,
125+ dragStartCommit : null ,
126+ modifiedIframes : null ,
127+ } ) ;
128+
129+ const startCommitDrag = ( newDragStartCommit : DragStartCommit ) => {
130+ const element = divRef . current ;
131+ if ( element !== null ) {
132+ const iframes = element . ownerDocument . querySelectorAll ( 'iframe' ) ;
133+ if ( iframes . length > 0 ) {
134+ const modifiedIframesMap = new Map ( ) ;
135+ for ( let i = 0 ; i < iframes . length ; i ++ ) {
136+ if ( iframes [ i ] . style . pointerEvents !== 'none' ) {
137+ modifiedIframesMap . set ( iframes [ i ] , iframes [ i ] . style . pointerEvents ) ;
138+ iframes [ i ] . style . pointerEvents = 'none' ;
139+ }
140+ }
141+ setState ( {
142+ dragCommitStarted : true ,
143+ dragStartCommit : newDragStartCommit ,
144+ modifiedIframes : modifiedIframesMap ,
145+ } ) ;
146+ }
147+ }
148+ } ;
149+
150+ const handleDragCommit = ( e : any ) => {
151+ const { dragCommitStarted, dragStartCommit, modifiedIframes} = state ;
152+ if ( dragCommitStarted === false || dragStartCommit === null ) return ;
153+ if ( e . buttons === 0 ) {
154+ if ( modifiedIframes !== null ) {
155+ modifiedIframes . forEach ( ( value , iframe ) => {
156+ iframe . style . pointerEvents = value ;
157+ } ) ;
158+ }
159+ setState ( {
160+ dragCommitStarted : false ,
161+ dragStartCommit : null ,
162+ modifiedIframes : null ,
163+ } ) ;
164+ return ;
165+ }
166+
167+ let newCommitIndex = dragStartCommit . dragStartCommitIndex ;
168+ let newCommitRectLeft = dragStartCommit . rectLeft ;
169+
170+ if ( e . pageX < dragStartCommit . rectLeft ) {
171+ while ( e . pageX < newCommitRectLeft ) {
172+ newCommitRectLeft = newCommitRectLeft - 1 - dragStartCommit . width ;
173+ newCommitIndex -= 1 ;
174+ }
175+ } else {
176+ let newCommitRectRight = newCommitRectLeft + dragStartCommit . width ;
177+ while ( e . pageX > newCommitRectRight ) {
178+ newCommitRectRight = newCommitRectRight + 1 + dragStartCommit . width ;
179+ newCommitIndex += 1 ;
180+ }
181+ }
182+
183+ if ( newCommitIndex < 0 ) {
184+ newCommitIndex = 0 ;
185+ } else if ( newCommitIndex > maxCommitIndex ) {
186+ newCommitIndex = maxCommitIndex ;
187+ }
188+ selectCommitIndex ( newCommitIndex ) ;
189+ } ;
190+
191+ useEffect ( ( ) => {
192+ const element = divRef . current ;
193+ if ( element !== null ) {
194+ const ownerDocument = element . ownerDocument ;
195+ ownerDocument . addEventListener ( 'mousemove' , handleDragCommit ) ;
196+ return ( ) => {
197+ ownerDocument . removeEventListener ( 'mousemove' , handleDragCommit ) ;
198+ } ;
199+ }
200+ } , [ state ] ) ;
201+
108202 // Pass required contextual data down to the ListItem renderer.
109203 const itemData = useMemo < ItemData > (
110204 ( ) => ( {
@@ -115,6 +209,7 @@ function List({
115209 selectedCommitIndex,
116210 selectedFilteredCommitIndex,
117211 selectCommitIndex,
212+ startCommitDrag,
118213 } ) ,
119214 [
120215 commitDurations ,
@@ -124,6 +219,7 @@ function List({
124219 selectedCommitIndex ,
125220 selectedFilteredCommitIndex ,
126221 selectCommitIndex ,
222+ startCommitDrag ,
127223 ] ,
128224 ) ;
129225
0 commit comments