aboutsummaryrefslogtreecommitdiffstats
path: root/frontend-vanilla/src/main.ts
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-16 16:35:38 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-16 16:35:38 -0800
commit72e131f9c273d15e8d3b5c8a9320ab7fb1d533d4 (patch)
tree8d02878300210d412f88d2890e42f3de8f1e8b80 /frontend-vanilla/src/main.ts
parentf04d8fbd9900d5326cdd65a725e57f4b08bbd655 (diff)
downloadneko-72e131f9c273d15e8d3b5c8a9320ab7fb1d533d4.tar.gz
neko-72e131f9c273d15e8d3b5c8a9320ab7fb1d533d4.tar.bz2
neko-72e131f9c273d15e8d3b5c8a9320ab7fb1d533d4.zip
Fix scroll-to-read functionality across all UIs (V1, V2, V3)
Diffstat (limited to 'frontend-vanilla/src/main.ts')
-rw-r--r--frontend-vanilla/src/main.ts50
1 files changed, 33 insertions, 17 deletions
diff --git a/frontend-vanilla/src/main.ts b/frontend-vanilla/src/main.ts
index c310144..a8606e3 100644
--- a/frontend-vanilla/src/main.ts
+++ b/frontend-vanilla/src/main.ts
@@ -276,24 +276,40 @@ export function renderItems() {
observer.observe(sentinel);
}
- // Setup item observer for marking read when items scroll past (above viewport)
- itemObserver = new IntersectionObserver((entries) => {
- entries.forEach(entry => {
- if (!entry.isIntersecting && entry.boundingClientRect.bottom < (entry.rootBounds?.top ?? 0)) {
- const target = entry.target as HTMLElement;
- const id = parseInt(target.getAttribute('data-id') || '0');
- if (id) {
- const item = store.items.find(i => i._id === id);
- if (item && !item.read) {
- updateItem(id, { read: true });
- itemObserver?.unobserve(target);
- }
- }
+ // Scroll listener for reading items
+ // We attach this to the scrollable container: #main-content
+ if (scrollRoot) {
+ let timeoutId: number | null = null;
+ const onScroll = () => {
+ if (timeoutId === null) {
+ timeoutId = window.setTimeout(() => {
+ const containerRect = scrollRoot.getBoundingClientRect();
+
+ store.items.forEach((item) => {
+ if (item.read) return;
+
+ const el = document.querySelector(`.feed-item[data-id="${item._id}"]`);
+ if (el) {
+ const rect = el.getBoundingClientRect();
+ // Mark as read if the top of the item is above the top of the container
+ if (rect.top < containerRect.top) {
+ updateItem(item._id, { read: true });
+ }
+ }
+ });
+ timeoutId = null;
+ }, 250);
}
- });
- }, { root: scrollRoot, threshold: 0 });
-
- contentArea.querySelectorAll('.feed-item').forEach(el => itemObserver!.observe(el));
+ };
+ // Remove existing listener if any (simplistic approach, ideally we track and remove)
+ // Since renderItems is called multiple times, we might be adding multiple listeners?
+ // attachLayoutListeners is called once, but renderItems is called on updates.
+ // We should probably attaching the scroll listener in the layout setup, NOT here.
+ // But we need access to 'items' which is in store.
+ // Let's attach it here but be careful.
+ // Actually, attaching to 'onscroll' property handles replacement automatically.
+ scrollRoot.onscroll = onScroll;
+ }
}
export function renderSettings() {