mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-02-20 07:44:01 -05:00
62 lines
1.7 KiB
TypeScript
62 lines
1.7 KiB
TypeScript
import { useEffect, useRef, useState } from 'react'
|
|
import { useEvent } from 'web/hooks/use-event'
|
|
|
|
export function VisibilityObserver(props: {
|
|
className?: string
|
|
onVisibilityUpdated: (visible: boolean) => void
|
|
}) {
|
|
const { className } = props
|
|
const [elem, setElem] = useState<HTMLElement | null>(null)
|
|
const onVisibilityUpdated = useEvent(props.onVisibilityUpdated)
|
|
|
|
useEffect(() => {
|
|
if (elem) {
|
|
const observer = new IntersectionObserver(([entry]) => {
|
|
onVisibilityUpdated(entry.isIntersecting)
|
|
}, {})
|
|
observer.observe(elem)
|
|
return () => observer.unobserve(elem)
|
|
}
|
|
}, [elem, onVisibilityUpdated])
|
|
|
|
return <div ref={setElem} className={className}></div>
|
|
}
|
|
|
|
export function LoadMoreUntilNotVisible(props: {
|
|
// Returns true if there are more results.
|
|
loadMore: () => Promise<boolean>
|
|
}) {
|
|
const { loadMore } = props
|
|
const isVisibleRef = useRef(false)
|
|
const loadMoreIfVisible = useEvent(async () => {
|
|
console.log('loadMoreIfVisible called')
|
|
if (isVisibleRef.current && loadMore) {
|
|
console.log('loadMore calling')
|
|
await loadMore()
|
|
// const hasMoreResults = await loadMore()
|
|
// if (hasMoreResults) {
|
|
// setTimeout(() => {
|
|
// if (isVisibleRef.current) {
|
|
// loadMoreIfVisible()
|
|
// }
|
|
// }, 500)
|
|
// }
|
|
}
|
|
})
|
|
|
|
const onVisibilityUpdated = useEvent((visible: boolean) => {
|
|
isVisibleRef.current = visible
|
|
loadMoreIfVisible()
|
|
})
|
|
|
|
return (
|
|
<div className="relative">
|
|
<VisibilityObserver
|
|
// Loads more as soon as one screen height of content is left.
|
|
className="pointer-events-none absolute bottom-0 h-screen w-full select-none"
|
|
onVisibilityUpdated={onVisibilityUpdated}
|
|
/>
|
|
</div>
|
|
)
|
|
}
|