// The feed page's scrolling (Pages/Index.razor): tells .NET when the end of the list comes near, so the next page loads // before the reader gets there, and whether the page is visible, so polling for new posts stops in a hidden tab. let observer = null let sentinel = null let reference = null export function observeEnd(dotNetReference, sentinelId, rootId) { dispose() reference = dotNetReference sentinel = document.getElementById(sentinelId) const root = document.getElementById(rootId) if (!sentinel || !root) return observer = new IntersectionObserver(entries => { if (entries.some(entry => entry.isIntersecting)) nearEnd() }, { root, rootMargin: "0px 0px 800px 0px" }) observer.observe(sentinel) } // After a page is added: if the end is still in sight (a short page), ask for the next one too. export function checkEnd() { if (!sentinel || !observer) return const root = observer.root const end = sentinel.getBoundingClientRect().top const bottom = root.getBoundingClientRect().bottom if (end < bottom + 800) nearEnd() } export function isVisible() { return document.visibilityState === "visible" } export function scrollToTop(rootId) { document.getElementById(rootId)?.scrollTo({ top: 0, behavior: matchMedia("(prefers-reduced-motion: reduce)").matches ? "auto" : "smooth" }) } export function dispose() { observer?.disconnect() observer = null sentinel = null reference = null } function nearEnd() { reference?.invokeMethodAsync("NearEnd").catch(e => console.error(e)) }