Avoid original image preview fallback
This commit is contained in:
@@ -164,17 +164,20 @@ export function CachedPreviewImage({
|
||||
}: CachedPreviewImageProps) {
|
||||
const [previewUrl, setPreviewUrl] = useState('');
|
||||
const [size, setSize] = useState<{ width: number; height: number } | null>(null);
|
||||
const [previewFailed, setPreviewFailed] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!src) {
|
||||
setPreviewUrl('');
|
||||
setSize(null);
|
||||
setPreviewFailed(false);
|
||||
return;
|
||||
}
|
||||
|
||||
let cancelled = false;
|
||||
let objectUrl = '';
|
||||
setSize(null);
|
||||
setPreviewFailed(false);
|
||||
|
||||
const usePreview = (preview: CachedPreview) => {
|
||||
if (cancelled) return;
|
||||
@@ -184,21 +187,25 @@ export function CachedPreviewImage({
|
||||
setPreviewUrl(objectUrl);
|
||||
};
|
||||
|
||||
getCachedPreview(src)
|
||||
.then(cached => {
|
||||
if (cancelled) return;
|
||||
if (cached?.blob) {
|
||||
usePreview(cached);
|
||||
return;
|
||||
}
|
||||
return createPreview(src).then(created => {
|
||||
if (cancelled) return;
|
||||
usePreview(created);
|
||||
void setCachedPreview(src, created).catch(() => undefined);
|
||||
});
|
||||
})
|
||||
async function loadPreview() {
|
||||
const cached = await getCachedPreview(src).catch(() => null);
|
||||
if (cancelled) return;
|
||||
if (cached?.blob) {
|
||||
usePreview(cached);
|
||||
return;
|
||||
}
|
||||
|
||||
const created = await createPreview(src);
|
||||
if (cancelled) return;
|
||||
usePreview(created);
|
||||
void setCachedPreview(src, created).catch(() => undefined);
|
||||
}
|
||||
|
||||
loadPreview()
|
||||
.catch(() => {
|
||||
if (!cancelled) setPreviewUrl('');
|
||||
if (cancelled) return;
|
||||
setPreviewUrl('');
|
||||
setPreviewFailed(true);
|
||||
});
|
||||
|
||||
return () => {
|
||||
@@ -207,7 +214,7 @@ export function CachedPreviewImage({
|
||||
};
|
||||
}, [src]);
|
||||
|
||||
const displaySrc = useMemo(() => previewUrl || src, [previewUrl, src]);
|
||||
const displaySrc = useMemo(() => previewUrl || (previewFailed ? src : ''), [previewFailed, previewUrl, src]);
|
||||
const metadataLabel = useMemo(() => {
|
||||
if (!size) return '';
|
||||
return `${getAspectLabel(size.width, size.height)} · ${size.width}×${size.height}`;
|
||||
@@ -225,18 +232,26 @@ export function CachedPreviewImage({
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src={displaySrc}
|
||||
alt={alt}
|
||||
className={className}
|
||||
style={style}
|
||||
onClick={onClick}
|
||||
onDoubleClick={onDoubleClick}
|
||||
onLoad={handleLoad}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
{displaySrc ? (
|
||||
/* eslint-disable-next-line @next/next/no-img-element */
|
||||
<img
|
||||
src={displaySrc}
|
||||
alt={alt}
|
||||
className={className}
|
||||
style={style}
|
||||
onClick={onClick}
|
||||
onDoubleClick={onDoubleClick}
|
||||
onLoad={handleLoad}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
className={`animate-pulse bg-muted/60 ${className}`}
|
||||
style={style}
|
||||
aria-label={alt}
|
||||
/>
|
||||
)}
|
||||
{metadataLabel && (
|
||||
<div
|
||||
className={`rounded-full border border-white/24 bg-black/48 px-3 py-1.5 text-xs font-semibold text-white shadow-[0_10px_32px_rgba(0,0,0,0.35)] backdrop-blur-md light:border-amber-900/18 light:bg-white/60 light:text-foreground light:shadow-[0_10px_32px_rgba(83,61,27,0.14)] ${badgeClassName}`}
|
||||
|
||||
Reference in New Issue
Block a user