aboutsummaryrefslogtreecommitdiffstats
path: root/frontend-vanilla/src/main.ts
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-17 10:35:09 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-17 10:35:09 -0800
commitea9ec7f41c0447027b66f52c0c4cd0d5c9777bfa (patch)
tree76df773b1891fbeaa4349be0787a8c7f8ba53c59 /frontend-vanilla/src/main.ts
parent6cf749948220f960d3fc0867f882588a3ca43019 (diff)
downloadneko-ea9ec7f41c0447027b66f52c0c4cd0d5c9777bfa.tar.gz
neko-ea9ec7f41c0447027b66f52c0c4cd0d5c9777bfa.tar.bz2
neko-ea9ec7f41c0447027b66f52c0c4cd0d5c9777bfa.zip
Fix infinite scroll not triggering on scroll
Diffstat (limited to 'frontend-vanilla/src/main.ts')
-rw-r--r--frontend-vanilla/src/main.ts59
1 files changed, 58 insertions, 1 deletions
diff --git a/frontend-vanilla/src/main.ts b/frontend-vanilla/src/main.ts
index 8d88470..aa00bd3 100644
--- a/frontend-vanilla/src/main.ts
+++ b/frontend-vanilla/src/main.ts
@@ -303,6 +303,60 @@ export function renderItems() {
}
}
+// Polling fallback for infinite scroll (matches V1 behavior)
+// This ensures that even if scroll events are missed or layout shifts occur without scroll,
+// we still load more items when near the bottom.
+if (typeof window !== 'undefined') {
+ setInterval(() => {
+ // We need to check if we are scrolling the window or an element.
+ // In V3 layout, .main-content handles the scroll if it's overflow-y: auto.
+ // But if .main-content is behaving like the body, we might need to check window.innerHeight.
+
+ // Let's check the container first
+ const scrollRoot = document.getElementById('main-content');
+ // console.log('Polling...', { scrollRoot: !!scrollRoot, loading: store.loading, hasMore: store.hasMore });
+
+ if (store.loading || !store.hasMore) return;
+
+ if (scrollRoot) {
+ // DEBUG LOGGING
+ /*
+ console.log('Scroll Poll', {
+ scrollHeight: scrollRoot.scrollHeight,
+ scrollTop: scrollRoot.scrollTop,
+ clientHeight: scrollRoot.clientHeight,
+ offset: scrollRoot.scrollHeight - scrollRoot.scrollTop - scrollRoot.clientHeight,
+ docHeight: document.documentElement.scrollHeight,
+ winHeight: window.innerHeight,
+ winScroll: window.scrollY
+ });
+ */
+
+ // Check container scroll (if container is scrollable)
+ if (scrollRoot.scrollHeight > scrollRoot.clientHeight) {
+ if (scrollRoot.scrollHeight - scrollRoot.scrollTop - scrollRoot.clientHeight < 200) {
+ loadMore();
+ return;
+ }
+ }
+ }
+
+ // Fallback: Check window scroll (if main-content isn't the scroller)
+ // This matches V1 logic: $(document).height() - $(window).height() - $(window).scrollTop()
+ const docHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
+ const winHeight = window.innerHeight;
+ const winScroll = window.scrollY || document.documentElement.scrollTop;
+
+ // Only if document is actually scrollable
+ if (docHeight > winHeight) {
+ if (docHeight - winHeight - winScroll < 200) {
+ loadMore();
+ }
+ }
+
+ }, 1000);
+}
+
export function renderSettings() {
const contentArea = document.getElementById('content-area');
if (!contentArea) return;
@@ -613,7 +667,10 @@ export async function fetchItems(feedId?: string, tagName?: string, append: bool
const res = await apiFetch(`/api/stream?${params.toString()}`);
if (res.ok) {
const items = await res.json();
- store.setHasMore(items.length >= 50);
+ // V1 logic: keep loading as long as we get results.
+ // Backend limit is currently 15, so checking >= 50 caused premature stop.
+ // We accept one extra empty fetch at the end to be robust against page size changes.
+ store.setHasMore(items.length > 0);
store.setItems(items, append);
}
} finally {