2024-03-26 11:35:02 +03:00
|
|
|
/*
|
|
|
|
Rendered but hidden. Only show when visible
|
|
|
|
*/
|
2024-04-03 11:06:37 +03:00
|
|
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
2024-03-26 11:35:02 +03:00
|
|
|
import { useInView } from 'react-intersection-observer';
|
|
|
|
|
2024-04-03 06:53:03 +03:00
|
|
|
// The sticky header, usually at the top
|
|
|
|
const TOP = 48;
|
|
|
|
|
2024-03-26 11:35:02 +03:00
|
|
|
export default function LazyShazam({ children }) {
|
|
|
|
const containerRef = useRef();
|
|
|
|
const [visible, setVisible] = useState(false);
|
|
|
|
const [visibleStart, setVisibleStart] = useState(false);
|
|
|
|
|
|
|
|
const { ref } = useInView({
|
|
|
|
root: null,
|
2024-04-03 06:53:03 +03:00
|
|
|
rootMargin: `-${TOP}px 0px 0px 0px`,
|
2024-03-26 11:35:02 +03:00
|
|
|
trackVisibility: true,
|
|
|
|
delay: 1000,
|
|
|
|
onChange: (inView) => {
|
|
|
|
if (inView) {
|
|
|
|
setVisible(true);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
triggerOnce: true,
|
|
|
|
skip: visibleStart || visible,
|
|
|
|
});
|
|
|
|
|
2024-04-03 11:06:37 +03:00
|
|
|
useEffect(() => {
|
2024-03-26 11:35:02 +03:00
|
|
|
if (!containerRef.current) return;
|
|
|
|
const rect = containerRef.current.getBoundingClientRect();
|
2024-04-03 06:53:03 +03:00
|
|
|
if (rect.bottom > TOP) {
|
2024-04-04 09:34:28 +03:00
|
|
|
if (rect.top < window.innerHeight) {
|
|
|
|
setVisible(true);
|
|
|
|
} else {
|
|
|
|
setVisibleStart(true);
|
|
|
|
}
|
2024-03-26 11:35:02 +03:00
|
|
|
}
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
if (visibleStart) return children;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div
|
|
|
|
ref={containerRef}
|
|
|
|
class="shazam-container no-animation"
|
|
|
|
hidden={!visible}
|
|
|
|
>
|
|
|
|
<div ref={ref} class="shazam-container-inner">
|
|
|
|
{children}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|