diff options
| author | Adam Soltys <[email protected]> | 2026-10-02 10:11:37 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-02 10:11:37 -0700 |
| commit | ef6729ceaf49d2d85bc8920c2c7756086ee7450d (patch) | |
| tree | 08c40899ded610444511b546681d8034cb869443 /src/features/messages.js | |
| parent | 8249fbe964ae63fa5a34b150b2e5819972d93e5c (diff) | |
| download | coinosv3-ef6729ceaf49d2d85bc8920c2c7756086ee7450d.tar.gz coinosv3-ef6729ceaf49d2d85bc8920c2c7756086ee7450d.zip | |
New-post tint fades the moment any of the post is on screen
It waited for half the row to sit in view for two seconds; scrolling
reset the clock and a replaced node lost it, so a tall post read in
passing or one the window remounted could stay green for good. Now the
first visible pixel starts a 3s fade (the row's background transition),
marked seen by id, whether the reader stays or scrolls on.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
Diffstat (limited to 'src/features/messages.js')
| -rw-r--r-- | src/features/messages.js | 29 |
1 files changed, 11 insertions, 18 deletions
diff --git a/src/features/messages.js b/src/features/messages.js index 10c9d56..176c779 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -5305,31 +5305,24 @@ export function messagesFeature(ctx) { finally { feedPaint = prev; } } - // New posts stay tinted until they've been in view for FRESH_SEEN_MS: a - // row at least half on screen (or filling most of it) starts its clock, - // leaving view stops it. Seen, it loses the tint in place — no repaint. - const FRESH_SEEN_MS = 2000; + // A new post wears its tint until any of it reaches the screen; from that + // moment it fades out (the row's 3s background transition, in the CSS) + // whether you stay or scroll on. It used to wait for half the row to sit + // in view for two seconds, with the clock reset by every scroll and lost + // when the row's node was replaced, so a tall post read in passing, or one + // the window remounted, could stay green for good. let freshObserver = null; - const freshTimers = new Map(); function watchFresh(c) { if (typeof IntersectionObserver === 'undefined') return; freshObserver ||= new IntersectionObserver((entries) => { for (const en of entries) { + if (!en.isIntersecting) continue; const el = en.target, id = el.getAttribute('data-key'); - const inView = en.isIntersecting && (en.intersectionRatio >= 0.5 || en.intersectionRect.height >= window.innerHeight * 0.5); - if (inView && !freshTimers.has(id)) { - freshTimers.set(id, setTimeout(() => { - freshTimers.delete(id); - if (!el.isConnected) return; - feed?.fresh?.delete(id); - el.classList.remove('note-fresh'); - freshObserver.unobserve(el); - }, FRESH_SEEN_MS)); - } else if (!inView && freshTimers.has(id)) { - clearTimeout(freshTimers.get(id)); freshTimers.delete(id); - } + feed?.fresh?.delete(id); // by id: the row may be re-rendered mid-fade + el.classList.remove('note-fresh'); + freshObserver.unobserve(el); } - }, { threshold: [0, 0.5, 1] }); + }, { threshold: 0 }); // after the paint, when the row nodes are the mounted ones requestAnimationFrame(() => { for (const el of document.querySelectorAll('.notes-feed > .row.note-fresh')) freshObserver.observe(el); |
