'use client'; import { ReactNode, useCallback, useEffect, useMemo, useState } from 'react'; import { SelectPhotosContext } from './SelectPhotosState'; import { PARAM_SELECT, PATH_GRID_INFERRED } from '@/app/path'; import { usePathname, useRouter } from 'next/navigation'; import { useAppState } from '@/app/AppState'; import useClientSearchParams from '@/utility/useClientSearchParams'; import { replacePathWithEvent } from '@/utility/url'; import { isElementPartiallyInViewport } from '@/utility/dom'; export const DATA_KEY_PHOTO_GRID = 'data-photo-grid'; export default function SelectPhotosProvider({ children, }: { children: ReactNode }) { const router = useRouter(); const pathname = usePathname(); const { isUserSignedIn } = useAppState(); const searchParamsSelect = useClientSearchParams( PARAM_SELECT, // Only scan urls when admin is signed in isUserSignedIn, ); const [canCurrentPageSelectPhotos, setCanCurrentPageSelectPhotos] = useState(false); const [selectedPhotoIds, setSelectedPhotoIds] = useState([]); const [isPerformingSelectEdit, setIsPerformingSelectEdit] = useState(false); const getPhotoGridElements = useCallback(() => document.querySelectorAll(`[${DATA_KEY_PHOTO_GRID}=true]`) , []); useEffect(() => { if (isUserSignedIn) { const doesPageHavePhotoGrids = getPhotoGridElements().length > 0; // eslint-disable-next-line react-hooks/set-state-in-effect setCanCurrentPageSelectPhotos(doesPageHavePhotoGrids); } }, [pathname, isUserSignedIn, getPhotoGridElements]); const isSelectingPhotos = useMemo(() => isUserSignedIn && searchParamsSelect === 'true' , [isUserSignedIn, searchParamsSelect]); const startSelectingPhotos = useCallback(() => canCurrentPageSelectPhotos // Use replacePathWithEvent because only query params change ? replacePathWithEvent(`${pathname}?${PARAM_SELECT}=true`) // Redirect to grid if current view does not support photo selection : router.push(`${PATH_GRID_INFERRED}?${PARAM_SELECT}=true`) , [router, canCurrentPageSelectPhotos, pathname]); const stopSelectingPhotos = useCallback(() => replacePathWithEvent(pathname) , [pathname]); useEffect(() => { if (isSelectingPhotos) { const photoGrids = Array.from(getPhotoGridElements()); const isSomePhotoGridVisible = photoGrids .some(element => isElementPartiallyInViewport(element, -20)); if (!isSomePhotoGridVisible) { photoGrids[0]?.scrollIntoView({ behavior: 'smooth' }); } } else { // eslint-disable-next-line react-hooks/set-state-in-effect setSelectedPhotoIds([]); } }, [isSelectingPhotos, getPhotoGridElements]); return ( {children} ); }