Scroll photo grid into view when selecting photos
This commit is contained in:
parent
2d72f12ddd
commit
57879706a2
@ -7,6 +7,7 @@ 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';
|
||||
|
||||
@ -28,10 +29,14 @@ export default function SelectPhotosProvider({
|
||||
const [isPerformingSelectEdit, setIsPerformingSelectEdit] =
|
||||
useState(false);
|
||||
|
||||
const getPhotoGridElements = useCallback(() =>
|
||||
document.querySelectorAll(`[${DATA_KEY_PHOTO_GRID}]`)
|
||||
, []);
|
||||
|
||||
useEffect(() => {
|
||||
setCanCurrentPageSelectPhotos(document
|
||||
.querySelector(`[${DATA_KEY_PHOTO_GRID}]`) !== null);
|
||||
}, [pathname]);
|
||||
const doesPageHavePhotoGrids = getPhotoGridElements().length > 0;
|
||||
setCanCurrentPageSelectPhotos(doesPageHavePhotoGrids);
|
||||
}, [pathname, getPhotoGridElements]);
|
||||
|
||||
const isSelectingPhotos = useMemo(() =>
|
||||
isUserSignedIn &&
|
||||
@ -50,10 +55,18 @@ export default function SelectPhotosProvider({
|
||||
, [pathname]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isSelectingPhotos) {
|
||||
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]);
|
||||
}, [isSelectingPhotos, getPhotoGridElements]);
|
||||
|
||||
return (
|
||||
<SelectPhotosContext.Provider value={{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
export const isElementEntirelyInViewport = (
|
||||
element?: HTMLElement | null,
|
||||
element?: Element | null,
|
||||
) => {
|
||||
if (element) {
|
||||
const rect = element.getBoundingClientRect();
|
||||
@ -11,7 +11,8 @@ export const isElementEntirelyInViewport = (
|
||||
document.documentElement.clientHeight
|
||||
) &&
|
||||
rect.right <= (
|
||||
window.innerWidth || document.documentElement.clientWidth
|
||||
window.innerWidth ||
|
||||
document.documentElement.clientWidth
|
||||
)
|
||||
);
|
||||
} else {
|
||||
@ -19,6 +20,28 @@ export const isElementEntirelyInViewport = (
|
||||
}
|
||||
};
|
||||
|
||||
export function isElementPartiallyInViewport(
|
||||
element?: Element | null,
|
||||
// Expand the viewport by `offset` pixels (negative offset = stricter)
|
||||
offset = 0,
|
||||
): boolean {
|
||||
if (element) {
|
||||
const rect = element.getBoundingClientRect();
|
||||
|
||||
const vh = window.innerHeight || document.documentElement.clientHeight;
|
||||
const vw = window.innerWidth || document.documentElement.clientWidth;
|
||||
|
||||
const topVisible = rect.bottom >= -offset;
|
||||
const leftVisible = rect.right >= -offset;
|
||||
const bottomVisible = rect.top <= vh + offset;
|
||||
const rightVisible = rect.left <= vw + offset;
|
||||
|
||||
return topVisible && leftVisible && bottomVisible && rightVisible;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export const clearGlobalFocus = () => {
|
||||
if (document.activeElement instanceof HTMLElement) {
|
||||
document.activeElement.blur();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user