fix(scroll): reset _lastScrollTop on session switch (Opus stage-302 follow-up)

Opus advisor on stage-302 (#1732 verification Q5) flagged that
_lastScrollTop is module-global and persists across chat switches. When
the user switches sessions, the new chat's first user scroll compares
against the previous chat's last scrollTop. If the previous was deep-
scrolled (e.g. 5000) and the new chat starts at top=0, scrolling down
to 100 would evaluate as movedUp=true → false-unpin, blocking auto-
scroll on the new chat's first incoming token.

Fix: expose _resetScrollDirectionTracker() from static/ui.js on window
so static/sessions.js loadSession() can reset _lastScrollTop=null when
S.session is reassigned. The scroll listener's existing _lastScrollTop!==null
guard then handles the first sample after reset correctly (no false-trigger
on the very first scroll event in the new chat).

Absorb-in-release per Opus stage-302 verdict — small, defensive, ≤20 LOC.
This commit is contained in:
nesquena-hermes committed 2026-05-06 08:21:42 +00:00
1 parent 97aa3247e1
commit 93f30ecfda
2 files changed
+11

No files matched your search

+6
View File
@@ -392,6 +392,12 @@ async function loadSession(sid){
S.session=data.session;
S.session._modelResolutionDeferred=true;
S.lastUsage={...(data.session.last_usage||{})};
// Reset scroll-direction tracker on session switch so the new chat's
// first scroll doesn't compare against the previous chat's scrollTop
// and false-trigger an unpin (#1731 follow-up — Opus stage-302 SHOULD-FIX).
if (typeof window !== 'undefined' && typeof window._resetScrollDirectionTracker === 'function') {
try { window._resetScrollDirectionTracker(); } catch (_) {}
}
// Sync workspace display immediately so the chip label reflects the new session's workspace
// before any async message-loading begins (mirrors how model is handled).
if(typeof syncTopbar==='function') syncTopbar();
+5
View File
@@ -1401,6 +1401,11 @@ let _scrollPinned=true;
let _programmaticScroll=false;
let _nearBottomCount=0;
let _lastScrollTop=null;
// Reset hook for session-switch — called from sessions.js loadSession() to
// prevent the new chat's first scroll comparing against the previous chat's
// scrollTop (Opus stage-302 SHOULD-FIX, #1731 follow-up).
function _resetScrollDirectionTracker(){ _lastScrollTop=null; }
if (typeof window !== 'undefined') window._resetScrollDirectionTracker = _resetScrollDirectionTracker;
(function(){
const el=document.getElementById('messages');
if(!el) return;