Skip to content

Commit 16ead91

Browse files
authored
Preview bugfixes (#11384)
* memoize initial time range and check for window visibility * assume window is visible with previewthumbnailplayer
1 parent 1757f4c commit 16ead91

File tree

2 files changed

+41
-13
lines changed

2 files changed

+41
-13
lines changed

web/src/components/card/AnimatedEventCard.tsx

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import TimeAgo from "../dynamic/TimeAgo";
22
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
3-
import { useCallback, useMemo } from "react";
3+
import { useCallback, useEffect, useMemo, useState } from "react";
44
import useSWR from "swr";
55
import { FrigateConfig } from "@/types/frigateConfig";
66
import { REVIEW_PADDING, ReviewSegment } from "@/types/review";
@@ -22,18 +22,34 @@ export function AnimatedEventCard({ event }: AnimatedEventCardProps) {
2222

2323
const currentHour = useMemo(() => isCurrentHour(event.start_time), [event]);
2424

25-
// preview
26-
27-
const previews = useCameraPreviews(
28-
{
25+
const initialTimeRange = useMemo(() => {
26+
return {
2927
after: Math.round(event.start_time),
3028
before: Math.round(event.end_time || event.start_time + 20),
31-
},
32-
{
33-
camera: event.camera,
34-
fetchPreviews: !currentHour,
35-
},
36-
);
29+
};
30+
}, [event]);
31+
32+
// preview
33+
34+
const previews = useCameraPreviews(initialTimeRange, {
35+
camera: event.camera,
36+
fetchPreviews: !currentHour,
37+
});
38+
39+
// visibility
40+
41+
const [windowVisible, setWindowVisible] = useState(true);
42+
const visibilityListener = useCallback(() => {
43+
setWindowVisible(document.visibilityState == "visible");
44+
}, []);
45+
46+
useEffect(() => {
47+
addEventListener("visibilitychange", visibilityListener);
48+
49+
return () => {
50+
removeEventListener("visibilitychange", visibilityListener);
51+
};
52+
}, [visibilityListener]);
3753

3854
// interaction
3955

@@ -86,6 +102,7 @@ export function AnimatedEventCard({ event }: AnimatedEventCardProps) {
86102
setReviewed={() => {}}
87103
setIgnoreClick={() => {}}
88104
isPlayingBack={() => {}}
105+
windowVisible={windowVisible}
89106
/>
90107
) : (
91108
<InProgressPreview
@@ -99,6 +116,7 @@ export function AnimatedEventCard({ event }: AnimatedEventCardProps) {
99116
setReviewed={() => {}}
100117
setIgnoreClick={() => {}}
101118
isPlayingBack={() => {}}
119+
windowVisible={windowVisible}
102120
/>
103121
)}
104122
</div>

web/src/components/player/PreviewThumbnailPlayer.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ function PreviewContent({
323323
setIgnoreClick={setIgnoreClick}
324324
isPlayingBack={isPlayingBack}
325325
onTimeUpdate={onTimeUpdate}
326+
windowVisible={true}
326327
/>
327328
);
328329
} else if (isCurrentHour(review.start_time)) {
@@ -334,6 +335,7 @@ function PreviewContent({
334335
setIgnoreClick={setIgnoreClick}
335336
isPlayingBack={isPlayingBack}
336337
onTimeUpdate={onTimeUpdate}
338+
windowVisible={true}
337339
/>
338340
);
339341
}
@@ -349,6 +351,7 @@ type VideoPreviewProps = {
349351
setIgnoreClick: (ignore: boolean) => void;
350352
isPlayingBack: (ended: boolean) => void;
351353
onTimeUpdate?: (time: number | undefined) => void;
354+
windowVisible: boolean;
352355
};
353356
export function VideoPreview({
354357
relevantPreview,
@@ -360,6 +363,7 @@ export function VideoPreview({
360363
setIgnoreClick,
361364
isPlayingBack,
362365
onTimeUpdate,
366+
windowVisible,
363367
}: VideoPreviewProps) {
364368
const playerRef = useRef<HTMLVideoElement | null>(null);
365369
const sliderRef = useRef<HTMLDivElement | null>(null);
@@ -409,6 +413,10 @@ export function VideoPreview({
409413
// time progress update
410414

411415
const onProgress = useCallback(() => {
416+
if (!windowVisible) {
417+
return;
418+
}
419+
412420
if (onTimeUpdate) {
413421
onTimeUpdate(
414422
relevantPreview.start + (playerRef.current?.currentTime || 0),
@@ -458,7 +466,7 @@ export function VideoPreview({
458466

459467
// we know that these deps are correct
460468
// eslint-disable-next-line react-hooks/exhaustive-deps
461-
}, [setProgress, lastPercent]);
469+
}, [setProgress, lastPercent, windowVisible]);
462470

463471
// manual playback
464472
// safari is incapable of playing at a speed > 2x
@@ -596,6 +604,7 @@ type InProgressPreviewProps = {
596604
setIgnoreClick: (ignore: boolean) => void;
597605
isPlayingBack: (ended: boolean) => void;
598606
onTimeUpdate?: (time: number | undefined) => void;
607+
windowVisible: boolean;
599608
};
600609
export function InProgressPreview({
601610
review,
@@ -606,6 +615,7 @@ export function InProgressPreview({
606615
setIgnoreClick,
607616
isPlayingBack,
608617
onTimeUpdate,
618+
windowVisible,
609619
}: InProgressPreviewProps) {
610620
const apiHost = useApiHost();
611621
const sliderRef = useRef<HTMLDivElement | null>(null);
@@ -620,7 +630,7 @@ export function InProgressPreview({
620630
const [key, setKey] = useState(0);
621631

622632
const handleLoad = useCallback(() => {
623-
if (!previewFrames) {
633+
if (!previewFrames || !windowVisible) {
624634
return;
625635
}
626636

0 commit comments

Comments
 (0)