mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-10 13:15:25 +03:00
Make it so motion persists the selected time
This commit is contained in:
parent
f5c01b7926
commit
2f20f5891a
@ -16,6 +16,7 @@ type PreviewVideoPlayerProps = {
|
|||||||
camera: string;
|
camera: string;
|
||||||
timeRange: { start: number; end: number };
|
timeRange: { start: number; end: number };
|
||||||
cameraPreviews: Preview[];
|
cameraPreviews: Preview[];
|
||||||
|
startTime?: number;
|
||||||
onControllerReady: (controller: PreviewVideoController) => void;
|
onControllerReady: (controller: PreviewVideoController) => void;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
};
|
};
|
||||||
@ -24,6 +25,7 @@ export default function PreviewVideoPlayer({
|
|||||||
camera,
|
camera,
|
||||||
timeRange,
|
timeRange,
|
||||||
cameraPreviews,
|
cameraPreviews,
|
||||||
|
startTime,
|
||||||
onControllerReady,
|
onControllerReady,
|
||||||
onClick,
|
onClick,
|
||||||
}: PreviewVideoPlayerProps) {
|
}: PreviewVideoPlayerProps) {
|
||||||
@ -128,6 +130,10 @@ export default function PreviewVideoPlayer({
|
|||||||
} else {
|
} else {
|
||||||
previewRef.current?.pause();
|
previewRef.current?.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (previewRef.current && startTime && currentPreview) {
|
||||||
|
previewRef.current.currentTime = startTime - currentPreview.start;
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{currentPreview != undefined && (
|
{currentPreview != undefined && (
|
||||||
|
|||||||
@ -31,6 +31,7 @@ export default function Events() {
|
|||||||
"alert",
|
"alert",
|
||||||
);
|
);
|
||||||
const [selectedReviewId, setSelectedReviewId] = useOverlayState("review");
|
const [selectedReviewId, setSelectedReviewId] = useOverlayState("review");
|
||||||
|
const [startTime, setStartTime] = useState<number>();
|
||||||
|
|
||||||
// review filter
|
// review filter
|
||||||
|
|
||||||
@ -221,11 +222,13 @@ export default function Events() {
|
|||||||
|
|
||||||
if (selectedReviewId.startsWith("motion")) {
|
if (selectedReviewId.startsWith("motion")) {
|
||||||
const motionData = selectedReviewId.split(",");
|
const motionData = selectedReviewId.split(",");
|
||||||
|
const motionStart = parseFloat(motionData[2]);
|
||||||
|
setStartTime(motionStart);
|
||||||
// format is motion,camera,start_time
|
// format is motion,camera,start_time
|
||||||
return {
|
return {
|
||||||
camera: motionData[1],
|
camera: motionData[1],
|
||||||
severity: "significant_motion" as ReviewSeverity,
|
severity: "significant_motion" as ReviewSeverity,
|
||||||
start_time: parseFloat(motionData[2]),
|
start_time: motionStart,
|
||||||
allCameras: allCameras,
|
allCameras: allCameras,
|
||||||
cameraSegments: reviews.filter((seg) =>
|
cameraSegments: reviews.filter((seg) =>
|
||||||
allCameras.includes(seg.camera),
|
allCameras.includes(seg.camera),
|
||||||
@ -292,6 +295,7 @@ export default function Events() {
|
|||||||
timeRange={selectedTimeRange}
|
timeRange={selectedTimeRange}
|
||||||
filter={reviewFilter}
|
filter={reviewFilter}
|
||||||
severity={severity ?? "alert"}
|
severity={severity ?? "alert"}
|
||||||
|
startTime={startTime}
|
||||||
setSeverity={setSeverity}
|
setSeverity={setSeverity}
|
||||||
markItemAsReviewed={markItemAsReviewed}
|
markItemAsReviewed={markItemAsReviewed}
|
||||||
onOpenReview={setSelectedReviewId}
|
onOpenReview={setSelectedReviewId}
|
||||||
|
|||||||
@ -44,6 +44,7 @@ type EventViewProps = {
|
|||||||
timeRange: { before: number; after: number };
|
timeRange: { before: number; after: number };
|
||||||
filter?: ReviewFilter;
|
filter?: ReviewFilter;
|
||||||
severity: ReviewSeverity;
|
severity: ReviewSeverity;
|
||||||
|
startTime?: number;
|
||||||
setSeverity: (severity: ReviewSeverity) => void;
|
setSeverity: (severity: ReviewSeverity) => void;
|
||||||
markItemAsReviewed: (review: ReviewSegment) => void;
|
markItemAsReviewed: (review: ReviewSegment) => void;
|
||||||
onOpenReview: (reviewId: string) => void;
|
onOpenReview: (reviewId: string) => void;
|
||||||
@ -57,6 +58,7 @@ export default function EventView({
|
|||||||
timeRange,
|
timeRange,
|
||||||
filter,
|
filter,
|
||||||
severity,
|
severity,
|
||||||
|
startTime,
|
||||||
setSeverity,
|
setSeverity,
|
||||||
markItemAsReviewed,
|
markItemAsReviewed,
|
||||||
onOpenReview,
|
onOpenReview,
|
||||||
@ -262,6 +264,7 @@ export default function EventView({
|
|||||||
reviewItems={reviewItems}
|
reviewItems={reviewItems}
|
||||||
relevantPreviews={relevantPreviews}
|
relevantPreviews={relevantPreviews}
|
||||||
timeRange={timeRange}
|
timeRange={timeRange}
|
||||||
|
startTime={startTime}
|
||||||
filter={filter}
|
filter={filter}
|
||||||
onSelectReview={onSelectReview}
|
onSelectReview={onSelectReview}
|
||||||
/>
|
/>
|
||||||
@ -518,6 +521,7 @@ type MotionReviewProps = {
|
|||||||
};
|
};
|
||||||
relevantPreviews?: Preview[];
|
relevantPreviews?: Preview[];
|
||||||
timeRange: { before: number; after: number };
|
timeRange: { before: number; after: number };
|
||||||
|
startTime?: number;
|
||||||
filter?: ReviewFilter;
|
filter?: ReviewFilter;
|
||||||
onSelectReview: (data: string, ctrl: boolean) => void;
|
onSelectReview: (data: string, ctrl: boolean) => void;
|
||||||
};
|
};
|
||||||
@ -526,6 +530,7 @@ function MotionReview({
|
|||||||
reviewItems,
|
reviewItems,
|
||||||
relevantPreviews,
|
relevantPreviews,
|
||||||
timeRange,
|
timeRange,
|
||||||
|
startTime,
|
||||||
filter,
|
filter,
|
||||||
onSelectReview,
|
onSelectReview,
|
||||||
}: MotionReviewProps) {
|
}: MotionReviewProps) {
|
||||||
@ -579,11 +584,21 @@ function MotionReview({
|
|||||||
[lastFullHour, timeRange],
|
[lastFullHour, timeRange],
|
||||||
);
|
);
|
||||||
|
|
||||||
const [selectedRangeIdx, setSelectedRangeIdx] = useState(
|
const initialIndex = useMemo(() => {
|
||||||
timeRangeSegments.ranges.length - 1,
|
if (!startTime) {
|
||||||
|
return timeRangeSegments.ranges.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return timeRangeSegments.ranges.findIndex(
|
||||||
|
(seg) => seg.start <= startTime && seg.end >= startTime,
|
||||||
);
|
);
|
||||||
|
// only render once
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const [selectedRangeIdx, setSelectedRangeIdx] = useState(initialIndex);
|
||||||
const [currentTime, setCurrentTime] = useState<number>(
|
const [currentTime, setCurrentTime] = useState<number>(
|
||||||
timeRangeSegments.ranges[selectedRangeIdx].start,
|
startTime ?? timeRangeSegments.ranges[selectedRangeIdx].start,
|
||||||
);
|
);
|
||||||
const currentTimeRange = useMemo(
|
const currentTimeRange = useMemo(
|
||||||
() => timeRangeSegments.ranges[selectedRangeIdx],
|
() => timeRangeSegments.ranges[selectedRangeIdx],
|
||||||
@ -642,6 +657,7 @@ function MotionReview({
|
|||||||
className={`${grow}`}
|
className={`${grow}`}
|
||||||
camera={camera.name}
|
camera={camera.name}
|
||||||
timeRange={currentTimeRange}
|
timeRange={currentTimeRange}
|
||||||
|
startTime={startTime}
|
||||||
cameraPreviews={relevantPreviews || []}
|
cameraPreviews={relevantPreviews || []}
|
||||||
onControllerReady={(controller) => {
|
onControllerReady={(controller) => {
|
||||||
videoPlayersRef.current[camera.name] = controller;
|
videoPlayersRef.current[camera.name] = controller;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user