Skip to content

Add TTS command-only mode and settings toggle - #3

Merged
LeMyst merged 1 commit into
mainfrom
feat/add-tts-command
Feb 28, 2026
Merged

Add TTS command-only mode and settings toggle#3
LeMyst merged 1 commit into
mainfrom
feat/add-tts-command

Conversation

@LeMyst

@LeMyst LeMyst commented Feb 22, 2026

Copy link
Copy Markdown
Owner

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.

Copilot AI review requested due to automatic review settings February 22, 2026 09:22
@LeMyst
LeMyst temporarily deployed to android-internal February 22, 2026 09:22 — with GitHub Actions Inactive

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 isTtsCommandEncouraged flag 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.

Comment thread lib/models/tts.dart
return;
}

if(model.isCommand && !model.message.toLowerCase().startsWith("!v")) {

Copilot AI Feb 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after the 'if' keyword. This should be if (model.isCommand instead of if(model.isCommand to follow Dart formatting conventions.

Suggested change
if(model.isCommand && !model.message.toLowerCase().startsWith("!v")) {
if (model.isCommand && !model.message.toLowerCase().startsWith("!v")) {

Copilot uses AI. Check for mistakes.
Comment thread lib/models/tts.dart
}
}).join("");

if (text.toLowerCase().startsWith("!v ")) {

Copilot AI Feb 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
if (text.toLowerCase().startsWith("!v ")) {
if (isTtsCommandEncouraged && text.toLowerCase().startsWith("!v ")) {

Copilot uses AI. Check for mistakes.
Comment thread lib/models/tts.dart
return;
}

if(model.isCommand && !model.message.toLowerCase().startsWith("!v")) {

Copilot AI Feb 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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".

Suggested change
if(model.isCommand && !model.message.toLowerCase().startsWith("!v")) {
if (model.isCommand) {

Copilot uses AI. Check for mistakes.
Comment thread lib/models/tts.dart
return;
}

if(model.isCommand && !model.message.toLowerCase().startsWith("!v")) {

Copilot AI Feb 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
if(model.isCommand && !model.message.toLowerCase().startsWith("!v")) {
if (model.isCommand && !model.message.toLowerCase().startsWith("!v ")) {

Copilot uses AI. Check for mistakes.
Comment thread lib/models/tts.dart
Comment on lines +146 to +148
if (text.toLowerCase().startsWith("!v ")) {
debugPrint("Message starts with TTS command prefix: $text");
text = text.substring("!v".length).trim();

Copilot AI Feb 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment thread lib/models/tts.dart
Comment on lines +146 to +149
if (text.toLowerCase().startsWith("!v ")) {
debugPrint("Message starts with TTS command prefix: $text");
text = text.substring("!v".length).trim();
}

Copilot AI Feb 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
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.
@LeMyst
LeMyst force-pushed the feat/add-tts-command branch from 71563f5 to fdd1f70 Compare February 28, 2026 13:20
@LeMyst
LeMyst merged commit 10ee8d0 into main Feb 28, 2026
6 checks passed
@LeMyst
LeMyst deleted the feat/add-tts-command branch August 4, 2026 20:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants