diff --git a/lib/pangea/choreographer/choreographer.dart b/lib/pangea/choreographer/choreographer.dart index 210a8ed16..8c936a3d7 100644 --- a/lib/pangea/choreographer/choreographer.dart +++ b/lib/pangea/choreographer/choreographer.dart @@ -14,10 +14,10 @@ import 'package:fluffychat/pangea/choreographer/it/completed_it_step_model.dart' import 'package:fluffychat/pangea/choreographer/pangea_message_content_model.dart'; import 'package:fluffychat/pangea/choreographer/text_editing/edit_type_enum.dart'; import 'package:fluffychat/pangea/choreographer/text_editing/pangea_text_controller.dart'; -import 'package:fluffychat/pangea/events/controllers/message_data_controller.dart'; import 'package:fluffychat/pangea/events/models/representation_content_model.dart'; import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart'; import 'package:fluffychat/pangea/events/repo/token_api_models.dart'; +import 'package:fluffychat/pangea/events/repo/tokens_repo.dart'; import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart'; import 'package:fluffychat/pangea/spaces/models/space_model.dart'; import 'package:fluffychat/pangea/subscription/controllers/subscription_controller.dart'; @@ -265,15 +265,14 @@ class Choreographer extends ChangeNotifier { final l1LangCode = MatrixState.pangeaController.languageController.userL1?.langCode; if (l1LangCode != null && l2LangCode != null) { - final res = await MessageDataController.getTokens( - repEventId: null, - room: null, - req: TokensRequestModel( + final res = await TokensRepo.get( + MatrixState.pangeaController.userController.accessToken, + TokensRequestModel( fullText: message, senderL1: l1LangCode, senderL2: l2LangCode, ), - ).timeout(const Duration(seconds: 10)); + ); tokensResp = res.isValue ? res.result : null; } diff --git a/lib/pangea/common/controllers/pangea_controller.dart b/lib/pangea/common/controllers/pangea_controller.dart index f61209428..2595b1819 100644 --- a/lib/pangea/common/controllers/pangea_controller.dart +++ b/lib/pangea/common/controllers/pangea_controller.dart @@ -21,7 +21,6 @@ import 'package:fluffychat/pangea/learning_settings/controllers/language_control import 'package:fluffychat/pangea/learning_settings/utils/locale_provider.dart'; import 'package:fluffychat/pangea/learning_settings/utils/p_language_store.dart'; import 'package:fluffychat/pangea/spaces/controllers/space_code_controller.dart'; -import 'package:fluffychat/pangea/speech_to_text/speech_to_text_controller.dart'; import 'package:fluffychat/pangea/subscription/controllers/subscription_controller.dart'; import 'package:fluffychat/pangea/toolbar/controllers/text_to_speech_controller.dart'; import 'package:fluffychat/pangea/toolbar/controllers/tts_controller.dart'; @@ -40,7 +39,6 @@ class PangeaController { late PutAnalyticsController putAnalytics; late SubscriptionController subscriptionController; late TextToSpeechController textToSpeech; - late SpeechToTextController speechToText; ///store Services final pLanguageStore = PLanguageStore(); @@ -85,7 +83,6 @@ class PangeaController { putAnalytics = PutAnalyticsController(this); subscriptionController = SubscriptionController(this); textToSpeech = TextToSpeechController(this); - speechToText = SpeechToTextController(this); PAuthGaurd.pController = this; } diff --git a/lib/pangea/events/controllers/message_data_controller.dart b/lib/pangea/events/controllers/message_data_controller.dart deleted file mode 100644 index 30319ce7c..000000000 --- a/lib/pangea/events/controllers/message_data_controller.dart +++ /dev/null @@ -1,198 +0,0 @@ -import 'dart:async'; - -import 'package:async/async.dart'; -import 'package:matrix/matrix.dart' hide Result; - -import 'package:fluffychat/pangea/common/utils/error_handler.dart'; -import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart'; -import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart'; -import 'package:fluffychat/pangea/events/models/representation_content_model.dart'; -import 'package:fluffychat/pangea/events/models/stt_translation_model.dart'; -import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart'; -import 'package:fluffychat/pangea/events/repo/token_api_models.dart'; -import 'package:fluffychat/pangea/events/repo/tokens_repo.dart'; -import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; -import 'package:fluffychat/pangea/translation/full_text_translation_repo.dart'; -import 'package:fluffychat/pangea/translation/full_text_translation_request_model.dart'; -import 'package:fluffychat/widgets/future_loading_dialog.dart'; -import 'package:fluffychat/widgets/matrix.dart'; - -// TODO - make this static and take it out of the _pangeaController -// will need to pass accessToken to the requests -class MessageDataController { - /// get tokens from the server - /// if repEventId is not null, send the tokens to the room - static Future> getTokens({ - required String? repEventId, - required TokensRequestModel req, - required Room? room, - }) async { - final res = await TokensRepo.get( - MatrixState.pangeaController.userController.accessToken, - req, - ); - if (res.isValue && repEventId != null && room != null) { - room - .sendPangeaEvent( - content: PangeaMessageTokens( - tokens: res.result!.tokens, - detections: res.result!.detections, - ).toJson(), - parentEventId: repEventId, - type: PangeaEventTypes.tokens, - ) - .catchError( - (e) => ErrorHandler.logError( - m: "error in _getTokens.sendPangeaEvent", - e: e, - s: StackTrace.current, - data: req.toJson(), - ), - ); - } - return res; - } - - /////// translation //////// - - /// get translation from the server - /// if in cache, return from cache - /// if not in cache, get from server - /// send the translation to the room as a representation event - static Future getPangeaRepresentation({ - required FullTextTranslationRequestModel req, - required Event messageEvent, - }) => - _getPangeaRepresentation(req: req, messageEvent: messageEvent); - - static Future _getPangeaRepresentation({ - required FullTextTranslationRequestModel req, - required Event messageEvent, - }) async { - final res = await FullTextTranslationRepo.get( - MatrixState.pangeaController.userController.accessToken, - req, - ); - - if (res.isError) { - throw res.error!; - } - - final rep = PangeaRepresentation( - langCode: req.tgtLang, - text: res.result!, - originalSent: false, - originalWritten: false, - ); - - messageEvent.room - .sendPangeaEvent( - content: rep.toJson(), - parentEventId: messageEvent.eventId, - type: PangeaEventTypes.representation, - ) - .catchError( - (e) => ErrorHandler.logError( - m: "error in _getPangeaRepresentation.sendPangeaEvent", - e: e, - s: StackTrace.current, - data: req.toJson(), - ), - ); - - return rep; - } - - static Future getPangeaRepresentationEvent({ - required FullTextTranslationRequestModel req, - required PangeaMessageEvent messageEvent, - bool originalSent = false, - }) async { - final res = await FullTextTranslationRepo.get( - MatrixState.pangeaController.userController.accessToken, - req, - ); - - if (res.isError) { - return null; - } - - if (originalSent && messageEvent.originalSent != null) { - originalSent = false; - } - - final rep = PangeaRepresentation( - langCode: req.tgtLang, - text: res.result!, - originalSent: originalSent, - originalWritten: false, - ); - - try { - final repEvent = await messageEvent.room.sendPangeaEvent( - content: rep.toJson(), - parentEventId: messageEvent.eventId, - type: PangeaEventTypes.representation, - ); - return repEvent?.eventId; - } catch (e, s) { - ErrorHandler.logError( - m: "error in _getPangeaRepresentation.sendPangeaEvent", - e: e, - s: s, - data: req.toJson(), - ); - return null; - } - } - - static Future getSttTranslation({ - required String? repEventId, - required FullTextTranslationRequestModel req, - required Room? room, - }) => - _getSttTranslation( - repEventId: repEventId, - req: req, - room: room, - ); - - static Future _getSttTranslation({ - required String? repEventId, - required FullTextTranslationRequestModel req, - required Room? room, - }) async { - final res = await FullTextTranslationRepo.get( - MatrixState.pangeaController.userController.accessToken, - req, - ); - - if (res.isError) { - throw res.error!; - } - - final translation = SttTranslationModel( - translation: res.result!, - langCode: req.tgtLang, - ); - - if (repEventId != null && room != null) { - room - .sendPangeaEvent( - content: translation.toJson(), - parentEventId: repEventId, - type: PangeaEventTypes.sttTranslation, - ) - .catchError( - (e) => ErrorHandler.logError( - m: "error in _getSttTranslation.sendPangeaEvent", - e: e, - s: StackTrace.current, - data: req.toJson(), - ), - ); - } - - return translation; - } -} diff --git a/lib/pangea/events/event_wrappers/pangea_message_event.dart b/lib/pangea/events/event_wrappers/pangea_message_event.dart index be1643194..cbdc481f2 100644 --- a/lib/pangea/events/event_wrappers/pangea_message_event.dart +++ b/lib/pangea/events/event_wrappers/pangea_message_event.dart @@ -10,20 +10,22 @@ import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:fluffychat/pangea/choreographer/choreo_record_model.dart'; import 'package:fluffychat/pangea/common/constants/model_keys.dart'; -import 'package:fluffychat/pangea/events/controllers/message_data_controller.dart'; import 'package:fluffychat/pangea/events/event_wrappers/pangea_representation_event.dart'; import 'package:fluffychat/pangea/events/models/representation_content_model.dart'; import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart'; import 'package:fluffychat/pangea/events/repo/language_detection_repo.dart'; import 'package:fluffychat/pangea/events/repo/language_detection_request.dart'; import 'package:fluffychat/pangea/events/repo/language_detection_response.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/pangea/learning_settings/utils/p_language_store.dart'; import 'package:fluffychat/pangea/spaces/models/space_model.dart'; import 'package:fluffychat/pangea/speech_to_text/audio_encoding_enum.dart'; +import 'package:fluffychat/pangea/speech_to_text/speech_to_text_repo.dart'; import 'package:fluffychat/pangea/speech_to_text/speech_to_text_request_model.dart'; import 'package:fluffychat/pangea/speech_to_text/speech_to_text_response_model.dart'; import 'package:fluffychat/pangea/toolbar/controllers/text_to_speech_controller.dart'; import 'package:fluffychat/pangea/toolbar/widgets/message_audio_card.dart'; +import 'package:fluffychat/pangea/translation/full_text_translation_repo.dart'; import 'package:fluffychat/pangea/translation/full_text_translation_request_model.dart'; import 'package:fluffychat/widgets/future_loading_dialog.dart'; import '../../../widgets/matrix.dart'; @@ -305,15 +307,13 @@ class PangeaMessageEvent { final matrixFile = await _event.downloadAndDecryptAttachment(); - final SpeechToTextResponseModel response = - await MatrixState.pangeaController.speechToText.get( + final result = await SpeechToTextRepo.get( + MatrixState.pangeaController.userController.accessToken, SpeechToTextRequestModel( audioContent: matrixFile.bytes, audioEvent: _event, config: SpeechToTextAudioConfigModel( encoding: mimeTypeToAudioEncoding(matrixFile.mimeType), - //this is the default in the RecordConfig in record package - //TODO: check if this is the correct value and make it a constant somewhere sampleRateHertz: 22050, userL1: l1Code, userL2: l2Code, @@ -321,6 +321,13 @@ class PangeaMessageEvent { ), ); + if (result.error != null) { + throw Exception( + "Error getting speech to text: ${result.error}", + ); + } + + final SpeechToTextResponseModel response = result.result!; _representations?.add( RepresentationEvent( timeline: timeline, @@ -540,17 +547,29 @@ class PangeaMessageEvent { // clear representations cache so the new representation event can be added when next requested _representations = null; - return MessageDataController.getPangeaRepresentationEvent( - req: FullTextTranslationRequestModel( + final res = await FullTextTranslationRepo.get( + MatrixState.pangeaController.userController.accessToken, + FullTextTranslationRequestModel( text: originalSent?.content.text ?? _latestEdit.body, srcLang: originalSent?.langCode, tgtLang: langCode, userL2: l2Code ?? LanguageKeys.unknownLanguage, userL1: l1Code ?? LanguageKeys.unknownLanguage, ), - messageEvent: this, - originalSent: true, ); + + if (res.isError) return null; + final repEvent = await room.sendPangeaEvent( + content: PangeaRepresentation( + langCode: langCode, + text: res.result!, + originalSent: originalSent == null, + originalWritten: false, + ).toJson(), + parentEventId: eventId, + type: PangeaEventTypes.representation, + ); + return repEvent?.eventId; } Future l1Respresentation() async { @@ -584,17 +603,30 @@ class PangeaMessageEvent { // clear representations cache so the new representation event can be added when next requested _representations = null; - final resp = await MessageDataController.getPangeaRepresentation( - req: FullTextTranslationRequestModel( + + final resp = await FullTextTranslationRepo.get( + MatrixState.pangeaController.userController.accessToken, + FullTextTranslationRequestModel( text: includedIT ? originalWrittenContent : messageDisplayText, srcLang: srcLang, tgtLang: l1Code!, userL2: l2Code!, userL1: l1Code!, ), - messageEvent: _event, ); - return resp.text; + + if (resp.isError) throw resp.error!; + room.sendPangeaEvent( + content: PangeaRepresentation( + langCode: l1Code!, + text: resp.result!, + originalSent: false, + originalWritten: false, + ).toJson(), + parentEventId: eventId, + type: PangeaEventTypes.representation, + ); + return resp.result!; } RepresentationEvent? get originalSent => representations diff --git a/lib/pangea/events/event_wrappers/pangea_representation_event.dart b/lib/pangea/events/event_wrappers/pangea_representation_event.dart index 6b5f81a75..06b28c16f 100644 --- a/lib/pangea/events/event_wrappers/pangea_representation_event.dart +++ b/lib/pangea/events/event_wrappers/pangea_representation_event.dart @@ -14,7 +14,6 @@ import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart'; import 'package:fluffychat/pangea/choreographer/choreo_record_model.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart'; -import 'package:fluffychat/pangea/events/controllers/message_data_controller.dart'; import 'package:fluffychat/pangea/events/event_wrappers/pangea_choreo_event.dart'; import 'package:fluffychat/pangea/events/extensions/pangea_event_extension.dart'; import 'package:fluffychat/pangea/events/models/language_detection_model.dart'; @@ -23,10 +22,13 @@ import 'package:fluffychat/pangea/events/models/representation_content_model.dar import 'package:fluffychat/pangea/events/models/stt_translation_model.dart'; import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart'; import 'package:fluffychat/pangea/events/repo/token_api_models.dart'; +import 'package:fluffychat/pangea/events/repo/tokens_repo.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart'; import 'package:fluffychat/pangea/morphs/morph_features_enum.dart'; import 'package:fluffychat/pangea/morphs/parts_of_speech_enum.dart'; import 'package:fluffychat/pangea/practice_activities/activity_type_enum.dart'; +import 'package:fluffychat/pangea/translation/full_text_translation_repo.dart'; import 'package:fluffychat/pangea/translation/full_text_translation_request_model.dart'; import 'package:fluffychat/widgets/future_loading_dialog.dart'; import 'package:fluffychat/widgets/matrix.dart'; @@ -113,23 +115,31 @@ class RepresentationEvent { ), ); } - final res = await MessageDataController.getTokens( - repEventId: _event?.eventId, - room: _event?.room ?? parentMessageEvent.room, - req: TokensRequestModel( + final res = await TokensRepo.get( + MatrixState.pangeaController.userController.accessToken, + TokensRequestModel( fullText: text, langCode: langCode, senderL1: MatrixState.pangeaController.languageController.userL1?.langCode ?? LanguageKeys.unknownLanguage, - // since langCode is known, senderL2 will be used to determine whether these tokens - // need pos/mporph tags whether lemmas are eligible to marked as "save_vocab=true" senderL2: MatrixState.pangeaController.languageController.userL2?.langCode ?? LanguageKeys.unknownLanguage, ), ); + if (_event != null) { + _event!.room.sendPangeaEvent( + content: PangeaMessageTokens( + tokens: res.result!.tokens, + detections: res.result!.detections, + ).toJson(), + parentEventId: _event!.eventId, + type: PangeaEventTypes.tokens, + ); + } + if (res.isError) { return Result.error(res.error!); } else { @@ -152,16 +162,25 @@ class RepresentationEvent { return; } - await MessageDataController.getTokens( - repEventId: repEventID, - room: room, - req: TokensRequestModel( + final resp = await TokensRepo.get( + MatrixState.pangeaController.userController.accessToken, + TokensRequestModel( fullText: text, langCode: langCode, senderL1: userl1, senderL2: userl2, ), ); + + if (resp.isError) return; + room.sendPangeaEvent( + content: PangeaMessageTokens( + tokens: resp.result!.tokens, + detections: resp.result!.detections, + ).toJson(), + parentEventId: _event!.eventId, + type: PangeaEventTypes.tokens, + ); } List get sttTranslations { @@ -217,16 +236,32 @@ class RepresentationEvent { final local = sttTranslations.firstWhereOrNull((t) => t.langCode == userL1); if (local != null) return local; - return MessageDataController.getSttTranslation( - repEventId: _event?.eventId, - room: _event?.room, - req: FullTextTranslationRequestModel( + final res = await FullTextTranslationRepo.get( + MatrixState.pangeaController.userController.accessToken, + FullTextTranslationRequestModel( text: content.speechToText!.transcript.text, tgtLang: userL1, userL2: userL2, userL1: userL1, ), ); + + if (res.isError) { + throw res.error!; + } + + final translation = SttTranslationModel( + translation: res.result!, + langCode: userL1, + ); + + _event?.room.sendPangeaEvent( + content: translation.toJson(), + parentEventId: _event!.eventId, + type: PangeaEventTypes.sttTranslation, + ); + + return translation; } ChoreoRecordModel? get choreo { diff --git a/lib/pangea/events/models/stt_translation_model.dart b/lib/pangea/events/models/stt_translation_model.dart index 47f31be4f..06becba21 100644 --- a/lib/pangea/events/models/stt_translation_model.dart +++ b/lib/pangea/events/models/stt_translation_model.dart @@ -1,3 +1,7 @@ +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart'; + class SttTranslationModel { final String translation; final String langCode; @@ -8,9 +12,14 @@ class SttTranslationModel { }); factory SttTranslationModel.fromJson(Map json) { + final content = json.tryGetMap(PangeaEventTypes.sttTranslation); + if (content == null) { + throw Exception("STT Translation content is null"); + } + return SttTranslationModel( - translation: json['translation'] as String, - langCode: json['lang_code'] as String, + translation: content['translation'] as String, + langCode: content['lang_code'] as String, ); }