2022-09-11 15:58:32 +02:00
|
|
|
import { useEffect, useState, MutableRefObject, useRef } from 'react';
|
2022-08-04 11:12:22 +02:00
|
|
|
|
|
|
|
|
2022-08-27 14:32:20 +02:00
|
|
|
const useIsVisible = (elementRef: MutableRefObject<HTMLElement>, rootRef: MutableRefObject<HTMLElement>) => {
|
2022-08-04 11:12:22 +02:00
|
|
|
const [isVisible, setIsVisible] = useState(false);
|
2022-09-11 15:58:32 +02:00
|
|
|
const lastVisible = useRef(0);
|
|
|
|
const invisibleOn = useRef(0);
|
2022-08-28 13:18:51 +02:00
|
|
|
|
2022-08-04 11:12:22 +02:00
|
|
|
useEffect(() => {
|
|
|
|
let observer: IntersectionObserver = null;
|
2022-09-11 15:58:32 +02:00
|
|
|
let timeout: number = null;
|
2022-08-04 11:12:22 +02:00
|
|
|
if (elementRef.current) {
|
|
|
|
observer = new IntersectionObserver((entries, _observer) => {
|
|
|
|
let visible = false;
|
2023-06-30 10:39:21 +02:00
|
|
|
// eslint-disable-next-line github/array-foreach -- Old code before rule was applied
|
2022-08-04 11:12:22 +02:00
|
|
|
entries.forEach((entry) => {
|
|
|
|
if (entry.isIntersecting) {
|
|
|
|
visible = true;
|
2022-09-11 15:58:32 +02:00
|
|
|
lastVisible.current = Date.now();
|
|
|
|
if ((invisibleOn.current - lastVisible.current) > 300) {
|
|
|
|
setIsVisible(true);
|
|
|
|
} else {
|
|
|
|
if (!timeout) {
|
|
|
|
timeout = window.setTimeout(() => {
|
|
|
|
if (invisibleOn.current < lastVisible.current) {
|
|
|
|
setIsVisible(true);
|
|
|
|
}
|
|
|
|
timeout = null;
|
|
|
|
}, 300);
|
|
|
|
}
|
|
|
|
}
|
2022-08-04 11:12:22 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
if (!visible) {
|
2022-09-11 15:58:32 +02:00
|
|
|
invisibleOn.current = Date.now();
|
2022-08-04 11:12:22 +02:00
|
|
|
setIsVisible(false);
|
|
|
|
}
|
|
|
|
}, {
|
|
|
|
root: rootRef.current,
|
|
|
|
rootMargin: '0px 0px 0px 0px',
|
|
|
|
threshold: 0,
|
|
|
|
});
|
|
|
|
observer.observe(elementRef.current);
|
|
|
|
}
|
|
|
|
return () => {
|
|
|
|
if (observer) {
|
|
|
|
observer.disconnect();
|
|
|
|
}
|
2022-09-11 15:58:32 +02:00
|
|
|
if (timeout) {
|
|
|
|
window.clearTimeout(timeout);
|
|
|
|
timeout = null;
|
|
|
|
}
|
2022-08-04 11:12:22 +02:00
|
|
|
};
|
2022-08-27 14:32:20 +02:00
|
|
|
}, [elementRef, rootRef]);
|
2022-08-04 11:12:22 +02:00
|
|
|
|
|
|
|
return isVisible;
|
|
|
|
};
|
|
|
|
|
|
|
|
export default useIsVisible;
|