1+ import { createResource , createSignal , For , Show , Suspense , type VoidComponent } from 'solid-js'
2+ import { createStore } from 'solid-js/store'
13import clsx from 'clsx'
2- import { createResource , createSignal , For , Show , Suspense } from 'solid-js'
3- import type { VoidComponent } from 'solid-js'
44
5+ import { takeSnapshot } from '~/api/athena'
56import { getDevice , SHARED_DEVICE } from '~/api/devices'
6- import { ATHENA_URL } from '~/api/config'
7- import { getAccessToken } from '~/api/auth/client'
8-
97import { DrawerToggleButton , useDrawerContext } from '~/components/material/Drawer'
108import Icon from '~/components/material/Icon'
119import IconButton from '~/components/material/IconButton'
1210import TopAppBar from '~/components/material/TopAppBar'
1311import DeviceLocation from '~/components/DeviceLocation'
1412import DeviceStatistics from '~/components/DeviceStatistics'
13+ import UploadQueue from '~/components/UploadQueue'
1514import { deviceIsOnline , getDeviceName } from '~/utils/device'
1615
1716import RouteList from '../components/RouteList'
18- import UploadQueue from '~/components/UploadQueue'
1917
2018type DeviceActivityProps = {
2119 dongleId : string
2220}
2321
24- interface SnapshotResponse {
25- result ?: {
26- jpegFront ?: string
27- jpegBack ?: string
28- }
29- }
30-
3122const DeviceActivity : VoidComponent < DeviceActivityProps > = ( props ) => {
3223 // TODO: device should be passed in from DeviceList
3324 const [ device ] = createResource ( ( ) => props . dongleId , getDevice )
@@ -36,7 +27,7 @@ const DeviceActivity: VoidComponent<DeviceActivityProps> = (props) => {
3627 // TODO: remove this. if we're listing the routes for a device you should always be a user, this is for viewing public routes which are being removed
3728 const isDeviceUser = ( ) => ( device . loading ? true : device . latest ?. is_owner || device . latest ?. alias !== SHARED_DEVICE )
3829 const [ queueVisible , setQueueVisible ] = createSignal ( false )
39- const [ snapshot , setSnapshot ] = createSignal < {
30+ const [ snapshot , setSnapshot ] = createStore < {
4031 error : string | null
4132 fetching : boolean
4233 images : string [ ]
@@ -46,37 +37,13 @@ const DeviceActivity: VoidComponent<DeviceActivityProps> = (props) => {
4637 images : [ ] ,
4738 } )
4839
49- const takeSnapshot = async ( ) => {
50- setSnapshot ( { error : null , fetching : true , images : [ ] } )
51-
40+ const onClickSnapshot = async ( ) => {
41+ setSnapshot ( { error : null , fetching : true } )
5242 try {
53- const payload = {
54- method : 'takeSnapshot' ,
55- jsonrpc : '2.0' ,
56- id : 0 ,
57- }
58-
59- const response = await fetch ( `${ ATHENA_URL } /${ props . dongleId } ` , {
60- method : 'POST' ,
61- headers : {
62- 'Content-Type' : 'application/json' ,
63- Authorization : `JWT ${ getAccessToken ( ) } ` ,
64- } ,
65- body : JSON . stringify ( payload ) ,
66- } )
67-
68- if ( ! response . ok ) {
69- throw new Error ( `HTTP error! status: ${ response . status } ` )
70- }
71-
72- const resp : SnapshotResponse = ( await response . json ( ) ) as SnapshotResponse
73- const images = [ ]
74-
75- if ( resp . result ?. jpegFront ) images . push ( resp . result . jpegFront )
76- if ( resp . result ?. jpegBack ) images . push ( resp . result . jpegBack )
77-
43+ const resp = await takeSnapshot ( props . dongleId )
44+ const images = [ resp . result ?. jpegFront , resp . result ?. jpegBack ] . filter ( ( it ) => it !== undefined )
7845 if ( images . length > 0 ) {
79- setSnapshot ( { error : null , fetching : false , images } )
46+ setSnapshot ( 'images' , images )
8047 } else {
8148 throw new Error ( 'No images found.' )
8249 }
@@ -85,7 +52,9 @@ const DeviceActivity: VoidComponent<DeviceActivityProps> = (props) => {
8552 if ( error . includes ( 'Device not registered' ) ) {
8653 error = 'Device offline'
8754 }
88- setSnapshot ( { error, fetching : false , images : [ ] } )
55+ setSnapshot ( 'error' , error )
56+ } finally {
57+ setSnapshot ( 'fetching' , false )
8958 }
9059 }
9160
@@ -99,13 +68,11 @@ const DeviceActivity: VoidComponent<DeviceActivityProps> = (props) => {
9968 }
10069
10170 const clearImage = ( index : number ) => {
102- const newImages = snapshot ( ) . images . filter ( ( _ , i ) => i !== index )
103- setSnapshot ( { ... snapshot ( ) , images : newImages } )
71+ const newImages = snapshot . images . filter ( ( _ , i ) => i !== index )
72+ setSnapshot ( 'images' , newImages )
10473 }
10574
106- const clearError = ( ) => {
107- setSnapshot ( { ...snapshot ( ) , error : null } )
108- }
75+ const clearError = ( ) => setSnapshot ( 'error' , null )
10976
11077 const { modal } = useDrawerContext ( )
11178
@@ -140,7 +107,7 @@ const DeviceActivity: VoidComponent<DeviceActivityProps> = (props) => {
140107 </ div >
141108 </ Suspense >
142109 < div class = "flex gap-4" >
143- < IconButton name = "camera" onClick = { ( ) => void takeSnapshot ( ) } />
110+ < IconButton name = "camera" onClick = { onClickSnapshot } />
144111 < IconButton name = "settings" href = { `/${ props . dongleId } /settings` } />
145112 </ div >
146113 </ div >
@@ -162,7 +129,7 @@ const DeviceActivity: VoidComponent<DeviceActivityProps> = (props) => {
162129 </ Show >
163130 </ div >
164131 < div class = "flex flex-col gap-2" >
165- < For each = { snapshot ( ) . images } >
132+ < For each = { snapshot . images } >
166133 { ( image , index ) => (
167134 < div class = "flex-1 overflow-hidden rounded-lg bg-surface-container-low" >
168135 < div class = "relative p-4" >
@@ -175,21 +142,21 @@ const DeviceActivity: VoidComponent<DeviceActivityProps> = (props) => {
175142 </ div >
176143 ) }
177144 </ For >
178- { snapshot ( ) . fetching && (
145+ < Show when = { snapshot . fetching } >
179146 < div class = "flex-1 overflow-hidden rounded-lg bg-surface-container-low" >
180147 < div class = "p-4" >
181148 < div > Loading snapshots...</ div >
182149 </ div >
183150 </ div >
184- ) }
185- { snapshot ( ) . error && (
151+ </ Show >
152+ < Show when = { snapshot . error } >
186153 < div class = "flex-1 overflow-hidden rounded-lg bg-surface-container-low" >
187154 < div class = "flex items-center p-4" >
188155 < IconButton class = "text-white" name = "clear" onClick = { clearError } />
189- < span > Error: { snapshot ( ) . error } </ span >
156+ < span > Error: { snapshot . error } </ span >
190157 </ div >
191158 </ div >
192- ) }
159+ </ Show >
193160 </ div >
194161 < RouteList dongleId = { props . dongleId } />
195162 </ div >
0 commit comments