Fix image fallback abrupt segue, add logging
This commit is contained in:
parent
a1886da3bc
commit
6d7c5d6903
@ -29,21 +29,45 @@ export default function ImageWithFallback({
|
|||||||
|
|
||||||
const [hideFallback, setHideFallback] = useState(false);
|
const [hideFallback, setHideFallback] = useState(false);
|
||||||
|
|
||||||
const imgRef = useRef<HTMLImageElement>(null);
|
const refImage = useRef<HTMLImageElement>(null);
|
||||||
|
const refFallback = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setWasCached(
|
setWasCached(
|
||||||
Boolean(imgRef.current?.complete) &&
|
Boolean(refImage.current?.complete) &&
|
||||||
(imgRef.current?.naturalWidth ?? 0) > 0,
|
(refImage.current?.naturalWidth ?? 0) > 0,
|
||||||
);
|
);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isLoading && !didError) {
|
if (!isLoading && !didError) {
|
||||||
|
let innerTimeout: NodeJS.Timeout;
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
setHideFallback(true);
|
if (refFallback.current) {
|
||||||
|
const fallbackOpacity = (refFallback
|
||||||
|
.current
|
||||||
|
.computedStyleMap()
|
||||||
|
.get('opacity') as CSSUnitValue
|
||||||
|
)?.value;
|
||||||
|
// Address race condition where cached image is initially loaded
|
||||||
|
// and fallback is still being shown at full opacity
|
||||||
|
if (fallbackOpacity === 0) {
|
||||||
|
// Image has loaded and fallback is already hidden
|
||||||
|
setHideFallback(true);
|
||||||
|
} else {
|
||||||
|
// Image has loaded but fallback is still visible
|
||||||
|
// Delay hiding fallback to avoid abrupt transition
|
||||||
|
innerTimeout = setTimeout(() =>{
|
||||||
|
console.log('Delayed hide fallback');
|
||||||
|
setHideFallback(true);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
return () => clearTimeout(timeout);
|
return () => {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
clearTimeout(innerTimeout);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}, [isLoading, didError]);
|
}, [isLoading, didError]);
|
||||||
|
|
||||||
@ -70,23 +94,26 @@ export default function ImageWithFallback({
|
|||||||
>
|
>
|
||||||
<Image {...{
|
<Image {...{
|
||||||
...props,
|
...props,
|
||||||
ref: imgRef,
|
ref: refImage,
|
||||||
priority,
|
priority,
|
||||||
className: classNameImage,
|
className: classNameImage,
|
||||||
onLoad,
|
onLoad,
|
||||||
onError,
|
onError,
|
||||||
}} />
|
}} />
|
||||||
<div className={clsx(
|
<div
|
||||||
'@container',
|
ref={refFallback}
|
||||||
'absolute inset-0 pointer-events-none',
|
className={clsx(
|
||||||
'overflow-hidden',
|
'@container',
|
||||||
(showFallback || shouldDebugImageFallbacks) &&
|
'absolute inset-0 pointer-events-none',
|
||||||
'transition-opacity duration-300 ease-in',
|
'overflow-hidden',
|
||||||
!(BLUR_ENABLED && blurDataURL) && 'bg-main',
|
(showFallback || shouldDebugImageFallbacks) &&
|
||||||
(isLoading || shouldDebugImageFallbacks)
|
'transition-opacity duration-300 ease-in',
|
||||||
? 'opacity-100'
|
!(BLUR_ENABLED && blurDataURL) && 'bg-main',
|
||||||
: 'opacity-0',
|
(isLoading || shouldDebugImageFallbacks)
|
||||||
)}>
|
? 'opacity-100'
|
||||||
|
: 'opacity-0',
|
||||||
|
)}
|
||||||
|
>
|
||||||
{(BLUR_ENABLED && blurDataURL)
|
{(BLUR_ENABLED && blurDataURL)
|
||||||
? <img {...{
|
? <img {...{
|
||||||
...props,
|
...props,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user