Skip to content

Commit ffdf6d9

Browse files
authored
Add route selection via URL (#485)
partial version of commaai/connect#484
1 parent cc03564 commit ffdf6d9

File tree

3 files changed

+36
-7
lines changed

3 files changed

+36
-7
lines changed

src/components/RouteVideoPlayer.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type Hls from '~/utils/hls'
99
type RouteVideoPlayerProps = {
1010
class?: string
1111
routeName: string
12-
startTime: number
12+
selection: { startTime: number; endTime: number | undefined }
1313
onProgress: (seekTime: number) => void
1414
ref: (el?: HTMLVideoElement) => void
1515
}
@@ -58,6 +58,16 @@ const RouteVideoPlayer: VoidComponent<RouteVideoPlayerProps> = (props) => {
5858

5959
const onTimeUpdate = (e: Event) => {
6060
setCurrentTime((e.currentTarget as HTMLVideoElement).currentTime)
61+
62+
// If there is a selection, loop within it
63+
if (currentTime() < props.selection.startTime) {
64+
video.currentTime = props.selection.startTime
65+
} else if (props.selection.endTime !== undefined) {
66+
if (currentTime() > props.selection.endTime) {
67+
video.currentTime = props.selection.startTime
68+
}
69+
}
70+
6171
if (video.paused) updateProgress()
6272
}
6373
const onLoadedMetadata = () => setDuration(video.duration)
@@ -73,8 +83,8 @@ const RouteVideoPlayer: VoidComponent<RouteVideoPlayerProps> = (props) => {
7383
}
7484

7585
onMount(() => {
76-
if (!Number.isNaN(props.startTime)) {
77-
video.currentTime = props.startTime
86+
if (props.selection.startTime > 0) {
87+
video.currentTime = props.selection.startTime
7888
}
7989

8090
props.ref?.(video)

src/pages/dashboard/Dashboard.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,13 @@ const Dashboard: Component<RouteSectionProps> = () => {
104104
const location = useLocation()
105105
const urlState = createMemo(() => {
106106
const parts = location.pathname.split('/').slice(1).filter(Boolean)
107+
const startTime = parts[2] ? Math.max(Number(parts[2]), 0) : 0
108+
const endTime = parts[3] ? Math.max(Number(parts[3]), startTime + 1) : undefined
107109
return {
108110
dongleId: parts[0] as string | undefined,
109111
dateStr: parts[1] as string | undefined,
110-
startTime: parts[2] ? Number(parts[2]) : 0,
112+
startTime: startTime,
113+
endTime: endTime,
111114
}
112115
})
113116

@@ -146,7 +149,9 @@ const Dashboard: Component<RouteSectionProps> = () => {
146149
<SettingsActivity dongleId={dongleId} />
147150
</Match>
148151
<Match when={urlState().dateStr} keyed>
149-
{(dateStr) => <RouteActivity dongleId={dongleId} dateStr={dateStr} startTime={urlState().startTime} />}
152+
{(dateStr) => (
153+
<RouteActivity dongleId={dongleId} dateStr={dateStr} startTime={urlState().startTime} endTime={urlState().endTime} />
154+
)}
150155
</Match>
151156
</Switch>
152157
}

src/pages/dashboard/activities/RouteActivity.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createEffect, createResource, createSignal, Suspense, type VoidComponent } from 'solid-js'
1+
import { Show, createEffect, createResource, createSignal, Suspense, type VoidComponent } from 'solid-js'
22

33
import { setRouteViewed } from '~/api/athena'
44
import { getDevice } from '~/api/devices'
@@ -15,11 +15,13 @@ import RouteVideoPlayer from '~/components/RouteVideoPlayer'
1515
import RouteUploadButtons from '~/components/RouteUploadButtons'
1616
import Timeline from '~/components/Timeline'
1717
import { generateTimelineStatistics, getTimelineEvents } from '~/api/derived'
18+
import { A } from '@solidjs/router'
1819

1920
type RouteActivityProps = {
2021
dongleId: string
2122
dateStr: string
2223
startTime: number
24+
endTime: number | undefined
2325
}
2426

2527
const RouteActivity: VoidComponent<RouteActivityProps> = (props) => {
@@ -30,6 +32,8 @@ const RouteActivity: VoidComponent<RouteActivityProps> = (props) => {
3032
const [route] = createResource(routeName, getRoute)
3133
const [startTime] = createResource(route, (route) => dayjs(route.start_time)?.format('ddd, MMM D, YYYY'))
3234

35+
const selection = () => ({ startTime: props.startTime, endTime: props.endTime })
36+
3337
// FIXME: generateTimelineStatistics is given different versions of TimelineEvents multiple times, leading to stuttering engaged % on switch
3438
const [events] = createResource(route, getTimelineEvents, { initialValue: [] })
3539
const [timeline] = createResource(
@@ -64,8 +68,18 @@ const RouteActivity: VoidComponent<RouteActivityProps> = (props) => {
6468

6569
<div class="flex flex-col gap-6 px-4 pb-4">
6670
<div class="flex flex-col">
67-
<RouteVideoPlayer ref={setVideoRef} routeName={routeName()} startTime={seekTime()} onProgress={setSeekTime} />
71+
<RouteVideoPlayer ref={setVideoRef} routeName={routeName()} selection={selection()} onProgress={setSeekTime} />
6872
<Timeline class="mb-1" route={route()} seekTime={seekTime()} updateTime={onTimelineChange} events={events()} />
73+
74+
<Show when={selection().startTime || selection().endTime}>
75+
<A
76+
class="flex items-center justify-center text-center text-label-lg text-gray-500 mt-4"
77+
href={`/${props.dongleId}/${props.dateStr}`}
78+
>
79+
Clear current route selection
80+
<IconButton name="close_small" />
81+
</A>
82+
</Show>
6983
</div>
7084

7185
<div class="flex flex-col gap-2">

0 commit comments

Comments
 (0)