diff options
| author | Adam Mathes <adam@adammathes.com> | 2026-02-14 10:44:18 -0800 |
|---|---|---|
| committer | Adam Mathes <adam@adammathes.com> | 2026-02-14 10:44:18 -0800 |
| commit | 419d84d2a8e84d028b145df57d1584a3fe163b37 (patch) | |
| tree | 5fc890921db2799a977a918d3a7f9e6c14775ed8 /frontend/src/components/FeedItems.tsx | |
| parent | 00512c639841dac9ca8d1cff5c2532ce7584eb15 (diff) | |
| download | neko-419d84d2a8e84d028b145df57d1584a3fe163b37.tar.gz neko-419d84d2a8e84d028b145df57d1584a3fe163b37.tar.bz2 neko-419d84d2a8e84d028b145df57d1584a3fe163b37.zip | |
fix: make infinite scroll less aggressive by using threshold 1.0 for sentinel observer
Diffstat (limited to 'frontend/src/components/FeedItems.tsx')
| -rw-r--r-- | frontend/src/components/FeedItems.tsx | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/frontend/src/components/FeedItems.tsx b/frontend/src/components/FeedItems.tsx index b497e9d..a058b70 100644 --- a/frontend/src/components/FeedItems.tsx +++ b/frontend/src/components/FeedItems.tsx @@ -164,17 +164,10 @@ export default function FeedItems() { useEffect(() => { - const observer = new IntersectionObserver( + // Observer for marking items as read + const itemObserver = new IntersectionObserver( (entries) => { entries.forEach((entry) => { - // Infinity scroll sentinel - if (entry.target.id === 'load-more-sentinel') { - if (entry.isIntersecting && !loadingMore && hasMore && items.length > 0) { - fetchItems(String(items[items.length - 1]._id)); - } - return; - } - // If item is not intersecting and is above the viewport, it's been scrolled past if (!entry.isIntersecting && entry.boundingClientRect.top < 0) { const index = Number(entry.target.getAttribute('data-index')); @@ -190,15 +183,30 @@ export default function FeedItems() { { root: null, threshold: 0 } ); + // Observer for infinite scroll (less aggressive, must be fully visible) + const sentinelObserver = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting && !loadingMore && hasMore && items.length > 0) { + fetchItems(String(items[items.length - 1]._id)); + } + }); + }, + { root: null, threshold: 1.0 } + ); + items.forEach((_, index) => { const el = document.getElementById(`item-${index}`); - if (el) observer.observe(el); + if (el) itemObserver.observe(el); }); const sentinel = document.getElementById('load-more-sentinel'); - if (sentinel) observer.observe(sentinel); + if (sentinel) sentinelObserver.observe(sentinel); - return () => observer.disconnect(); + return () => { + itemObserver.disconnect(); + sentinelObserver.disconnect(); + }; }, [items, loadingMore, hasMore]); if (loading) return <div className="feed-items-loading">Loading items...</div>; |
