From dc79a50fda7606140a485bcf67b29794c27c8ab0 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Thu, 24 Oct 2024 13:44:32 -0400 Subject: [PATCH] only init one instance of ttscontroller, don't stop tts twice --- .../widgets/chat/message_audio_card.dart | 8 +++---- .../chat/message_selection_overlay.dart | 8 +++++-- lib/pangea/widgets/chat/message_toolbar.dart | 5 ++++ lib/pangea/widgets/chat/tts_controller.dart | 5 ++-- .../multiple_choice_activity.dart | 8 ++++++- .../practice_activity_card.dart | 5 ++++ .../practice_activity/word_audio_button.dart | 24 ++++--------------- pubspec.yaml | 6 ++--- 8 files changed, 37 insertions(+), 32 deletions(-) diff --git a/lib/pangea/widgets/chat/message_audio_card.dart b/lib/pangea/widgets/chat/message_audio_card.dart index 97ffe36d5..e66e69477 100644 --- a/lib/pangea/widgets/chat/message_audio_card.dart +++ b/lib/pangea/widgets/chat/message_audio_card.dart @@ -21,11 +21,13 @@ class MessageAudioCard extends StatefulWidget { final PangeaMessageEvent messageEvent; final MessageOverlayController overlayController; final PangeaTokenText? selection; + final TtsController tts; const MessageAudioCard({ super.key, required this.messageEvent, required this.overlayController, + required this.tts, this.selection, }); @@ -40,8 +42,6 @@ class MessageAudioCardState extends State { int? sectionStartMS; int? sectionEndMS; - TtsController tts = TtsController(); - @override void initState() { super.initState(); @@ -68,7 +68,7 @@ class MessageAudioCardState extends State { final PangeaTokenText selection = widget.selection!; final tokenText = selection.content; - await tts.speak(tokenText); + await widget.tts.speak(tokenText); } void setSectionStartAndEnd(int? start, int? end) => mounted @@ -204,7 +204,7 @@ class MessageAudioCardState extends State { color: Theme.of(context).colorScheme.onPrimaryContainer, ), - tts.missingVoiceButton, + widget.tts.missingVoiceButton, ], ) : const CardErrorWidget( diff --git a/lib/pangea/widgets/chat/message_selection_overlay.dart b/lib/pangea/widgets/chat/message_selection_overlay.dart index 5cf9e70b5..dbce6f2b8 100644 --- a/lib/pangea/widgets/chat/message_selection_overlay.dart +++ b/lib/pangea/widgets/chat/message_selection_overlay.dart @@ -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_header.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/matrix.dart'; import 'package:flutter/foundation.dart'; @@ -61,11 +62,11 @@ class MessageOverlayController extends State /// 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 static const int neededActivities = 3; - int activitiesLeftToComplete = neededActivities; - PangeaMessageEvent get pangeaMessageEvent => widget._pangeaMessageEvent; + final TtsController tts = TtsController(); + @override void initState() { super.initState(); @@ -98,6 +99,7 @@ class MessageOverlayController extends State ).listen((_) => setState(() {})); setInitialToolbarMode(); + tts.setupTTS(); } /// We need to check if the setState call is safe to call immediately @@ -359,6 +361,7 @@ class MessageOverlayController extends State void dispose() { _animationController.dispose(); _reactionSubscription?.cancel(); + tts.dispose(); super.dispose(); } @@ -455,6 +458,7 @@ class MessageOverlayController extends State MessageToolbar( pangeaMessageEvent: widget._pangeaMessageEvent, overLayController: this, + tts: tts, ), SizedBox( height: adjustedMessageHeight, diff --git a/lib/pangea/widgets/chat/message_toolbar.dart b/lib/pangea/widgets/chat/message_toolbar.dart index cf4192691..2f2f2b736 100644 --- a/lib/pangea/widgets/chat/message_toolbar.dart +++ b/lib/pangea/widgets/chat/message_toolbar.dart @@ -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_translation_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/practice_activity/practice_activity_card.dart'; import 'package:fluffychat/pangea/widgets/select_to_define.dart'; @@ -22,11 +23,13 @@ const double minCardHeight = 70; class MessageToolbar extends StatelessWidget { final PangeaMessageEvent pangeaMessageEvent; final MessageOverlayController overLayController; + final TtsController tts; const MessageToolbar({ super.key, required this.pangeaMessageEvent, required this.overLayController, + required this.tts, }); Widget get toolbarContent { @@ -50,6 +53,7 @@ class MessageToolbar extends StatelessWidget { messageEvent: pangeaMessageEvent, overlayController: overLayController, selection: overLayController.selectedSpan, + tts: tts, ); case MessageMode.speechToText: return MessageSpeechToTextCard( @@ -87,6 +91,7 @@ class MessageToolbar extends StatelessWidget { return PracticeActivityCard( pangeaMessageEvent: pangeaMessageEvent, overlayController: overLayController, + tts: tts, ); default: debugger(when: kDebugMode); diff --git a/lib/pangea/widgets/chat/tts_controller.dart b/lib/pangea/widgets/chat/tts_controller.dart index 225d7a04e..c98cb6220 100644 --- a/lib/pangea/widgets/chat/tts_controller.dart +++ b/lib/pangea/widgets/chat/tts_controller.dart @@ -23,7 +23,8 @@ class TtsController { } onError(dynamic message) => ErrorHandler.logError( - m: 'TTS error', + e: message, + m: (message.toString().isNotEmpty) ? message.toString() : 'TTS error', data: { 'message': message, }, @@ -82,13 +83,11 @@ class TtsController { debugger(when: kDebugMode); ErrorHandler.logError(e: e, s: s); } - await tts.stop(); } Future speak(String text) async { try { stop(); - targetLanguage ??= MatrixState.pangeaController.languageController.userL2?.langCode; diff --git a/lib/pangea/widgets/practice_activity/multiple_choice_activity.dart b/lib/pangea/widgets/practice_activity/multiple_choice_activity.dart index ee892837b..e76021000 100644 --- a/lib/pangea/widgets/practice_activity/multiple_choice_activity.dart +++ b/lib/pangea/widgets/practice_activity/multiple_choice_activity.dart @@ -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/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/widgets/chat/tts_controller.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/widgets/matrix.dart'; @@ -16,11 +17,13 @@ import 'package:flutter/material.dart'; class MultipleChoiceActivity extends StatefulWidget { final PracticeActivityCardState practiceCardController; final PracticeActivityModel currentActivity; + final TtsController tts; const MultipleChoiceActivity({ super.key, required this.practiceCardController, required this.currentActivity, + required this.tts, }); @override @@ -112,7 +115,10 @@ class MultipleChoiceActivityState extends State { // #freeze-activity if (practiceActivity.activityType == ActivityTypeEnum.wordFocusListening) - WordAudioButton(text: practiceActivity.content.answer), + WordAudioButton( + text: practiceActivity.content.answer, + ttsController: widget.tts, + ), ChoicesArray( isLoading: false, uniqueKeyForLayerLink: (index) => "multiple_choice_$index", diff --git a/lib/pangea/widgets/practice_activity/practice_activity_card.dart b/lib/pangea/widgets/practice_activity/practice_activity_card.dart index c9c42b85b..dbb98de73 100644 --- a/lib/pangea/widgets/practice_activity/practice_activity_card.dart +++ b/lib/pangea/widgets/practice_activity/practice_activity_card.dart @@ -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/chat/message_selection_overlay.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/practice_activity/multiple_choice_activity.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 { final PangeaMessageEvent pangeaMessageEvent; final MessageOverlayController overlayController; + final TtsController tts; const PracticeActivityCard({ super.key, required this.pangeaMessageEvent, required this.overlayController, + required this.tts, }); @override @@ -294,6 +297,7 @@ class PracticeActivityCardState extends State { return MultipleChoiceActivity( practiceCardController: this, currentActivity: currentActivity!, + tts: widget.tts, ); case ActivityTypeEnum.wordFocusListening: // return WordFocusListeningActivity( @@ -301,6 +305,7 @@ class PracticeActivityCardState extends State { return MultipleChoiceActivity( practiceCardController: this, currentActivity: currentActivity!, + tts: widget.tts, ); // default: // ErrorHandler.logError( diff --git a/lib/pangea/widgets/practice_activity/word_audio_button.dart b/lib/pangea/widgets/practice_activity/word_audio_button.dart index 24835fcb2..2f56299c8 100644 --- a/lib/pangea/widgets/practice_activity/word_audio_button.dart +++ b/lib/pangea/widgets/practice_activity/word_audio_button.dart @@ -4,10 +4,12 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; class WordAudioButton extends StatefulWidget { final String text; + final TtsController ttsController; const WordAudioButton({ super.key, required this.text, + required this.ttsController, }); @override @@ -17,22 +19,6 @@ class WordAudioButton extends StatefulWidget { class WordAudioButtonState extends State { 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 Widget build(BuildContext context) { debugPrint('build WordAudioButton'); @@ -54,7 +40,7 @@ class WordAudioButtonState extends State { _isPlaying ? L10n.of(context)!.stop : L10n.of(context)!.playAudio, onPressed: () async { if (_isPlaying) { - await ttsController.tts.stop(); + await widget.ttsController.tts.stop(); if (mounted) { setState(() => _isPlaying = false); } @@ -62,7 +48,7 @@ class WordAudioButtonState extends State { if (mounted) { setState(() => _isPlaying = true); } - await ttsController.speak(widget.text); + await widget.ttsController.speak(widget.text); if (mounted) { setState(() => _isPlaying = false); } @@ -70,7 +56,7 @@ class WordAudioButtonState extends State { }, // Disable button if language isn't supported ), // #freeze-activity - ttsController.missingVoiceButton, + widget.ttsController.missingVoiceButton, ], ); } diff --git a/pubspec.yaml b/pubspec.yaml index f8f00ee8f..25403c0ec 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -6,7 +6,7 @@ description: Learn a language while texting your friends. # Pangea# publish_to: none # On version bump also increase the build number for F-Droid -version: 1.22.4+3554 +version: 1.22.5+3555 environment: sdk: ">=3.0.0 <4.0.0" @@ -162,8 +162,8 @@ flutter: # #Pangea # uncomment this to enable mobile builds # causes error with github actions - # - .env - # - assets/.env + - .env + - assets/.env - assets/pangea/ - assets/pangea/bot_faces/ # Pangea#