import { memo, useCallback, useEffect, useEffectEvent, useState } from "react"; import { ChevronLeftIcon, ChevronRightIcon, XIcon } from "lucide-react"; import { Button } from "../ui/button"; import type { ExpandedImagePreview } from "./ExpandedImagePreview"; interface ExpandedImageDialogProps { preview: ExpandedImagePreview; onClose: () => void; } function useExpandedImageDialogKeyboardShortcuts(input: { readonly imageCount: number; readonly onClose: () => void; readonly onNavigate: (direction: -1 | 1) => void; }) { const close = useEffectEvent(input.onClose); const navigate = useEffectEvent(input.onNavigate); useEffect(() => { const onKeyDown = (event: globalThis.KeyboardEvent) => { if (event.key === "Escape") { event.preventDefault(); event.stopPropagation(); close(); return; } if (input.imageCount <= 1) return; if (event.key === "ArrowLeft") { event.preventDefault(); event.stopPropagation(); navigate(-1); return; } if (event.key !== "ArrowRight") return; event.preventDefault(); event.stopPropagation(); navigate(1); }; window.addEventListener("keydown", onKeyDown); return () => window.removeEventListener("keydown", onKeyDown); }, [close, input.imageCount, navigate]); } export const ExpandedImageDialog = memo(function ExpandedImageDialog({ preview, onClose, }: ExpandedImageDialogProps) { const [navigationOffset, setNavigationOffset] = useState(0); const imageCount = preview.images.length; const activeIndex = imageCount > 0 ? (preview.index + navigationOffset + imageCount) % imageCount : preview.index; const navigateImage = useCallback( (direction: -1 | 1) => { setNavigationOffset((offset) => { if (imageCount <= 1) return offset; return offset + direction; }); }, [imageCount], ); useExpandedImageDialogKeyboardShortcuts({ imageCount, onClose, onNavigate: navigateImage, }); const item = preview.images[activeIndex]; if (!item) return null; return (
)}
{item.name}

{item.name} {imageCount > 1 ? ` (${activeIndex + 1}/${imageCount})` : ""}

{imageCount > 1 && ( )}
); });