fix: voice-mode pref toggle-off now stops the recognizer (#1491)#1518
Conversation
When a user disables 'Hands-free voice mode' in Settings while voice mode is active, the button hides but the SpeechRecognition keeps running — the user can't stop it because the button is invisible. Fix: _applyVoiceModePref() now checks if voice mode is active and calls _deactivate() when the pref is toggled off. Move _voiceModeActive declaration above the function to avoid TDZ. Also removes a duplicate window._applyVoiceModePref assignment.
|
Confirmed the TDZ risk in
The call at line 476 happens to work today because the current body of Behavioral fix is right too: if the pref is toggled off while Things I'll spot-check on review:
Pulling locally to verify on a live Settings → Preferences toggle. Thanks @franksong2702. |
f8ed6da
…stops the recognizer — closes nesquena#1491
…sorbed CHANGELOG, ROADMAP, TESTING bumped (3936 \u2192 3946). 8 constituent PRs: - nesquena#1523 (@franksong2702) branch indicator codepoint fix - nesquena#1519 (@franksong2702) onboarding API-key focus loss fix - nesquena#1518 (@franksong2702) voice-mode toggle-off recognizer stop - nesquena#1516 (@franksong2702) YAML newline CSS rules - nesquena#1517 (@franksong2702) __CACHE_VERSION__ \u2192 __WEBUI_VERSION__ rename - nesquena#1532 (@ai-ag2026) state.db WebUI session recovery - nesquena#1525 (@ai-ag2026) stale stream state proactive cleanup - nesquena#1526 (@ai-ag2026) max_tokens forwarding + OpenRouter quota classifier Opus MUST-FIX absorbed: sw.js conflict-marker cleanup + regression guard. Opus SHOULD-FIX deferred to follow-up nesquena#1533 (race in _clear_stale_stream_state). 2 closed as duplicates: nesquena#1528 (identical to nesquena#1517), nesquena#1529 (superseded by nesquena#1516). 1 maintainer-review label: nesquena#1531 (Asunfly stowaway change in force-push). 5 stay on hold: nesquena#1418 nesquena#1464 nesquena#1404 nesquena#1353 nesquena#1311.
Thinking Path
_applyVoiceModePref()controls button visibility but doesn't stop the SpeechRecognition when toggled off mid-session_applyVoiceModePref()now checks if voice mode is active and calls_deactivate()when the pref is toggled off_voiceModeActivemust be declared before_applyVoiceModePref()to avoid Temporal Dead Zone (TDZ) — the variable was previously declared after the functionWhat Changed
static/boot.js— 3 changes:let _voiceModeActive=falseabove_applyVoiceModePref()(was below, causing TDZ risk)_applyVoiceModePref()now reads the pref into a localenabledvariable and calls_deactivate()when!enabled && _voiceModeActivewindow._applyVoiceModePref = _applyVoiceModePrefassignmentWhy It Matters
_deactivate()function (line 706) properly cleans up: stops recognition, clears timers, restores TTS, resets UI stateVerification
_deactivateis a function declaration (hoisted) — safe to call from_applyVoiceModePrefdespite being defined latertest_v050255_opus_followups.pyare Python 3.9int | Nonesyntax, unrelated)window._applyVoiceModePref()viapanels.jsonchange handler — no changes needed thereRisks / Follow-ups
_deactivate()is already the standard cleanup path for voice mode (called on button click, error, etc.). Calling it from the pref toggle is the same code path.Model Used