86 lines
2.7 KiB
TypeScript
86 lines
2.7 KiB
TypeScript
'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 } from 'next/navigation';
|
|
import { useAppState } from '@/app/AppState';
|
|
import useClientSearchParams from '@/utility/useClientSearchParams';
|
|
import { pushPathWithEvent } 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 pathname = usePathname();
|
|
|
|
const { isUserSignedIn } = useAppState();
|
|
|
|
const searchParamsSelect = useClientSearchParams(PARAM_SELECT);
|
|
|
|
const [canCurrentPageSelectPhotos, setCanCurrentPageSelectPhotos] =
|
|
useState(false);
|
|
const [selectedPhotoIds, setSelectedPhotoIds] =
|
|
useState<string[]>([]);
|
|
const [isPerformingSelectEdit, setIsPerformingSelectEdit] =
|
|
useState(false);
|
|
|
|
const getPhotoGridElements = useCallback(() =>
|
|
document.querySelectorAll(`[${DATA_KEY_PHOTO_GRID}]`)
|
|
, []);
|
|
|
|
useEffect(() => {
|
|
const doesPageHavePhotoGrids = getPhotoGridElements().length > 0;
|
|
setCanCurrentPageSelectPhotos(doesPageHavePhotoGrids);
|
|
}, [pathname, getPhotoGridElements]);
|
|
|
|
const isSelectingPhotos = useMemo(() =>
|
|
isUserSignedIn &&
|
|
searchParamsSelect === 'true'
|
|
, [isUserSignedIn, searchParamsSelect]);
|
|
|
|
const startSelectingPhotos = useCallback(() =>
|
|
pushPathWithEvent(canCurrentPageSelectPhotos
|
|
? `${pathname}?${PARAM_SELECT}=true`
|
|
// Redirect to grid if current view does not support photo selection
|
|
: `${PATH_GRID_INFERRED}?${PARAM_SELECT}=true`)
|
|
, [canCurrentPageSelectPhotos, pathname]);
|
|
|
|
const stopSelectingPhotos = useCallback(() =>
|
|
pushPathWithEvent(pathname)
|
|
, [pathname]);
|
|
|
|
useEffect(() => {
|
|
if (isSelectingPhotos) {
|
|
const photoGrids = Array.from(getPhotoGridElements());
|
|
const isSomePhotoGridVisible = photoGrids
|
|
.some(element => isElementPartiallyInViewport(element, -20));
|
|
if (!isSomePhotoGridVisible) {
|
|
console.log('scrolling to photo grid');
|
|
photoGrids[0]?.scrollIntoView({ behavior: 'smooth' });
|
|
}
|
|
} else {
|
|
setSelectedPhotoIds([]);
|
|
}
|
|
}, [isSelectingPhotos, getPhotoGridElements]);
|
|
|
|
return (
|
|
<SelectPhotosContext.Provider value={{
|
|
canCurrentPageSelectPhotos,
|
|
isSelectingPhotos,
|
|
startSelectingPhotos,
|
|
stopSelectingPhotos,
|
|
selectedPhotoIds,
|
|
setSelectedPhotoIds,
|
|
isPerformingSelectEdit,
|
|
setIsPerformingSelectEdit,
|
|
}}>
|
|
{children}
|
|
</SelectPhotosContext.Provider>
|
|
);
|
|
}
|