From 16ead917ead5f70039e79e64a62571be79eb7adc Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Wed, 15 May 2024 10:51:58 -0500 Subject: [PATCH] Preview bugfixes (#11384) * memoize initial time range and check for window visibility * assume window is visible with previewthumbnailplayer --- web/src/components/card/AnimatedEventCard.tsx | 40 ++++++++++++++----- .../player/PreviewThumbnailPlayer.tsx | 14 ++++++- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/web/src/components/card/AnimatedEventCard.tsx b/web/src/components/card/AnimatedEventCard.tsx index 6714ed82c..b2a4750a9 100644 --- a/web/src/components/card/AnimatedEventCard.tsx +++ b/web/src/components/card/AnimatedEventCard.tsx @@ -1,6 +1,6 @@ import TimeAgo from "../dynamic/TimeAgo"; import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; -import { useCallback, useMemo } from "react"; +import { useCallback, useEffect, useMemo, useState } from "react"; import useSWR from "swr"; import { FrigateConfig } from "@/types/frigateConfig"; import { REVIEW_PADDING, ReviewSegment } from "@/types/review"; @@ -22,18 +22,34 @@ export function AnimatedEventCard({ event }: AnimatedEventCardProps) { const currentHour = useMemo(() => isCurrentHour(event.start_time), [event]); - // preview - - const previews = useCameraPreviews( - { + const initialTimeRange = useMemo(() => { + return { after: Math.round(event.start_time), before: Math.round(event.end_time || event.start_time + 20), - }, - { - camera: event.camera, - fetchPreviews: !currentHour, - }, - ); + }; + }, [event]); + + // preview + + const previews = useCameraPreviews(initialTimeRange, { + camera: event.camera, + fetchPreviews: !currentHour, + }); + + // visibility + + const [windowVisible, setWindowVisible] = useState(true); + const visibilityListener = useCallback(() => { + setWindowVisible(document.visibilityState == "visible"); + }, []); + + useEffect(() => { + addEventListener("visibilitychange", visibilityListener); + + return () => { + removeEventListener("visibilitychange", visibilityListener); + }; + }, [visibilityListener]); // interaction @@ -86,6 +102,7 @@ export function AnimatedEventCard({ event }: AnimatedEventCardProps) { setReviewed={() => {}} setIgnoreClick={() => {}} isPlayingBack={() => {}} + windowVisible={windowVisible} /> ) : ( {}} setIgnoreClick={() => {}} isPlayingBack={() => {}} + windowVisible={windowVisible} /> )} diff --git a/web/src/components/player/PreviewThumbnailPlayer.tsx b/web/src/components/player/PreviewThumbnailPlayer.tsx index 1bdde7812..a69a3bd85 100644 --- a/web/src/components/player/PreviewThumbnailPlayer.tsx +++ b/web/src/components/player/PreviewThumbnailPlayer.tsx @@ -323,6 +323,7 @@ function PreviewContent({ setIgnoreClick={setIgnoreClick} isPlayingBack={isPlayingBack} onTimeUpdate={onTimeUpdate} + windowVisible={true} /> ); } else if (isCurrentHour(review.start_time)) { @@ -334,6 +335,7 @@ function PreviewContent({ setIgnoreClick={setIgnoreClick} isPlayingBack={isPlayingBack} onTimeUpdate={onTimeUpdate} + windowVisible={true} /> ); } @@ -349,6 +351,7 @@ type VideoPreviewProps = { setIgnoreClick: (ignore: boolean) => void; isPlayingBack: (ended: boolean) => void; onTimeUpdate?: (time: number | undefined) => void; + windowVisible: boolean; }; export function VideoPreview({ relevantPreview, @@ -360,6 +363,7 @@ export function VideoPreview({ setIgnoreClick, isPlayingBack, onTimeUpdate, + windowVisible, }: VideoPreviewProps) { const playerRef = useRef(null); const sliderRef = useRef(null); @@ -409,6 +413,10 @@ export function VideoPreview({ // time progress update const onProgress = useCallback(() => { + if (!windowVisible) { + return; + } + if (onTimeUpdate) { onTimeUpdate( relevantPreview.start + (playerRef.current?.currentTime || 0), @@ -458,7 +466,7 @@ export function VideoPreview({ // we know that these deps are correct // eslint-disable-next-line react-hooks/exhaustive-deps - }, [setProgress, lastPercent]); + }, [setProgress, lastPercent, windowVisible]); // manual playback // safari is incapable of playing at a speed > 2x @@ -596,6 +604,7 @@ type InProgressPreviewProps = { setIgnoreClick: (ignore: boolean) => void; isPlayingBack: (ended: boolean) => void; onTimeUpdate?: (time: number | undefined) => void; + windowVisible: boolean; }; export function InProgressPreview({ review, @@ -606,6 +615,7 @@ export function InProgressPreview({ setIgnoreClick, isPlayingBack, onTimeUpdate, + windowVisible, }: InProgressPreviewProps) { const apiHost = useApiHost(); const sliderRef = useRef(null); @@ -620,7 +630,7 @@ export function InProgressPreview({ const [key, setKey] = useState(0); const handleLoad = useCallback(() => { - if (!previewFrames) { + if (!previewFrames || !windowVisible) { return; }