From e7516c4124d033332922db91a3dc0e8dc417c2aa Mon Sep 17 00:00:00 2001 From: Adam Mathes Date: Mon, 16 Feb 2026 07:38:51 -0800 Subject: Fix scroll mark as read in V3 UI - Close NK-k2fh32: scroll mark as read broken in V3 UI - Add IntersectionObserver to item list in renderItems - Add test case ensuring apiFetch is called when item intersects --- frontend-vanilla/src/main.ts | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'frontend-vanilla/src/main.ts') diff --git a/frontend-vanilla/src/main.ts b/frontend-vanilla/src/main.ts index 93bee63..b167a18 100644 --- a/frontend-vanilla/src/main.ts +++ b/frontend-vanilla/src/main.ts @@ -18,6 +18,7 @@ let activeItemId: number | null = null; // Cache elements (initialized in renderLayout) let appEl: HTMLDivElement | null = null; +let itemObserver: IntersectionObserver | null = null; // Initial Layout (v2-style 2-pane) export function renderLayout() { @@ -216,6 +217,11 @@ export function renderFilters() { export function renderItems() { const { items, loading } = store; + + if (itemObserver) { + itemObserver.disconnect(); + itemObserver = null; + } const contentArea = document.getElementById('content-area'); if (!contentArea || router.getCurrentRoute().path === '/settings') return; @@ -246,6 +252,25 @@ export function renderItems() { }, { threshold: 0.1 }); observer.observe(sentinel); } + + // Setup item observer for marking read + itemObserver = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + 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); + } + } + } + }); + }, { threshold: 0.5 }); + + contentArea.querySelectorAll('.feed-item').forEach(el => itemObserver!.observe(el)); } export function renderSettings() { @@ -622,7 +647,6 @@ window.app = { navigate: (path: string) => router.navigate(path) }; -// Start // Start export async function init() { const authRes = await apiFetch('/api/auth'); -- cgit v1.2.3