diff options
Diffstat (limited to 'src/features/messages.js')
| -rw-r--r-- | src/features/messages.js | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/src/features/messages.js b/src/features/messages.js index 2580ed9..9cba810 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -11934,12 +11934,48 @@ export function messagesFeature(ctx) { let tries = 0; const go = () => { if (ui.mediaPager || !document.querySelector('.notes-feed')) { if (++tries < 90) requestAnimationFrame(go); return; } - const list = c.winList ? c.winList() : c.notes; - const i = list.findIndex((e) => e.id === rowId); - if (i >= 0) glideToPost(c, list, i); + landOnPost(c, rowId); }; requestAnimationFrame(go); } + // Put the feed on a post the reader hasn't been near — one the pager went + // on to, maybe paged in while it was open and never drawn. Its place is + // only a guess until it is drawn, and the rows around it settle as they + // draw (a long post, a picture finding its size), so: jump to the guess, + // draw, and set the row under the top again each frame — until it has sat + // still a moment, a couple of seconds have gone, or the reader touches the + // page. A jump, not a glide: the pager was covering the feed. + function landOnPost(c, rowId) { + const MARGIN = 8, t0 = Date.now(); + const find = () => document.querySelector('.notes-feed > [data-key="' + CSS.escape(rowId) + '"]'); + let still = 0, misses = 0, lastY = null; + const step = () => { + if (c !== feed || ui.mediaPager || !document.querySelector('.notes-feed') || lastInputAt > t0 || Date.now() - t0 > 2500) return; + // the page sent somewhere else meanwhile (not by a finger: a glide, a link) + if (lastY !== null && Math.abs(window.scrollY - lastY) > window.innerHeight / 2) return; + const el = find(); + if (!el) { + const list = c.winList ? c.winList() : c.notes; + const i = list.findIndex((e) => e.id === rowId); + if (i < 0 || ++misses > 20) return; + let sum = 0, n = 0; + for (const v of (c.heights || new Map()).values()) { sum += v; n++; } + const avg = n ? sum / n : 200; + let y = 0; + for (let j = 0; j < i; j++) y += ((c.heights && c.heights.get(list[j].id)) || avg) + ROW_GAP; + window.scrollTo(0, Math.max(0, (c.listTop || 0) + y - MARGIN)); + render(); + requestAnimationFrame(step); + return; + } + const off = el.getBoundingClientRect().top - MARGIN; + if (Math.abs(off) > 2) { window.scrollTo(0, Math.max(0, window.scrollY + off)); still = 0; } + else if (++still >= 20 && Date.now() - t0 > 600) return; + lastY = window.scrollY; + requestAnimationFrame(step); + }; + step(); + } // Leaving the pager for another page (a profile, sign-in, the zap amount): // only the feed's own render syncs the pager, and those pages don't paint // the feed — so the overlay goes now, not on the next feed render. @@ -12262,11 +12298,13 @@ export function messagesFeature(ctx) { } // A pager opened from the feed walks the feed's own posts, which page in // ten at a time as the feed is scrolled. Swiping is the scrolling here: - // with only a few slides left past the one on screen, the feed pages on + // with only a few slides left past the one on screen (PAGER_AHEAD), the feed pages on // (the posts it holds, then older ones from the relays) until there are // more — several pages if those posts carry none. A page that brings // nothing (the feed busy, or at its end) stops it; the tick tries again. - const PAGER_AHEAD = 3; + // how many slides ahead to keep: clips are fewer and further between + // (more pages to find the next) and each is watched a while, so further + const PAGER_AHEAD = { images: 4, videos: 6 }; let pagerFeeding = false; async function pagerFeedAhead() { if (pagerFeeding || !pager || !pager.fromFeed) return; @@ -12275,7 +12313,7 @@ export function messagesFeature(ctx) { const c = feedNow(); for (let pages = 0; pages < 8 && pager && pager.fromFeed; pages++) { const slides = [...pager.scroller.children]; - if (slides.length - 1 - slides.indexOf(pager.cur) > PAGER_AHEAD) break; + if (slides.length - 1 - slides.indexOf(pager.cur) > (PAGER_AHEAD[pager.kind] || 4)) break; const shown = c.shown, held = c.notes.length; await loadOlderFeed(); growPager(); |
