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 { useAppState } from '@/app/AppState';
|
||||||
import useClientSearchParams from '@/utility/useClientSearchParams';
|
import useClientSearchParams from '@/utility/useClientSearchParams';
|
||||||
import { pushPathWithEvent } from '@/utility/url';
|
import { pushPathWithEvent } from '@/utility/url';
|
||||||
|
import { isElementPartiallyInViewport } from '@/utility/dom';
|
||||||
|
|
||||||
export const DATA_KEY_PHOTO_GRID = 'data-photo-grid';
|
export const DATA_KEY_PHOTO_GRID = 'data-photo-grid';
|
||||||
|
|
||||||
@ -28,10 +29,14 @@ export default function SelectPhotosProvider({
|
|||||||
const [isPerformingSelectEdit, setIsPerformingSelectEdit] =
|
const [isPerformingSelectEdit, setIsPerformingSelectEdit] =
|
||||||
useState(false);
|
useState(false);
|
||||||
|
|
||||||
|
const getPhotoGridElements = useCallback(() =>
|
||||||
|
document.querySelectorAll(`[${DATA_KEY_PHOTO_GRID}]`)
|
||||||
|
, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCanCurrentPageSelectPhotos(document
|
const doesPageHavePhotoGrids = getPhotoGridElements().length > 0;
|
||||||
.querySelector(`[${DATA_KEY_PHOTO_GRID}]`) !== null);
|
setCanCurrentPageSelectPhotos(doesPageHavePhotoGrids);
|
||||||
}, [pathname]);
|
}, [pathname, getPhotoGridElements]);
|
||||||
|
|
||||||
const isSelectingPhotos = useMemo(() =>
|
const isSelectingPhotos = useMemo(() =>
|
||||||
isUserSignedIn &&
|
isUserSignedIn &&
|
||||||
@ -50,10 +55,18 @@ export default function SelectPhotosProvider({
|
|||||||
, [pathname]);
|
, [pathname]);
|
||||||
|
|
||||||
useEffect(() => {
|
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([]);
|
setSelectedPhotoIds([]);
|
||||||
}
|
}
|
||||||
}, [isSelectingPhotos]);
|
}, [isSelectingPhotos, getPhotoGridElements]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SelectPhotosContext.Provider value={{
|
<SelectPhotosContext.Provider value={{
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
export const isElementEntirelyInViewport = (
|
export const isElementEntirelyInViewport = (
|
||||||
element?: HTMLElement | null,
|
element?: Element | null,
|
||||||
) => {
|
) => {
|
||||||
if (element) {
|
if (element) {
|
||||||
const rect = element.getBoundingClientRect();
|
const rect = element.getBoundingClientRect();
|
||||||
@ -11,7 +11,8 @@ export const isElementEntirelyInViewport = (
|
|||||||
document.documentElement.clientHeight
|
document.documentElement.clientHeight
|
||||||
) &&
|
) &&
|
||||||
rect.right <= (
|
rect.right <= (
|
||||||
window.innerWidth || document.documentElement.clientWidth
|
window.innerWidth ||
|
||||||
|
document.documentElement.clientWidth
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} else {
|
} 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 = () => {
|
export const clearGlobalFocus = () => {
|
||||||
if (document.activeElement instanceof HTMLElement) {
|
if (document.activeElement instanceof HTMLElement) {
|
||||||
document.activeElement.blur();
|
document.activeElement.blur();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user