mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-11 13:45:25 +03:00
Don't remove items from list when navigating back
This commit is contained in:
parent
fc032cff9b
commit
1838b6bb9f
@ -10,6 +10,7 @@ import {
|
|||||||
ReviewSegment,
|
ReviewSegment,
|
||||||
ReviewSeverity,
|
ReviewSeverity,
|
||||||
ReviewSummary,
|
ReviewSummary,
|
||||||
|
SegmentedReviewData,
|
||||||
} from "@/types/review";
|
} from "@/types/review";
|
||||||
import { getTimestampOffset } from "@/utils/dateUtil";
|
import { getTimestampOffset } from "@/utils/dateUtil";
|
||||||
import EventView from "@/views/events/EventView";
|
import EventView from "@/views/events/EventView";
|
||||||
@ -138,6 +139,66 @@ export default function Events() {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const reviewItems = useMemo<SegmentedReviewData>(() => {
|
||||||
|
if (!reviews) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const all: ReviewSegment[] = [];
|
||||||
|
const alerts: ReviewSegment[] = [];
|
||||||
|
const detections: ReviewSegment[] = [];
|
||||||
|
const motion: ReviewSegment[] = [];
|
||||||
|
|
||||||
|
reviews?.forEach((segment) => {
|
||||||
|
all.push(segment);
|
||||||
|
|
||||||
|
switch (segment.severity) {
|
||||||
|
case "alert":
|
||||||
|
alerts.push(segment);
|
||||||
|
break;
|
||||||
|
case "detection":
|
||||||
|
detections.push(segment);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
motion.push(segment);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
all: all,
|
||||||
|
alert: alerts,
|
||||||
|
detection: detections,
|
||||||
|
significant_motion: motion,
|
||||||
|
};
|
||||||
|
}, [reviews]);
|
||||||
|
|
||||||
|
const currentItems = useMemo(() => {
|
||||||
|
if (!reviewItems || !severity) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let current;
|
||||||
|
|
||||||
|
if (reviewFilter?.showAll) {
|
||||||
|
current = reviewItems.all;
|
||||||
|
} else {
|
||||||
|
current = reviewItems[severity];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!current || current.length == 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reviewFilter?.showReviewed != 1) {
|
||||||
|
return current.filter((seg) => !seg.has_been_reviewed);
|
||||||
|
} else {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
// only refresh when severity or filter changes
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [severity, reviewFilter, reviewItems?.all.length]);
|
||||||
|
|
||||||
// review summary
|
// review summary
|
||||||
|
|
||||||
const { data: reviewSummary, mutate: updateSummary } = useSWR<ReviewSummary>(
|
const { data: reviewSummary, mutate: updateSummary } = useSWR<ReviewSummary>(
|
||||||
@ -353,7 +414,8 @@ export default function Events() {
|
|||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<EventView
|
<EventView
|
||||||
reviews={reviews}
|
reviewItems={reviewItems}
|
||||||
|
currentReviewItems={currentItems}
|
||||||
reviewSummary={reviewSummary}
|
reviewSummary={reviewSummary}
|
||||||
relevantPreviews={allPreviews}
|
relevantPreviews={allPreviews}
|
||||||
timeRange={selectedTimeRange}
|
timeRange={selectedTimeRange}
|
||||||
|
|||||||
@ -20,6 +20,15 @@ export type ReviewData = {
|
|||||||
zones: string[];
|
zones: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type SegmentedReviewData =
|
||||||
|
| {
|
||||||
|
all: ReviewSegment[];
|
||||||
|
alert: ReviewSegment[];
|
||||||
|
detection: ReviewSegment[];
|
||||||
|
significant_motion: ReviewSegment[];
|
||||||
|
}
|
||||||
|
| undefined;
|
||||||
|
|
||||||
export type ReviewFilter = {
|
export type ReviewFilter = {
|
||||||
cameras?: string[];
|
cameras?: string[];
|
||||||
labels?: string[];
|
labels?: string[];
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import {
|
|||||||
ReviewSegment,
|
ReviewSegment,
|
||||||
ReviewSeverity,
|
ReviewSeverity,
|
||||||
ReviewSummary,
|
ReviewSummary,
|
||||||
|
SegmentedReviewData,
|
||||||
} from "@/types/review";
|
} from "@/types/review";
|
||||||
import { getChunkedTimeRange } from "@/utils/timelineUtil";
|
import { getChunkedTimeRange } from "@/utils/timelineUtil";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
@ -49,7 +50,8 @@ import { Toaster } from "@/components/ui/sonner";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
type EventViewProps = {
|
type EventViewProps = {
|
||||||
reviews?: ReviewSegment[];
|
reviewItems?: SegmentedReviewData;
|
||||||
|
currentReviewItems: ReviewSegment[] | null;
|
||||||
reviewSummary?: ReviewSummary;
|
reviewSummary?: ReviewSummary;
|
||||||
relevantPreviews?: Preview[];
|
relevantPreviews?: Preview[];
|
||||||
timeRange: TimeRange;
|
timeRange: TimeRange;
|
||||||
@ -64,7 +66,8 @@ type EventViewProps = {
|
|||||||
updateFilter: (filter: ReviewFilter) => void;
|
updateFilter: (filter: ReviewFilter) => void;
|
||||||
};
|
};
|
||||||
export default function EventView({
|
export default function EventView({
|
||||||
reviews,
|
reviewItems,
|
||||||
|
currentReviewItems,
|
||||||
reviewSummary,
|
reviewSummary,
|
||||||
relevantPreviews,
|
relevantPreviews,
|
||||||
timeRange,
|
timeRange,
|
||||||
@ -116,42 +119,6 @@ export default function EventView({
|
|||||||
}
|
}
|
||||||
}, [filter, reviewSummary]);
|
}, [filter, reviewSummary]);
|
||||||
|
|
||||||
// review paging
|
|
||||||
|
|
||||||
const reviewItems = useMemo(() => {
|
|
||||||
if (!reviews) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const all: ReviewSegment[] = [];
|
|
||||||
const alerts: ReviewSegment[] = [];
|
|
||||||
const detections: ReviewSegment[] = [];
|
|
||||||
const motion: ReviewSegment[] = [];
|
|
||||||
|
|
||||||
reviews?.forEach((segment) => {
|
|
||||||
all.push(segment);
|
|
||||||
|
|
||||||
switch (segment.severity) {
|
|
||||||
case "alert":
|
|
||||||
alerts.push(segment);
|
|
||||||
break;
|
|
||||||
case "detection":
|
|
||||||
detections.push(segment);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
motion.push(segment);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
all: all,
|
|
||||||
alert: alerts,
|
|
||||||
detection: detections,
|
|
||||||
significant_motion: motion,
|
|
||||||
};
|
|
||||||
}, [reviews]);
|
|
||||||
|
|
||||||
// review interaction
|
// review interaction
|
||||||
|
|
||||||
const [selectedReviews, setSelectedReviews] = useState<string[]>([]);
|
const [selectedReviews, setSelectedReviews] = useState<string[]>([]);
|
||||||
@ -182,6 +149,7 @@ export default function EventView({
|
|||||||
severity: review.severity,
|
severity: review.severity,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
review.has_been_reviewed = true;
|
||||||
markItemAsReviewed(review);
|
markItemAsReviewed(review);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -332,6 +300,7 @@ export default function EventView({
|
|||||||
<DetectionReview
|
<DetectionReview
|
||||||
contentRef={contentRef}
|
contentRef={contentRef}
|
||||||
reviewItems={reviewItems}
|
reviewItems={reviewItems}
|
||||||
|
currentItems={currentReviewItems}
|
||||||
relevantPreviews={relevantPreviews}
|
relevantPreviews={relevantPreviews}
|
||||||
selectedReviews={selectedReviews}
|
selectedReviews={selectedReviews}
|
||||||
itemsToReview={reviewCounts[severityToggle]}
|
itemsToReview={reviewCounts[severityToggle]}
|
||||||
@ -372,6 +341,7 @@ type DetectionReviewProps = {
|
|||||||
detection: ReviewSegment[];
|
detection: ReviewSegment[];
|
||||||
significant_motion: ReviewSegment[];
|
significant_motion: ReviewSegment[];
|
||||||
};
|
};
|
||||||
|
currentItems: ReviewSegment[] | null;
|
||||||
itemsToReview?: number;
|
itemsToReview?: number;
|
||||||
relevantPreviews?: Preview[];
|
relevantPreviews?: Preview[];
|
||||||
selectedReviews: string[];
|
selectedReviews: string[];
|
||||||
@ -388,6 +358,7 @@ type DetectionReviewProps = {
|
|||||||
function DetectionReview({
|
function DetectionReview({
|
||||||
contentRef,
|
contentRef,
|
||||||
reviewItems,
|
reviewItems,
|
||||||
|
currentItems,
|
||||||
itemsToReview,
|
itemsToReview,
|
||||||
relevantPreviews,
|
relevantPreviews,
|
||||||
selectedReviews,
|
selectedReviews,
|
||||||
@ -405,33 +376,6 @@ function DetectionReview({
|
|||||||
|
|
||||||
const segmentDuration = 60;
|
const segmentDuration = 60;
|
||||||
|
|
||||||
// review data
|
|
||||||
const currentItems = useMemo(() => {
|
|
||||||
if (!reviewItems) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let current;
|
|
||||||
|
|
||||||
if (filter?.showAll) {
|
|
||||||
current = reviewItems.all;
|
|
||||||
} else {
|
|
||||||
current = reviewItems[severity];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!current || current.length == 0) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filter?.showReviewed != 1) {
|
|
||||||
return current.filter((seg) => !seg.has_been_reviewed);
|
|
||||||
} else {
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
// only refresh when severity or filter changes
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [severity, filter, reviewItems?.all.length]);
|
|
||||||
|
|
||||||
// preview
|
// preview
|
||||||
|
|
||||||
const [previewTime, setPreviewTime] = useState<number>();
|
const [previewTime, setPreviewTime] = useState<number>();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user