diff --git a/web/src/components/card/AnimatedEventCard.tsx b/web/src/components/card/AnimatedEventCard.tsx index 93ecbe919..08a2670bd 100644 --- a/web/src/components/card/AnimatedEventCard.tsx +++ b/web/src/components/card/AnimatedEventCard.tsx @@ -1,14 +1,17 @@ -import { baseUrl } from "@/api/baseUrl"; import TimeAgo from "../dynamic/TimeAgo"; import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; -import { useCallback, useMemo, useState } from "react"; +import { useCallback, useMemo } from "react"; import useSWR from "swr"; import { FrigateConfig } from "@/types/frigateConfig"; import { ReviewSegment } from "@/types/review"; import { useNavigate } from "react-router-dom"; -import { Skeleton } from "../ui/skeleton"; import { RecordingStartingPoint } from "@/types/record"; import axios from "axios"; +import { Preview } from "@/types/preview"; +import { + InProgressPreview, + VideoPreview, +} from "../player/PreviewThumbnailPlayer"; type AnimatedEventCardProps = { event: ReviewSegment; @@ -16,6 +19,12 @@ type AnimatedEventCardProps = { export function AnimatedEventCard({ event }: AnimatedEventCardProps) { const { data: config } = useSWR("config"); + // preview + + const { data: previews } = useSWR( + `/preview/${event.camera}/start/${Math.round(event.start_time)}/end/${Math.round(event.end_time || event.start_time + 20)}`, + ); + // interaction const navigate = useNavigate(); @@ -35,16 +44,6 @@ export function AnimatedEventCard({ event }: AnimatedEventCardProps) { // image behavior - const [loaded, setLoaded] = useState(false); - const [error, setError] = useState(0); - const imageUrl = useMemo(() => { - if (error > 0) { - return `${baseUrl}api/review/${event.id}/preview.gif?key=${error}`; - } - - return `${baseUrl}api/review/${event.id}/preview.gif`; - }, [error, event]); - const aspectRatio = useMemo(() => { if (!config) { return 1; @@ -63,18 +62,36 @@ export function AnimatedEventCard({ event }: AnimatedEventCardProps) { aspectRatio: aspectRatio, }} > - setLoaded(true)} - onError={() => { - if (error < 2) { - setError(error + 1); - } - }} - /> - {!loaded && } + > + {previews ? ( + {}} + setIgnoreClick={() => {}} + isPlayingBack={() => {}} + /> + ) : ( + {}} + setIgnoreClick={() => {}} + isPlayingBack={() => {}} + /> + )} +
diff --git a/web/src/components/player/PreviewThumbnailPlayer.tsx b/web/src/components/player/PreviewThumbnailPlayer.tsx index 5d7cc6a15..a7968075d 100644 --- a/web/src/components/player/PreviewThumbnailPlayer.tsx +++ b/web/src/components/player/PreviewThumbnailPlayer.tsx @@ -342,15 +342,19 @@ type VideoPreviewProps = { relevantPreview: Preview; startTime: number; endTime?: number; + showProgress?: boolean; + loop?: boolean; setReviewed: () => void; setIgnoreClick: (ignore: boolean) => void; isPlayingBack: (ended: boolean) => void; onTimeUpdate?: (time: number | undefined) => void; }; -function VideoPreview({ +export function VideoPreview({ relevantPreview, startTime, endTime, + showProgress = true, + loop = false, setReviewed, setIgnoreClick, isPlayingBack, @@ -425,6 +429,11 @@ function VideoPreview({ if (playerPercent > 100) { setReviewed(); + if (loop && playerRef.current) { + playerRef.current.currentTime = playerStartTime; + return; + } + if (isMobile) { isPlayingBack(false); @@ -553,17 +562,19 @@ function VideoPreview({ > - + {showProgress && ( + + )}
); } @@ -572,14 +583,18 @@ const MIN_LOAD_TIMEOUT_MS = 200; type InProgressPreviewProps = { review: ReviewSegment; timeRange: TimeRange; + showProgress?: boolean; + loop?: boolean; setReviewed: (reviewId: string) => void; setIgnoreClick: (ignore: boolean) => void; isPlayingBack: (ended: boolean) => void; onTimeUpdate?: (time: number | undefined) => void; }; -function InProgressPreview({ +export function InProgressPreview({ review, timeRange, + showProgress = true, + loop = false, setReviewed, setIgnoreClick, isPlayingBack, @@ -615,6 +630,11 @@ function InProgressPreview({ setReviewed(review.id); } + if (loop) { + setKey(0); + return; + } + if (isMobile) { isPlayingBack(false); @@ -717,17 +737,19 @@ function InProgressPreview({ src={`${apiHost}api/preview/${previewFrames[key]}/thumbnail.webp`} onLoad={handleLoad} /> - + {showProgress && ( + + )}
); }