Avoid original image preview fallback

This commit is contained in:
Codex
2026-05-13 05:30:47 +00:00
parent a2b2fb82ba
commit 2fcf9c9773

View File

@@ -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}`}