mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-04-19 23:08:08 +02:00
Add Detail stream in History view (#20525)
* new type * activity stream panel * use context provider for activity stream * new activity stream panel in history view * overlay for object tracking details in history view * use overlay in video player * don't refetch timeline * fix activity stream group from being highlighted prematurely * use annotation offset * fix scrolling and use custom hook for interaction * memoize to prevent unnecessary renders * i18n and timestamp formatting * add annotation offset slider * bg color * add collapsible component * refactor * rename activity to detail * fix merge conflicts * i18n * more i18n
This commit is contained in:
82
web/src/context/detail-stream-context.tsx
Normal file
82
web/src/context/detail-stream-context.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
import React, { createContext, useContext, useState, useEffect } from "react";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import useSWR from "swr";
|
||||
import { ObjectLifecycleSequence } from "@/types/timeline";
|
||||
|
||||
interface DetailStreamContextType {
|
||||
selectedObjectId: string | undefined;
|
||||
selectedObjectTimeline?: ObjectLifecycleSequence[];
|
||||
currentTime: number;
|
||||
camera: string;
|
||||
annotationOffset: number; // milliseconds
|
||||
setAnnotationOffset: (ms: number) => void;
|
||||
setSelectedObjectId: (id: string | undefined) => void;
|
||||
isDetailMode: boolean;
|
||||
}
|
||||
|
||||
const DetailStreamContext = createContext<DetailStreamContextType | undefined>(
|
||||
undefined,
|
||||
);
|
||||
|
||||
interface DetailStreamProviderProps {
|
||||
children: React.ReactNode;
|
||||
isDetailMode: boolean;
|
||||
currentTime: number;
|
||||
camera: string;
|
||||
}
|
||||
|
||||
export function DetailStreamProvider({
|
||||
children,
|
||||
isDetailMode,
|
||||
currentTime,
|
||||
camera,
|
||||
}: DetailStreamProviderProps) {
|
||||
const [selectedObjectId, setSelectedObjectId] = useState<
|
||||
string | undefined
|
||||
>();
|
||||
|
||||
const { data: selectedObjectTimeline } = useSWR<ObjectLifecycleSequence[]>(
|
||||
selectedObjectId ? ["timeline", { source_id: selectedObjectId }] : null,
|
||||
);
|
||||
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
|
||||
const [annotationOffset, setAnnotationOffset] = useState<number>(() => {
|
||||
if (!config) return 0;
|
||||
return config.cameras[camera]?.detect?.annotation_offset || 0;
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!config) return;
|
||||
const cfgOffset = config.cameras[camera]?.detect?.annotation_offset || 0;
|
||||
setAnnotationOffset(cfgOffset);
|
||||
}, [config, camera]);
|
||||
|
||||
const value: DetailStreamContextType = {
|
||||
selectedObjectId,
|
||||
selectedObjectTimeline,
|
||||
currentTime,
|
||||
camera,
|
||||
annotationOffset,
|
||||
setAnnotationOffset,
|
||||
setSelectedObjectId,
|
||||
isDetailMode,
|
||||
};
|
||||
|
||||
return (
|
||||
<DetailStreamContext.Provider value={value}>
|
||||
{children}
|
||||
</DetailStreamContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
export function useDetailStream() {
|
||||
const context = useContext(DetailStreamContext);
|
||||
if (context === undefined) {
|
||||
throw new Error(
|
||||
"useDetailStream must be used within an DetailStreamProvider",
|
||||
);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
Reference in New Issue
Block a user