Add basic show/hide recipe behavior

This commit is contained in:
Sam Becker 2025-02-22 19:10:05 -06:00
parent bd733a285a
commit 78a4d03f6a
2 changed files with 48 additions and 54 deletions

View File

@ -32,7 +32,7 @@ import {
} from '@/app/config'; } from '@/app/config';
import AdminPhotoMenuClient from '@/admin/AdminPhotoMenuClient'; import AdminPhotoMenuClient from '@/admin/AdminPhotoMenuClient';
import { RevalidatePhoto } from './InfinitePhotoScroll'; import { RevalidatePhoto } from './InfinitePhotoScroll';
import { useRef } from 'react'; import { useRef, useState } from 'react';
import useVisible from '@/utility/useVisible'; import useVisible from '@/utility/useVisible';
import PhotoDate from './PhotoDate'; import PhotoDate from './PhotoDate';
import { useAppState } from '@/state/AppState'; import { useAppState } from '@/state/AppState';
@ -41,6 +41,8 @@ import LoaderButton from '@/components/primitives/LoaderButton';
import Tooltip from '@/components/Tooltip'; import Tooltip from '@/components/Tooltip';
import ZoomControls, { ZoomControlsRef } from '@/components/image/ZoomControls'; import ZoomControls, { ZoomControlsRef } from '@/components/image/ZoomControls';
import PhotoRecipe from './PhotoRecipe'; import PhotoRecipe from './PhotoRecipe';
import { TbChecklist } from 'react-icons/tb';
import { IoCloseSharp } from 'react-icons/io5';
export default function PhotoLarge({ export default function PhotoLarge({
photo, photo,
@ -89,6 +91,8 @@ export default function PhotoLarge({
const zoomControlsRef = useRef<ZoomControlsRef>(null); const zoomControlsRef = useRef<ZoomControlsRef>(null);
const [shouldShowRecipe, setShouldShowRecipe] = useState(false);
const { const {
areZoomControlsShown, areZoomControlsShown,
arePhotosMatted, arePhotosMatted,
@ -165,14 +169,14 @@ export default function PhotoLarge({
priority={priority} priority={priority}
/> />
</ZoomControls> </ZoomControls>
{photo.fujifilmRecipe && photo.filmSimulation && {shouldShowRecipe && photo.fujifilmRecipe && photo.filmSimulation &&
<div className={clsx( <div className={clsx(
'absolute inset-0', 'absolute inset-0',
'flex items-center justify-center', 'flex items-center justify-center',
)}> )}>
<PhotoRecipe <PhotoRecipe
recipe={photo.fujifilmRecipe!} recipe={photo.fujifilmRecipe}
simulation={photo.filmSimulation!} simulation={photo.filmSimulation}
iso={photo.isoFormatted} iso={photo.isoFormatted}
exposure={photo.exposureCompensationFormatted} exposure={photo.exposureCompensationFormatted}
/> />
@ -289,11 +293,30 @@ export default function PhotoLarge({
<li>{photo.exposureCompensationFormatted ?? '0ev'}</li> <li>{photo.exposureCompensationFormatted ?? '0ev'}</li>
</ul> </ul>
{showSimulation && photo.filmSimulation && {showSimulation && photo.filmSimulation &&
<PhotoFilmSimulation <div className="flex items-center gap-2 *:w-auto">
simulation={photo.filmSimulation} <PhotoFilmSimulation
prefetch={prefetchRelatedLinks} simulation={photo.filmSimulation}
recipe={photo.fujifilmRecipe} prefetch={prefetchRelatedLinks}
/>} />
{photo.fujifilmRecipe &&
<Tooltip content="Fujifilm Recipe">
<button
onClick={() => setShouldShowRecipe(!shouldShowRecipe)}
className={clsx(
'text-medium',
'border-medium rounded-md',
'px-[4px] py-[2.5px] my-[-2.5px]',
'hover:bg-dim active:bg-main',
)}>
{shouldShowRecipe
? <IoCloseSharp size={15} />
: <TbChecklist
className="translate-x-[0.5px]"
size={15}
/>}
</button>
</Tooltip>}
</div>}
</>} </>}
<div className={clsx( <div className={clsx(
'flex gap-x-3 gap-y-baseline', 'flex gap-x-3 gap-y-baseline',

View File

@ -1,5 +1,3 @@
'use client';
import { labelForFilmSimulation } from '@/platforms/fujifilm/simulation'; import { labelForFilmSimulation } from '@/platforms/fujifilm/simulation';
import PhotoFilmSimulationIcon from './PhotoFilmSimulationIcon'; import PhotoFilmSimulationIcon from './PhotoFilmSimulationIcon';
import { pathForFilmSimulation } from '@/app/paths'; import { pathForFilmSimulation } from '@/app/paths';
@ -8,11 +6,7 @@ import { FujifilmRecipe } from '@/platforms/fujifilm/recipe';
import EntityLink, { import EntityLink, {
EntityLinkExternalProps, EntityLinkExternalProps,
} from '@/components/primitives/EntityLink'; } from '@/components/primitives/EntityLink';
import { LuChevronsUpDown } from 'react-icons/lu';
import clsx from 'clsx/lite'; import clsx from 'clsx/lite';
import { useState } from 'react';
import Tooltip from '@/components/Tooltip';
import PhotoRecipe from '@/photo/PhotoRecipe';
export default function PhotoFilmSimulation({ export default function PhotoFilmSimulation({
simulation, simulation,
@ -21,8 +15,6 @@ export default function PhotoFilmSimulation({
contrast = 'low', contrast = 'low',
prefetch, prefetch,
countOnHover, countOnHover,
recipe,
className,
}: { }: {
simulation: FilmSimulation simulation: FilmSimulation
countOnHover?: number countOnHover?: number
@ -31,43 +23,22 @@ export default function PhotoFilmSimulation({
} & EntityLinkExternalProps) { } & EntityLinkExternalProps) {
const { small, medium, large } = labelForFilmSimulation(simulation); const { small, medium, large } = labelForFilmSimulation(simulation);
const [shouldShowRecipe, setShouldShowRecipe] = useState(false);
return ( return (
<div className={clsx('space-y-baseline', className)}> <EntityLink
<div className="flex items-center gap-2 *:w-auto"> label={medium}
<EntityLink labelSmall={small}
label={medium} href={pathForFilmSimulation(simulation)}
labelSmall={small} icon={<PhotoFilmSimulationIcon
href={pathForFilmSimulation(simulation)} simulation={simulation}
icon={<PhotoFilmSimulationIcon className={clsx(contrast === 'frosted' && 'text-black')}
simulation={simulation} />}
className={clsx(contrast === 'frosted' && 'text-black')} title={`Film Simulation: ${large}`}
/>} type={type}
title={`Film Simulation: ${large}`} badged={badged}
type={type} contrast={contrast}
badged={badged} prefetch={prefetch}
contrast={contrast} hoverEntity={countOnHover}
prefetch={prefetch} iconWide
hoverEntity={countOnHover} />
iconWide
/>
{recipe &&
<Tooltip content="Fujifilm Recipe">
<button
onClick={() => setShouldShowRecipe(!shouldShowRecipe)}
className={clsx(
'text-medium',
'border-medium rounded-md',
'px-[4px] py-[2.5px] my-[-2.5px]',
'hover:bg-dim active:bg-main',
)}>
<LuChevronsUpDown size={15} />
</button>
</Tooltip>}
</div>
{recipe && shouldShowRecipe &&
<PhotoRecipe {...{ recipe, simulation }} />}
</div>
); );
} }