aboutsummaryrefslogtreecommitdiffstats
path: root/frontend/src/components/FeedItems.tsx
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-14 10:44:18 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-14 10:44:18 -0800
commit419d84d2a8e84d028b145df57d1584a3fe163b37 (patch)
tree5fc890921db2799a977a918d3a7f9e6c14775ed8 /frontend/src/components/FeedItems.tsx
parent00512c639841dac9ca8d1cff5c2532ce7584eb15 (diff)
downloadneko-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.tsx32
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>;