8
8
*/
9
9
10
10
import * as React from 'react' ;
11
- import { useCallback , useEffect , useMemo , useRef , useState } 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' ;
@@ -20,11 +20,11 @@ export type ItemData = {|
20
20
commitDurations : Array < number > ,
21
21
commitTimes : Array < number > ,
22
22
filteredCommitIndices : Array < number > ,
23
- isMouseDown : boolean ,
24
23
maxDuration : number ,
25
24
selectedCommitIndex : number | null ,
26
25
selectedFilteredCommitIndex : number | null ,
27
26
selectCommitIndex : ( index : number ) => void ,
27
+ startCommitDrag : ( newDragState : DragState ) => void ,
28
28
| } ;
29
29
30
30
type Props = { |
@@ -73,6 +73,12 @@ type ListProps = {|
73
73
width : number ,
74
74
| } ;
75
75
76
+ type DragState = {
77
+ commitIndex : number ,
78
+ left : number ,
79
+ sizeIncrement : number ,
80
+ } ;
81
+
76
82
function List ( {
77
83
commitDurations,
78
84
selectedCommitIndex,
@@ -97,28 +103,6 @@ function List({
97
103
}
98
104
} , [ listRef , selectedFilteredCommitIndex ] ) ;
99
105
100
- // When the mouse is down, dragging over a commit should auto-select it.
101
- // This provides a nice way for users to swipe across a range of commits to compare them.
102
- const [ isMouseDown , setIsMouseDown ] = useState ( false ) ;
103
- const handleMouseDown = useCallback ( ( ) => {
104
- setIsMouseDown ( true ) ;
105
- } , [ ] ) ;
106
- const handleMouseUp = useCallback ( ( ) => {
107
- setIsMouseDown ( false ) ;
108
- } , [ ] ) ;
109
- useEffect ( ( ) => {
110
- if ( divRef . current === null ) {
111
- return ( ) => { } ;
112
- }
113
-
114
- // It's important to listen to the ownerDocument to support the browser extension.
115
- // Here we use portals to render individual tabs (e.g. Profiler),
116
- // and the root document might belong to a different window.
117
- const ownerDocument = divRef . current . ownerDocument ;
118
- ownerDocument . addEventListener ( 'mouseup' , handleMouseUp ) ;
119
- return ( ) => ownerDocument . removeEventListener ( 'mouseup' , handleMouseUp ) ;
120
- } , [ divRef , handleMouseUp ] ) ;
121
-
122
106
const itemSize = useMemo (
123
107
( ) => Math . max ( minBarWidth , width / filteredCommitIndices . length ) ,
124
108
[ filteredCommitIndices , width ] ,
@@ -128,23 +112,76 @@ function List({
128
112
[ commitDurations ] ,
129
113
) ;
130
114
115
+ const maxCommitIndex = filteredCommitIndices . length - 1 ;
116
+
117
+ const [ dragState , setDragState ] = useState < DragState | null > ( null ) ;
118
+
119
+ const handleDragCommit = ( { buttons, pageX} : any ) => {
120
+ if ( buttons === 0 ) {
121
+ setDragState ( null ) ;
122
+ return ;
123
+ }
124
+
125
+ if ( dragState !== null ) {
126
+ const { commitIndex, left, sizeIncrement} = dragState ;
127
+
128
+ let newCommitIndex = commitIndex ;
129
+ let newCommitLeft = left ;
130
+
131
+ if ( pageX < newCommitLeft ) {
132
+ while ( pageX < newCommitLeft ) {
133
+ newCommitLeft -= sizeIncrement ;
134
+ newCommitIndex -= 1 ;
135
+ }
136
+ } else {
137
+ let newCommitRectRight = newCommitLeft + sizeIncrement ;
138
+ while ( pageX > newCommitRectRight ) {
139
+ newCommitRectRight += sizeIncrement ;
140
+ newCommitIndex += 1 ;
141
+ }
142
+ }
143
+
144
+ if ( newCommitIndex < 0 ) {
145
+ newCommitIndex = 0 ;
146
+ } else if ( newCommitIndex > maxCommitIndex ) {
147
+ newCommitIndex = maxCommitIndex ;
148
+ }
149
+
150
+ selectCommitIndex ( newCommitIndex ) ;
151
+ }
152
+ } ;
153
+
154
+ useEffect ( ( ) => {
155
+ if ( dragState === null ) {
156
+ return ;
157
+ }
158
+
159
+ const element = divRef . current ;
160
+ if ( element !== null ) {
161
+ const ownerDocument = element . ownerDocument ;
162
+ ownerDocument . addEventListener ( 'mousemove' , handleDragCommit ) ;
163
+ return ( ) => {
164
+ ownerDocument . removeEventListener ( 'mousemove' , handleDragCommit ) ;
165
+ } ;
166
+ }
167
+ } , [ dragState ] ) ;
168
+
131
169
// Pass required contextual data down to the ListItem renderer.
132
170
const itemData = useMemo < ItemData > (
133
171
( ) => ( {
134
172
commitDurations,
135
173
commitTimes,
136
174
filteredCommitIndices,
137
- isMouseDown,
138
175
maxDuration,
139
176
selectedCommitIndex,
140
177
selectedFilteredCommitIndex,
141
178
selectCommitIndex,
179
+ startCommitDrag : setDragState ,
142
180
} ) ,
143
181
[
144
182
commitDurations ,
145
183
commitTimes ,
146
184
filteredCommitIndices ,
147
- isMouseDown ,
148
185
maxDuration ,
149
186
selectedCommitIndex ,
150
187
selectedFilteredCommitIndex ,
@@ -153,11 +190,7 @@ function List({
153
190
) ;
154
191
155
192
return (
156
- < div
157
- onMouseDown = { handleMouseDown }
158
- onMouseUp = { handleMouseUp }
159
- ref = { divRef }
160
- style = { { height, width} } >
193
+ < div ref = { divRef } style = { { height, width} } >
161
194
< FixedSizeList
162
195
className = { styles . List }
163
196
layout = "horizontal"
0 commit comments