'use client'; import { AnimatePresence, motion } from 'framer-motion'; import { useCallback, useEffect, useRef } from 'react'; import { downloadMedia } from '../lib/download'; import { editFilterCss, editTransformCss } from '../lib/edits'; import { formatDate, formatTime } from '../lib/format'; import { Icon } from '../icons'; import { useFocusTrap } from '../hooks/useFocusTrap'; import { useViewMedia } from '../hooks/useViewMedia'; import { useGallery, useGalleryStoreApi } from '../store/context'; import { Annotations } from './editor/Annotations'; import { openShareModal } from './modals'; import { VideoPlayer } from './VideoPlayer'; export function Lightbox() { const api = useGalleryStoreApi(); const lightboxId = useGallery((s) => s.lightboxId); const media = useGallery((s) => s.media); const features = useGallery((s) => s.config.features); const ordered = useViewMedia(); const item = media.find((m) => m.id === lightboxId) ?? null; const index = ordered.findIndex((m) => m.id === lightboxId); const dialogRef = useRef(null); // Escape is handled by the window listener below; trap only manages Tab + focus. useFocusTrap(dialogRef, Boolean(item)); const go = useCallback( (dir: -1 | 1) => { if (index === -1) return; const next = ordered[index + dir]; if (next) api.getState().openLightbox(next.id); }, [api, index, ordered], ); useEffect(() => { if (!lightboxId) return; const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') api.getState().closeLightbox(); else if (e.key === 'ArrowLeft') go(-1); else if (e.key === 'ArrowRight') go(1); }; window.addEventListener('keydown', onKey); return () => window.removeEventListener('keydown', onKey); }, [lightboxId, api, go]); return ( {item ? (
{item.name}
{formatDate(item.takenAt)} · {formatTime(item.takenAt)} {item.location?.place ? ` · ${item.location.place}` : ''}
{features.editor ? ( ) : null} {features.sharing ? ( ) : null} {features.export ? ( ) : null}
{index > 0 ? ( ) : null} {item.kind === 'video' ? ( ) : (
{item.name} {item.edits?.annotations?.length ? ( ) : null}
)}
{index < ordered.length - 1 && index !== -1 ? ( ) : null}
) : null} ); }