diff --git a/src/components/AnimateItems.tsx b/src/components/AnimateItems.tsx index 797cf986..f268e8a4 100644 --- a/src/components/AnimateItems.tsx +++ b/src/components/AnimateItems.tsx @@ -48,9 +48,12 @@ function AnimateItems({ const { hasLoaded, nextPhotoAnimation, + getNextPhotoAnimationId, clearNextPhotoAnimation, } = useAppState(); + const nextPhotoAnimationId = useRef(undefined); + const prefersReducedMotion = usePrefersReducedMotion(); const hasLoadedInitial = useRef(hasLoaded); @@ -104,9 +107,12 @@ function AnimateItems({ }, }, } : undefined} + onAnimationStart={() => { + nextPhotoAnimationId.current = getNextPhotoAnimationId?.(); + }} onAnimationComplete={() => { if (animateFromAppState) { - clearNextPhotoAnimation?.(); + clearNextPhotoAnimation?.(nextPhotoAnimationId.current); } onAnimationComplete?.(); }} diff --git a/src/photo/PhotoLink.tsx b/src/photo/PhotoLink.tsx index 71e763f8..57bcc88b 100644 --- a/src/photo/PhotoLink.tsx +++ b/src/photo/PhotoLink.tsx @@ -39,6 +39,7 @@ export default function PhotoLink({ href: pathForPhoto({ photo, ...categories }), onClick: () => { if (nextPhotoAnimation) { + console.log('setNextPhotoAnimation', nextPhotoAnimation); setNextPhotoAnimation?.(nextPhotoAnimation); } }, diff --git a/src/state/AppState.ts b/src/state/AppState.ts index 590a6ebc..c7da18b3 100644 --- a/src/state/AppState.ts +++ b/src/state/AppState.ts @@ -21,8 +21,9 @@ export type AppStateContextType = { swrTimestamp?: number invalidateSwr?: () => void nextPhotoAnimation?: AnimationConfig - setNextPhotoAnimation?: Dispatch> - clearNextPhotoAnimation?: () => void + setNextPhotoAnimation?: (animationConfig?: AnimationConfig) => void + getNextPhotoAnimationId?: () => string + clearNextPhotoAnimation?: (id?: string) => void shouldRespondToKeyboardCommands?: boolean setShouldRespondToKeyboardCommands?: Dispatch> categoriesWithCounts?: diff --git a/src/state/AppStateProvider.tsx b/src/state/AppStateProvider.tsx index db8c9f6e..f83d0cc9 100644 --- a/src/state/AppStateProvider.tsx +++ b/src/state/AppStateProvider.tsx @@ -25,6 +25,7 @@ import { isPathAdmin, PATH_ROOT } from '@/app/paths'; import { INITIAL_UPLOAD_STATE, UploadState } from '@/admin/upload'; import { RecipeProps } from '@/recipe'; import { getCountsForCategoriesCachedAction } from '@/category/actions'; +import { nanoid } from 'nanoid'; export default function AppStateProvider({ children, @@ -42,8 +43,25 @@ export default function AppStateProvider({ useState(false); const [swrTimestamp, setSwrTimestamp] = useState(Date.now()); - const [nextPhotoAnimation, setNextPhotoAnimation] = + const [nextPhotoAnimation, _setNextPhotoAnimation] = useState(); + const setNextPhotoAnimation = useCallback((animation?: AnimationConfig) => { + _setNextPhotoAnimation(animation); + setNextPhotoAnimationId(undefined); + }, []); + const [nextPhotoAnimationId, setNextPhotoAnimationId] = + useState(); + const getNextPhotoAnimationId = useCallback(() => { + const id = nanoid(); + setNextPhotoAnimationId(id); + return id; + }, []); + const clearNextPhotoAnimation = useCallback((id?: string) => { + if (id === nextPhotoAnimationId) { + setNextPhotoAnimation(undefined); + setNextPhotoAnimationId(undefined); + } + }, [nextPhotoAnimationId, setNextPhotoAnimation]); const [shouldRespondToKeyboardCommands, setShouldRespondToKeyboardCommands] = useState(true); // MODAL @@ -172,7 +190,8 @@ export default function AppStateProvider({ invalidateSwr, nextPhotoAnimation, setNextPhotoAnimation, - clearNextPhotoAnimation: () => setNextPhotoAnimation?.(undefined), + getNextPhotoAnimationId, + clearNextPhotoAnimation, shouldRespondToKeyboardCommands, setShouldRespondToKeyboardCommands, categoriesWithCounts,