aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-14 22:35:27 -0700
committerAdam Soltys <[email protected]>2026-10-14 22:35:27 -0700
commit1f2ad6bcf369f17f8710a078293b31e7584e6bba (patch)
treeb84fa5141962a35ba8fd9d00d09127fc05a55904 /src
parentebc59e50cf86e8edfab21a5be9063e5d5eeab07b (diff)
downloadcoinosv3-1f2ad6bcf369f17f8710a078293b31e7584e6bba.tar.gz
coinosv3-1f2ad6bcf369f17f8710a078293b31e7584e6bba.zip
Media pager: the slide meant stays on screen through a resize, from the first moment. The pager's resize handler re-showed pager.cur, which the slide observer sets a frame after the pager opens — so a resize in that first frame (the page going full screen for the pager, as the player's full-screen button does: a taller window, the address bar gone) had nothing to re-show, and the pager was left to the browser's re-snap. Now the slide meant is an anchor: the start slide the moment the pager opens, then each slide arrived at; a resize re-shows it (or the tail, when the reader is waiting there), and an arrival the observer reports at a size other than the one the pager last laid out at is taken as the resize's doing, not the reader's: the anchor goes back instead. Hardening: Adam's full-screen button on a clip 23 posts down showed another post's still, which a headless run of the same path (a user-gesture requestFullscreen on the feed clip) and tools/pager-resize-test.js (the window grows as the pager opens, shrinks and grows again, changes shape) did not reproduce; the recorder on his tab is for the next time.
Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01J1Kon8bxJoHRpJdSzshCkp
Diffstat (limited to 'src')
-rw-r--r--src/features/messages.js20
1 files changed, 19 insertions, 1 deletions
diff --git a/src/features/messages.js b/src/features/messages.js
index ae801cd..55deaa1 100644
--- a/src/features/messages.js
+++ b/src/features/messages.js
@@ -12746,6 +12746,7 @@ export function messagesFeature(ctx) {
if (pager.fromFeed && video) el.classList.remove('show');
}
pager.cur = slide;
+ pager.anchor = slide;
pager.curAt = Date.now();
pagerArrows(slide);
if (pager.fromFeed) { const row = feedNow().notes.find((x) => x.id === slide._rowId); markSeen(row || slide._ev); }
@@ -12759,6 +12760,8 @@ export function messagesFeature(ctx) {
for (const e of entries) {
if (!e.isIntersecting || e.intersectionRatio < 0.6 || !pager) continue;
if (pager.flying) continue; // passing, not arriving: the landing is pagerFly's
+ // a slide the screen's new size put there, not the reader: the anchor goes back
+ if (pager.screenH && scroller.clientHeight !== pager.screenH) { pager.onResize(); continue; }
pager.arrive(e.target);
}
}, { root: scroller, threshold: [0.6] });
@@ -12767,6 +12770,8 @@ export function messagesFeature(ctx) {
document.documentElement.classList.add('no-scroll');
const first = pagerSlides().find((s) => s.getAttribute('data-k') === want.start) || pagerSlides()[0];
if (first) pagerShow(first);
+ pager.anchor = first; // the slide meant to be on screen, from the first moment
+ pager.screenH = scroller.clientHeight;
// the clip on screen's seek bar, every frame (timeupdate comes a few times a second)
if (video) {
const p = pager;
@@ -12774,7 +12779,20 @@ export function messagesFeature(ctx) {
p.raf = requestAnimationFrame(frame);
}
// turned on its side (or back), the slides change height: stay on this one
- pager.onResize = () => { if (pager && pager.cur) pagerShow(pager.cur); };
+ // The screen changed size — a turn of the phone, or the page going full
+ // screen for the pager (the address bar and tabs gone: a taller window).
+ // The posts are a screen tall each, so a scroll position in pixels
+ // deep in the pager now sits in a different post: put the one meant
+ // back on screen. The slide meant is the anchor, set the moment the
+ // pager opens (cur is set by the observer a frame later, and the full
+ // screen's resize beat it: Adam's full-screen button on a clip 23 posts
+ // down landed him on another post's picture) and on each arrival.
+ pager.onResize = () => {
+ if (!pager) return;
+ pager.screenH = pager.scroller.clientHeight;
+ if (pager.onTail) pager.scroller.scrollTop = pager.tail.offsetTop;
+ else if (pager.anchor) pagerShow(pager.anchor);
+ };
window.addEventListener('resize', pager.onResize);
// new posts land in the feed while the pager is open; counts move
pager.tick = setInterval(() => { if (pager) { growPager(); pagerFeedAhead(); if (el.classList.contains('show')) pagerCounts(pager.cur); } }, 1500);