From 5f3f73e4c950b791c7b6041da861197b80e57e86 Mon Sep 17 00:00:00 2001 From: Nicolas Varrot Date: Fri, 13 Feb 2026 04:56:47 +0000 Subject: [PATCH] fix: add loading skeleton and error fallback for images - Show a pulsing placeholder while images load - Display a graceful error state with ImageOff icon when images fail to load - Prevents broken image icons from cluttering the chat --- src/components/ImageBlock.tsx | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/components/ImageBlock.tsx b/src/components/ImageBlock.tsx index f6636a2..87776a1 100644 --- a/src/components/ImageBlock.tsx +++ b/src/components/ImageBlock.tsx @@ -1,5 +1,5 @@ import { useState, useEffect, useCallback } from 'react'; -import { X } from 'lucide-react'; +import { X, ImageOff } from 'lucide-react'; interface ImageBlockProps { src: string; @@ -43,6 +43,17 @@ function Lightbox({ src, alt, onClose }: ImageBlockProps & { onClose: () => void export function ImageBlock({ src, alt }: ImageBlockProps) { const [lightbox, setLightbox] = useState(false); + const [error, setError] = useState(false); + const [loading, setLoading] = useState(true); + + if (error) { + return ( +
+ + {alt || 'Image failed to load'} +
+ ); + } return ( <> @@ -53,11 +64,16 @@ export function ImageBlock({ src, alt }: ImageBlockProps) { aria-label={`View ${alt || 'image'} full size`} className="block rounded-xl border border-pc-border cursor-pointer hover:brightness-110 transition-all focus:outline-none focus:ring-2 focus:ring-[var(--pc-accent-dim)]" > + {loading && ( +
+ )} {alt setLoading(false)} + onError={() => { setLoading(false); setError(true); }} />