Add TTS command-only mode and settings toggle - #3
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a command-only mode for text-to-speech functionality, allowing users to require messages to start with the "!v" prefix to be spoken. The implementation adds a new boolean flag isTtsCommandEncouraged to the TTS model, exposes it in the settings UI, and modifies message filtering and vocalization logic to handle the prefix.
Changes:
- Added
isTtsCommandEncouragedflag to TtsModel with getter/setter following the existing pattern - Added a Switch in TTS settings UI to toggle command-only mode
- Modified message gating logic in
say()method to filter messages without the "!v" prefix when enabled - Added prefix stripping in
getVocalization()to remove "!v" from spoken text - Included the new flag in JSON serialization/deserialization for persistence
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| lib/screens/settings/tts.dart | Added SwitchListTile for toggling command-only mode in TTS settings UI |
| lib/models/tts.dart | Added isTtsCommandEncouraged field, getter/setter, JSON persistence, prefix checking in message filtering, and prefix stripping in vocalization |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return; | ||
| } | ||
|
|
||
| if(model.isCommand && !model.message.toLowerCase().startsWith("!v")) { |
There was a problem hiding this comment.
Missing space after the 'if' keyword. This should be if (model.isCommand instead of if(model.isCommand to follow Dart formatting conventions.
| if(model.isCommand && !model.message.toLowerCase().startsWith("!v")) { | |
| if (model.isCommand && !model.message.toLowerCase().startsWith("!v")) { |
| } | ||
| }).join(""); | ||
|
|
||
| if (text.toLowerCase().startsWith("!v ")) { |
There was a problem hiding this comment.
The prefix stripping logic in getVocalization (lines 146-149) strips the "!v" prefix unconditionally from all messages that start with it, regardless of whether isTtsCommandEncouraged is enabled or not. This means even when the command-only mode is disabled, the "!v" prefix will still be removed from spoken messages. Consider making the prefix stripping conditional on the isTtsCommandEncouraged flag, or clarify if this is intentional behavior.
| if (text.toLowerCase().startsWith("!v ")) { | |
| if (isTtsCommandEncouraged && text.toLowerCase().startsWith("!v ")) { |
| return; | ||
| } | ||
|
|
||
| if(model.isCommand && !model.message.toLowerCase().startsWith("!v")) { |
There was a problem hiding this comment.
This condition is redundant. At lines 407-411, you already return if isTtsCommandEncouraged is enabled and the message doesn't start with "!v ". So if execution reaches this point, either isTtsCommandEncouraged is false (in which case all commands should be filtered) or the message starts with "!v " (which means the second part of this condition will never be true). The condition should be simplified to just if (model.isCommand) to filter out all commands except "!v".
| if(model.isCommand && !model.message.toLowerCase().startsWith("!v")) { | |
| if (model.isCommand) { |
| return; | ||
| } | ||
|
|
||
| if(model.isCommand && !model.message.toLowerCase().startsWith("!v")) { |
There was a problem hiding this comment.
Inconsistent prefix checking: This line checks for "!v" without a space, but line 408 checks for "!v " with a space. This inconsistency could lead to unexpected behavior where messages like "!vtest" would pass the check at line 408 but fail here at line 423 (though given the redundancy noted in another comment, this may not be reached). Ensure all prefix checks use the same pattern.
| if(model.isCommand && !model.message.toLowerCase().startsWith("!v")) { | |
| if (model.isCommand && !model.message.toLowerCase().startsWith("!v ")) { |
| if (text.toLowerCase().startsWith("!v ")) { | ||
| debugPrint("Message starts with TTS command prefix: $text"); | ||
| text = text.substring("!v".length).trim(); |
There was a problem hiding this comment.
Case sensitivity mismatch: The check uses text.toLowerCase().startsWith("!v ") to detect the prefix, but the substring extraction uses the original case with text.substring("!v".length). This means if a user types "!V hello" (uppercase V), the check will pass but the substring will incorrectly extract "V hello" instead of "hello". Use a case-insensitive extraction or normalize the case before checking.
| if (text.toLowerCase().startsWith("!v ")) { | ||
| debugPrint("Message starts with TTS command prefix: $text"); | ||
| text = text.substring("!v".length).trim(); | ||
| } |
There was a problem hiding this comment.
The new TTS command prefix feature lacks test coverage. Given that the codebase has comprehensive tests for other models (e.g., test/models/messages/twitch/message_test.dart), consider adding tests to verify the prefix stripping logic and message filtering behavior when isTtsCommandEncouraged is enabled/disabled. This would help catch issues like the case-sensitivity and redundancy bugs identified in this review.
Introduce a new isTtsCommandEncouraged flag to TtsModel and expose it in the TTS settings UI as a Switch. When enabled, messages must start with the "!v" prefix to be spoken; the prefix is stripped from the vocalized text. Adjusted message gating logic to separately handle bot muting and command checks, added getters/setters, included the new flag in JSON (de)serialization, and added debug logging for prefix handling.
71563f5 to
fdd1f70
Compare
Introduce a new isTtsCommandEncouraged flag to TtsModel and expose it in the TTS settings UI as a Switch. When enabled, messages must start with the "!v" prefix to be spoken; the prefix is stripped from the vocalized text. Adjusted message gating logic to separately handle bot muting and command checks, added getters/setters, included the new flag in JSON (de)serialization, and added debug logging for prefix handling.