diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bd401e1..543e7e67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Hermes Web UI -- Changelog +## [Unreleased] + +### Fixed +- **New-chat button (`+`) and Cmd/Ctrl+K were no-ops while the first message was streaming** (#1432, closes #1432) — the empty-session guard from #1171 (`message_count===0` → focus composer instead of creating a new session) didn't account for in-flight streams, where the user's message hasn't been merged into `s.messages` server-side yet. Clicking `+` during the first response of a brand-new session was silently dropped, so users couldn't actually start a parallel conversation. The guard now also requires `!S.busy && !S.session.active_stream_id && !S.session.pending_user_message` — the same in-flight signal already used by `_restoreSettledSession()` in `messages.js:1081`. (`static/boot.js`) +- **Profile-name field auto-capitalized typed values despite the "lowercase only" hint** (#1423, closes #1423) — the input had `autocomplete="off"` but was missing `autocapitalize="none"`, `autocorrect="off"`, and `spellcheck="false"`, so mobile keyboards (iOS Safari/WKWebView, Android Chrome) silently capitalized the first letter and desktop spellcheck could rewrite the value on blur. The form lowercases on submit, so stored data was always correct — the bug was a misleading display during typing. Same attributes added to the Base URL field for the same reason (URLs are not natural-language text). The API key field is `type="password"` and already has correct browser behavior. (`static/panels.js`) + ## [v0.50.261] — 2026-05-02 ### Changed diff --git a/static/boot.js b/static/boot.js index e4134258..15e51e9d 100644 --- a/static/boot.js +++ b/static/boot.js @@ -689,9 +689,24 @@ window._micPendingSend=window._micPendingSend||false; })(); $('fileInput').onchange=e=>{addFiles(Array.from(e.target.files));e.target.value='';}; $('btnNewChat').onclick=async()=>{ - // If the current session has no messages, just focus the composer rather than - // creating another empty session that will clutter the sidebar list (#1171). - if(S.session&&(S.session.message_count||0)===0){$('msg').focus();closeMobileSidebar();return;} + // If the current session has no messages AND nothing is in flight, just focus + // the composer rather than creating another empty session that will clutter the + // sidebar list (#1171). + // + // The "nothing in flight" half is critical (#1432): if the user clicks + while + // their first message is still streaming (or queued), `message_count` is still 0 + // server-side because the user turn hasn't been merged yet. The old guard treated + // that as "empty" and made + a no-op for the entire stream duration, so users + // couldn't actually start a parallel chat. Use the same in-flight signal as + // `_restoreSettledSession()` in messages.js: an active stream id or a queued + // pending user message means the session is real, not empty. + if(S.session + && (S.session.message_count||0)===0 + && !S.busy + && !S.session.active_stream_id + && !S.session.pending_user_message){ + $('msg').focus();closeMobileSidebar();return; + } await newSession();await renderSessionList();closeMobileSidebar();$('msg').focus(); }; $('btnDownload').onclick=()=>{ @@ -839,9 +854,17 @@ document.addEventListener('keydown',async e=>{ } if((e.metaKey||e.ctrlKey)&&e.key==='k'){ e.preventDefault(); - // If the current session has no messages, just focus the composer rather than - // creating another empty session that will clutter the sidebar list (#1171). - if(S.session&&(S.session.message_count||0)===0){$('msg').focus();return;} + // If the current session has no messages AND nothing is in flight, just focus + // the composer rather than creating another empty session that will clutter + // the sidebar list (#1171). See the matching guard in $('btnNewChat').onclick + // and bug #1432 for why the in-flight check is needed. + if(S.session + && (S.session.message_count||0)===0 + && !S.busy + && !S.session.active_stream_id + && !S.session.pending_user_message){ + $('msg').focus();return; + } // Cmd/Ctrl+K should always create a new conversation, even while the current // one is still streaming. The old !S.busy guard meant users had to wait for // a long generation to finish before they could start something new — exactly diff --git a/static/panels.js b/static/panels.js index b744cebb..2be1fa33 100644 --- a/static/panels.js +++ b/static/panels.js @@ -2529,7 +2529,7 @@ function _renderProfileForm(){