Preview bugfixes (#11384)

* memoize initial time range and check for window visibility

* assume window is visible with previewthumbnailplayer
This commit is contained in:
Josh Hawkins 2024-05-15 10:51:58 -05:00 committed by GitHub
parent 1757f4cb04
commit 16ead917ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 41 additions and 13 deletions

View File

@ -1,6 +1,6 @@
import TimeAgo from "../dynamic/TimeAgo"; import TimeAgo from "../dynamic/TimeAgo";
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
import { useCallback, useMemo } from "react"; import { useCallback, useEffect, useMemo, useState } from "react";
import useSWR from "swr"; import useSWR from "swr";
import { FrigateConfig } from "@/types/frigateConfig"; import { FrigateConfig } from "@/types/frigateConfig";
import { REVIEW_PADDING, ReviewSegment } from "@/types/review"; import { REVIEW_PADDING, ReviewSegment } from "@/types/review";
@ -22,18 +22,34 @@ export function AnimatedEventCard({ event }: AnimatedEventCardProps) {
const currentHour = useMemo(() => isCurrentHour(event.start_time), [event]); const currentHour = useMemo(() => isCurrentHour(event.start_time), [event]);
// preview const initialTimeRange = useMemo(() => {
return {
const previews = useCameraPreviews(
{
after: Math.round(event.start_time), after: Math.round(event.start_time),
before: Math.round(event.end_time || event.start_time + 20), before: Math.round(event.end_time || event.start_time + 20),
}, };
{ }, [event]);
camera: event.camera,
fetchPreviews: !currentHour, // 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 // interaction
@ -86,6 +102,7 @@ export function AnimatedEventCard({ event }: AnimatedEventCardProps) {
setReviewed={() => {}} setReviewed={() => {}}
setIgnoreClick={() => {}} setIgnoreClick={() => {}}
isPlayingBack={() => {}} isPlayingBack={() => {}}
windowVisible={windowVisible}
/> />
) : ( ) : (
<InProgressPreview <InProgressPreview
@ -99,6 +116,7 @@ export function AnimatedEventCard({ event }: AnimatedEventCardProps) {
setReviewed={() => {}} setReviewed={() => {}}
setIgnoreClick={() => {}} setIgnoreClick={() => {}}
isPlayingBack={() => {}} isPlayingBack={() => {}}
windowVisible={windowVisible}
/> />
)} )}
</div> </div>

View File

@ -323,6 +323,7 @@ function PreviewContent({
setIgnoreClick={setIgnoreClick} setIgnoreClick={setIgnoreClick}
isPlayingBack={isPlayingBack} isPlayingBack={isPlayingBack}
onTimeUpdate={onTimeUpdate} onTimeUpdate={onTimeUpdate}
windowVisible={true}
/> />
); );
} else if (isCurrentHour(review.start_time)) { } else if (isCurrentHour(review.start_time)) {
@ -334,6 +335,7 @@ function PreviewContent({
setIgnoreClick={setIgnoreClick} setIgnoreClick={setIgnoreClick}
isPlayingBack={isPlayingBack} isPlayingBack={isPlayingBack}
onTimeUpdate={onTimeUpdate} onTimeUpdate={onTimeUpdate}
windowVisible={true}
/> />
); );
} }
@ -349,6 +351,7 @@ type VideoPreviewProps = {
setIgnoreClick: (ignore: boolean) => void; setIgnoreClick: (ignore: boolean) => void;
isPlayingBack: (ended: boolean) => void; isPlayingBack: (ended: boolean) => void;
onTimeUpdate?: (time: number | undefined) => void; onTimeUpdate?: (time: number | undefined) => void;
windowVisible: boolean;
}; };
export function VideoPreview({ export function VideoPreview({
relevantPreview, relevantPreview,
@ -360,6 +363,7 @@ export function VideoPreview({
setIgnoreClick, setIgnoreClick,
isPlayingBack, isPlayingBack,
onTimeUpdate, onTimeUpdate,
windowVisible,
}: VideoPreviewProps) { }: VideoPreviewProps) {
const playerRef = useRef<HTMLVideoElement | null>(null); const playerRef = useRef<HTMLVideoElement | null>(null);
const sliderRef = useRef<HTMLDivElement | null>(null); const sliderRef = useRef<HTMLDivElement | null>(null);
@ -409,6 +413,10 @@ export function VideoPreview({
// time progress update // time progress update
const onProgress = useCallback(() => { const onProgress = useCallback(() => {
if (!windowVisible) {
return;
}
if (onTimeUpdate) { if (onTimeUpdate) {
onTimeUpdate( onTimeUpdate(
relevantPreview.start + (playerRef.current?.currentTime || 0), relevantPreview.start + (playerRef.current?.currentTime || 0),
@ -458,7 +466,7 @@ export function VideoPreview({
// we know that these deps are correct // we know that these deps are correct
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [setProgress, lastPercent]); }, [setProgress, lastPercent, windowVisible]);
// manual playback // manual playback
// safari is incapable of playing at a speed > 2x // safari is incapable of playing at a speed > 2x
@ -596,6 +604,7 @@ type InProgressPreviewProps = {
setIgnoreClick: (ignore: boolean) => void; setIgnoreClick: (ignore: boolean) => void;
isPlayingBack: (ended: boolean) => void; isPlayingBack: (ended: boolean) => void;
onTimeUpdate?: (time: number | undefined) => void; onTimeUpdate?: (time: number | undefined) => void;
windowVisible: boolean;
}; };
export function InProgressPreview({ export function InProgressPreview({
review, review,
@ -606,6 +615,7 @@ export function InProgressPreview({
setIgnoreClick, setIgnoreClick,
isPlayingBack, isPlayingBack,
onTimeUpdate, onTimeUpdate,
windowVisible,
}: InProgressPreviewProps) { }: InProgressPreviewProps) {
const apiHost = useApiHost(); const apiHost = useApiHost();
const sliderRef = useRef<HTMLDivElement | null>(null); const sliderRef = useRef<HTMLDivElement | null>(null);
@ -620,7 +630,7 @@ export function InProgressPreview({
const [key, setKey] = useState(0); const [key, setKey] = useState(0);
const handleLoad = useCallback(() => { const handleLoad = useCallback(() => {
if (!previewFrames) { if (!previewFrames || !windowVisible) {
return; return;
} }