mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-10-23 23:14:46 +03:00
retry camera snapshots after a failed load
AutoUpdatingCameraImage only scheduled the next frame from onLoad, so a single failed latest.webp request froze the image until the component remounted. It now retries on error, dropping the periodic cache key so the retry requests a fresh URL.
This commit is contained in:
@@ -12,6 +12,7 @@ type AutoUpdatingCameraImageProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const MIN_LOAD_TIMEOUT_MS = 200;
|
const MIN_LOAD_TIMEOUT_MS = 200;
|
||||||
|
const ERROR_RETRY_MS = 1000;
|
||||||
|
|
||||||
export default function AutoUpdatingCameraImage({
|
export default function AutoUpdatingCameraImage({
|
||||||
camera,
|
camera,
|
||||||
@@ -68,6 +69,24 @@ export default function AutoUpdatingCameraImage({
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [key, setFps]);
|
}, [key, setFps]);
|
||||||
|
|
||||||
|
const handleError = useCallback(() => {
|
||||||
|
if (reloadInterval == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the periodic cache url doesn't change between retries, so drop it
|
||||||
|
setIsCached(true);
|
||||||
|
|
||||||
|
if (timeoutRef.current) {
|
||||||
|
clearTimeout(timeoutRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
timeoutRef.current = setTimeout(
|
||||||
|
() => setKey(Date.now()),
|
||||||
|
Math.max(reloadInterval, ERROR_RETRY_MS),
|
||||||
|
);
|
||||||
|
}, [reloadInterval]);
|
||||||
|
|
||||||
// periodic cache to reduce loading indicator
|
// periodic cache to reduce loading indicator
|
||||||
|
|
||||||
const [isCached, setIsCached] = useState(false);
|
const [isCached, setIsCached] = useState(false);
|
||||||
@@ -92,6 +111,7 @@ export default function AutoUpdatingCameraImage({
|
|||||||
<CameraImage
|
<CameraImage
|
||||||
camera={camera}
|
camera={camera}
|
||||||
onload={handleLoad}
|
onload={handleLoad}
|
||||||
|
onerror={handleError}
|
||||||
searchParams={cacheKey}
|
searchParams={cacheKey}
|
||||||
className={cameraClasses}
|
className={cameraClasses}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ type CameraImageProps = {
|
|||||||
className?: string;
|
className?: string;
|
||||||
camera: string;
|
camera: string;
|
||||||
onload?: () => void;
|
onload?: () => void;
|
||||||
|
onerror?: () => void;
|
||||||
searchParams?: string;
|
searchParams?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -18,6 +19,7 @@ export default function CameraImage({
|
|||||||
className,
|
className,
|
||||||
camera,
|
camera,
|
||||||
onload,
|
onload,
|
||||||
|
onerror,
|
||||||
searchParams = "",
|
searchParams = "",
|
||||||
}: CameraImageProps) {
|
}: CameraImageProps) {
|
||||||
const { data: config } = useSWR("config");
|
const { data: config } = useSWR("config");
|
||||||
@@ -96,6 +98,7 @@ export default function CameraImage({
|
|||||||
"rounded-lg md:rounded-2xl",
|
"rounded-lg md:rounded-2xl",
|
||||||
)}
|
)}
|
||||||
onLoad={handleImageLoad}
|
onLoad={handleImageLoad}
|
||||||
|
onError={onerror}
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
Reference in New Issue
Block a user