Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion lib/models/tts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class TtsModel extends ChangeNotifier {
var _isBotMuted = false;
var _isEmoteMuted = false;
var _isPreludeMuted = false;
var _isUnderscoreReplacementEnabled = false;
var _speed = Platform.isAndroid ? 0.8 : 0.395;
var _pitch = 1.0;
var _mode = TtsMode.disabled;
Expand Down Expand Up @@ -144,7 +145,13 @@ class TtsModel extends ChangeNotifier {
if (text.trim().isEmpty) {
return "";
}
final author = model.author.displayName ?? model.author.login;
var author = model.author.displayName ?? model.author.login;
if (_isUnderscoreReplacementEnabled) {
author = author
.replaceAll("_", " ")
.replaceAll(RegExp(r'\s+'), ' ')
.trim();
}
Comment on lines +148 to +154
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

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

The underscore replacement is only applied to author names in TwitchMessageModel, but not to other event types that also use display names, such as TwitchRaidEventModel (line 169) and TwitchFollowEventModel (line 184). This creates an inconsistent user experience where some spoken names will have underscores replaced and others won't. Consider applying the same transformation to all user display names for consistency.

Copilot uses AI. Check for mistakes.
if (!includeAuthorPrelude || isPreludeMuted) {
return text;
}
Expand Down Expand Up @@ -328,6 +335,15 @@ class TtsModel extends ChangeNotifier {
notifyListeners();
}

bool get isUnderscoreReplacementEnabled {
return _isUnderscoreReplacementEnabled;
}

set isUnderscoreReplacementEnabled(bool value) {
_isUnderscoreReplacementEnabled = value;
notifyListeners();
}

bool get isCloudTtsEnabled {
return _isCloudTtsEnabled;
}
Expand Down Expand Up @@ -509,6 +525,9 @@ class TtsModel extends ChangeNotifier {
if (json['isPreludeMuted'] != null) {
_isPreludeMuted = json['isPreludeMuted'];
}
if (json['isUnderscoreReplacementEnabled'] != null) {
_isUnderscoreReplacementEnabled = json['isUnderscoreReplacementEnabled'];
}
if (json['isRandomVoiceEnabled'] != null) {
_isRandomVoiceEnabled = json['isRandomVoiceEnabled'];
}
Expand All @@ -534,6 +553,7 @@ class TtsModel extends ChangeNotifier {
"isBotMuted": isBotMuted,
"isEmoteMuted": isEmoteMuted,
"isPreludeMuted": isPreludeMuted,
"isUnderscoreReplacementEnabled": isUnderscoreReplacementEnabled,
"isRandomVoiceEnabled": isRandomVoiceEnabled,
"language": language.languageCode,
"pitch": pitch,
Expand Down
7 changes: 7 additions & 0 deletions lib/screens/settings/tts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,13 @@ class TextToSpeechScreen extends StatelessWidget {
model.isPreludeMuted = value;
},
),
SwitchListTile.adaptive(
title: const Text("Replace underscores with spaces in names"),
value: model.isUnderscoreReplacementEnabled,
onChanged: (value) {
model.isUnderscoreReplacementEnabled = value;
},
),
SwitchListTile.adaptive(
title: const Text("Subscribers only"),
value: model.isSubscribersOnly,
Expand Down
Loading