From 6c3f5eda0a4e4322e0f9bbfa77f42abf9df63619 Mon Sep 17 00:00:00 2001 From: kang Date: Tue, 19 May 2026 20:35:16 +0800 Subject: [PATCH] fix: preserve result thumbnail aspect ratios --- src/components/HoverImagePreview.tsx | 7 ++++++- src/components/ResultGrid.tsx | 21 +++++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/components/HoverImagePreview.tsx b/src/components/HoverImagePreview.tsx index f2a2d43..d222e62 100644 --- a/src/components/HoverImagePreview.tsx +++ b/src/components/HoverImagePreview.tsx @@ -11,7 +11,9 @@ type PreviewState = { function parseRatio(aspectRatio?: string) { if (!aspectRatio || aspectRatio === 'long') return aspectRatio === 'long' ? 1 / 3 : 1; - const [w, h] = aspectRatio.split(':').map(Number); + const [w, h] = aspectRatio.includes('/') + ? aspectRatio.split('/').map(part => Number(part.trim())) + : aspectRatio.split(':').map(Number); return w && h ? w / h : 1; } @@ -42,11 +44,13 @@ export function HoverImagePreview({ alt, imageClassName, aspectRatio, + onImageLoad, }: { src: string; alt: string; imageClassName?: string; aspectRatio?: string; + onImageLoad?: (image: HTMLImageElement) => void; }) { const [preview, setPreview] = useState(null); @@ -61,6 +65,7 @@ export function HoverImagePreview({ setPreview(nextPreviewState(event, aspectRatio)); }} onPointerLeave={() => setPreview(null)} + onLoad={event => onImageLoad?.(event.currentTarget)} /> {preview && (
>({}); + useEffect(() => { function handler(e: KeyboardEvent) { const target = e.target as HTMLElement; @@ -27,7 +29,7 @@ export default function ResultGrid({ images, onAction }: ResultGridProps) { return () => window.removeEventListener('keydown', handler); }, [images, onAction]); - const cols = images.length <= 4 ? 'grid-cols-2' : images.length <= 9 ? 'grid-cols-3' : 'grid-cols-4'; + const cols = images.length === 1 ? 'grid-cols-[minmax(220px,520px)]' : images.length <= 4 ? 'grid-cols-2' : images.length <= 9 ? 'grid-cols-3' : 'grid-cols-4'; const selectedCount = images.filter(i => i.status === 'selected').length; return ( @@ -51,13 +53,24 @@ export default function ResultGrid({ images, onAction }: ResultGridProps) {
-
+
{images.map((img, i) => (
- + { + if (!image.naturalWidth || !image.naturalHeight) return; + const next = `${image.naturalWidth} / ${image.naturalHeight}`; + setRatios(prev => prev[img.id] === next ? prev : { ...prev, [img.id]: next }); + }} + />
{i + 1}
{img.status === 'selected' && (