mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Persist show reviewed locally so it maintains state (#12560)
* Persist show reviewed locally so it maintains state * fix * Theming fixes
This commit is contained in:
parent
68e6ffdfef
commit
524f03a650
@ -55,6 +55,8 @@ type ReviewFilterGroupProps = {
|
|||||||
filter?: ReviewFilter;
|
filter?: ReviewFilter;
|
||||||
motionOnly: boolean;
|
motionOnly: boolean;
|
||||||
filterList?: FilterList;
|
filterList?: FilterList;
|
||||||
|
showReviewed: boolean;
|
||||||
|
setShowReviewed: (show: boolean) => void;
|
||||||
onUpdateFilter: (filter: ReviewFilter) => void;
|
onUpdateFilter: (filter: ReviewFilter) => void;
|
||||||
setMotionOnly: React.Dispatch<React.SetStateAction<boolean>>;
|
setMotionOnly: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
};
|
};
|
||||||
@ -66,6 +68,8 @@ export default function ReviewFilterGroup({
|
|||||||
filter,
|
filter,
|
||||||
motionOnly,
|
motionOnly,
|
||||||
filterList,
|
filterList,
|
||||||
|
showReviewed,
|
||||||
|
setShowReviewed,
|
||||||
onUpdateFilter,
|
onUpdateFilter,
|
||||||
setMotionOnly,
|
setMotionOnly,
|
||||||
}: ReviewFilterGroupProps) {
|
}: ReviewFilterGroupProps) {
|
||||||
@ -190,10 +194,8 @@ export default function ReviewFilterGroup({
|
|||||||
)}
|
)}
|
||||||
{filters.includes("reviewed") && (
|
{filters.includes("reviewed") && (
|
||||||
<ShowReviewFilter
|
<ShowReviewFilter
|
||||||
showReviewed={filter?.showReviewed || 0}
|
showReviewed={showReviewed}
|
||||||
setShowReviewed={(reviewed) =>
|
setShowReviewed={setShowReviewed}
|
||||||
onUpdateFilter({ ...filter, showReviewed: reviewed })
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{isDesktop && filters.includes("date") && (
|
{isDesktop && filters.includes("date") && (
|
||||||
@ -418,8 +420,8 @@ export function CamerasFilterButton({
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ShowReviewedFilterProps = {
|
type ShowReviewedFilterProps = {
|
||||||
showReviewed?: 0 | 1;
|
showReviewed: boolean;
|
||||||
setShowReviewed: (reviewed?: 0 | 1) => void;
|
setShowReviewed: (reviewed: boolean) => void;
|
||||||
};
|
};
|
||||||
function ShowReviewFilter({
|
function ShowReviewFilter({
|
||||||
showReviewed,
|
showReviewed,
|
||||||
@ -434,9 +436,9 @@ function ShowReviewFilter({
|
|||||||
<div className="hidden h-9 cursor-pointer items-center justify-start rounded-md bg-secondary p-2 text-sm hover:bg-secondary/80 md:flex">
|
<div className="hidden h-9 cursor-pointer items-center justify-start rounded-md bg-secondary p-2 text-sm hover:bg-secondary/80 md:flex">
|
||||||
<Switch
|
<Switch
|
||||||
id="reviewed"
|
id="reviewed"
|
||||||
checked={showReviewedSwitch == 1}
|
checked={showReviewedSwitch}
|
||||||
onCheckedChange={() =>
|
onCheckedChange={() =>
|
||||||
setShowReviewedSwitch(showReviewedSwitch == 0 ? 1 : 0)
|
setShowReviewedSwitch(showReviewedSwitch == false ? true : false)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Label className="ml-2 cursor-pointer text-primary" htmlFor="reviewed">
|
<Label className="ml-2 cursor-pointer text-primary" htmlFor="reviewed">
|
||||||
@ -446,12 +448,14 @@ function ShowReviewFilter({
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
className="block duration-0 md:hidden"
|
className="block duration-0 md:hidden"
|
||||||
variant={showReviewedSwitch == 1 ? "select" : "default"}
|
variant={showReviewedSwitch ? "select" : "default"}
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => setShowReviewedSwitch(showReviewedSwitch == 0 ? 1 : 0)}
|
onClick={() =>
|
||||||
|
setShowReviewedSwitch(showReviewedSwitch == false ? true : false)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<FaCheckCircle
|
<FaCheckCircle
|
||||||
className={`${showReviewedSwitch == 1 ? "text-selected-foreground" : "text-secondary-foreground"}`}
|
className={`${showReviewedSwitch ? "text-selected-foreground" : "text-secondary-foreground"}`}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
|
@ -328,7 +328,7 @@ function PreviewVideoPlayer({
|
|||||||
)}
|
)}
|
||||||
</video>
|
</video>
|
||||||
{cameraPreviews && !currentPreview && (
|
{cameraPreviews && !currentPreview && (
|
||||||
<div className="absolute inset-0 flex items-center justify-center rounded-lg bg-background_alt text-primary md:rounded-2xl">
|
<div className="absolute inset-0 flex items-center justify-center rounded-lg bg-background_alt text-primary dark:bg-black md:rounded-2xl">
|
||||||
No Preview Found for {camera.replaceAll("_", " ")}
|
No Preview Found for {camera.replaceAll("_", " ")}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -547,7 +547,7 @@ function PreviewFramesPlayer({
|
|||||||
onLoad={onImageLoaded}
|
onLoad={onImageLoaded}
|
||||||
/>
|
/>
|
||||||
{previewFrames?.length === 0 && (
|
{previewFrames?.length === 0 && (
|
||||||
<div className="-y-translate-1/2 align-center absolute inset-x-0 top-1/2 rounded-lg bg-background_alt text-center text-primary md:rounded-2xl">
|
<div className="-y-translate-1/2 align-center absolute inset-x-0 top-1/2 rounded-lg bg-background_alt text-center text-primary dark:bg-black md:rounded-2xl">
|
||||||
No Preview Found for {camera.replaceAll("_", " ")}
|
No Preview Found for {camera.replaceAll("_", " ")}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -3,6 +3,7 @@ import useApiFilter from "@/hooks/use-api-filter";
|
|||||||
import { useCameraPreviews } from "@/hooks/use-camera-previews";
|
import { useCameraPreviews } from "@/hooks/use-camera-previews";
|
||||||
import { useTimezone } from "@/hooks/use-date-utils";
|
import { useTimezone } from "@/hooks/use-date-utils";
|
||||||
import { useOverlayState, useSearchEffect } from "@/hooks/use-overlay-state";
|
import { useOverlayState, useSearchEffect } from "@/hooks/use-overlay-state";
|
||||||
|
import { usePersistence } from "@/hooks/use-persistence";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import { RecordingStartingPoint } from "@/types/record";
|
import { RecordingStartingPoint } from "@/types/record";
|
||||||
import {
|
import {
|
||||||
@ -32,6 +33,8 @@ export default function Events() {
|
|||||||
"alert",
|
"alert",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [showReviewed, setShowReviewed] = usePersistence("showReviewed", false);
|
||||||
|
|
||||||
const [recording, setRecording] =
|
const [recording, setRecording] =
|
||||||
useOverlayState<RecordingStartingPoint>("recording");
|
useOverlayState<RecordingStartingPoint>("recording");
|
||||||
|
|
||||||
@ -206,14 +209,14 @@ export default function Events() {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reviewFilter?.showReviewed != 1) {
|
if (!showReviewed) {
|
||||||
return current.filter((seg) => !seg.has_been_reviewed);
|
return current.filter((seg) => !seg.has_been_reviewed);
|
||||||
} else {
|
} else {
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
// only refresh when severity or filter changes
|
// only refresh when severity or filter changes
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [severity, reviewFilter, reviewItems?.all.length]);
|
}, [severity, reviewFilter, showReviewed, reviewItems?.all.length]);
|
||||||
|
|
||||||
// review summary
|
// review summary
|
||||||
|
|
||||||
@ -436,6 +439,8 @@ export default function Events() {
|
|||||||
filter={reviewFilter}
|
filter={reviewFilter}
|
||||||
severity={severity ?? "alert"}
|
severity={severity ?? "alert"}
|
||||||
startTime={startTime}
|
startTime={startTime}
|
||||||
|
showReviewed={showReviewed ?? false}
|
||||||
|
setShowReviewed={setShowReviewed}
|
||||||
setSeverity={setSeverity}
|
setSeverity={setSeverity}
|
||||||
markItemAsReviewed={markItemAsReviewed}
|
markItemAsReviewed={markItemAsReviewed}
|
||||||
markAllItemsAsReviewed={markAllItemsAsReviewed}
|
markAllItemsAsReviewed={markAllItemsAsReviewed}
|
||||||
|
@ -35,7 +35,6 @@ export type ReviewFilter = {
|
|||||||
zones?: string[];
|
zones?: string[];
|
||||||
before?: number;
|
before?: number;
|
||||||
after?: number;
|
after?: number;
|
||||||
showReviewed?: 0 | 1;
|
|
||||||
showAll?: boolean;
|
showAll?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -62,6 +62,8 @@ type EventViewProps = {
|
|||||||
filter?: ReviewFilter;
|
filter?: ReviewFilter;
|
||||||
severity: ReviewSeverity;
|
severity: ReviewSeverity;
|
||||||
startTime?: number;
|
startTime?: number;
|
||||||
|
showReviewed: boolean;
|
||||||
|
setShowReviewed: (show: boolean) => void;
|
||||||
setSeverity: (severity: ReviewSeverity) => void;
|
setSeverity: (severity: ReviewSeverity) => void;
|
||||||
markItemAsReviewed: (review: ReviewSegment) => void;
|
markItemAsReviewed: (review: ReviewSegment) => void;
|
||||||
markAllItemsAsReviewed: (currentItems: ReviewSegment[]) => void;
|
markAllItemsAsReviewed: (currentItems: ReviewSegment[]) => void;
|
||||||
@ -78,6 +80,8 @@ export default function EventView({
|
|||||||
filter,
|
filter,
|
||||||
severity,
|
severity,
|
||||||
startTime,
|
startTime,
|
||||||
|
showReviewed,
|
||||||
|
setShowReviewed,
|
||||||
setSeverity,
|
setSeverity,
|
||||||
markItemAsReviewed,
|
markItemAsReviewed,
|
||||||
markAllItemsAsReviewed,
|
markAllItemsAsReviewed,
|
||||||
@ -108,7 +112,7 @@ export default function EventView({
|
|||||||
return { alert: 0, detection: 0, significant_motion: 0 };
|
return { alert: 0, detection: 0, significant_motion: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter?.showReviewed == 1) {
|
if (showReviewed) {
|
||||||
return {
|
return {
|
||||||
alert: summary.total_alert ?? 0,
|
alert: summary.total_alert ?? 0,
|
||||||
detection: summary.total_detection ?? 0,
|
detection: summary.total_detection ?? 0,
|
||||||
@ -121,7 +125,7 @@ export default function EventView({
|
|||||||
significant_motion: summary.total_motion - summary.reviewed_motion,
|
significant_motion: summary.total_motion - summary.reviewed_motion,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, [filter, reviewSummary]);
|
}, [filter, showReviewed, reviewSummary]);
|
||||||
|
|
||||||
// review interaction
|
// review interaction
|
||||||
|
|
||||||
@ -358,6 +362,8 @@ export default function EventView({
|
|||||||
filter={filter}
|
filter={filter}
|
||||||
motionOnly={motionOnly}
|
motionOnly={motionOnly}
|
||||||
filterList={reviewFilterList}
|
filterList={reviewFilterList}
|
||||||
|
showReviewed={showReviewed}
|
||||||
|
setShowReviewed={setShowReviewed}
|
||||||
onUpdateFilter={updateFilter}
|
onUpdateFilter={updateFilter}
|
||||||
setMotionOnly={setMotionOnly}
|
setMotionOnly={setMotionOnly}
|
||||||
/>
|
/>
|
||||||
|
@ -418,6 +418,8 @@ export function RecordingView({
|
|||||||
filter={filter}
|
filter={filter}
|
||||||
motionOnly={false}
|
motionOnly={false}
|
||||||
filterList={reviewFilterList}
|
filterList={reviewFilterList}
|
||||||
|
showReviewed
|
||||||
|
setShowReviewed={() => {}}
|
||||||
onUpdateFilter={updateFilter}
|
onUpdateFilter={updateFilter}
|
||||||
setMotionOnly={() => {}}
|
setMotionOnly={() => {}}
|
||||||
/>
|
/>
|
||||||
@ -699,10 +701,10 @@ function Timeline({
|
|||||||
<Skeleton className="size-full" />
|
<Skeleton className="size-full" />
|
||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<div className="h-full overflow-auto bg-secondary">
|
<div className="scrollbar-container h-full overflow-auto bg-secondary">
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"grid h-auto grid-cols-1 gap-4 overflow-auto p-4",
|
"scrollbar-container grid h-auto grid-cols-1 gap-4 overflow-auto p-4",
|
||||||
isMobile && "sm:grid-cols-2",
|
isMobile && "sm:grid-cols-2",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
Loading…
Reference in New Issue
Block a user