import { useEffect, useState } from 'react'; import { debugImageProxyUrl, type DebugImageSearchManyResult, type DebugImageSearchResultItem } from '../api/client'; import './DebugSearchResultsModal.css'; function formatResolution(width?: number, height?: number): string | null { if (!width || !height || width <= 0 || height <= 0) return null; return `${width} × ${height}`; } function ResultResolution({ item, searchUrl, }: { item: DebugImageSearchResultItem; searchUrl: string; }) { const initial = formatResolution(item.width, item.height); const [label, setLabel] = useState(initial); useEffect(() => { if (initial) { setLabel(initial); return; } let cancelled = false; const img = new Image(); img.onload = () => { if (cancelled) return; const text = formatResolution(img.naturalWidth, img.naturalHeight); setLabel(text ?? '—'); }; img.onerror = () => { if (!cancelled) setLabel('—'); }; img.src = debugImageProxyUrl(item.imageUrl, { searchUrl, source: item.source, }); return () => { cancelled = true; img.onload = null; img.onerror = null; }; }, [item.imageUrl, item.source, item.width, item.height, searchUrl, initial]); return ( ); } interface Props { open: boolean; title: string; data: DebugImageSearchManyResult | null; loading: boolean; error: string | null; applyingUrl: string | null; onClose: () => void; onSelect: (item: DebugImageSearchResultItem) => void; } export default function DebugSearchResultsModal({ open, title, data, loading, error, applyingUrl, onClose, onSelect, }: Props) { useEffect(() => { if (!open) return; const onKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; window.addEventListener('keydown', onKeyDown); return () => window.removeEventListener('keydown', onKeyDown); }, [open, onClose]); if (!open) return null; return (
e.stopPropagation()}>

{title}

{data?.query &&

{data.query}

}
{loading &&

Loading results…

} {error &&

{error}

} {!loading && !error && data && data.results.length === 0 && (

No images found.

)} {!loading && data && data.results.length > 0 && ( <>

Click an image to replace the current one.

{data.results.map((item, index) => { const busy = applyingUrl === item.imageUrl; return ( ); })}
)}
); }