diff options
| author | Adam Soltys <[email protected]> | 2026-10-14 22:35:27 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-14 22:35:27 -0700 |
| commit | 1f2ad6bcf369f17f8710a078293b31e7584e6bba (patch) | |
| tree | b84fa5141962a35ba8fd9d00d09127fc05a55904 /src | |
| parent | ebc59e50cf86e8edfab21a5be9063e5d5eeab07b (diff) | |
| download | coinosv3-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.js | 20 |
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); |
