mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-11 05:35:25 +03:00
Make each item in review filter group optional
This commit is contained in:
parent
802a266f87
commit
12bda571df
@ -10,7 +10,7 @@ import {
|
|||||||
DropdownMenuSeparator,
|
DropdownMenuSeparator,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from "../ui/dropdown-menu";
|
} from "../ui/dropdown-menu";
|
||||||
import { ReviewFilter, ReviewSeverity, ReviewSummary } from "@/types/review";
|
import { ReviewFilter, ReviewSummary } from "@/types/review";
|
||||||
import { getEndOfDayTimestamp } from "@/utils/dateUtil";
|
import { getEndOfDayTimestamp } from "@/utils/dateUtil";
|
||||||
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
||||||
import { FaCalendarAlt, FaFilter, FaRunning, FaVideo } from "react-icons/fa";
|
import { FaCalendarAlt, FaFilter, FaRunning, FaVideo } from "react-icons/fa";
|
||||||
@ -22,21 +22,29 @@ import FilterCheckBox from "./FilterCheckBox";
|
|||||||
import ReviewActivityCalendar from "../overlay/ReviewActivityCalendar";
|
import ReviewActivityCalendar from "../overlay/ReviewActivityCalendar";
|
||||||
|
|
||||||
const ATTRIBUTES = ["amazon", "face", "fedex", "license_plate", "ups"];
|
const ATTRIBUTES = ["amazon", "face", "fedex", "license_plate", "ups"];
|
||||||
|
const REVIEW_FILTERS = ["cameras", "date", "general", "motionOnly"] as const;
|
||||||
|
type ReviewFilters = (typeof REVIEW_FILTERS)[number];
|
||||||
|
const DEFAULT_REVIEW_FILTERS: ReviewFilters[] = [
|
||||||
|
"cameras",
|
||||||
|
"date",
|
||||||
|
"general",
|
||||||
|
"motionOnly",
|
||||||
|
];
|
||||||
|
|
||||||
type ReviewFilterGroupProps = {
|
type ReviewFilterGroupProps = {
|
||||||
|
filters?: ReviewFilters[];
|
||||||
reviewSummary?: ReviewSummary;
|
reviewSummary?: ReviewSummary;
|
||||||
filter?: ReviewFilter;
|
filter?: ReviewFilter;
|
||||||
onUpdateFilter: (filter: ReviewFilter) => void;
|
onUpdateFilter: (filter: ReviewFilter) => void;
|
||||||
severity: ReviewSeverity;
|
|
||||||
motionOnly: boolean;
|
motionOnly: boolean;
|
||||||
setMotionOnly: React.Dispatch<React.SetStateAction<boolean>>;
|
setMotionOnly: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ReviewFilterGroup({
|
export default function ReviewFilterGroup({
|
||||||
|
filters = DEFAULT_REVIEW_FILTERS,
|
||||||
reviewSummary,
|
reviewSummary,
|
||||||
filter,
|
filter,
|
||||||
onUpdateFilter,
|
onUpdateFilter,
|
||||||
severity,
|
|
||||||
motionOnly,
|
motionOnly,
|
||||||
setMotionOnly,
|
setMotionOnly,
|
||||||
}: ReviewFilterGroupProps) {
|
}: ReviewFilterGroupProps) {
|
||||||
@ -101,6 +109,7 @@ export default function ReviewFilterGroup({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-center">
|
<div className="flex justify-center">
|
||||||
|
{filters.includes("cameras") && (
|
||||||
<CamerasFilterButton
|
<CamerasFilterButton
|
||||||
allCameras={filterValues.cameras}
|
allCameras={filterValues.cameras}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
@ -109,19 +118,25 @@ export default function ReviewFilterGroup({
|
|||||||
onUpdateFilter({ ...filter, cameras: newCameras });
|
onUpdateFilter({ ...filter, cameras: newCameras });
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
{filters.includes("date") && (
|
||||||
<CalendarFilterButton
|
<CalendarFilterButton
|
||||||
reviewSummary={reviewSummary}
|
reviewSummary={reviewSummary}
|
||||||
day={
|
day={
|
||||||
filter?.after == undefined ? undefined : new Date(filter.after * 1000)
|
filter?.after == undefined
|
||||||
|
? undefined
|
||||||
|
: new Date(filter.after * 1000)
|
||||||
}
|
}
|
||||||
updateSelectedDay={onUpdateSelectedDay}
|
updateSelectedDay={onUpdateSelectedDay}
|
||||||
/>
|
/>
|
||||||
{severity == "significant_motion" ? (
|
)}
|
||||||
|
{filters.includes("motionOnly") && (
|
||||||
<ShowMotionOnlyButton
|
<ShowMotionOnlyButton
|
||||||
motionOnly={motionOnly}
|
motionOnly={motionOnly}
|
||||||
setMotionOnly={setMotionOnly}
|
setMotionOnly={setMotionOnly}
|
||||||
/>
|
/>
|
||||||
) : (
|
)}
|
||||||
|
{filters.includes("general") && (
|
||||||
<GeneralFilterButton
|
<GeneralFilterButton
|
||||||
allLabels={filterValues.labels}
|
allLabels={filterValues.labels}
|
||||||
selectedLabels={filter?.labels}
|
selectedLabels={filter?.labels}
|
||||||
@ -293,7 +308,7 @@ type CalendarFilterButtonProps = {
|
|||||||
day?: Date;
|
day?: Date;
|
||||||
updateSelectedDay: (day?: Date) => void;
|
updateSelectedDay: (day?: Date) => void;
|
||||||
};
|
};
|
||||||
export function CalendarFilterButton({
|
function CalendarFilterButton({
|
||||||
reviewSummary,
|
reviewSummary,
|
||||||
day,
|
day,
|
||||||
updateSelectedDay,
|
updateSelectedDay,
|
||||||
|
|||||||
@ -254,10 +254,14 @@ export default function EventView({
|
|||||||
|
|
||||||
{selectedReviews.length <= 0 ? (
|
{selectedReviews.length <= 0 ? (
|
||||||
<ReviewFilterGroup
|
<ReviewFilterGroup
|
||||||
|
filters={
|
||||||
|
severity == "significant_motion"
|
||||||
|
? ["cameras", "date", "motionOnly"]
|
||||||
|
: ["cameras", "date", "general"]
|
||||||
|
}
|
||||||
reviewSummary={reviewSummary}
|
reviewSummary={reviewSummary}
|
||||||
filter={filter}
|
filter={filter}
|
||||||
onUpdateFilter={updateFilter}
|
onUpdateFilter={updateFilter}
|
||||||
severity={severity}
|
|
||||||
motionOnly={motionOnly}
|
motionOnly={motionOnly}
|
||||||
setMotionOnly={setMotionOnly}
|
setMotionOnly={setMotionOnly}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import FilterCheckBox from "@/components/filter/FilterCheckBox";
|
import FilterCheckBox from "@/components/filter/FilterCheckBox";
|
||||||
import { CalendarFilterButton } from "@/components/filter/ReviewFilterGroup";
|
import ReviewFilterGroup from "@/components/filter/ReviewFilterGroup";
|
||||||
import PreviewPlayer, {
|
import PreviewPlayer, {
|
||||||
PreviewController,
|
PreviewController,
|
||||||
} from "@/components/player/PreviewPlayer";
|
} from "@/components/player/PreviewPlayer";
|
||||||
@ -16,7 +16,6 @@ import {
|
|||||||
ReviewSegment,
|
ReviewSegment,
|
||||||
ReviewSummary,
|
ReviewSummary,
|
||||||
} from "@/types/review";
|
} from "@/types/review";
|
||||||
import { getEndOfDayTimestamp } from "@/utils/dateUtil";
|
|
||||||
import { getChunkedTimeDay } from "@/utils/timelineUtil";
|
import { getChunkedTimeDay } from "@/utils/timelineUtil";
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { isDesktop, isMobile } from "react-device-detect";
|
import { isDesktop, isMobile } from "react-device-detect";
|
||||||
@ -205,30 +204,12 @@ export function RecordingView({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={contentRef} className="size-full flex flex-col">
|
<div ref={contentRef} className="size-full flex flex-col">
|
||||||
<div
|
<div className={`w-full h-10 flex items-center justify-between pr-1`}>
|
||||||
className={`w-full h-10 flex items-center justify-between ${isMobile ? "right-0" : "right-24"}`}
|
|
||||||
>
|
|
||||||
<Button className="rounded-lg" onClick={() => navigate(-1)}>
|
<Button className="rounded-lg" onClick={() => navigate(-1)}>
|
||||||
<IoMdArrowRoundBack className="size-5 mr-[10px]" />
|
<IoMdArrowRoundBack className="size-5 mr-[10px]" />
|
||||||
Back
|
Back
|
||||||
</Button>
|
</Button>
|
||||||
<div className="flex items-center justify-end">
|
<div className="flex items-center justify-end">
|
||||||
<CalendarFilterButton
|
|
||||||
day={
|
|
||||||
filter?.after == undefined
|
|
||||||
? undefined
|
|
||||||
: new Date(filter.after * 1000)
|
|
||||||
}
|
|
||||||
reviewSummary={reviewSummary}
|
|
||||||
updateSelectedDay={(day) => {
|
|
||||||
updateFilter({
|
|
||||||
...filter,
|
|
||||||
after: day == undefined ? undefined : day.getTime() / 1000,
|
|
||||||
before:
|
|
||||||
day == undefined ? undefined : getEndOfDayTimestamp(day),
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{isMobile && (
|
{isMobile && (
|
||||||
<Drawer>
|
<Drawer>
|
||||||
<DrawerTrigger asChild>
|
<DrawerTrigger asChild>
|
||||||
@ -258,11 +239,20 @@ export function RecordingView({
|
|||||||
</DrawerContent>
|
</DrawerContent>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
)}
|
)}
|
||||||
|
<ReviewFilterGroup
|
||||||
|
filters={["date", "general"]}
|
||||||
|
reviewSummary={reviewSummary}
|
||||||
|
filter={filter}
|
||||||
|
onUpdateFilter={updateFilter}
|
||||||
|
severity={"alert"}
|
||||||
|
motionOnly={false}
|
||||||
|
setMotionOnly={() => {}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={`flex h-full justify-center overflow-hidden ${isDesktop ? "" : "flex-col pt-12"}`}
|
className={`flex h-full justify-center overflow-hidden ${isDesktop ? "" : "flex-col"}`}
|
||||||
>
|
>
|
||||||
<div className="flex flex-1 flex-wrap">
|
<div className="flex flex-1 flex-wrap">
|
||||||
<div
|
<div
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user