aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/features/messages.js21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/features/messages.js b/src/features/messages.js
index 540f942..d3c8e87 100644
--- a/src/features/messages.js
+++ b/src/features/messages.js
@@ -6595,18 +6595,27 @@ export function messagesFeature(ctx) {
}
return changed;
}
- // On scroll: when the window should move, repaint with the reader's row
- // held still. One frame at a time.
+ // On scroll: replenish the buffer before the reader reaches its edge,
+ // holding their row still. Coalesce scroll events into one check per frame.
let windowRaf = 0;
function windowScrolled(c) {
if (!c || !c.win || windowRaf) return;
windowRaf = requestAnimationFrame(() => {
windowRaf = 0;
- measureNow(c);
const list = c.winList ? c.winList() : null;
- if (!list) return;
- const next = listWindow(c, list);
- if (next.start !== c.win.start || next.end !== c.win.end) holdScroll(render);
+ if (!list || !c.win || (!c.win.start && c.win.end >= list.length)) return;
+ // Keep using the 2.5-screen overscan until only one screen remains.
+ // Recentring it every time an offscreen row crossed the ideal boundary
+ // rebuilt the whole pane repeatedly during a coast. Two edge reads
+ // suffice here; measure all rows only when the window actually moves.
+ const rows = document.querySelectorAll('.notes-feed > .row[data-key]');
+ const first = rows[0], last = rows[rows.length - 1], H = window.innerHeight;
+ if (!first || !last) return;
+ const nearTop = c.win.start > 0 && first.getBoundingClientRect().top > -H;
+ const nearBottom = c.win.end < list.length && last.getBoundingClientRect().bottom < 2 * H;
+ if (!nearTop && !nearBottom) return;
+ measureNow(c);
+ holdScroll(render, c);
});
}