mirror of
https://github.com/azaion/ui.git
synced 2026-06-21 06:51:10 +00:00
82 lines
2.4 KiB
TypeScript
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>
|
|
)
|
|
}
|