fix(sessions): reset busy/stream flags before the visit-ack repaint (gate)
Gate finding: the idle-session S.busy/S.activeStreamId reset ran AFTER _acknowledgeSessionVisit(), so the ack's sidebar repaint could inherit the PREVIOUS session's busy state and manufacture a phantom unread/streaming indicator on the freshly-loaded idle session. Moved the activeStreamId calc + idle reset BEFORE the acknowledge call. Co-authored-by: neaucode-bot.
This commit is contained in:
1 parent
05f6e8c7f4
commit
cb94cecc1a
1 file changed
+24
-20
+24
-20
@@ -1779,6 +1779,30 @@ async function loadSession(sid){
|
||||
if(typeof syncTopbar==='function') syncTopbar();
|
||||
// Acknowledge the visit as soon as the session metadata is accepted for the
|
||||
// in-flight load: clears the viewed count + any stale completion-unread marker
|
||||
// `let` (not const): re-read below, after the awaited _ensureMessagesLoaded,
|
||||
// so a server_turn_started that attaches a live stream MID-RELOAD is honored
|
||||
// by the attach/idle decision instead of being clobbered by the stale snapshot.
|
||||
let activeStreamId=S.session.active_stream_id||null;
|
||||
// If the server says the session is idle, reset browser-side streaming flags
|
||||
// NOW — BEFORE _acknowledgeSessionVisit() below (whose sidebar repaint would
|
||||
// otherwise inherit the PREVIOUS session's busy/stream state) and before the
|
||||
// async _ensureMessagesLoaded gap. Without this, S.busy can remain true from a
|
||||
// still-running stream in the PREVIOUS session while S.session.session_id has
|
||||
// already advanced to the new one. _isSessionLocallyStreaming() checks
|
||||
// (isActive && S.busy), so the new session would appear locally-streaming
|
||||
// (sidebar spinner, Stop button, thinking state on an idle chat) and the visit
|
||||
// repaint would manufacture a phantom unread. Also clears stale INFLIGHT
|
||||
// entries left behind by a crashed/restarted stream. (#5917 gate: reset must
|
||||
// precede the acknowledge repaint.)
|
||||
if(!activeStreamId){
|
||||
S.activeStreamId=null;
|
||||
S.busy=false;
|
||||
if(INFLIGHT[sid]){
|
||||
delete INFLIGHT[sid];
|
||||
if(typeof clearInflightState==='function') clearInflightState(sid);
|
||||
}
|
||||
}
|
||||
|
||||
// and syncs the polling snapshot so a deferred /api/sessions poll landing
|
||||
// during the async message-load gap below cannot re-flag a stale unread dot.
|
||||
_acknowledgeSessionVisit(
|
||||
@@ -1790,26 +1814,6 @@ async function loadSession(sid){
|
||||
_setActiveSessionUrl(S.session.session_id);
|
||||
if(typeof startSessionStream==='function') startSessionStream(S.session.session_id);
|
||||
|
||||
// `let` (not const): re-read below, after the awaited _ensureMessagesLoaded,
|
||||
// so a server_turn_started that attaches a live stream MID-RELOAD is honored
|
||||
// by the attach/idle decision instead of being clobbered by the stale snapshot.
|
||||
let activeStreamId=S.session.active_stream_id||null;
|
||||
// If the server says the session is idle, reset browser-side streaming flags
|
||||
// NOW — before the async _ensureMessagesLoaded gap below. Without this,
|
||||
// S.busy can remain true from a still-running stream in the PREVIOUS session
|
||||
// while S.session.session_id has already advanced to the new one.
|
||||
// _isSessionLocallyStreaming() checks (isActive && S.busy), so during the
|
||||
// async window the new session would appear locally-streaming (sidebar spinner,
|
||||
// Stop button, thinking state on an idle chat). Also clears stale INFLIGHT
|
||||
// entries left behind by a crashed/restarted stream.
|
||||
if(!activeStreamId){
|
||||
S.activeStreamId=null;
|
||||
S.busy=false;
|
||||
if(INFLIGHT[sid]){
|
||||
delete INFLIGHT[sid];
|
||||
if(typeof clearInflightState==='function') clearInflightState(sid);
|
||||
}
|
||||
}
|
||||
|
||||
function _mergePendingSessionMessage(session,messages){
|
||||
if(!Array.isArray(messages)) return false;
|
||||
|
||||
Reference in new issue
Block a user