'use client'; import { useCallback, useRef } from 'react'; import { Photo, downloadFileNameForPhoto, getNextPhoto, getPreviousPhoto, } from '@/photo'; import { PhotoSetCategory } from '../category'; import PhotoLink from './PhotoLink'; import { pathForAdminPhotoEdit, pathForPhoto } from '@/app/paths'; import { useAppState } from '@/state/AppState'; import { AnimationConfig } from '@/components/AnimateItems'; import { clsx } from 'clsx/lite'; import { FiChevronLeft, FiChevronRight } from 'react-icons/fi'; import useNavigateOrRunActionWithToast from '@/components/useNavigateOrRunActionWithToast'; import { deletePhotoAction, syncPhotoAction, toggleFavoritePhotoAction, } from './actions'; import { isPhotoFav } from '@/tag'; import Tooltip from '@/components/Tooltip'; import { ALLOW_PUBLIC_DOWNLOADS } from '@/app/config'; import { downloadFileFromBrowser } from '@/utility/url'; import useKeydownHandler from '@/utility/useKeydownHandler'; import { KEY_COMMANDS } from './key-commands'; const ANIMATION_LEFT: AnimationConfig = { type: 'left', duration: 0.3 }; const ANIMATION_RIGHT: AnimationConfig = { type: 'right', duration: 0.3 }; export default function PhotoPrevNextActions({ photo, photos = [], className, ...categories }: { photo?: Photo photos?: Photo[] className?: string } & PhotoSetCategory) { const { setNextPhotoAnimation, isUserSignedIn } = useAppState(); const photoTitle = photo ? photo.title ? `'${photo.title}'` : 'photo' : undefined; const downloadUrl = photo?.url; const downloadFileName = photo ? downloadFileNameForPhoto(photo) : undefined; const toggleFavorite = useCallback(() => { if (photo?.id) { return toggleFavoritePhotoAction(photo.id); } }, [photo?.id]); const navigateToPhotoEdit = useNavigateOrRunActionWithToast({ pathOrAction: photo ? pathForAdminPhotoEdit(photo) : undefined, toastMessage: `Editing ${photoTitle} ...`, }); const favoritePhoto = useNavigateOrRunActionWithToast({ pathOrAction: toggleFavorite, toastMessage: `Favoriting ${photoTitle} ...`, }); const unfavoritePhoto = useNavigateOrRunActionWithToast({ pathOrAction: toggleFavorite, toastMessage: `Unfavoriting ${photoTitle} ...`, }); const syncPhoto = useNavigateOrRunActionWithToast({ pathOrAction: useCallback(() => { if (photo?.id) { return syncPhotoAction(photo.id); } }, [photo?.id]), toastMessage: `Syncing ${photoTitle} ...`, }); const deletePhoto = useNavigateOrRunActionWithToast({ pathOrAction: useCallback(() => { if (photo?.id && photo.url) { return deletePhotoAction(photo.id, photo.url, true); } }, [photo?.id, photo?.url]), toastMessage: `Deleting ${photoTitle} ...`, }); const refPrevious = useRef(null); const refNext = useRef(null); const previousPhoto = photo ? getPreviousPhoto(photo, photos) : undefined; const nextPhoto = photo ? getNextPhoto(photo, photos) : undefined; const pathPrevious = previousPhoto ? pathForPhoto({ photo: previousPhoto, ...categories }) : undefined; const pathNext = nextPhoto ? pathForPhoto({ photo: nextPhoto, ...categories }) : undefined; const onKeyDown = useCallback((e: KeyboardEvent) => { switch (e.key.toUpperCase()) { case KEY_COMMANDS.prev[0]: case KEY_COMMANDS.prev[1]: if (pathPrevious) { setNextPhotoAnimation?.(ANIMATION_RIGHT); refPrevious.current?.click(); } break; case KEY_COMMANDS.next[0]: case KEY_COMMANDS.next[1]: if (pathNext) { setNextPhotoAnimation?.(ANIMATION_LEFT); refNext.current?.click(); } break; case KEY_COMMANDS.edit: if (isUserSignedIn) { navigateToPhotoEdit(); } break; case KEY_COMMANDS.favorite: if (isUserSignedIn && photo && !isPhotoFav(photo)) { favoritePhoto(); } break; case KEY_COMMANDS.unfavorite: if (isUserSignedIn && photo && isPhotoFav(photo)) { unfavoritePhoto(); } break; case KEY_COMMANDS.download: if ( (isUserSignedIn || ALLOW_PUBLIC_DOWNLOADS) && downloadUrl && downloadFileName ) { downloadFileFromBrowser(downloadUrl, downloadFileName); } break; case KEY_COMMANDS.sync: if (isUserSignedIn) { syncPhoto(); } break; case KEY_COMMANDS.delete[1]: if (e.metaKey && isUserSignedIn) { deletePhoto(); } break; }; }, [ setNextPhotoAnimation, pathPrevious, pathNext, isUserSignedIn, navigateToPhotoEdit, photo, favoritePhoto, unfavoritePhoto, downloadUrl, downloadFileName, syncPhoto, deletePhoto, ]); useKeydownHandler({ onKeyDown }); return (
PREV / NEXT
); };