Files
decePubClient/wwwroot/js/feed.js
T
thepraandClaude Opus 5.5 23dbc68fb4 Coming back to the feed shows it as it was left
Leaving the feed keeps it in Services/FeedMemory.cs (posts, waiting posts, cursors and scroll; ten minutes, for the same
feed of the same persona), so coming back from a thread or a profile shows it again at once, older pages included,
instead of reading it anew; newer posts come behind the "new" button and through the stream as before.
tests/e2e FeedMemoryTests goes to a thread and back without a new read of the home timeline; the whole suite passes
(123, 5 skipped).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
2026-10-06 01:21:41 +02:00

62 lines
1.8 KiB
JavaScript

// 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"
}
// The scroll a feed was left at, and the way back to it (Services/FeedMemory.cs).
export function scrollOffset(rootId) {
return document.getElementById(rootId)?.scrollTop ?? 0
}
export function scrollToOffset(rootId, top) {
const root = document.getElementById(rootId)
if (root)
root.scrollTop = top
}
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))
}