From 29ceed3a72b2ecb68d234b2e034e9b8f7b370979 Mon Sep 17 00:00:00 2001 From: nesquena-hermes Date: Tue, 23 Jun 2026 16:19:50 +0000 Subject: [PATCH] fix(#4778): gate deferred rAF re-restore on still-unpinned (Opus gate) Opus caught a narrow timing race: if a reader re-pins between the scroll-rebuild guard engaging and its deferred rAF firing, the stale re-restore would yank them back off the bottom. Gate the re-restore on _messageUserUnpinned at rAF time; the minHeight release still always runs. Normal single-render unpinned case unaffected. --- static/ui.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/static/ui.js b/static/ui.js index a7b23cef..cedaca31 100644 --- a/static/ui.js +++ b/static/ui.js @@ -9682,7 +9682,10 @@ function renderLiveAnchorActivityScene(streamId, scene, opts){ if(scrollRebuildGuard&&scrollRebuildGuard.release){ requestAnimationFrame(()=>{ scrollRebuildGuard.release(); - _restoreMessageScrollSnapshotSameFrame(scrollSnapshot); + // Only re-restore the unpinned snapshot if the reader is STILL unpinned at + // rAF time. If they re-pinned between guard-engage and this frame, the + // stale re-restore would yank them back off the bottom (Opus gate finding). + if(_messageUserUnpinned) _restoreMessageScrollSnapshotSameFrame(scrollSnapshot); }); } if(!scrollRebuildGuard.readerAwayFromBottom&&typeof scrollIfPinned==='function') scrollIfPinned();