4
4
useParams ,
5
5
useNavigate ,
6
6
} from "react-router-dom" ;
7
- import { useCallback , useEffect , useState } from "react" ;
7
+ import { useCallback , useEffect , useState , useRef } from "react" ;
8
8
import { useAtom , useAtomValue } from "jotai" ;
9
9
import { Flow , FullFlow , useTulip } from "../api" ;
10
10
import {
@@ -14,7 +14,7 @@ import {
14
14
END_FILTER_KEY ,
15
15
} from "../App" ;
16
16
17
- import { HeartIcon , FilterIcon } from "@heroicons/react/solid" ;
17
+ import { HeartIcon , FilterIcon , LinkIcon } from "@heroicons/react/solid" ;
18
18
import {
19
19
HeartIcon as EmptyHeartIcon ,
20
20
FilterIcon as EmptyFilterIcon ,
@@ -23,7 +23,7 @@ import {
23
23
import classes from "./FlowList.module.css" ;
24
24
import { format } from "date-fns" ;
25
25
import useDebounce from "../hooks/useDebounce" ;
26
- import { Virtuoso } from "react-virtuoso" ;
26
+ import { Virtuoso , VirtuosoHandle } from "react-virtuoso" ;
27
27
import classNames from "classnames" ;
28
28
import { Tag } from "./Tag" ;
29
29
import { lastRefreshAtom } from "./Header" ;
@@ -36,6 +36,11 @@ export function FlowList() {
36
36
37
37
const [ flowList , setFlowList ] = useState < Flow [ ] > ( [ ] ) ;
38
38
39
+ // Set default flowIndex to Infinity, so that initialTopMostItemIndex != 0 and therefore scrolledToInitialItem != true
40
+ const [ flowIndex , setFlowIndex ] = useState < number > ( Infinity ) ;
41
+
42
+ const virtuoso = useRef < VirtuosoHandle > ( null ) ;
43
+
39
44
const service_name = searchParams . get ( SERVICE_FILTER_KEY ) ?? "" ;
40
45
const service = services . find ( ( s ) => s . name == service_name ) ;
41
46
@@ -73,8 +78,13 @@ export function FlowList() {
73
78
service : "" , // FIXME
74
79
tags : selectedTags ,
75
80
} ) ;
81
+ data . forEach ( ( flow , index ) => {
82
+ if ( flow . _id . $oid === params . id ) { setFlowIndex ( index ) }
83
+ } )
84
+
76
85
setFlowList ( data ) ;
77
86
setLoading ( false ) ;
87
+
78
88
} ;
79
89
fetchData ( ) . catch ( console . error ) ;
80
90
} , [
@@ -84,12 +94,14 @@ export function FlowList() {
84
94
to_filter ,
85
95
selectedTags ,
86
96
lastRefresh ,
97
+ params ,
98
+ virtuoso
87
99
] ) ;
88
100
89
101
const onHeartHandler = useCallback ( async ( flow : Flow ) => {
90
- await api . starFlow ( flow . _id . $oid , ! flow . starred ) ;
102
+ await api . starFlow ( flow . _id . $oid , ! flow . tags . includes ( " starred" ) ) ;
91
103
// optimistic update
92
- const newFlow = { ...flow , starred : ! flow . starred } ;
104
+ const newFlow = { ...flow } ;
93
105
setFlowList ( ( prev ) =>
94
106
prev . map ( ( f ) => ( f . _id . $oid === flow . _id . $oid ? newFlow : f ) )
95
107
) ;
@@ -147,6 +159,8 @@ export function FlowList() {
147
159
"sidebar-loading" : loading ,
148
160
} ) }
149
161
data = { flowList }
162
+ ref = { virtuoso }
163
+ initialTopMostItemIndex = { flowIndex }
150
164
itemContent = { ( index , flow ) => (
151
165
< Link
152
166
to = { `/flow/${ flow . _id . $oid } ?${ searchParams } ` }
@@ -178,15 +192,14 @@ function FlowListEntry({ flow, isActive, onHeartClick }: FlowListEntryProps) {
178
192
179
193
const isStarred = flow . tags . includes ( "starred" ) ;
180
194
// Filter tag list for tags that are handled specially
181
- const filtered_tag_list = flow . tags . filter ( ( t ) => ! [ "starred" ] . includes ( t ) ) ;
195
+ const filtered_tag_list = flow . tags . filter ( ( t ) => t != "starred" ) ;
182
196
183
197
const duration =
184
198
flow . duration > 10000 ? (
185
199
< div className = "text-red-500" > >10s</ div >
186
200
) : (
187
201
< div > { flow . duration } ms</ div >
188
202
) ;
189
-
190
203
return (
191
204
< li
192
205
className = { classNames ( {
@@ -195,17 +208,23 @@ function FlowListEntry({ flow, isActive, onHeartClick }: FlowListEntryProps) {
195
208
>
196
209
< div className = "flex" >
197
210
< div
198
- className = "w-5 ml-2 mr-4 self-center shrink-0"
211
+ className = "w-5 ml-1 mr-1 self-center shrink-0"
199
212
onClick = { ( ) => {
200
213
onHeartClick ( flow ) ;
201
214
} }
202
215
>
203
- { flow . starred ? (
216
+ { flow . tags . includes ( " starred" ) ? (
204
217
< HeartIcon className = "text-red-500" />
205
218
) : (
206
219
< EmptyHeartIcon />
207
220
) }
208
221
</ div >
222
+
223
+ < div className = "w-5 mr-2 self-center shrink-0" >
224
+ { flow . child_id . $oid != "000000000000000000000000" || flow . parent_id . $oid != "000000000000000000000000" ? (
225
+ < LinkIcon className = "text-blue-500" />
226
+ ) : undefined }
227
+ </ div >
209
228
< div className = "flex-1 shrink" >
210
229
< div className = "flex" >
211
230
< div className = "shrink-0" >
0 commit comments