From 11b9716482e418448c70059c2d97a0aac0f46bd9 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Sat, 5 Apr 2025 00:31:19 -0500 Subject: [PATCH] Refine image fallback behavior --- src/components/image/ImageWithFallback.tsx | 66 +++++++++++++--------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/src/components/image/ImageWithFallback.tsx b/src/components/image/ImageWithFallback.tsx index 0e97f315..a3973001 100644 --- a/src/components/image/ImageWithFallback.tsx +++ b/src/components/image/ImageWithFallback.tsx @@ -5,7 +5,7 @@ import { BLUR_ENABLED } from '@/app/config'; import { useAppState } from '@/state/AppState'; import { clsx} from 'clsx/lite'; import Image, { ImageProps } from 'next/image'; -import { useCallback, useEffect, useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; export default function ImageWithFallback(props: ImageProps & { blurCompatibilityLevel?: 'none' | 'low' | 'high' @@ -22,7 +22,7 @@ export default function ImageWithFallback(props: ImageProps & { const { shouldDebugImageFallbacks } = useAppState(); - const [wasCached, setWasCached] = useState(false); + const [wasCached, setWasCached] = useState(true); const [isLoading, setIsLoading] = useState(true); const [didError, setDidError] = useState(false); @@ -31,6 +31,16 @@ export default function ImageWithFallback(props: ImageProps & { const [hideFallback, setHideFallback] = useState(false); + const imgRef = useRef(null); + + useEffect(() => { + const timeout = setTimeout( + () => setWasCached(imgRef.current?.complete ?? false), + 100, + ); + return () => clearTimeout(timeout); + }, []); + useEffect(() => { if (!isLoading && !didError) { const timeout = setTimeout(() => { @@ -61,34 +71,34 @@ export default function ImageWithFallback(props: ImageProps & { className, )} > - {(showFallback || shouldDebugImageFallbacks) && -
- {(BLUR_ENABLED && blurDataURL) - ? - :
} -
} + !(BLUR_ENABLED && blurDataURL) && 'bg-main', + (isLoading || shouldDebugImageFallbacks) + ? 'opacity-100' + : 'opacity-0', + )}> + {(BLUR_ENABLED && blurDataURL) + ? + :
} +
setWasCached(element?.complete ?? false), + ref: imgRef, priority, className: classNameImage, onLoad, @@ -96,4 +106,4 @@ export default function ImageWithFallback(props: ImageProps & { }} />
); -} +} \ No newline at end of file