From bacf202fd43236821c2d9d6c67e72b88437c3122 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Tue, 26 Mar 2024 09:58:55 -0600 Subject: [PATCH] Add events list view to recordings view --- web/src/components/card/ReviewCard.tsx | 65 +++++++++++++++++++ web/src/components/dynamic/TimeAgo.tsx | 5 +- .../player/PreviewThumbnailPlayer.tsx | 2 +- web/src/views/events/EventView.tsx | 10 +-- web/src/views/events/RecordingView.tsx | 14 ++++ 5 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 web/src/components/card/ReviewCard.tsx diff --git a/web/src/components/card/ReviewCard.tsx b/web/src/components/card/ReviewCard.tsx new file mode 100644 index 000000000..546409538 --- /dev/null +++ b/web/src/components/card/ReviewCard.tsx @@ -0,0 +1,65 @@ +import { baseUrl } from "@/api/baseUrl"; +import { useFormattedTimestamp } from "@/hooks/use-date-utils"; +import { FrigateConfig } from "@/types/frigateConfig"; +import { ReviewSegment } from "@/types/review"; +import { getIconForLabel, getIconForSubLabel } from "@/utils/iconUtil"; +import { isSafari } from "react-device-detect"; +import useSWR from "swr"; +import TimeAgo from "../dynamic/TimeAgo"; +import { useMemo } from "react"; + +type ReviewCardProps = { + event: ReviewSegment; + currentTime: number; + onClick?: () => void; +}; +export default function ReviewCard({ + event, + currentTime, + onClick, +}: ReviewCardProps) { + const { data: config } = useSWR("config"); + const formattedDate = useFormattedTimestamp( + event.start_time, + config?.ui.time_format == "24hour" ? "%H:%M" : "%I:%M %p", + ); + const isSelected = useMemo( + () => event.start_time <= currentTime && event.end_time >= currentTime, + [event, currentTime], + ); + + return ( +
+ { + //onImgLoad(); + }} + /> +
+
+ {event.data.objects.map((object) => { + return getIconForLabel(object, "size-3 text-white"); + })} + {event.data.audio.map((audio) => { + return getIconForLabel(audio, "size-3 text-white"); + })} + {event.data.sub_labels?.map((sub) => { + return getIconForSubLabel(sub, "size-3 text-white"); + })} +
{formattedDate}
+
+ +
+
+ ); +} diff --git a/web/src/components/dynamic/TimeAgo.tsx b/web/src/components/dynamic/TimeAgo.tsx index a9993db8a..13892180e 100644 --- a/web/src/components/dynamic/TimeAgo.tsx +++ b/web/src/components/dynamic/TimeAgo.tsx @@ -1,6 +1,8 @@ import { FunctionComponent, useEffect, useMemo, useState } from "react"; interface IProp { + /** OPTIONAL: classname */ + className?: string; /** The time to calculate time-ago from */ time: number; /** OPTIONAL: overwrite current time */ @@ -73,6 +75,7 @@ const timeAgo = ({ }; const TimeAgo: FunctionComponent = ({ + className, time, manualRefreshInterval, ...rest @@ -105,6 +108,6 @@ const TimeAgo: FunctionComponent = ({ [currentTime, rest, time], ); - return {timeAgoValue}; + return {timeAgoValue}; }; export default TimeAgo; diff --git a/web/src/components/player/PreviewThumbnailPlayer.tsx b/web/src/components/player/PreviewThumbnailPlayer.tsx index 12e4bd706..3c11d79c0 100644 --- a/web/src/components/player/PreviewThumbnailPlayer.tsx +++ b/web/src/components/player/PreviewThumbnailPlayer.tsx @@ -191,7 +191,7 @@ export default function PreviewThumbnailPlayer({
seg.start <= startTime && seg.end >= startTime, + (seg) => seg.after <= startTime && seg.before >= startTime, ); // only render once // eslint-disable-next-line react-hooks/exhaustive-deps @@ -679,7 +679,7 @@ function MotionReview({ const [selectedRangeIdx, setSelectedRangeIdx] = useState(initialIndex); const [currentTime, setCurrentTime] = useState( - startTime ?? timeRangeSegments.ranges[selectedRangeIdx]?.end, + startTime ?? timeRangeSegments.ranges[selectedRangeIdx]?.before, ); const currentTimeRange = useMemo( () => timeRangeSegments.ranges[selectedRangeIdx], @@ -693,11 +693,11 @@ function MotionReview({ useEffect(() => { if ( - currentTime > currentTimeRange.end + 60 || - currentTime < currentTimeRange.start - 60 + currentTime > currentTimeRange.before + 60 || + currentTime < currentTimeRange.after - 60 ) { const index = timeRangeSegments.ranges.findIndex( - (seg) => seg.start <= currentTime && seg.end >= currentTime, + (seg) => seg.after <= currentTime && seg.before >= currentTime, ); if (index != -1) { diff --git a/web/src/views/events/RecordingView.tsx b/web/src/views/events/RecordingView.tsx index 8d84d6fa2..4f023231f 100644 --- a/web/src/views/events/RecordingView.tsx +++ b/web/src/views/events/RecordingView.tsx @@ -1,3 +1,4 @@ +import ReviewCard from "@/components/card/ReviewCard"; import FilterCheckBox from "@/components/filter/FilterCheckBox"; import ReviewFilterGroup from "@/components/filter/ReviewFilterGroup"; import PreviewPlayer, { @@ -414,4 +415,17 @@ function Timeline({
); } + + return ( +
+ {mainCameraReviewItems.map((review) => ( + setCurrentTime(review.start_time)} + /> + ))} +
+ ); }