( total: number, enabled: boolean, )
| 3724 | } |
| 3725 | |
| 3726 | function useProgressiveEntryLimit( |
| 3727 | total: number, |
| 3728 | enabled: boolean, |
| 3729 | ): [number, (node: HTMLDivElement | null) => void] { |
| 3730 | const initial = getInitialSidebarEntryLimit(total, enabled); |
| 3731 | const [limit, setLimit] = useState(initial); |
| 3732 | const observerRef = useRef<IntersectionObserver | null>(null); |
| 3733 | |
| 3734 | useEffect(() => { |
| 3735 | setLimit(getInitialSidebarEntryLimit(total, enabled)); |
| 3736 | }, [enabled, total]); |
| 3737 | |
| 3738 | useEffect(() => { |
| 3739 | return () => { |
| 3740 | observerRef.current?.disconnect(); |
| 3741 | observerRef.current = null; |
| 3742 | }; |
| 3743 | }, []); |
| 3744 | |
| 3745 | const setSentinelRef = useCallback( |
| 3746 | (node: HTMLDivElement | null): void => { |
| 3747 | observerRef.current?.disconnect(); |
| 3748 | observerRef.current = null; |
| 3749 | |
| 3750 | if (!enabled || !node || limit >= total) return; |
| 3751 | if (typeof IntersectionObserver === "undefined") return; |
| 3752 | |
| 3753 | const observer = new IntersectionObserver( |
| 3754 | (entries) => { |
| 3755 | if (!entries.some((entry) => entry.isIntersecting)) return; |
| 3756 | setLimit((current) => getNextSidebarEntryLimit(current, total)); |
| 3757 | }, |
| 3758 | { |
| 3759 | root: null, |
| 3760 | rootMargin: `${SIDEBAR_PROGRESSIVE_SENTINEL_MARGIN_PX}px 0px`, |
| 3761 | }, |
| 3762 | ); |
| 3763 | observer.observe(node); |
| 3764 | observerRef.current = observer; |
| 3765 | }, |
| 3766 | [enabled, limit, total], |
| 3767 | ); |
| 3768 | |
| 3769 | return [enabled ? Math.min(limit, total) : total, setSentinelRef]; |
| 3770 | } |
| 3771 | |
| 3772 | function buildTree( |
| 3773 | notes: NoteMeta[], |
no test coverage detected