Files
ui/src/components/SavedAnnotationsContext.tsx
T

82 lines
2.4 KiB
TypeScript

import { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from 'react'
import { AnnotationSource, AnnotationStatus } from '../types'
import type { Detection } from '../types'
export interface SavedDetection {
id: string
annotationLocalId: string
mediaId: string
mediaName: string
thumbnail: string
fullFrame: string
status: AnnotationStatus
source: AnnotationSource
createdDate: string
detection: Detection
time: string | null
flightId: string | null
}
interface SavedAnnotationsState {
saved: SavedDetection[]
addMany: (items: SavedDetection[]) => void
replaceGroup: (annotationLocalId: string, items: SavedDetection[]) => void
updateStatus: (ids: string[], status: AnnotationStatus) => void
removeSaved: (id: string) => void
clear: () => void
}
const STORAGE_KEY = 'az.savedAnnotations.v2'
const SavedAnnotationsContext = createContext<SavedAnnotationsState>(null!)
export function useSavedAnnotations() {
return useContext(SavedAnnotationsContext)
}
export function SavedAnnotationsProvider({ children }: { children: ReactNode }) {
const [saved, setSaved] = useState<SavedDetection[]>(() => {
try {
const raw = localStorage.getItem(STORAGE_KEY)
return raw ? (JSON.parse(raw) as SavedDetection[]) : []
} catch {
return []
}
})
useEffect(() => {
try { localStorage.setItem(STORAGE_KEY, JSON.stringify(saved)) } catch {}
}, [saved])
const addMany = useCallback((items: SavedDetection[]) => {
if (!items.length) return
const ids = new Set(items.map(i => i.id))
setSaved(prev => [...items, ...prev.filter(x => !ids.has(x.id))])
}, [])
const replaceGroup = useCallback((annotationLocalId: string, items: SavedDetection[]) => {
setSaved(prev => [
...items,
...prev.filter(x => x.annotationLocalId !== annotationLocalId),
])
}, [])
const updateStatus = useCallback((ids: string[], status: AnnotationStatus) => {
if (!ids.length) return
const idSet = new Set(ids)
setSaved(prev => prev.map(x => idSet.has(x.id) ? { ...x, status } : x))
}, [])
const removeSaved = useCallback((id: string) => {
setSaved(prev => prev.filter(x => x.id !== id))
}, [])
const clear = useCallback(() => setSaved([]), [])
return (
<SavedAnnotationsContext.Provider value={{ saved, addMany, replaceGroup, updateStatus, removeSaved, clear }}>
{children}
</SavedAnnotationsContext.Provider>
)
}