From f569c8ded22580beee0b0c219459584e844c500a Mon Sep 17 00:00:00 2001 From: Richard R Date: Thu, 28 May 2026 04:51:04 -0600 Subject: [PATCH] style(doclist): improve gallery view tile visuals and image preview readiness Update gallery view document tiles with refined border, shadow, and background styles for better visual feedback and accessibility. Enhance image preview component to immediately reveal cached images by checking decode state on mount, preventing opacity glitches on remount. Adjust gallery rail scrolling to reset on document list changes for consistent navigation. --- src/components/doclist/DocumentPreview.tsx | 13 ++++++ src/components/doclist/views/GalleryView.tsx | 49 ++++++++++++++++---- 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/components/doclist/DocumentPreview.tsx b/src/components/doclist/DocumentPreview.tsx index 6210a3f..7f23165 100644 --- a/src/components/doclist/DocumentPreview.tsx +++ b/src/components/doclist/DocumentPreview.tsx @@ -62,6 +62,7 @@ export function DocumentPreview({ doc }: DocumentPreviewProps) { lowerName.endsWith('.mkd')); const containerRef = useRef(null); + const imageRef = useRef(null); const [isVisible, setIsVisible] = useState(false); const [imagePreview, setImagePreview] = useState(null); const [isImageReady, setIsImageReady] = useState(false); @@ -206,6 +207,17 @@ export function DocumentPreview({ doc }: DocumentPreviewProps) { setIsImageReady(false); }, [imagePreview]); + // Cached blob/http sources can already be decoded before React's onLoad handler + // runs on remount, leaving opacity at 0. Promote already-complete images. + useEffect(() => { + if (!imagePreview) return; + const img = imageRef.current; + if (!img) return; + if (img.complete && img.naturalWidth > 0) { + setIsImageReady(true); + } + }, [imagePreview]); + const gradientClass = isPDF ? 'from-red-500/80 via-red-400/60 to-red-600/80' : isEPUB @@ -246,6 +258,7 @@ export function DocumentPreview({ doc }: DocumentPreviewProps) { ) : null} {/* eslint-disable-next-line @next/next/no-img-element */} {`${doc.name} -
- - {doc.name} +
+ + + {doc.name} +
); @@ -92,6 +111,7 @@ export function GalleryView({ onMergeIntoFolder, }: GalleryViewProps) { const { setVisibleOrder } = useDocumentSelection(); + const railRef = useRef(null); const [activeIdx, setActiveIdx] = useState(0); const activeDoc = useMemo(() => documents[activeIdx], [documents, activeIdx]); @@ -105,6 +125,12 @@ export function GalleryView({ } }, [documents.length, activeIdx]); + useEffect(() => { + const rail = railRef.current; + if (!rail) return; + rail.scrollLeft = 0; + }, [documents.length]); + useEffect(() => { const onKey = (e: KeyboardEvent) => { const target = e.target as HTMLElement; @@ -156,8 +182,11 @@ export function GalleryView({ )} -
-
+
+
{documents.map((doc, i) => (