16 files changed
+721
-6
lib/features/tts/providers/tts_providers.dart
+7
-6
@@ -196,8 +196,6 @@ class TtsNotifier extends Notifier<TtsState> {
196
}
197
});
198
199
- _player.setAudioSources([]);
200
-
199
_playerCompleteSubscription = _player.playerStateStream.listen((
200
playerState,
201
) {
@@ -831,7 +829,7 @@ class TtsNotifier extends Notifier<TtsState> {
829
_isPreview = isPreview;
830
_playlistBuffer.clear();
831
_nextPlaylistIndexToAdd = 0;
834
- await _player.clearAudioSources();
832
+ await _player.stop();
833
834
try {
835
AudioSession.instance.then((session) {
@@ -899,7 +897,11 @@ class TtsNotifier extends Notifier<TtsState> {
897
while (_playlistBuffer.containsKey(_nextPlaylistIndexToAdd)) {
898
final indexBeingAdded = _nextPlaylistIndexToAdd;
899
final src = _playlistBuffer.remove(indexBeingAdded)!;
902
- await _player.addAudioSource(src);
900
+ if (indexBeingAdded == 0) {
901
+ await _player.setAudioSources([src]);
902
+ } else {
903
+ await _player.addAudioSource(src);
904
+ }
905
906
if (indexBeingAdded == 0 && !state.isPaused) {
907
await _player.setSpeed(state.playbackSpeed);
@@ -1092,7 +1094,6 @@ class TtsNotifier extends Notifier<TtsState> {
1094
}
1095
try {
1096
await _player.stop();
1095
- await _player.clearAudioSources();
1097
} catch (_) {}
1098
await _flutterTts?.stop();
1099
_cleanupSessionFiles(_currentSessionId, _chunks.length);
@@ -1172,7 +1173,7 @@ class TtsNotifier extends Notifier<TtsState> {
1173
_isPreview = isPreview;
1174
_playlistBuffer.clear();
1175
_nextPlaylistIndexToAdd = 0;
1175
- await _player.clearAudioSources();
1176
+ await _player.stop();
1177
1178
state = state.copyWith(
1179
isSpeaking: true,
lib/l10n/app_localizations_ar.dart
+40
@@ -2167,6 +2167,46 @@ class AppLocalizationsAr extends AppLocalizations {
2167
@override
2168
String get gguf_curated_models_short => 'Curated on-device models';
2169
2170
+ @override
2171
+ String get gguf_vision_projector => 'Vision Projector';
2172
+
2173
+ @override
2174
+ String get gguf_attach_projector => 'Attach Vision Projector';
2175
+
2176
+ @override
2177
+ String get gguf_change_projector => 'Change Vision Projector';
2178
+
2179
+ @override
2180
+ String get gguf_remove_projector => 'Remove Projector';
2181
+
2182
+ @override
2183
+ String get gguf_projector_attached =>
2184
+ 'Vision projector attached successfully';
2185
+
2186
+ @override
2187
+ String get gguf_projector_removed => 'Vision projector removed';
2188
+
2189
+ @override
2190
+ String gguf_projector_auto_detected(String name) {
2191
+ return 'Auto-detected and linked vision projector: $name';
2192
+ }
2193
+
2194
+ @override
2195
+ String get gguf_is_projector_file =>
2196
+ 'The selected file is a vision projector (mmproj), not a standalone model.';
2197
+
2198
+ @override
2199
+ String get gguf_projector_url_label =>
2200
+ 'Vision Projector URL (optional mmproj)';
2201
+
2202
+ @override
2203
+ String get gguf_projector_url_hint =>
2204
+ 'https://huggingface.co/.../mmproj-...gguf';
2205
+
2206
+ @override
2207
+ String get gguf_vision_not_supported_error =>
2208
+ 'The active model does not support image attachments. Please attach a vision projector (mmproj) or select a vision-supported model.';
2209
+
2210
@override
2211
String get execute_tool_title => 'Execute Tool';
2212
lib/l10n/app_localizations_bn.dart
+40
@@ -2188,6 +2188,46 @@ class AppLocalizationsBn extends AppLocalizations {
2188
@override
2189
String get gguf_curated_models_short => 'Curated on-device models';
2190
2191
+ @override
2192
+ String get gguf_vision_projector => 'Vision Projector';
2193
+
2194
+ @override
2195
+ String get gguf_attach_projector => 'Attach Vision Projector';
2196
+
2197
+ @override
2198
+ String get gguf_change_projector => 'Change Vision Projector';
2199
+
2200
+ @override
2201
+ String get gguf_remove_projector => 'Remove Projector';
2202
+
2203
+ @override
2204
+ String get gguf_projector_attached =>
2205
+ 'Vision projector attached successfully';
2206
+
2207
+ @override
2208
+ String get gguf_projector_removed => 'Vision projector removed';
2209
+
2210
+ @override
2211
+ String gguf_projector_auto_detected(String name) {
2212
+ return 'Auto-detected and linked vision projector: $name';
2213
+ }
2214
+
2215
+ @override
2216
+ String get gguf_is_projector_file =>
2217
+ 'The selected file is a vision projector (mmproj), not a standalone model.';
2218
+
2219
+ @override
2220
+ String get gguf_projector_url_label =>
2221
+ 'Vision Projector URL (optional mmproj)';
2222
+
2223
+ @override
2224
+ String get gguf_projector_url_hint =>
2225
+ 'https://huggingface.co/.../mmproj-...gguf';
2226
+
2227
+ @override
2228
+ String get gguf_vision_not_supported_error =>
2229
+ 'The active model does not support image attachments. Please attach a vision projector (mmproj) or select a vision-supported model.';
2230
+
2231
@override
2232
String get execute_tool_title => 'Execute Tool';
2233
lib/l10n/app_localizations_de.dart
+40
@@ -2174,6 +2174,46 @@ class AppLocalizationsDe extends AppLocalizations {
2174
@override
2175
String get gguf_curated_models_short => 'Curated on-device models';
2176
2177
+ @override
2178
+ String get gguf_vision_projector => 'Vision Projector';
2179
+
2180
+ @override
2181
+ String get gguf_attach_projector => 'Attach Vision Projector';
2182
+
2183
+ @override
2184
+ String get gguf_change_projector => 'Change Vision Projector';
2185
+
2186
+ @override
2187
+ String get gguf_remove_projector => 'Remove Projector';
2188
+
2189
+ @override
2190
+ String get gguf_projector_attached =>
2191
+ 'Vision projector attached successfully';
2192
+
2193
+ @override
2194
+ String get gguf_projector_removed => 'Vision projector removed';
2195
+
2196
+ @override
2197
+ String gguf_projector_auto_detected(String name) {
2198
+ return 'Auto-detected and linked vision projector: $name';
2199
+ }
2200
+
2201
+ @override
2202
+ String get gguf_is_projector_file =>
2203
+ 'The selected file is a vision projector (mmproj), not a standalone model.';
2204
+
2205
+ @override
2206
+ String get gguf_projector_url_label =>
2207
+ 'Vision Projector URL (optional mmproj)';
2208
+
2209
+ @override
2210
+ String get gguf_projector_url_hint =>
2211
+ 'https://huggingface.co/.../mmproj-...gguf';
2212
+
2213
+ @override
2214
+ String get gguf_vision_not_supported_error =>
2215
+ 'The active model does not support image attachments. Please attach a vision projector (mmproj) or select a vision-supported model.';
2216
+
2217
@override
2218
String get execute_tool_title => 'Execute Tool';
2219
lib/l10n/app_localizations_es.dart
+40
@@ -2194,6 +2194,46 @@ class AppLocalizationsEs extends AppLocalizations {
2194
@override
2195
String get gguf_curated_models_short => 'Curated on-device models';
2196
2197
+ @override
2198
+ String get gguf_vision_projector => 'Vision Projector';
2199
+
2200
+ @override
2201
+ String get gguf_attach_projector => 'Attach Vision Projector';
2202
+
2203
+ @override
2204
+ String get gguf_change_projector => 'Change Vision Projector';
2205
+
2206
+ @override
2207
+ String get gguf_remove_projector => 'Remove Projector';
2208
+
2209
+ @override
2210
+ String get gguf_projector_attached =>
2211
+ 'Vision projector attached successfully';
2212
+
2213
+ @override
2214
+ String get gguf_projector_removed => 'Vision projector removed';
2215
+
2216
+ @override
2217
+ String gguf_projector_auto_detected(String name) {
2218
+ return 'Auto-detected and linked vision projector: $name';
2219
+ }
2220
+
2221
+ @override
2222
+ String get gguf_is_projector_file =>
2223
+ 'The selected file is a vision projector (mmproj), not a standalone model.';
2224
+
2225
+ @override
2226
+ String get gguf_projector_url_label =>
2227
+ 'Vision Projector URL (optional mmproj)';
2228
+
2229
+ @override
2230
+ String get gguf_projector_url_hint =>
2231
+ 'https://huggingface.co/.../mmproj-...gguf';
2232
+
2233
+ @override
2234
+ String get gguf_vision_not_supported_error =>
2235
+ 'The active model does not support image attachments. Please attach a vision projector (mmproj) or select a vision-supported model.';
2236
+
2237
@override
2238
String get execute_tool_title => 'Execute Tool';
2239
lib/l10n/app_localizations_fr.dart
+40
@@ -2177,6 +2177,46 @@ class AppLocalizationsFr extends AppLocalizations {
2177
@override
2178
String get gguf_curated_models_short => 'Curated on-device models';
2179
2180
+ @override
2181
+ String get gguf_vision_projector => 'Vision Projector';
2182
+
2183
+ @override
2184
+ String get gguf_attach_projector => 'Attach Vision Projector';
2185
+
2186
+ @override
2187
+ String get gguf_change_projector => 'Change Vision Projector';
2188
+
2189
+ @override
2190
+ String get gguf_remove_projector => 'Remove Projector';
2191
+
2192
+ @override
2193
+ String get gguf_projector_attached =>
2194
+ 'Vision projector attached successfully';
2195
+
2196
+ @override
2197
+ String get gguf_projector_removed => 'Vision projector removed';
2198
+
2199
+ @override
2200
+ String gguf_projector_auto_detected(String name) {
2201
+ return 'Auto-detected and linked vision projector: $name';
2202
+ }
2203
+
2204
+ @override
2205
+ String get gguf_is_projector_file =>
2206
+ 'The selected file is a vision projector (mmproj), not a standalone model.';
2207
+
2208
+ @override
2209
+ String get gguf_projector_url_label =>
2210
+ 'Vision Projector URL (optional mmproj)';
2211
+
2212
+ @override
2213
+ String get gguf_projector_url_hint =>
2214
+ 'https://huggingface.co/.../mmproj-...gguf';
2215
+
2216
+ @override
2217
+ String get gguf_vision_not_supported_error =>
2218
+ 'The active model does not support image attachments. Please attach a vision projector (mmproj) or select a vision-supported model.';
2219
+
2220
@override
2221
String get execute_tool_title => 'Execute Tool';
2222
lib/l10n/app_localizations_hi.dart
+40
@@ -2181,6 +2181,46 @@ class AppLocalizationsHi extends AppLocalizations {
2181
@override
2182
String get gguf_curated_models_short => 'Curated on-device models';
2183
2184
+ @override
2185
+ String get gguf_vision_projector => 'Vision Projector';
2186
+
2187
+ @override
2188
+ String get gguf_attach_projector => 'Attach Vision Projector';
2189
+
2190
+ @override
2191
+ String get gguf_change_projector => 'Change Vision Projector';
2192
+
2193
+ @override
2194
+ String get gguf_remove_projector => 'Remove Projector';
2195
+
2196
+ @override
2197
+ String get gguf_projector_attached =>
2198
+ 'Vision projector attached successfully';
2199
+
2200
+ @override
2201
+ String get gguf_projector_removed => 'Vision projector removed';
2202
+
2203
+ @override
2204
+ String gguf_projector_auto_detected(String name) {
2205
+ return 'Auto-detected and linked vision projector: $name';
2206
+ }
2207
+
2208
+ @override
2209
+ String get gguf_is_projector_file =>
2210
+ 'The selected file is a vision projector (mmproj), not a standalone model.';
2211
+
2212
+ @override
2213
+ String get gguf_projector_url_label =>
2214
+ 'Vision Projector URL (optional mmproj)';
2215
+
2216
+ @override
2217
+ String get gguf_projector_url_hint =>
2218
+ 'https://huggingface.co/.../mmproj-...gguf';
2219
+
2220
+ @override
2221
+ String get gguf_vision_not_supported_error =>
2222
+ 'The active model does not support image attachments. Please attach a vision projector (mmproj) or select a vision-supported model.';
2223
+
2224
@override
2225
String get execute_tool_title => 'Execute Tool';
2226
lib/l10n/app_localizations_it.dart
+40
@@ -2195,6 +2195,46 @@ class AppLocalizationsIt extends AppLocalizations {
2195
@override
2196
String get gguf_curated_models_short => 'Curated on-device models';
2197
2198
+ @override
2199
+ String get gguf_vision_projector => 'Vision Projector';
2200
+
2201
+ @override
2202
+ String get gguf_attach_projector => 'Attach Vision Projector';
2203
+
2204
+ @override
2205
+ String get gguf_change_projector => 'Change Vision Projector';
2206
+
2207
+ @override
2208
+ String get gguf_remove_projector => 'Remove Projector';
2209
+
2210
+ @override
2211
+ String get gguf_projector_attached =>
2212
+ 'Vision projector attached successfully';
2213
+
2214
+ @override
2215
+ String get gguf_projector_removed => 'Vision projector removed';
2216
+
2217
+ @override
2218
+ String gguf_projector_auto_detected(String name) {
2219
+ return 'Auto-detected and linked vision projector: $name';
2220
+ }
2221
+
2222
+ @override
2223
+ String get gguf_is_projector_file =>
2224
+ 'The selected file is a vision projector (mmproj), not a standalone model.';
2225
+
2226
+ @override
2227
+ String get gguf_projector_url_label =>
2228
+ 'Vision Projector URL (optional mmproj)';
2229
+
2230
+ @override
2231
+ String get gguf_projector_url_hint =>
2232
+ 'https://huggingface.co/.../mmproj-...gguf';
2233
+
2234
+ @override
2235
+ String get gguf_vision_not_supported_error =>
2236
+ 'The active model does not support image attachments. Please attach a vision projector (mmproj) or select a vision-supported model.';
2237
+
2238
@override
2239
String get execute_tool_title => 'Execute Tool';
2240
lib/l10n/app_localizations_ja.dart
+40
@@ -2136,6 +2136,46 @@ class AppLocalizationsJa extends AppLocalizations {
2136
@override
2137
String get gguf_curated_models_short => 'Curated on-device models';
2138
2139
+ @override
2140
+ String get gguf_vision_projector => 'Vision Projector';
2141
+
2142
+ @override
2143
+ String get gguf_attach_projector => 'Attach Vision Projector';
2144
+
2145
+ @override
2146
+ String get gguf_change_projector => 'Change Vision Projector';
2147
+
2148
+ @override
2149
+ String get gguf_remove_projector => 'Remove Projector';
2150
+
2151
+ @override
2152
+ String get gguf_projector_attached =>
2153
+ 'Vision projector attached successfully';
2154
+
2155
+ @override
2156
+ String get gguf_projector_removed => 'Vision projector removed';
2157
+
2158
+ @override
2159
+ String gguf_projector_auto_detected(String name) {
2160
+ return 'Auto-detected and linked vision projector: $name';
2161
+ }
2162
+
2163
+ @override
2164
+ String get gguf_is_projector_file =>
2165
+ 'The selected file is a vision projector (mmproj), not a standalone model.';
2166
+
2167
+ @override
2168
+ String get gguf_projector_url_label =>
2169
+ 'Vision Projector URL (optional mmproj)';
2170
+
2171
+ @override
2172
+ String get gguf_projector_url_hint =>
2173
+ 'https://huggingface.co/.../mmproj-...gguf';
2174
+
2175
+ @override
2176
+ String get gguf_vision_not_supported_error =>
2177
+ 'The active model does not support image attachments. Please attach a vision projector (mmproj) or select a vision-supported model.';
2178
+
2179
@override
2180
String get execute_tool_title => 'Execute Tool';
2181
lib/l10n/app_localizations_ko.dart
+40
@@ -2127,6 +2127,46 @@ class AppLocalizationsKo extends AppLocalizations {
2127
@override
2128
String get gguf_curated_models_short => '선별된 온디바이스 모델';
2129
2130
+ @override
2131
+ String get gguf_vision_projector => 'Vision Projector';
2132
+
2133
+ @override
2134
+ String get gguf_attach_projector => 'Attach Vision Projector';
2135
+
2136
+ @override
2137
+ String get gguf_change_projector => 'Change Vision Projector';
2138
+
2139
+ @override
2140
+ String get gguf_remove_projector => 'Remove Projector';
2141
+
2142
+ @override
2143
+ String get gguf_projector_attached =>
2144
+ 'Vision projector attached successfully';
2145
+
2146
+ @override
2147
+ String get gguf_projector_removed => 'Vision projector removed';
2148
+
2149
+ @override
2150
+ String gguf_projector_auto_detected(String name) {
2151
+ return 'Auto-detected and linked vision projector: $name';
2152
+ }
2153
+
2154
+ @override
2155
+ String get gguf_is_projector_file =>
2156
+ 'The selected file is a vision projector (mmproj), not a standalone model.';
2157
+
2158
+ @override
2159
+ String get gguf_projector_url_label =>
2160
+ 'Vision Projector URL (optional mmproj)';
2161
+
2162
+ @override
2163
+ String get gguf_projector_url_hint =>
2164
+ 'https://huggingface.co/.../mmproj-...gguf';
2165
+
2166
+ @override
2167
+ String get gguf_vision_not_supported_error =>
2168
+ 'The active model does not support image attachments. Please attach a vision projector (mmproj) or select a vision-supported model.';
2169
+
2170
@override
2171
String get execute_tool_title => '도구 실행';
2172
lib/l10n/app_localizations_pt.dart
+40
@@ -2194,6 +2194,46 @@ class AppLocalizationsPt extends AppLocalizations {
2194
@override
2195
String get gguf_curated_models_short => 'Modelos selecionados no dispositivo';
2196
2197
+ @override
2198
+ String get gguf_vision_projector => 'Vision Projector';
2199
+
2200
+ @override
2201
+ String get gguf_attach_projector => 'Attach Vision Projector';
2202
+
2203
+ @override
2204
+ String get gguf_change_projector => 'Change Vision Projector';
2205
+
2206
+ @override
2207
+ String get gguf_remove_projector => 'Remove Projector';
2208
+
2209
+ @override
2210
+ String get gguf_projector_attached =>
2211
+ 'Vision projector attached successfully';
2212
+
2213
+ @override
2214
+ String get gguf_projector_removed => 'Vision projector removed';
2215
+
2216
+ @override
2217
+ String gguf_projector_auto_detected(String name) {
2218
+ return 'Auto-detected and linked vision projector: $name';
2219
+ }
2220
+
2221
+ @override
2222
+ String get gguf_is_projector_file =>
2223
+ 'The selected file is a vision projector (mmproj), not a standalone model.';
2224
+
2225
+ @override
2226
+ String get gguf_projector_url_label =>
2227
+ 'Vision Projector URL (optional mmproj)';
2228
+
2229
+ @override
2230
+ String get gguf_projector_url_hint =>
2231
+ 'https://huggingface.co/.../mmproj-...gguf';
2232
+
2233
+ @override
2234
+ String get gguf_vision_not_supported_error =>
2235
+ 'The active model does not support image attachments. Please attach a vision projector (mmproj) or select a vision-supported model.';
2236
+
2237
@override
2238
String get execute_tool_title => 'Executar ferramenta';
2239
lib/l10n/app_localizations_ru.dart
+40
@@ -2192,6 +2192,46 @@ class AppLocalizationsRu extends AppLocalizations {
2192
@override
2193
String get gguf_curated_models_short => 'Кураторские модели на устройстве';
2194
2195
+ @override
2196
+ String get gguf_vision_projector => 'Vision Projector';
2197
+
2198
+ @override
2199
+ String get gguf_attach_projector => 'Attach Vision Projector';
2200
+
2201
+ @override
2202
+ String get gguf_change_projector => 'Change Vision Projector';
2203
+
2204
+ @override
2205
+ String get gguf_remove_projector => 'Remove Projector';
2206
+
2207
+ @override
2208
+ String get gguf_projector_attached =>
2209
+ 'Vision projector attached successfully';
2210
+
2211
+ @override
2212
+ String get gguf_projector_removed => 'Vision projector removed';
2213
+
2214
+ @override
2215
+ String gguf_projector_auto_detected(String name) {
2216
+ return 'Auto-detected and linked vision projector: $name';
2217
+ }
2218
+
2219
+ @override
2220
+ String get gguf_is_projector_file =>
2221
+ 'The selected file is a vision projector (mmproj), not a standalone model.';
2222
+
2223
+ @override
2224
+ String get gguf_projector_url_label =>
2225
+ 'Vision Projector URL (optional mmproj)';
2226
+
2227
+ @override
2228
+ String get gguf_projector_url_hint =>
2229
+ 'https://huggingface.co/.../mmproj-...gguf';
2230
+
2231
+ @override
2232
+ String get gguf_vision_not_supported_error =>
2233
+ 'The active model does not support image attachments. Please attach a vision projector (mmproj) or select a vision-supported model.';
2234
+
2235
@override
2236
String get execute_tool_title => 'Выполнить инструмент';
2237
lib/l10n/app_localizations_tr.dart
+40
@@ -2190,6 +2190,46 @@ class AppLocalizationsTr extends AppLocalizations {
2190
@override
2191
String get gguf_curated_models_short => 'Curated on-device models';
2192
2193
+ @override
2194
+ String get gguf_vision_projector => 'Vision Projector';
2195
+
2196
+ @override
2197
+ String get gguf_attach_projector => 'Attach Vision Projector';
2198
+
2199
+ @override
2200
+ String get gguf_change_projector => 'Change Vision Projector';
2201
+
2202
+ @override
2203
+ String get gguf_remove_projector => 'Remove Projector';
2204
+
2205
+ @override
2206
+ String get gguf_projector_attached =>
2207
+ 'Vision projector attached successfully';
2208
+
2209
+ @override
2210
+ String get gguf_projector_removed => 'Vision projector removed';
2211
+
2212
+ @override
2213
+ String gguf_projector_auto_detected(String name) {
2214
+ return 'Auto-detected and linked vision projector: $name';
2215
+ }
2216
+
2217
+ @override
2218
+ String get gguf_is_projector_file =>
2219
+ 'The selected file is a vision projector (mmproj), not a standalone model.';
2220
+
2221
+ @override
2222
+ String get gguf_projector_url_label =>
2223
+ 'Vision Projector URL (optional mmproj)';
2224
+
2225
+ @override
2226
+ String get gguf_projector_url_hint =>
2227
+ 'https://huggingface.co/.../mmproj-...gguf';
2228
+
2229
+ @override
2230
+ String get gguf_vision_not_supported_error =>
2231
+ 'The active model does not support image attachments. Please attach a vision projector (mmproj) or select a vision-supported model.';
2232
+
2233
@override
2234
String get execute_tool_title => 'Execute Tool';
2235
lib/l10n/app_localizations_zh.dart
+40
@@ -2121,6 +2121,46 @@ class AppLocalizationsZh extends AppLocalizations {
2121
@override
2122
String get gguf_curated_models_short => 'Curated on-device models';
2123
2124
+ @override
2125
+ String get gguf_vision_projector => 'Vision Projector';
2126
+
2127
+ @override
2128
+ String get gguf_attach_projector => 'Attach Vision Projector';
2129
+
2130
+ @override
2131
+ String get gguf_change_projector => 'Change Vision Projector';
2132
+
2133
+ @override
2134
+ String get gguf_remove_projector => 'Remove Projector';
2135
+
2136
+ @override
2137
+ String get gguf_projector_attached =>
2138
+ 'Vision projector attached successfully';
2139
+
2140
+ @override
2141
+ String get gguf_projector_removed => 'Vision projector removed';
2142
+
2143
+ @override
2144
+ String gguf_projector_auto_detected(String name) {
2145
+ return 'Auto-detected and linked vision projector: $name';
2146
+ }
2147
+
2148
+ @override
2149
+ String get gguf_is_projector_file =>
2150
+ 'The selected file is a vision projector (mmproj), not a standalone model.';
2151
+
2152
+ @override
2153
+ String get gguf_projector_url_label =>
2154
+ 'Vision Projector URL (optional mmproj)';
2155
+
2156
+ @override
2157
+ String get gguf_projector_url_hint =>
2158
+ 'https://huggingface.co/.../mmproj-...gguf';
2159
+
2160
+ @override
2161
+ String get gguf_vision_not_supported_error =>
2162
+ 'The active model does not support image attachments. Please attach a vision projector (mmproj) or select a vision-supported model.';
2163
+
2164
@override
2165
String get execute_tool_title => 'Execute Tool';
2166
lib/l10n/untranslated.txt
+154
@@ -1,5 +1,16 @@
1
{
2
"ar": [
3
+ "gguf_vision_projector",
4
+ "gguf_attach_projector",
5
+ "gguf_change_projector",
6
+ "gguf_remove_projector",
7
+ "gguf_projector_attached",
8
+ "gguf_projector_removed",
9
+ "gguf_projector_auto_detected",
10
+ "gguf_is_projector_file",
11
+ "gguf_projector_url_label",
12
+ "gguf_projector_url_hint",
13
+ "gguf_vision_not_supported_error",
14
"calendar_access",
15
"calendar_access_desc",
16
"calendar_permission_denied",
@@ -16,6 +27,17 @@
27
],
28
29
"bn": [
30
+ "gguf_vision_projector",
31
+ "gguf_attach_projector",
32
+ "gguf_change_projector",
33
+ "gguf_remove_projector",
34
+ "gguf_projector_attached",
35
+ "gguf_projector_removed",
36
+ "gguf_projector_auto_detected",
37
+ "gguf_is_projector_file",
38
+ "gguf_projector_url_label",
39
+ "gguf_projector_url_hint",
40
+ "gguf_vision_not_supported_error",
41
"file_explorer_not_found",
42
"export_data_failed",
43
"file_pick_failed",
@@ -36,6 +58,17 @@
58
],
59
60
"de": [
61
+ "gguf_vision_projector",
62
+ "gguf_attach_projector",
63
+ "gguf_change_projector",
64
+ "gguf_remove_projector",
65
+ "gguf_projector_attached",
66
+ "gguf_projector_removed",
67
+ "gguf_projector_auto_detected",
68
+ "gguf_is_projector_file",
69
+ "gguf_projector_url_label",
70
+ "gguf_projector_url_hint",
71
+ "gguf_vision_not_supported_error",
72
"file_explorer_not_found",
73
"export_data_failed",
74
"file_pick_failed",
@@ -56,6 +89,17 @@
89
],
90
91
"es": [
92
+ "gguf_vision_projector",
93
+ "gguf_attach_projector",
94
+ "gguf_change_projector",
95
+ "gguf_remove_projector",
96
+ "gguf_projector_attached",
97
+ "gguf_projector_removed",
98
+ "gguf_projector_auto_detected",
99
+ "gguf_is_projector_file",
100
+ "gguf_projector_url_label",
101
+ "gguf_projector_url_hint",
102
+ "gguf_vision_not_supported_error",
103
"file_explorer_not_found",
104
"export_data_failed",
105
"file_pick_failed",
@@ -76,6 +120,17 @@
120
],
121
122
"fr": [
123
+ "gguf_vision_projector",
124
+ "gguf_attach_projector",
125
+ "gguf_change_projector",
126
+ "gguf_remove_projector",
127
+ "gguf_projector_attached",
128
+ "gguf_projector_removed",
129
+ "gguf_projector_auto_detected",
130
+ "gguf_is_projector_file",
131
+ "gguf_projector_url_label",
132
+ "gguf_projector_url_hint",
133
+ "gguf_vision_not_supported_error",
134
"file_explorer_not_found",
135
"export_data_failed",
136
"file_pick_failed",
@@ -96,6 +151,17 @@
151
],
152
153
"hi": [
154
+ "gguf_vision_projector",
155
+ "gguf_attach_projector",
156
+ "gguf_change_projector",
157
+ "gguf_remove_projector",
158
+ "gguf_projector_attached",
159
+ "gguf_projector_removed",
160
+ "gguf_projector_auto_detected",
161
+ "gguf_is_projector_file",
162
+ "gguf_projector_url_label",
163
+ "gguf_projector_url_hint",
164
+ "gguf_vision_not_supported_error",
165
"file_explorer_not_found",
166
"export_data_failed",
167
"file_pick_failed",
@@ -116,6 +182,17 @@
182
],
183
184
"it": [
185
+ "gguf_vision_projector",
186
+ "gguf_attach_projector",
187
+ "gguf_change_projector",
188
+ "gguf_remove_projector",
189
+ "gguf_projector_attached",
190
+ "gguf_projector_removed",
191
+ "gguf_projector_auto_detected",
192
+ "gguf_is_projector_file",
193
+ "gguf_projector_url_label",
194
+ "gguf_projector_url_hint",
195
+ "gguf_vision_not_supported_error",
196
"file_explorer_not_found",
197
"export_data_failed",
198
"file_pick_failed",
@@ -136,6 +213,17 @@
213
],
214
215
"ja": [
216
+ "gguf_vision_projector",
217
+ "gguf_attach_projector",
218
+ "gguf_change_projector",
219
+ "gguf_remove_projector",
220
+ "gguf_projector_attached",
221
+ "gguf_projector_removed",
222
+ "gguf_projector_auto_detected",
223
+ "gguf_is_projector_file",
224
+ "gguf_projector_url_label",
225
+ "gguf_projector_url_hint",
226
+ "gguf_vision_not_supported_error",
227
"file_explorer_not_found",
228
"export_data_failed",
229
"file_pick_failed",
@@ -156,18 +244,51 @@
244
],
245
246
"ko": [
247
+ "gguf_vision_projector",
248
+ "gguf_attach_projector",
249
+ "gguf_change_projector",
250
+ "gguf_remove_projector",
251
+ "gguf_projector_attached",
252
+ "gguf_projector_removed",
253
+ "gguf_projector_auto_detected",
254
+ "gguf_is_projector_file",
255
+ "gguf_projector_url_label",
256
+ "gguf_projector_url_hint",
257
+ "gguf_vision_not_supported_error",
258
"sms_access",
259
"sms_access_desc",
260
"sms_permission_denied"
261
],
262
263
"pt": [
264
+ "gguf_vision_projector",
265
+ "gguf_attach_projector",
266
+ "gguf_change_projector",
267
+ "gguf_remove_projector",
268
+ "gguf_projector_attached",
269
+ "gguf_projector_removed",
270
+ "gguf_projector_auto_detected",
271
+ "gguf_is_projector_file",
272
+ "gguf_projector_url_label",
273
+ "gguf_projector_url_hint",
274
+ "gguf_vision_not_supported_error",
275
"sms_access",
276
"sms_access_desc",
277
"sms_permission_denied"
278
],
279
280
"ru": [
281
+ "gguf_vision_projector",
282
+ "gguf_attach_projector",
283
+ "gguf_change_projector",
284
+ "gguf_remove_projector",
285
+ "gguf_projector_attached",
286
+ "gguf_projector_removed",
287
+ "gguf_projector_auto_detected",
288
+ "gguf_is_projector_file",
289
+ "gguf_projector_url_label",
290
+ "gguf_projector_url_hint",
291
+ "gguf_vision_not_supported_error",
292
"file_explorer_not_found",
293
"export_data_failed",
294
"file_pick_failed",
@@ -188,6 +309,17 @@
309
],
310
311
"tr": [
312
+ "gguf_vision_projector",
313
+ "gguf_attach_projector",
314
+ "gguf_change_projector",
315
+ "gguf_remove_projector",
316
+ "gguf_projector_attached",
317
+ "gguf_projector_removed",
318
+ "gguf_projector_auto_detected",
319
+ "gguf_is_projector_file",
320
+ "gguf_projector_url_label",
321
+ "gguf_projector_url_hint",
322
+ "gguf_vision_not_supported_error",
323
"file_explorer_not_found",
324
"export_data_failed",
325
"file_pick_failed",
@@ -208,6 +340,17 @@
340
],
341
342
"zh": [
343
+ "gguf_vision_projector",
344
+ "gguf_attach_projector",
345
+ "gguf_change_projector",
346
+ "gguf_remove_projector",
347
+ "gguf_projector_attached",
348
+ "gguf_projector_removed",
349
+ "gguf_projector_auto_detected",
350
+ "gguf_is_projector_file",
351
+ "gguf_projector_url_label",
352
+ "gguf_projector_url_hint",
353
+ "gguf_vision_not_supported_error",
354
"file_explorer_not_found",
355
"export_data_failed",
356
"file_pick_failed",
@@ -228,6 +371,17 @@
371
],
372
373
"zh_TW": [
374
+ "gguf_vision_projector",
375
+ "gguf_attach_projector",
376
+ "gguf_change_projector",
377
+ "gguf_remove_projector",
378
+ "gguf_projector_attached",
379
+ "gguf_projector_removed",
380
+ "gguf_projector_auto_detected",
381
+ "gguf_is_projector_file",
382
+ "gguf_projector_url_label",
383
+ "gguf_projector_url_hint",
384
+ "gguf_vision_not_supported_error",
385
"file_explorer_not_found",
386
"export_data_failed",
387
"file_pick_failed",
test/features/issue_crash_fixes_test.dart
+40
@@ -7,6 +7,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
7
import 'package:flutter_test/flutter_test.dart';
8
import 'package:just_audio/just_audio.dart';
9
import 'package:just_audio_background/just_audio_background.dart';
10
+import 'package:localmind/features/tts/providers/tts_providers.dart';
11
import 'package:localmind/bootstrap/safe_riverpod_scope_host.dart';
12
import 'package:localmind/core/models/enums.dart';
13
import 'package:localmind/core/providers/app_providers.dart';
@@ -1090,6 +1091,45 @@ void main() {
1091
);
1092
},
1093
);
1094
+
1095
+ group('Issue #86: TTS Empty AudioSource RangeError Prevention', () {
1096
+ test(
1097
+ 'ConcatenatingAudioSource is initialized with at least one chunk to avoid RangeError',
1098
+ () {
1099
+ final tempDir = Directory.systemTemp;
1100
+ final tempFile = File('${tempDir.path}/tts_chunk_test_86.wav');
1101
+ tempFile.writeAsBytesSync(Uint8List(100));
1102
+ addTearDown(() {
1103
+ if (tempFile.existsSync()) tempFile.deleteSync();
1104
+ });
1105
+
1106
+ final firstSource = AudioSource.file(
1107
+ tempFile.path,
1108
+ tag: const MediaItem(
1109
+ id: 'tts_chunk_0',
1110
+ album: 'LocalMind TTS',
1111
+ title: 'Test chunk',
1112
+ ),
1113
+ );
1114
+
1115
+ // ignore: deprecated_member_use
1116
+ final playlist = ConcatenatingAudioSource(children: [firstSource]);
1117
+ expect(playlist.children, isNotEmpty);
1118
+ expect(playlist.children.length, 1);
1119
+ expect(playlist.children.first, equals(firstSource));
1120
+ },
1121
+ );
1122
+
1123
+ test(
1124
+ 'TtsNotifier does not initialize player with empty AudioSources on startup',
1125
+ () {
1126
+ final notifier = TtsNotifier();
1127
+ // On startup before playback begins, player should not have an empty audioSource
1128
+ // which causes RangeError: Valid value range is empty: 0 in just_audio_background.
1129
+ expect(notifier.player.audioSource, isNull);
1130
+ },
1131
+ );
1132
+ });
1133
}
1134
1135
class _MutableActiveServerNotifier extends ActiveServerNotifier {