Finalize recipe query param handling
This commit is contained in:
parent
4ff7473a00
commit
0872834db5
@ -110,8 +110,8 @@ export const pathForPhoto = ({
|
||||
simulation,
|
||||
focal,
|
||||
showRecipe,
|
||||
}: PhotoPathParams) =>
|
||||
typeof photo !== 'string' && photo.hidden
|
||||
}: PhotoPathParams) => {
|
||||
const path = typeof photo !== 'string' && photo.hidden
|
||||
? `${pathForTag(TAG_HIDDEN)}/${getPhotoId(photo)}`
|
||||
: tag
|
||||
? `${pathForTag(tag)}/${getPhotoId(photo)}`
|
||||
@ -121,9 +121,11 @@ export const pathForPhoto = ({
|
||||
? `${pathForFilmSimulation(simulation)}/${getPhotoId(photo)}`
|
||||
: focal
|
||||
? `${pathForFocalLength(focal)}/${getPhotoId(photo)}`
|
||||
: `${PREFIX_PHOTO}/${getPhotoId(photo)}` + (showRecipe
|
||||
? `?${SEARCH_PARAM_SHOW}=${SEARCH_PARAM_SHOW_RECIPE}`
|
||||
: '');
|
||||
: `${PREFIX_PHOTO}/${getPhotoId(photo)}`;
|
||||
return showRecipe
|
||||
? `${path}?${SEARCH_PARAM_SHOW}=${SEARCH_PARAM_SHOW_RECIPE}`
|
||||
: path;
|
||||
};
|
||||
|
||||
export const pathForTag = (tag: string) =>
|
||||
`${PREFIX_TAG}/${tag}`;
|
||||
|
||||
@ -12,12 +12,7 @@ import SiteGrid from '@/components/SiteGrid';
|
||||
import ImageLarge from '@/components/image/ImageLarge';
|
||||
import { clsx } from 'clsx/lite';
|
||||
import Link from 'next/link';
|
||||
import {
|
||||
pathForFocalLength,
|
||||
pathForPhoto,
|
||||
SEARCH_PARAM_SHOW,
|
||||
SEARCH_PARAM_SHOW_RECIPE,
|
||||
} from '@/app/paths';
|
||||
import { pathForFocalLength, pathForPhoto } from '@/app/paths';
|
||||
import PhotoTags from '@/tag/PhotoTags';
|
||||
import ShareButton from '@/share/ShareButton';
|
||||
import DownloadButton from '@/components/DownloadButton';
|
||||
@ -34,7 +29,7 @@ import {
|
||||
} from '@/app/config';
|
||||
import AdminPhotoMenuClient from '@/admin/AdminPhotoMenuClient';
|
||||
import { RevalidatePhoto } from './InfinitePhotoScroll';
|
||||
import { useRef, useState } from 'react';
|
||||
import { useRef } from 'react';
|
||||
import useVisible from '@/utility/useVisible';
|
||||
import PhotoDate from './PhotoDate';
|
||||
import { useAppState } from '@/state/AppState';
|
||||
@ -45,7 +40,8 @@ import ZoomControls, { ZoomControlsRef } from '@/components/image/ZoomControls';
|
||||
import PhotoRecipe from './PhotoRecipe';
|
||||
import { TbChecklist } from 'react-icons/tb';
|
||||
import { IoCloseSharp } from 'react-icons/io5';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import useRecipeState from './useRecipeState';
|
||||
|
||||
export default function PhotoLarge({
|
||||
photo,
|
||||
@ -94,12 +90,6 @@ export default function PhotoLarge({
|
||||
|
||||
const zoomControlsRef = useRef<ZoomControlsRef>(null);
|
||||
|
||||
const params = useSearchParams();
|
||||
const showRecipeInitially =
|
||||
params.get(SEARCH_PARAM_SHOW) === SEARCH_PARAM_SHOW_RECIPE;
|
||||
const [shouldShowRecipe, setShouldShowRecipe] = useState(showRecipeInitially);
|
||||
const recipeButtonRef = useRef<HTMLButtonElement>(null);
|
||||
|
||||
const {
|
||||
areZoomControlsShown,
|
||||
arePhotosMatted,
|
||||
@ -108,6 +98,12 @@ export default function PhotoLarge({
|
||||
|
||||
const showZoomControls = showZoomControlsProp && areZoomControlsShown;
|
||||
|
||||
const {
|
||||
shouldShowRecipe,
|
||||
toggleRecipe,
|
||||
recipeButtonRef,
|
||||
} = useRecipeState();
|
||||
|
||||
const tags = sortTags(photo.tags, primaryTag);
|
||||
|
||||
const camera = cameraFromPhoto(photo);
|
||||
@ -176,20 +172,24 @@ export default function PhotoLarge({
|
||||
priority={priority}
|
||||
/>
|
||||
</ZoomControls>
|
||||
{shouldShowRecipe && photo.fujifilmRecipe && photo.filmSimulation &&
|
||||
<div className={clsx(
|
||||
'absolute inset-0',
|
||||
'flex items-center justify-center',
|
||||
)}>
|
||||
<PhotoRecipe
|
||||
recipe={photo.fujifilmRecipe}
|
||||
simulation={photo.filmSimulation}
|
||||
iso={photo.isoFormatted}
|
||||
exposure={photo.exposureCompensationFormatted}
|
||||
onClose={() => setShouldShowRecipe(false)}
|
||||
externalTriggerRef={recipeButtonRef}
|
||||
/>
|
||||
</div>}
|
||||
<AnimatePresence>
|
||||
{shouldShowRecipe && photo.fujifilmRecipe && photo.filmSimulation &&
|
||||
<motion.div
|
||||
className={clsx(
|
||||
'absolute inset-0',
|
||||
'flex items-center justify-center',
|
||||
)}
|
||||
>
|
||||
<PhotoRecipe
|
||||
recipe={photo.fujifilmRecipe}
|
||||
simulation={photo.filmSimulation}
|
||||
iso={photo.isoFormatted}
|
||||
exposure={photo.exposureCompensationFormatted}
|
||||
onClose={toggleRecipe}
|
||||
externalTriggerRef={recipeButtonRef}
|
||||
/>
|
||||
</motion.div>}
|
||||
</AnimatePresence>
|
||||
</div>;
|
||||
|
||||
const largePhotoContainerClassName = clsx(arePhotosMatted &&
|
||||
@ -311,7 +311,7 @@ export default function PhotoLarge({
|
||||
<button
|
||||
ref={recipeButtonRef}
|
||||
title="Fujifilm Recipe"
|
||||
onClick={() => setShouldShowRecipe(!shouldShowRecipe)}
|
||||
onClick={toggleRecipe}
|
||||
className={clsx(
|
||||
'text-medium',
|
||||
'border-medium rounded-md',
|
||||
|
||||
62
src/photo/useRecipeState.ts
Normal file
62
src/photo/useRecipeState.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import {
|
||||
getPathComponents,
|
||||
pathForPhoto,
|
||||
SEARCH_PARAM_SHOW_RECIPE,
|
||||
} from '@/app/paths';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { SEARCH_PARAM_SHOW } from '@/app/paths';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import { useCallback, useRef, useState } from 'react';
|
||||
|
||||
export default function useRecipeState() {
|
||||
const pathname = usePathname();
|
||||
const params = useSearchParams();
|
||||
|
||||
const {
|
||||
photoId,
|
||||
...pathComponents
|
||||
} = getPathComponents(pathname);
|
||||
const showRecipeInitially =
|
||||
params.get(SEARCH_PARAM_SHOW) === SEARCH_PARAM_SHOW_RECIPE;
|
||||
|
||||
const [shouldShowRecipe, setShouldShowRecipe] = useState(showRecipeInitially);
|
||||
|
||||
const recipeButtonRef = useRef<HTMLButtonElement>(null);
|
||||
|
||||
const toggleRecipe = useCallback(() => {
|
||||
if (shouldShowRecipe) {
|
||||
setShouldShowRecipe(false);
|
||||
// Only remove query param for photo details
|
||||
if (photoId) {
|
||||
window.history.pushState(
|
||||
null,
|
||||
'',
|
||||
pathForPhoto({
|
||||
photo: photoId,
|
||||
...pathComponents,
|
||||
}),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
setShouldShowRecipe(true);
|
||||
// Only add query param for photo details
|
||||
if (photoId) {
|
||||
window.history.pushState(
|
||||
null,
|
||||
'',
|
||||
pathForPhoto({
|
||||
photo: photoId,
|
||||
...pathComponents,
|
||||
showRecipe: true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}, [pathComponents, photoId, shouldShowRecipe]);
|
||||
|
||||
return {
|
||||
toggleRecipe,
|
||||
recipeButtonRef,
|
||||
shouldShowRecipe,
|
||||
};
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user