1- import { For , createResource , createSignal , createEffect , createMemo , Show , Suspense , onMount , onCleanup } from 'solid-js'
2- import type { VoidComponent , Accessor } from 'solid-js'
1+ import { For , createResource , createSignal , createEffect , onMount , onCleanup , Suspense } from 'solid-js'
2+ import type { VoidComponent } from 'solid-js'
33import clsx from 'clsx'
44
55import { TimelineEvent , getTimelineEvents } from '~/api/derived'
66import type { Route } from '~/types'
77import { getRouteDuration } from '~/utils/format'
88
9- function renderTimelineEvents ( route : Route , events : TimelineEvent [ ] ) {
9+ function renderTimelineEvents ( route : Route | undefined , events : TimelineEvent [ ] ) {
10+ if ( ! route ) return
1011 const duration = getRouteDuration ( route ) ?. asMilliseconds ( ) ?? 0
1112 return (
1213 < For each = { events } >
@@ -90,17 +91,17 @@ const MARKER_WIDTH = 3
9091
9192interface TimelineProps {
9293 class ?: string
93- routeName : string
94- route : Accessor < Route | undefined >
95- seekTime : Accessor < number >
96- updateTime : ( newTime : number ) => void
94+ route ?: Route
95+ seekTime : number
96+ updateTime : ( time : number ) => void
9797}
9898
9999const Timeline : VoidComponent < TimelineProps > = ( props ) => {
100- const [ events ] = createResource ( props . route , getTimelineEvents )
100+ const route = ( ) => props . route
101+ const [ events ] = createResource ( route , getTimelineEvents , { initialValue : [ ] } )
101102 // TODO: align to first camera frame event
102103 const [ markerOffsetPct , setMarkerOffsetPct ] = createSignal ( 0 )
103- const duration = createMemo ( ( ) => ( props . route ( ) ? ( getRouteDuration ( props . route ( ) ! ) ?. asSeconds ( ) ?? 0 ) : 0 ) )
104+ const [ duration ] = createResource ( route , ( route ) => getRouteDuration ( route ) ?. asSeconds ( ) ?? 0 , { initialValue : 0 } )
104105
105106 let ref ! : HTMLDivElement
106107
@@ -134,13 +135,13 @@ const Timeline: VoidComponent<TimelineProps> = (props) => {
134135 }
135136
136137 const onMouseDown = ( ev : MouseEvent ) => {
137- if ( ! props . route ( ) ) return
138+ if ( ! props . route ) return
138139 updateMarker ( ev . clientX )
139140 onStart ( )
140141 }
141142
142143 const onTouchStart = ( ev : TouchEvent ) => {
143- if ( ev . touches . length !== 1 || ! props . route ( ) ) return
144+ if ( ev . touches . length !== 1 || ! props . route ) return
144145 updateMarker ( ev . touches [ 0 ] . clientX )
145146 onStart ( )
146147 }
@@ -154,7 +155,7 @@ const Timeline: VoidComponent<TimelineProps> = (props) => {
154155 } )
155156
156157 createEffect ( ( ) => {
157- setMarkerOffsetPct ( ( props . seekTime ( ) / duration ( ) ) * 100 )
158+ setMarkerOffsetPct ( ( props . seekTime / duration ( ) ) * 100 )
158159 } )
159160
160161 return (
@@ -167,25 +168,15 @@ const Timeline: VoidComponent<TimelineProps> = (props) => {
167168 ) }
168169 title = "Disengaged"
169170 >
170- < Suspense fallback = { < div class = "skeleton-loader size-full" /> } >
171- < Show when = { props . route ( ) } keyed >
172- { ( route ) => (
173- < >
174- < Show when = { events ( ) } keyed >
175- { ( events ) => renderTimelineEvents ( route , events ) }
176- </ Show >
177- < div
178- class = "absolute top-0 z-10 h-full"
179- style = { {
180- 'background-color' : 'rgba(255,255,255,0.7)' ,
181- width : `${ MARKER_WIDTH } px` ,
182- left : `${ markerOffsetPct ( ) } %` ,
183- } }
184- />
185- </ >
186- ) }
187- </ Show >
188- </ Suspense >
171+ < Suspense fallback = { < div class = "skeleton-loader size-full" > </ div > } > { renderTimelineEvents ( props . route , events ( ) ) } </ Suspense >
172+ < div
173+ class = "absolute top-0 z-10 h-full"
174+ style = { {
175+ 'background-color' : 'rgba(255,255,255,0.7)' ,
176+ width : `${ MARKER_WIDTH } px` ,
177+ left : `${ markerOffsetPct ( ) } %` ,
178+ } }
179+ />
189180 </ div >
190181 )
191182}
0 commit comments