mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-04-03 22:04:53 +03:00
Snapshot: guard against repeated download clicks
This commit is contained in:
parent
84c18365cc
commit
9e563823ac
@ -231,6 +231,7 @@ export default function HlsVideoPlayer({
|
|||||||
const [mobileCtrlTimeout, setMobileCtrlTimeout] = useState<NodeJS.Timeout>();
|
const [mobileCtrlTimeout, setMobileCtrlTimeout] = useState<NodeJS.Timeout>();
|
||||||
const [controls, setControls] = useState(isMobile);
|
const [controls, setControls] = useState(isMobile);
|
||||||
const [controlsOpen, setControlsOpen] = useState(false);
|
const [controlsOpen, setControlsOpen] = useState(false);
|
||||||
|
const [isSnapshotLoading, setIsSnapshotLoading] = useState(false);
|
||||||
const [zoomScale, setZoomScale] = useState(1.0);
|
const [zoomScale, setZoomScale] = useState(1.0);
|
||||||
const [videoDimensions, setVideoDimensions] = useState<{
|
const [videoDimensions, setVideoDimensions] = useState<{
|
||||||
width: number;
|
width: number;
|
||||||
@ -277,6 +278,12 @@ export default function HlsVideoPlayer({
|
|||||||
}, [videoRef, inpointOffset]);
|
}, [videoRef, inpointOffset]);
|
||||||
|
|
||||||
const handleSnapshot = useCallback(async () => {
|
const handleSnapshot = useCallback(async () => {
|
||||||
|
if (isSnapshotLoading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsSnapshotLoading(true);
|
||||||
|
try {
|
||||||
const frameTime = getVideoTime();
|
const frameTime = getVideoTime();
|
||||||
const result = await grabVideoSnapshot(videoRef.current);
|
const result = await grabVideoSnapshot(videoRef.current);
|
||||||
|
|
||||||
@ -297,7 +304,18 @@ export default function HlsVideoPlayer({
|
|||||||
position: "top-center",
|
position: "top-center",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [camera, config?.ui?.timezone, currentTime, getVideoTime, t, videoRef]);
|
} finally {
|
||||||
|
setIsSnapshotLoading(false);
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
camera,
|
||||||
|
config?.ui?.timezone,
|
||||||
|
currentTime,
|
||||||
|
getVideoTime,
|
||||||
|
isSnapshotLoading,
|
||||||
|
t,
|
||||||
|
videoRef,
|
||||||
|
]);
|
||||||
const onSnapshot = camera ? handleSnapshot : undefined;
|
const onSnapshot = camera ? handleSnapshot : undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -365,6 +383,7 @@ export default function HlsVideoPlayer({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onSnapshot={onSnapshot}
|
onSnapshot={onSnapshot}
|
||||||
|
snapshotLoading={isSnapshotLoading}
|
||||||
snapshotTitle={t("snapshot.takeSnapshot", { ns: "views/live" })}
|
snapshotTitle={t("snapshot.takeSnapshot", { ns: "views/live" })}
|
||||||
fullscreen={fullscreen}
|
fullscreen={fullscreen}
|
||||||
toggleFullscreen={toggleFullscreen}
|
toggleFullscreen={toggleFullscreen}
|
||||||
|
|||||||
@ -75,6 +75,7 @@ type VideoControlsProps = {
|
|||||||
onSetPlaybackRate: (rate: number) => void;
|
onSetPlaybackRate: (rate: number) => void;
|
||||||
onUploadFrame?: () => void;
|
onUploadFrame?: () => void;
|
||||||
onSnapshot?: () => void;
|
onSnapshot?: () => void;
|
||||||
|
snapshotLoading?: boolean;
|
||||||
snapshotTitle?: string;
|
snapshotTitle?: string;
|
||||||
toggleFullscreen?: () => void;
|
toggleFullscreen?: () => void;
|
||||||
containerRef?: React.MutableRefObject<HTMLDivElement | null>;
|
containerRef?: React.MutableRefObject<HTMLDivElement | null>;
|
||||||
@ -98,6 +99,7 @@ export default function VideoControls({
|
|||||||
onSetPlaybackRate,
|
onSetPlaybackRate,
|
||||||
onUploadFrame,
|
onUploadFrame,
|
||||||
onSnapshot,
|
onSnapshot,
|
||||||
|
snapshotLoading = false,
|
||||||
snapshotTitle,
|
snapshotTitle,
|
||||||
toggleFullscreen,
|
toggleFullscreen,
|
||||||
containerRef,
|
containerRef,
|
||||||
@ -302,10 +304,17 @@ export default function VideoControls({
|
|||||||
{features.snapshot && onSnapshot && (
|
{features.snapshot && onSnapshot && (
|
||||||
<TbCameraDown
|
<TbCameraDown
|
||||||
aria-label={snapshotTitle}
|
aria-label={snapshotTitle}
|
||||||
className="size-5 cursor-pointer"
|
aria-disabled={snapshotLoading}
|
||||||
|
className={cn(
|
||||||
|
"size-5",
|
||||||
|
snapshotLoading ? "cursor-not-allowed opacity-50" : "cursor-pointer",
|
||||||
|
)}
|
||||||
title={snapshotTitle}
|
title={snapshotTitle}
|
||||||
onClick={(e: React.MouseEvent<SVGElement>) => {
|
onClick={(e: React.MouseEvent<SVGElement>) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
if (snapshotLoading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
onSnapshot();
|
onSnapshot();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user