From 16434a5e41504104cb9a5464d3895397e933aecf Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Mon, 4 Mar 2024 17:09:53 -0700 Subject: [PATCH] Adjust remaining summary items when items are marked as reviewed --- .../player/PreviewThumbnailPlayer.tsx | 6 +- web/src/pages/Events.tsx | 63 ++++++++++++++++--- web/src/views/events/EventView.tsx | 4 +- 3 files changed, 58 insertions(+), 15 deletions(-) diff --git a/web/src/components/player/PreviewThumbnailPlayer.tsx b/web/src/components/player/PreviewThumbnailPlayer.tsx index 6908aec81..9a6e91e91 100644 --- a/web/src/components/player/PreviewThumbnailPlayer.tsx +++ b/web/src/components/player/PreviewThumbnailPlayer.tsx @@ -25,7 +25,7 @@ type PreviewPlayerProps = { allPreviews?: Preview[]; scrollLock?: boolean; onTimeUpdate?: React.Dispatch>; - setReviewed: (reviewId: string) => void; + setReviewed: (review: ReviewSegment) => void; onClick: (reviewId: string, ctrl: boolean) => void; }; @@ -65,13 +65,13 @@ export default function PreviewThumbnailPlayer({ ); const swipeHandlers = useSwipeable({ - onSwipedLeft: () => (setReviewed ? setReviewed(review.id) : null), + onSwipedLeft: () => (setReviewed ? setReviewed(review) : null), onSwipedRight: () => setPlayback(true), preventScrollOnSwipe: true, }); const handleSetReviewed = useCallback( - () => setReviewed(review.id), + () => setReviewed(review), [review, setReviewed], ); diff --git a/web/src/pages/Events.tsx b/web/src/pages/Events.tsx index 3d601e290..92bf6c731 100644 --- a/web/src/pages/Events.tsx +++ b/web/src/pages/Events.tsx @@ -4,7 +4,12 @@ import { useTimezone } from "@/hooks/use-date-utils"; import useOverlayState from "@/hooks/use-overlay-state"; import { FrigateConfig } from "@/types/frigateConfig"; import { Preview } from "@/types/preview"; -import { ReviewFilter, ReviewSegment, ReviewSeverity } from "@/types/review"; +import { + ReviewFilter, + ReviewSegment, + ReviewSeverity, + ReviewSummary, +} from "@/types/review"; import EventView from "@/views/events/EventView"; import RecordingView from "@/views/events/RecordingView"; import axios from "axios"; @@ -108,11 +113,9 @@ export default function Events() { // review summary - const { data: reviewSummary } = useSWR([ - "review/summary", - { timezone: timezone }, - { revalidateOnFocus: false }, - ]); + const { data: reviewSummary, mutate: updateSummary } = useSWR< + ReviewSummary[] + >(["review/summary", { timezone: timezone }, { revalidateOnFocus: false }]); // preview videos @@ -145,8 +148,8 @@ export default function Events() { // review status const markItemAsReviewed = useCallback( - async (reviewId: string) => { - const resp = await axios.post(`review/${reviewId}/viewed`); + async (review: ReviewSegment) => { + const resp = await axios.post(`review/${review.id}/viewed`); if (resp.status == 200) { updateSegments( @@ -158,7 +161,9 @@ export default function Events() { const newData: ReviewSegment[][] = []; data.forEach((page) => { - const reviewIndex = page.findIndex((item) => item.id == reviewId); + const reviewIndex = page.findIndex( + (item) => item.id == review.id, + ); if (reviewIndex == -1) { newData.push([...page]); @@ -175,9 +180,47 @@ export default function Events() { }, { revalidate: false, populateCache: true }, ); + + updateSummary( + (data: ReviewSummary[] | undefined) => { + if (!data) { + return data; + } + + const day = new Date(review.start_time * 1000); + const key = `${day.getFullYear()}-${("0" + (day.getMonth() + 1)).slice(-2)}-${("0" + day.getDate()).slice(-2)}`; + const index = data.findIndex((summary) => summary.day == key); + + if (index == -1) { + return data; + } + + const item = data[index]; + return [ + ...data.slice(0, index), + { + ...item, + reviewed_alert: + review.severity == "alert" + ? item.reviewed_alert + 1 + : item.reviewed_alert, + reviewed_detection: + review.severity == "detection" + ? item.reviewed_detection + 1 + : item.reviewed_detection, + reviewed_motion: + review.severity == "significant_motion" + ? item.reviewed_motion + 1 + : item.reviewed_motion, + }, + ...data.slice(index + 1), + ]; + }, + { revalidate: false, populateCache: true }, + ); } }, - [updateSegments], + [updateSegments, updateSummary], ); // selected items diff --git a/web/src/views/events/EventView.tsx b/web/src/views/events/EventView.tsx index e00a10a30..ec9dda500 100644 --- a/web/src/views/events/EventView.tsx +++ b/web/src/views/events/EventView.tsx @@ -45,7 +45,7 @@ type EventViewProps = { severity: ReviewSeverity; setSeverity: (severity: ReviewSeverity) => void; loadNextPage: () => void; - markItemAsReviewed: (reviewId: string) => void; + markItemAsReviewed: (review: ReviewSegment) => void; onOpenReview: (reviewId: string) => void; pullLatestData: () => void; updateFilter: (filter: ReviewFilter) => void; @@ -303,7 +303,7 @@ type DetectionReviewProps = { reachedEnd: boolean; timeRange: { before: number; after: number }; loadNextPage: () => void; - markItemAsReviewed: (id: string) => void; + markItemAsReviewed: (review: ReviewSegment) => void; onSelectReview: (id: string, ctrl: boolean) => void; pullLatestData: () => void; };