only init one instance of ttscontroller, don't stop tts twice

pull/1428/head
ggurdin 1 year ago
parent ba0d7f98bf
commit dc79a50fda
No known key found for this signature in database
GPG Key ID: A01CB41737CBB478

@ -21,11 +21,13 @@ class MessageAudioCard extends StatefulWidget {
final PangeaMessageEvent messageEvent; final PangeaMessageEvent messageEvent;
final MessageOverlayController overlayController; final MessageOverlayController overlayController;
final PangeaTokenText? selection; final PangeaTokenText? selection;
final TtsController tts;
const MessageAudioCard({ const MessageAudioCard({
super.key, super.key,
required this.messageEvent, required this.messageEvent,
required this.overlayController, required this.overlayController,
required this.tts,
this.selection, this.selection,
}); });
@ -40,8 +42,6 @@ class MessageAudioCardState extends State<MessageAudioCard> {
int? sectionStartMS; int? sectionStartMS;
int? sectionEndMS; int? sectionEndMS;
TtsController tts = TtsController();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -68,7 +68,7 @@ class MessageAudioCardState extends State<MessageAudioCard> {
final PangeaTokenText selection = widget.selection!; final PangeaTokenText selection = widget.selection!;
final tokenText = selection.content; final tokenText = selection.content;
await tts.speak(tokenText); await widget.tts.speak(tokenText);
} }
void setSectionStartAndEnd(int? start, int? end) => mounted void setSectionStartAndEnd(int? start, int? end) => mounted
@ -204,7 +204,7 @@ class MessageAudioCardState extends State<MessageAudioCard> {
color: color:
Theme.of(context).colorScheme.onPrimaryContainer, Theme.of(context).colorScheme.onPrimaryContainer,
), ),
tts.missingVoiceButton, widget.tts.missingVoiceButton,
], ],
) )
: const CardErrorWidget( : const CardErrorWidget(

@ -17,6 +17,7 @@ import 'package:fluffychat/pangea/widgets/chat/message_toolbar_buttons.dart';
import 'package:fluffychat/pangea/widgets/chat/overlay_footer.dart'; import 'package:fluffychat/pangea/widgets/chat/overlay_footer.dart';
import 'package:fluffychat/pangea/widgets/chat/overlay_header.dart'; import 'package:fluffychat/pangea/widgets/chat/overlay_header.dart';
import 'package:fluffychat/pangea/widgets/chat/overlay_message.dart'; import 'package:fluffychat/pangea/widgets/chat/overlay_message.dart';
import 'package:fluffychat/pangea/widgets/chat/tts_controller.dart';
import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -61,11 +62,11 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
/// The number of activities that need to be completed before the toolbar is unlocked /// The number of activities that need to be completed before the toolbar is unlocked
/// If we don't have any good activities for them, we'll decrease this number /// If we don't have any good activities for them, we'll decrease this number
static const int neededActivities = 3; static const int neededActivities = 3;
int activitiesLeftToComplete = neededActivities; int activitiesLeftToComplete = neededActivities;
PangeaMessageEvent get pangeaMessageEvent => widget._pangeaMessageEvent; PangeaMessageEvent get pangeaMessageEvent => widget._pangeaMessageEvent;
final TtsController tts = TtsController();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -98,6 +99,7 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
).listen((_) => setState(() {})); ).listen((_) => setState(() {}));
setInitialToolbarMode(); setInitialToolbarMode();
tts.setupTTS();
} }
/// We need to check if the setState call is safe to call immediately /// We need to check if the setState call is safe to call immediately
@ -359,6 +361,7 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
void dispose() { void dispose() {
_animationController.dispose(); _animationController.dispose();
_reactionSubscription?.cancel(); _reactionSubscription?.cancel();
tts.dispose();
super.dispose(); super.dispose();
} }
@ -455,6 +458,7 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
MessageToolbar( MessageToolbar(
pangeaMessageEvent: widget._pangeaMessageEvent, pangeaMessageEvent: widget._pangeaMessageEvent,
overLayController: this, overLayController: this,
tts: tts,
), ),
SizedBox( SizedBox(
height: adjustedMessageHeight, height: adjustedMessageHeight,

@ -10,6 +10,7 @@ import 'package:fluffychat/pangea/widgets/chat/message_selection_overlay.dart';
import 'package:fluffychat/pangea/widgets/chat/message_speech_to_text_card.dart'; import 'package:fluffychat/pangea/widgets/chat/message_speech_to_text_card.dart';
import 'package:fluffychat/pangea/widgets/chat/message_translation_card.dart'; import 'package:fluffychat/pangea/widgets/chat/message_translation_card.dart';
import 'package:fluffychat/pangea/widgets/chat/message_unsubscribed_card.dart'; import 'package:fluffychat/pangea/widgets/chat/message_unsubscribed_card.dart';
import 'package:fluffychat/pangea/widgets/chat/tts_controller.dart';
import 'package:fluffychat/pangea/widgets/igc/word_data_card.dart'; import 'package:fluffychat/pangea/widgets/igc/word_data_card.dart';
import 'package:fluffychat/pangea/widgets/practice_activity/practice_activity_card.dart'; import 'package:fluffychat/pangea/widgets/practice_activity/practice_activity_card.dart';
import 'package:fluffychat/pangea/widgets/select_to_define.dart'; import 'package:fluffychat/pangea/widgets/select_to_define.dart';
@ -22,11 +23,13 @@ const double minCardHeight = 70;
class MessageToolbar extends StatelessWidget { class MessageToolbar extends StatelessWidget {
final PangeaMessageEvent pangeaMessageEvent; final PangeaMessageEvent pangeaMessageEvent;
final MessageOverlayController overLayController; final MessageOverlayController overLayController;
final TtsController tts;
const MessageToolbar({ const MessageToolbar({
super.key, super.key,
required this.pangeaMessageEvent, required this.pangeaMessageEvent,
required this.overLayController, required this.overLayController,
required this.tts,
}); });
Widget get toolbarContent { Widget get toolbarContent {
@ -50,6 +53,7 @@ class MessageToolbar extends StatelessWidget {
messageEvent: pangeaMessageEvent, messageEvent: pangeaMessageEvent,
overlayController: overLayController, overlayController: overLayController,
selection: overLayController.selectedSpan, selection: overLayController.selectedSpan,
tts: tts,
); );
case MessageMode.speechToText: case MessageMode.speechToText:
return MessageSpeechToTextCard( return MessageSpeechToTextCard(
@ -87,6 +91,7 @@ class MessageToolbar extends StatelessWidget {
return PracticeActivityCard( return PracticeActivityCard(
pangeaMessageEvent: pangeaMessageEvent, pangeaMessageEvent: pangeaMessageEvent,
overlayController: overLayController, overlayController: overLayController,
tts: tts,
); );
default: default:
debugger(when: kDebugMode); debugger(when: kDebugMode);

@ -23,7 +23,8 @@ class TtsController {
} }
onError(dynamic message) => ErrorHandler.logError( onError(dynamic message) => ErrorHandler.logError(
m: 'TTS error', e: message,
m: (message.toString().isNotEmpty) ? message.toString() : 'TTS error',
data: { data: {
'message': message, 'message': message,
}, },
@ -82,13 +83,11 @@ class TtsController {
debugger(when: kDebugMode); debugger(when: kDebugMode);
ErrorHandler.logError(e: e, s: s); ErrorHandler.logError(e: e, s: s);
} }
await tts.stop();
} }
Future<void> speak(String text) async { Future<void> speak(String text) async {
try { try {
stop(); stop();
targetLanguage ??= targetLanguage ??=
MatrixState.pangeaController.languageController.userL2?.langCode; MatrixState.pangeaController.languageController.userL2?.langCode;

@ -6,6 +6,7 @@ import 'package:fluffychat/pangea/controllers/my_analytics_controller.dart';
import 'package:fluffychat/pangea/enum/activity_type_enum.dart'; import 'package:fluffychat/pangea/enum/activity_type_enum.dart';
import 'package:fluffychat/pangea/models/practice_activities.dart/practice_activity_model.dart'; import 'package:fluffychat/pangea/models/practice_activities.dart/practice_activity_model.dart';
import 'package:fluffychat/pangea/models/practice_activities.dart/practice_activity_record_model.dart'; import 'package:fluffychat/pangea/models/practice_activities.dart/practice_activity_record_model.dart';
import 'package:fluffychat/pangea/widgets/chat/tts_controller.dart';
import 'package:fluffychat/pangea/widgets/practice_activity/practice_activity_card.dart'; import 'package:fluffychat/pangea/widgets/practice_activity/practice_activity_card.dart';
import 'package:fluffychat/pangea/widgets/practice_activity/word_audio_button.dart'; import 'package:fluffychat/pangea/widgets/practice_activity/word_audio_button.dart';
import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/matrix.dart';
@ -16,11 +17,13 @@ import 'package:flutter/material.dart';
class MultipleChoiceActivity extends StatefulWidget { class MultipleChoiceActivity extends StatefulWidget {
final PracticeActivityCardState practiceCardController; final PracticeActivityCardState practiceCardController;
final PracticeActivityModel currentActivity; final PracticeActivityModel currentActivity;
final TtsController tts;
const MultipleChoiceActivity({ const MultipleChoiceActivity({
super.key, super.key,
required this.practiceCardController, required this.practiceCardController,
required this.currentActivity, required this.currentActivity,
required this.tts,
}); });
@override @override
@ -112,7 +115,10 @@ class MultipleChoiceActivityState extends State<MultipleChoiceActivity> {
// #freeze-activity // #freeze-activity
if (practiceActivity.activityType == if (practiceActivity.activityType ==
ActivityTypeEnum.wordFocusListening) ActivityTypeEnum.wordFocusListening)
WordAudioButton(text: practiceActivity.content.answer), WordAudioButton(
text: practiceActivity.content.answer,
ttsController: widget.tts,
),
ChoicesArray( ChoicesArray(
isLoading: false, isLoading: false,
uniqueKeyForLayerLink: (index) => "multiple_choice_$index", uniqueKeyForLayerLink: (index) => "multiple_choice_$index",

@ -13,6 +13,7 @@ import 'package:fluffychat/pangea/utils/error_handler.dart';
import 'package:fluffychat/pangea/widgets/animations/gain_points.dart'; import 'package:fluffychat/pangea/widgets/animations/gain_points.dart';
import 'package:fluffychat/pangea/widgets/chat/message_selection_overlay.dart'; import 'package:fluffychat/pangea/widgets/chat/message_selection_overlay.dart';
import 'package:fluffychat/pangea/widgets/chat/toolbar_content_loading_indicator.dart'; import 'package:fluffychat/pangea/widgets/chat/toolbar_content_loading_indicator.dart';
import 'package:fluffychat/pangea/widgets/chat/tts_controller.dart';
import 'package:fluffychat/pangea/widgets/content_issue_button.dart'; import 'package:fluffychat/pangea/widgets/content_issue_button.dart';
import 'package:fluffychat/pangea/widgets/practice_activity/multiple_choice_activity.dart'; import 'package:fluffychat/pangea/widgets/practice_activity/multiple_choice_activity.dart';
import 'package:fluffychat/pangea/widgets/practice_activity/no_more_practice_card.dart'; import 'package:fluffychat/pangea/widgets/practice_activity/no_more_practice_card.dart';
@ -28,11 +29,13 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
class PracticeActivityCard extends StatefulWidget { class PracticeActivityCard extends StatefulWidget {
final PangeaMessageEvent pangeaMessageEvent; final PangeaMessageEvent pangeaMessageEvent;
final MessageOverlayController overlayController; final MessageOverlayController overlayController;
final TtsController tts;
const PracticeActivityCard({ const PracticeActivityCard({
super.key, super.key,
required this.pangeaMessageEvent, required this.pangeaMessageEvent,
required this.overlayController, required this.overlayController,
required this.tts,
}); });
@override @override
@ -294,6 +297,7 @@ class PracticeActivityCardState extends State<PracticeActivityCard> {
return MultipleChoiceActivity( return MultipleChoiceActivity(
practiceCardController: this, practiceCardController: this,
currentActivity: currentActivity!, currentActivity: currentActivity!,
tts: widget.tts,
); );
case ActivityTypeEnum.wordFocusListening: case ActivityTypeEnum.wordFocusListening:
// return WordFocusListeningActivity( // return WordFocusListeningActivity(
@ -301,6 +305,7 @@ class PracticeActivityCardState extends State<PracticeActivityCard> {
return MultipleChoiceActivity( return MultipleChoiceActivity(
practiceCardController: this, practiceCardController: this,
currentActivity: currentActivity!, currentActivity: currentActivity!,
tts: widget.tts,
); );
// default: // default:
// ErrorHandler.logError( // ErrorHandler.logError(

@ -4,10 +4,12 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
class WordAudioButton extends StatefulWidget { class WordAudioButton extends StatefulWidget {
final String text; final String text;
final TtsController ttsController;
const WordAudioButton({ const WordAudioButton({
super.key, super.key,
required this.text, required this.text,
required this.ttsController,
}); });
@override @override
@ -17,22 +19,6 @@ class WordAudioButton extends StatefulWidget {
class WordAudioButtonState extends State<WordAudioButton> { class WordAudioButtonState extends State<WordAudioButton> {
bool _isPlaying = false; bool _isPlaying = false;
TtsController ttsController = TtsController();
@override
void initState() {
// TODO: implement initState
debugPrint('initState WordAudioButton');
super.initState();
ttsController.setupTTS().then((value) => setState(() {}));
}
@override
void dispose() {
ttsController.dispose();
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
debugPrint('build WordAudioButton'); debugPrint('build WordAudioButton');
@ -54,7 +40,7 @@ class WordAudioButtonState extends State<WordAudioButton> {
_isPlaying ? L10n.of(context)!.stop : L10n.of(context)!.playAudio, _isPlaying ? L10n.of(context)!.stop : L10n.of(context)!.playAudio,
onPressed: () async { onPressed: () async {
if (_isPlaying) { if (_isPlaying) {
await ttsController.tts.stop(); await widget.ttsController.tts.stop();
if (mounted) { if (mounted) {
setState(() => _isPlaying = false); setState(() => _isPlaying = false);
} }
@ -62,7 +48,7 @@ class WordAudioButtonState extends State<WordAudioButton> {
if (mounted) { if (mounted) {
setState(() => _isPlaying = true); setState(() => _isPlaying = true);
} }
await ttsController.speak(widget.text); await widget.ttsController.speak(widget.text);
if (mounted) { if (mounted) {
setState(() => _isPlaying = false); setState(() => _isPlaying = false);
} }
@ -70,7 +56,7 @@ class WordAudioButtonState extends State<WordAudioButton> {
}, // Disable button if language isn't supported }, // Disable button if language isn't supported
), ),
// #freeze-activity // #freeze-activity
ttsController.missingVoiceButton, widget.ttsController.missingVoiceButton,
], ],
); );
} }

@ -6,7 +6,7 @@ description: Learn a language while texting your friends.
# Pangea# # Pangea#
publish_to: none publish_to: none
# On version bump also increase the build number for F-Droid # On version bump also increase the build number for F-Droid
version: 1.22.4+3554 version: 1.22.5+3555
environment: environment:
sdk: ">=3.0.0 <4.0.0" sdk: ">=3.0.0 <4.0.0"
@ -162,8 +162,8 @@ flutter:
# #Pangea # #Pangea
# uncomment this to enable mobile builds # uncomment this to enable mobile builds
# causes error with github actions # causes error with github actions
# - .env - .env
# - assets/.env - assets/.env
- assets/pangea/ - assets/pangea/
- assets/pangea/bot_faces/ - assets/pangea/bot_faces/
# Pangea# # Pangea#

Loading…
Cancel
Save