From 5855cb2de509522aa396ec961fd9061d5ac07a4d Mon Sep 17 00:00:00 2001 From: ggurdin Date: Tue, 14 May 2024 14:59:58 -0400 Subject: [PATCH 01/17] updated record package version for iOS fix --- assets/l10n/intl_en.arb | 3 +- lib/pages/chat/recording_dialog.dart | 30 +++++++++++++++----- lib/pangea/models/speech_to_text_models.dart | 4 +-- lib/pangea/utils/any_state_holder.dart | 13 ++++++++- lib/pangea/utils/update_version_dialog.dart | 26 +++++++++++++++++ pubspec.yaml | 5 +++- 6 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 lib/pangea/utils/update_version_dialog.dart diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 21874cc9e..41eeb498d 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3944,5 +3944,6 @@ "score": "Score", "accuracy": "Accuracy", "points": "Points", - "noPaymentInfo": "No payment info necessary!" + "noPaymentInfo": "No payment info necessary!", + "updatePhoneOS": "You may need to update your device's OS version." } \ No newline at end of file diff --git a/lib/pages/chat/recording_dialog.dart b/lib/pages/chat/recording_dialog.dart index b3bff4187..8751d60a5 100644 --- a/lib/pages/chat/recording_dialog.dart +++ b/lib/pages/chat/recording_dialog.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/utils/update_version_dialog.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -27,7 +28,7 @@ class RecordingDialogState extends State { bool error = false; String? _recordedPath; - final _audioRecorder = Record(); + final _audioRecorder = AudioRecorder(); final List amplitudeTimeline = []; static const int bitRate = 64000; @@ -45,13 +46,28 @@ class RecordingDialogState extends State { return; } await WakelockPlus.enable(); - await _audioRecorder.start( - path: _recordedPath, - bitRate: bitRate, - samplingRate: samplingRate, - encoder: AudioEncoder.wav, - numChannels: 1, + // #Pangea + final bool isNotError = await showUpdateVersionDialog( + future: () => + // Pangea# + _audioRecorder.start( + path: _recordedPath!, + const RecordConfig( + bitRate: bitRate, + sampleRate: samplingRate, + encoder: AudioEncoder.wav, + numChannels: 1, + ), + ), + // #Pangea + context: context, ); + + if (!isNotError) { + Navigator.of(context).pop(); + return; + } + // Pangea# setState(() => _duration = Duration.zero); _recorderSubscription?.cancel(); _recorderSubscription = diff --git a/lib/pangea/models/speech_to_text_models.dart b/lib/pangea/models/speech_to_text_models.dart index 05ab6ccbe..ad5fd96dd 100644 --- a/lib/pangea/models/speech_to_text_models.dart +++ b/lib/pangea/models/speech_to_text_models.dart @@ -107,10 +107,10 @@ class STTToken { return STTToken( token: PangeaToken.fromJson(json['token']), startTime: json['start_time'] != null - ? Duration(milliseconds: json['start_time'] * 1000.toInt()) + ? Duration(milliseconds: (json['start_time'] * 1000).round()) : null, endTime: json['end_time'] != null - ? Duration(milliseconds: json['end_time'] * 1000.toInt()) + ? Duration(milliseconds: (json['end_time'] * 1000).round()) : null, confidence: json['confidence'], ); diff --git a/lib/pangea/utils/any_state_holder.dart b/lib/pangea/utils/any_state_holder.dart index 2c3d1df7f..bd09c7131 100644 --- a/lib/pangea/utils/any_state_holder.dart +++ b/lib/pangea/utils/any_state_holder.dart @@ -1,3 +1,4 @@ +import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:flutter/material.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; @@ -39,7 +40,17 @@ class PangeaAnyState { void closeOverlay() { if (overlay != null) { - overlay?.remove(); + try { + overlay?.remove(); + } catch (err, s) { + ErrorHandler.logError( + e: err, + s: s, + data: { + "overlay": overlay, + }, + ); + } overlay = null; } } diff --git a/lib/pangea/utils/update_version_dialog.dart b/lib/pangea/utils/update_version_dialog.dart new file mode 100644 index 000000000..f1c41d286 --- /dev/null +++ b/lib/pangea/utils/update_version_dialog.dart @@ -0,0 +1,26 @@ +import 'package:adaptive_dialog/adaptive_dialog.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +Future showUpdateVersionDialog({ + required Future Function() future, + required BuildContext context, +}) async { + try { + await future(); + return true; + } catch (err, s) { + ErrorHandler.logError( + e: err, + s: s, + ); + await showOkAlertDialog( + context: context, + title: L10n.of(context)!.oopsSomethingWentWrong, + message: L10n.of(context)!.updatePhoneOS, + okLabel: L10n.of(context)!.close, + ); + return false; + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 3a60f60a8..0c3b2faac 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -83,7 +83,10 @@ dependencies: punycode: ^1.0.0 qr_code_scanner: ^1.0.1 receive_sharing_intent: 1.4.5 # Update needs more work - record: 4.4.4 # Upgrade to 5 currently breaks playing on iOS + # #Pangea + # record: 4.4.4 # Upgrade to 5 currently breaks playing on iOS + record: ^5.0.5 + # Pangea# scroll_to_index: ^3.0.1 share_plus: ^8.0.2 shared_preferences: ^2.2.0 # Pinned because https://github.com/flutter/flutter/issues/118401 From 8b8fc7e4b88241a5c8f75fcef5f73c015afee496 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Tue, 14 May 2024 15:01:12 -0400 Subject: [PATCH 02/17] replaced pangea comments --- lib/pages/chat/recording_dialog.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/pages/chat/recording_dialog.dart b/lib/pages/chat/recording_dialog.dart index 8751d60a5..805f090df 100644 --- a/lib/pages/chat/recording_dialog.dart +++ b/lib/pages/chat/recording_dialog.dart @@ -28,7 +28,10 @@ class RecordingDialogState extends State { bool error = false; String? _recordedPath; + // #Pangea + // final _audioRecorder = Record(); final _audioRecorder = AudioRecorder(); + // Pangea# final List amplitudeTimeline = []; static const int bitRate = 64000; From 326d2b5fbd494cf4aa1a26d5c307a8080230378d Mon Sep 17 00:00:00 2001 From: William Jordan-Cooley Date: Wed, 15 May 2024 10:57:34 -0400 Subject: [PATCH 03/17] adding words per minute to speech to text feedback --- assets/l10n/intl_en.arb | 4 + lib/config/app_config.dart | 2 + .../pangea_message_event.dart | 16 +- lib/pangea/models/speech_to_text_models.dart | 23 ++- .../chat/message_speech_to_text_card.dart | 18 ++- needed-translations.txt | 144 ++++++++++++------ 6 files changed, 138 insertions(+), 69 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 41eeb498d..643ee9a98 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3945,5 +3945,9 @@ "accuracy": "Accuracy", "points": "Points", "noPaymentInfo": "No payment info necessary!", +<<<<<<< Updated upstream "updatePhoneOS": "You may need to update your device's OS version." +======= + "wordsPerMinute": "Words per minute" +>>>>>>> Stashed changes } \ No newline at end of file diff --git a/lib/config/app_config.dart b/lib/config/app_config.dart index 2b3e74f96..a21a2caad 100644 --- a/lib/config/app_config.dart +++ b/lib/config/app_config.dart @@ -29,6 +29,8 @@ abstract class AppConfig { static const Color primaryColorLight = Color(0xFFDBC9FF); static const Color secondaryColor = Color(0xFF41a2bc); static const Color activeToggleColor = Color(0xFF33D057); + static const Color success = Color(0xFF33D057); + static const Color warning = Color.fromARGB(255, 210, 124, 12); // static String _privacyUrl = // 'https://gitlab.com/famedly/fluffychat/-/blob/main/PRIVACY.md'; static String _privacyUrl = "https://www.pangeachat.com/privacy"; diff --git a/lib/pangea/matrix_event_wrappers/pangea_message_event.dart b/lib/pangea/matrix_event_wrappers/pangea_message_event.dart index 3f2f23616..bea286ba8 100644 --- a/lib/pangea/matrix_event_wrappers/pangea_message_event.dart +++ b/lib/pangea/matrix_event_wrappers/pangea_message_event.dart @@ -296,14 +296,14 @@ class PangeaMessageEvent { return null; } - final SpeechToTextModel? speechToTextLocal = representations - .firstWhereOrNull( - (element) => element.content.speechToText != null, - ) - ?.content - .speechToText; - - if (speechToTextLocal != null) return speechToTextLocal; + // final SpeechToTextModel? speechToTextLocal = representations + // .firstWhereOrNull( + // (element) => element.content.speechToText != null, + // ) + // ?.content + // .speechToText; + + // if (speechToTextLocal != null) return speechToTextLocal; final matrixFile = await _event.downloadAndDecryptAttachment(); // Pangea# diff --git a/lib/pangea/models/speech_to_text_models.dart b/lib/pangea/models/speech_to_text_models.dart index ad5fd96dd..005d2371f 100644 --- a/lib/pangea/models/speech_to_text_models.dart +++ b/lib/pangea/models/speech_to_text_models.dart @@ -1,11 +1,14 @@ import 'dart:convert'; +import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/enum/audio_encoding_enum.dart'; import 'package:fluffychat/pangea/models/pangea_token_model.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:matrix/matrix.dart'; +const int THRESHOLD_FOR_GREEN = 80; + class SpeechToTextAudioConfigModel { final AudioEncodingEnum encoding; final int sampleRateHertz; @@ -93,13 +96,10 @@ class STTToken { ? Colors.white : Colors.black); } - if (confidence! > 80) { - return const Color.fromARGB(255, 0, 152, 0); - } - if (confidence! > 50) { - return const Color.fromARGB(255, 184, 142, 43); + if (confidence! > THRESHOLD_FOR_GREEN) { + return AppConfig.success; } - return Colors.red; + return AppConfig.warning; } factory STTToken.fromJson(Map json) { @@ -148,6 +148,7 @@ class STTToken { class Transcript { final String text; final int confidence; + final double? wordsPerMinute; final List sttTokens; final String langCode; @@ -156,6 +157,7 @@ class Transcript { required this.confidence, required this.sttTokens, required this.langCode, + required this.wordsPerMinute, }); factory Transcript.fromJson(Map json) => Transcript( @@ -167,6 +169,7 @@ class Transcript { .map((e) => STTToken.fromJson(e)) .toList(), langCode: json['lang_code'], + wordsPerMinute: json['words_per_minute'], ); Map toJson() => { @@ -174,7 +177,15 @@ class Transcript { "confidence": confidence, "stt_tokens": sttTokens.map((e) => e.toJson()).toList(), "lang_code": langCode, + "words_per_minute": wordsPerMinute, }; + + Color color(BuildContext context) { + if (confidence > THRESHOLD_FOR_GREEN) { + return AppConfig.success; + } + return AppConfig.warning; + } } class SpeechToTextResult { diff --git a/lib/pangea/widgets/chat/message_speech_to_text_card.dart b/lib/pangea/widgets/chat/message_speech_to_text_card.dart index c516d4447..6fc02ffe1 100644 --- a/lib/pangea/widgets/chat/message_speech_to_text_card.dart +++ b/lib/pangea/widgets/chat/message_speech_to_text_card.dart @@ -133,6 +133,9 @@ class MessageSpeechToTextCardState extends State { getSpeechToText(); } + String? get wordsPerMinuteString => + speechToTextResponse?.transcript.wordsPerMinute?.toString(); + @override Widget build(BuildContext context) { if (_fetchingTranscription) { @@ -158,11 +161,11 @@ class MessageSpeechToTextCardState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - IconNumberWidget( - icon: Icons.abc, - number: (selectedToken == null ? words : 1).toString(), - toolTip: L10n.of(context)!.words, - ), + // IconNumberWidget( + // icon: Icons.abc, + // number: (selectedToken == null ? words : 1).toString(), + // toolTip: L10n.of(context)!.words, + // ), IconNumberWidget( icon: Symbols.target, number: @@ -171,8 +174,9 @@ class MessageSpeechToTextCardState extends State { ), IconNumberWidget( icon: Icons.speed, - number: (selectedToken?.confidence ?? total).toString(), - toolTip: L10n.of(context)!.points, + number: + wordsPerMinuteString != null ? "$wordsPerMinuteString" : "??", + toolTip: L10n.of(context)!.wordsPerMinute, ), ], ), diff --git a/needed-translations.txt b/needed-translations.txt index c93f52d05..74f684f74 100644 --- a/needed-translations.txt +++ b/needed-translations.txt @@ -820,7 +820,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "be": [ @@ -2239,7 +2240,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "bn": [ @@ -3120,7 +3122,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "bo": [ @@ -4001,7 +4004,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "ca": [ @@ -4882,7 +4886,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "cs": [ @@ -5763,7 +5768,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "de": [ @@ -6591,7 +6597,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "el": [ @@ -7472,7 +7479,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "eo": [ @@ -8353,7 +8361,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "es": [ @@ -8382,7 +8391,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "et": [ @@ -9206,7 +9216,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "eu": [ @@ -10030,7 +10041,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "fa": [ @@ -10911,7 +10923,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "fi": [ @@ -11792,7 +11805,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "fr": [ @@ -12673,7 +12687,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "ga": [ @@ -13554,7 +13569,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "gl": [ @@ -14378,7 +14394,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "he": [ @@ -15259,7 +15276,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "hi": [ @@ -16140,7 +16158,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "hr": [ @@ -17008,7 +17027,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "hu": [ @@ -17889,7 +17909,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "ia": [ @@ -19294,7 +19315,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "id": [ @@ -20175,7 +20197,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "ie": [ @@ -21056,7 +21079,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "it": [ @@ -21922,7 +21946,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "ja": [ @@ -22803,7 +22828,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "ko": [ @@ -23684,7 +23710,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "lt": [ @@ -24565,7 +24592,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "lv": [ @@ -25446,7 +25474,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "nb": [ @@ -26327,7 +26356,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "nl": [ @@ -27208,7 +27238,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "pl": [ @@ -28089,7 +28120,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "pt": [ @@ -28970,7 +29002,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "pt_BR": [ @@ -29820,7 +29853,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "pt_PT": [ @@ -30701,7 +30735,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "ro": [ @@ -31582,7 +31617,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "ru": [ @@ -32406,7 +32442,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "sk": [ @@ -33287,7 +33324,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "sl": [ @@ -34168,7 +34206,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "sr": [ @@ -35049,7 +35088,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "sv": [ @@ -35895,7 +35935,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "ta": [ @@ -36776,7 +36817,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "th": [ @@ -37657,7 +37699,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "tr": [ @@ -38523,7 +38566,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "uk": [ @@ -39347,7 +39391,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "vi": [ @@ -40228,7 +40273,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "zh": [ @@ -41052,7 +41098,8 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ], "zh_Hant": [ @@ -41933,6 +41980,7 @@ "score", "accuracy", "points", - "noPaymentInfo" + "noPaymentInfo", + "wordsPerMinute" ] } From daaa83b00df2dd2bf57145da105ec14a1733f4a1 Mon Sep 17 00:00:00 2001 From: William Jordan-Cooley Date: Wed, 15 May 2024 11:01:20 -0400 Subject: [PATCH 04/17] fixing two oops --- assets/l10n/intl_en.arb | 5 +---- .../pangea_message_event.dart | 16 ++++++++-------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 643ee9a98..2ea0bc307 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3945,9 +3945,6 @@ "accuracy": "Accuracy", "points": "Points", "noPaymentInfo": "No payment info necessary!", -<<<<<<< Updated upstream - "updatePhoneOS": "You may need to update your device's OS version." -======= + "updatePhoneOS": "You may need to update your device's OS version.", "wordsPerMinute": "Words per minute" ->>>>>>> Stashed changes } \ No newline at end of file diff --git a/lib/pangea/matrix_event_wrappers/pangea_message_event.dart b/lib/pangea/matrix_event_wrappers/pangea_message_event.dart index bea286ba8..3f2f23616 100644 --- a/lib/pangea/matrix_event_wrappers/pangea_message_event.dart +++ b/lib/pangea/matrix_event_wrappers/pangea_message_event.dart @@ -296,14 +296,14 @@ class PangeaMessageEvent { return null; } - // final SpeechToTextModel? speechToTextLocal = representations - // .firstWhereOrNull( - // (element) => element.content.speechToText != null, - // ) - // ?.content - // .speechToText; - - // if (speechToTextLocal != null) return speechToTextLocal; + final SpeechToTextModel? speechToTextLocal = representations + .firstWhereOrNull( + (element) => element.content.speechToText != null, + ) + ?.content + .speechToText; + + if (speechToTextLocal != null) return speechToTextLocal; final matrixFile = await _event.downloadAndDecryptAttachment(); // Pangea# From 8f7f9a8a18d3e05747e0d73ed882ffd4d5a9a896 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Wed, 15 May 2024 11:24:56 -0400 Subject: [PATCH 05/17] spanish translations --- assets/l10n/intl_es.arb | 51 +++++++++++++++++++++++++-- needed-translations.txt | 77 +++++++++++++++++++++++++---------------- 2 files changed, 96 insertions(+), 32 deletions(-) diff --git a/assets/l10n/intl_es.arb b/assets/l10n/intl_es.arb index f9f596f16..795a83ef7 100644 --- a/assets/l10n/intl_es.arb +++ b/assets/l10n/intl_es.arb @@ -4587,5 +4587,52 @@ "refresh": "Actualizar", "joinToView": "Únete a esta sala para ver los detalles", "autoPlayTitle": "Reproducción automática de mensajes", - "autoPlayDesc": "Cuando está activado, el audio de texto a voz de los mensajes se reproducirá automáticamente cuando se seleccione." -} \ No newline at end of file + "autoPlayDesc": "Cuando está activado, el audio de texto a voz de los mensajes se reproducirá automáticamente cuando se seleccione.", + "presenceStyle": "Presencia:", + "presencesToggle": "Mostrar mensajes de estado de otros usuarios", + "writeAMessageFlag": "Escribe un mensaje en {l1flag} o {l2flag}...", + "@writeAMessageFlag": { + "type": "text", + "placeholders": { + "l1flag": {}, + "l2flag": {} + } + }, + "youInvitedToBy": "📩 Has sido invitado a través de un enlace a:\n{alias}", + "@youInvitedToBy": { + "placeholders": { + "alias": {} + } + }, + "hidePresences": "¿Ocultar la lista de estados?", + "sendReadReceipts": "Enviar recibos de lectura", + "sendTypingNotificationsDescription": "Los demás participantes en un chat pueden ver cuándo estás escribiendo un nuevo mensaje.", + "sendReadReceiptsDescription": "Los demás participantes en un chat pueden ver cuándo has leído un mensaje.", + "formattedMessages": "Mensajes con formato", + "formattedMessagesDescription": "Mostrar contenido de mensajes enriquecido como texto en negrita utilizando markdown.", + "verifyOtherUser": "🔐 Verificar otro usuario", + "verifyOtherUserDescription": "Si verificas a otro usuario, puedes estar seguro de saber a quién estás escribiendo realmente. 💪\n\nCuando inicies una verificación, tú y el otro usuario veréis una ventana emergente en la aplicación. Allí veréis una serie de emojis o números que tendréis que comparar entre vosotros.\n\nLa mejor forma de hacerlo es quedar o iniciar una videollamada. 👭", + "verifyOtherDevice": "🔐 Verificar otro dispositivo", + "verifyOtherDeviceDescription": "Cuando verificas otro dispositivo, esos dispositivos pueden intercambiar claves, aumentando tu seguridad general. 💪 Cuando inicies una verificación, aparecerá una ventana emergente en la app de ambos dispositivos. Allí verás entonces una serie de emojis o números que tienes que comparar entre sí. Lo mejor es que tengas ambos dispositivos a mano antes de iniciar la verificación. 🤳", + "transparent": "Transparente", + "incomingMessages": "Mensajes entrantes", + "stickers": "Pegatinas", + "commandHint_ignore": "Ignorar el ID de matriz dado", + "commandHint_unignore": "Designorar el ID de matriz dado", + "unreadChatsInApp": "{appname}: {unread} chats no leídos", + "@unreadChatsInApp": { + "type": "text", + "placeholders": { + "appname": {}, + "unread": {} + } + }, + "messageAnalytics": "Análisis de mensajes", + "words": "Palabras", + "score": "Puntuación", + "accuracy": "Precisión", + "points": "Puntos", + "noPaymentInfo": "No se necesitan datos de pago.", + "updatePhoneOS": "Puede que necesites actualizar la versión del sistema operativo de tu dispositivo.", + "wordsPerMinute": "Palabras por minuto" +} diff --git a/needed-translations.txt b/needed-translations.txt index 74f684f74..7cbcc8a05 100644 --- a/needed-translations.txt +++ b/needed-translations.txt @@ -821,6 +821,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -2241,6 +2242,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -3123,6 +3125,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -4005,6 +4008,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -4887,6 +4891,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -5769,6 +5774,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -6598,6 +6604,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -7480,6 +7487,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -8362,36 +8370,7 @@ "accuracy", "points", "noPaymentInfo", - "wordsPerMinute" - ], - - "es": [ - "presenceStyle", - "presencesToggle", - "writeAMessageFlag", - "youInvitedToBy", - "hidePresences", - "sendReadReceipts", - "sendTypingNotificationsDescription", - "sendReadReceiptsDescription", - "formattedMessages", - "formattedMessagesDescription", - "verifyOtherUser", - "verifyOtherUserDescription", - "verifyOtherDevice", - "verifyOtherDeviceDescription", - "transparent", - "incomingMessages", - "stickers", - "commandHint_ignore", - "commandHint_unignore", - "unreadChatsInApp", - "messageAnalytics", - "words", - "score", - "accuracy", - "points", - "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -9217,6 +9196,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -10042,6 +10022,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -10924,6 +10905,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -11806,6 +11788,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -12688,6 +12671,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -13570,6 +13554,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -14395,6 +14380,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -15277,6 +15263,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -16159,6 +16146,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -17028,6 +17016,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -17910,6 +17899,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -19316,6 +19306,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -20198,6 +20189,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -21080,6 +21072,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -21947,6 +21940,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -22829,6 +22823,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -23711,6 +23706,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -24593,6 +24589,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -25475,6 +25472,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -26357,6 +26355,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -27239,6 +27238,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -28121,6 +28121,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -29003,6 +29004,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -29854,6 +29856,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -30736,6 +30739,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -31618,6 +31622,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -32443,6 +32448,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -33325,6 +33331,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -34207,6 +34214,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -35089,6 +35097,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -35936,6 +35945,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -36818,6 +36828,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -37700,6 +37711,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -38567,6 +38579,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -39392,6 +39405,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -40274,6 +40288,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -41099,6 +41114,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ], @@ -41981,6 +41997,7 @@ "accuracy", "points", "noPaymentInfo", + "updatePhoneOS", "wordsPerMinute" ] } From 7131fd47a8b693cbac8a38014d2a26b84a930bdb Mon Sep 17 00:00:00 2001 From: ggurdin Date: Wed, 15 May 2024 13:43:21 -0400 Subject: [PATCH 06/17] fix for speech to text matrix event --- .../speech_to_text_controller.dart | 27 ++++++++++--------- lib/pangea/models/pangea_token_model.dart | 2 +- lib/pangea/models/speech_to_text_models.dart | 2 +- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/lib/pangea/controllers/speech_to_text_controller.dart b/lib/pangea/controllers/speech_to_text_controller.dart index 6b302b101..8b61da79e 100644 --- a/lib/pangea/controllers/speech_to_text_controller.dart +++ b/lib/pangea/controllers/speech_to_text_controller.dart @@ -74,18 +74,21 @@ class SpeechToTextController { } debugPrint('Saving transcript as matrix event'); - requestModel.audioEvent?.room.sendPangeaEvent( - content: PangeaRepresentation( - langCode: response.langCode, - text: response.transcript.text, - originalSent: false, - originalWritten: false, - speechToText: response, - ).toJson(), - parentEventId: requestModel.audioEvent!.eventId, - type: PangeaEventTypes.representation, - ); - debugPrint('Transcript saved as matrix event'); + requestModel.audioEvent?.room + .sendPangeaEvent( + content: PangeaRepresentation( + langCode: response.langCode, + text: response.transcript.text, + originalSent: false, + originalWritten: false, + speechToText: response, + ).toJson(), + parentEventId: requestModel.audioEvent!.eventId, + type: PangeaEventTypes.representation, + ) + .then( + (_) => debugPrint('Transcript saved as matrix event'), + ); return Future.value(null); } diff --git a/lib/pangea/models/pangea_token_model.dart b/lib/pangea/models/pangea_token_model.dart index 19eaba750..a671256ab 100644 --- a/lib/pangea/models/pangea_token_model.dart +++ b/lib/pangea/models/pangea_token_model.dart @@ -60,7 +60,7 @@ class PangeaToken { static const String _lemmaKey = ModelKey.lemma; Map toJson() => { - _textKey: text, + _textKey: text.toJson(), _hasInfoKey: hasInfo, _lemmaKey: lemmas.map((e) => e.toJson()).toList(), }; diff --git a/lib/pangea/models/speech_to_text_models.dart b/lib/pangea/models/speech_to_text_models.dart index 005d2371f..7d21fd718 100644 --- a/lib/pangea/models/speech_to_text_models.dart +++ b/lib/pangea/models/speech_to_text_models.dart @@ -117,7 +117,7 @@ class STTToken { } Map toJson() => { - "token": token, + "token": token.toJson(), "start_time": startTime?.inMilliseconds, "end_time": endTime?.inMilliseconds, "confidence": confidence, From 36c1eaaf47540c467bdeab04a5b05a0828bef42c Mon Sep 17 00:00:00 2001 From: Kelrap <99418823+Kelrap@users.noreply.github.com> Date: Wed, 15 May 2024 13:50:35 -0400 Subject: [PATCH 07/17] Update intl_en.arb Change Settings/Learning Settings to Main Menu/My Learning Settings --- assets/l10n/intl_en.arb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 2ea0bc307..ec8261740 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -2504,7 +2504,7 @@ "type": "text", "placeholders": {} }, - "interactiveTranslatorAllowedDesc": "Students can choose whether to use translation assistance in space group chats in Settings > Learning Settings.", + "interactiveTranslatorAllowedDesc": "Students can choose whether to use translation assistance in space group chats in Main Menu > My Learning Settings.", "@interactiveTranslatorAllowedDesc": { "type": "text", "placeholders": {} @@ -2984,9 +2984,9 @@ "errorDisableLanguageAssistanceClassDesc": "Translation assistance and grammar assistance are turned off for the space that this chat is in.", "itIsDisabled": "Interactive Translation is disabled", "igcIsDisabled": "Interactive Grammar Checking is disabled", - "goToLearningSettings": "Go to Learning Settings", + "goToLearningSettings": "Go to My Learning Settings", "error405Title": "Languages not set", - "error405Desc": "Please set your languages in Settings > Learning Settings", + "error405Desc": "Please set your languages in Main Menu > My Learning Settings.", "loginOrSignup": "Sign in with", "@loginOrSignup": { "type": "text", @@ -3049,7 +3049,7 @@ "type": "text", "placeholders": {} }, - "learningSettings": "Learning Settings", + "learningSettings": "My Learning Settings", "classNameRequired": "Please enter a space name", "@classNameRequired": { "type": "text", @@ -3947,4 +3947,4 @@ "noPaymentInfo": "No payment info necessary!", "updatePhoneOS": "You may need to update your device's OS version.", "wordsPerMinute": "Words per minute" -} \ No newline at end of file +} From cd0545058129e16e8e46971721b1cdd68f079a93 Mon Sep 17 00:00:00 2001 From: Kelrap <99418823+Kelrap@users.noreply.github.com> Date: Wed, 15 May 2024 13:52:55 -0400 Subject: [PATCH 08/17] Removed the Learning Settings button --- lib/pages/settings/settings_view.dart | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/pages/settings/settings_view.dart b/lib/pages/settings/settings_view.dart index 36766ea65..cc52f0ef0 100644 --- a/lib/pages/settings/settings_view.dart +++ b/lib/pages/settings/settings_view.dart @@ -181,14 +181,6 @@ class SettingsView extends StatelessWidget { trailing: const Icon(Icons.chevron_right_outlined), ), // #Pangea - ListTile( - leading: const Icon(Icons.account_circle_outlined), - title: Text(L10n.of(context)!.learningSettings), - onTap: () => context.go('/rooms/settings/learning'), - trailing: const Icon( - Icons.chevron_right_outlined, - ), - ), ListTile( leading: const Icon(Icons.account_circle_outlined), title: Text(L10n.of(context)!.subscriptionManagement), From bc47e84de26576ecff39e62f32e063fac11cbfdd Mon Sep 17 00:00:00 2001 From: ggurdin Date: Wed, 15 May 2024 13:58:57 -0400 Subject: [PATCH 09/17] uncommented error handling so warning message shows on card, instead of loading circle --- .../chat/message_speech_to_text_card.dart | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/lib/pangea/widgets/chat/message_speech_to_text_card.dart b/lib/pangea/widgets/chat/message_speech_to_text_card.dart index 6fc02ffe1..bc2cf3327 100644 --- a/lib/pangea/widgets/chat/message_speech_to_text_card.dart +++ b/lib/pangea/widgets/chat/message_speech_to_text_card.dart @@ -1,9 +1,13 @@ +import 'dart:developer'; + import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart'; import 'package:fluffychat/pangea/models/speech_to_text_models.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/pangea/widgets/chat/toolbar_content_loading_indicator.dart'; import 'package:fluffychat/pangea/widgets/common/icon_number_widget.dart'; import 'package:fluffychat/pangea/widgets/igc/card_error_widget.dart'; import 'package:fluffychat/widgets/matrix.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -41,27 +45,27 @@ class MessageSpeechToTextCardState extends State { // look for transcription in message event // if not found, call API to transcribe audio Future getSpeechToText() async { - // try { - if (l1Code == null || l2Code == null) { - throw Exception('Language selection not found'); - } - speechToTextResponse ??= - await widget.messageEvent.getSpeechToText(l1Code!, l2Code!); + try { + if (l1Code == null || l2Code == null) { + throw Exception('Language selection not found'); + } + speechToTextResponse ??= + await widget.messageEvent.getSpeechToText(l1Code!, l2Code!); - debugPrint( - 'Speech to text transcript: ${speechToTextResponse?.transcript.text}', - ); - // } catch (e, s) { - // debugger(when: kDebugMode); - // error = e; - // ErrorHandler.logError( - // e: e, - // s: s, - // data: widget.messageEvent.event.content, - // ); - // } finally { - setState(() => _fetchingTranscription = false); - // } + debugPrint( + 'Speech to text transcript: ${speechToTextResponse?.transcript.text}', + ); + } catch (e, s) { + debugger(when: kDebugMode); + error = e; + ErrorHandler.logError( + e: e, + s: s, + data: widget.messageEvent.event.content, + ); + } finally { + setState(() => _fetchingTranscription = false); + } } TextSpan _buildTranscriptText(BuildContext context) { From 09e4feb6c22b42e45f3ce00103ecfde96413b6f3 Mon Sep 17 00:00:00 2001 From: Kelrap <99418823+Kelrap@users.noreply.github.com> Date: Wed, 15 May 2024 14:01:17 -0400 Subject: [PATCH 10/17] Added My Learning Settings button to main menu --- lib/pages/chat_list/client_chooser_button.dart | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/pages/chat_list/client_chooser_button.dart b/lib/pages/chat_list/client_chooser_button.dart index 896b6dc36..af21a177a 100644 --- a/lib/pages/chat_list/client_chooser_button.dart +++ b/lib/pages/chat_list/client_chooser_button.dart @@ -154,6 +154,18 @@ class ClientChooserButton extends StatelessWidget { ], ), ), + // #Pangea + PopupMenuItem( + value: SettingsAction.learning, + child: Row( + children: [ + const Icon(Icons.psychology_outlined), + const SizedBox(width: 18), + Expanded(child: Text(L10n.of(context)!.learningSettings)), + ], + ), + ), + // Pangea# PopupMenuItem( value: SettingsAction.settings, child: Row( @@ -382,6 +394,9 @@ class ClientChooserButton extends StatelessWidget { case SettingsAction.setStatus: controller.setStatus(); // #Pangea + case SettingsAction.learning: + context.go('/rooms/settings/learning'); + break; case SettingsAction.newClass: context.go('/rooms/newspace'); break; @@ -493,6 +508,7 @@ enum SettingsAction { settings, archive, // #Pangea + learning, joinWithClassCode, classAnalytics, myAnalytics, From b26d786d9505561e42bb22ea91df43ad4b905f7f Mon Sep 17 00:00:00 2001 From: ggurdin Date: Wed, 15 May 2024 14:18:08 -0400 Subject: [PATCH 11/17] fix for JSON datatype error --- lib/pangea/models/speech_to_text_models.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pangea/models/speech_to_text_models.dart b/lib/pangea/models/speech_to_text_models.dart index 7d21fd718..dd07f3fc6 100644 --- a/lib/pangea/models/speech_to_text_models.dart +++ b/lib/pangea/models/speech_to_text_models.dart @@ -148,7 +148,7 @@ class STTToken { class Transcript { final String text; final int confidence; - final double? wordsPerMinute; + final int wordsPerMinute; final List sttTokens; final String langCode; @@ -169,7 +169,7 @@ class Transcript { .map((e) => STTToken.fromJson(e)) .toList(), langCode: json['lang_code'], - wordsPerMinute: json['words_per_minute'], + wordsPerMinute: json['words_per_minute'].round(), ); Map toJson() => { From f15d79179d75c61df02aa2525c7c0c66b8a347a4 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Wed, 15 May 2024 15:03:35 -0400 Subject: [PATCH 12/17] usability test updates - don't stack space details, always suggest new chats in spaces --- assets/l10n/intl_en.arb | 2 +- lib/config/routes.dart | 25 ---- lib/pages/chat/chat.dart | 11 +- lib/pages/chat_details/chat_details_view.dart | 17 ++- lib/pages/chat_list/chat_list_view.dart | 7 +- lib/pages/chat_list/space_view.dart | 26 +++- lib/pages/new_group/new_group_view.dart | 2 +- lib/pages/new_space/new_space.dart | 4 +- lib/pages/new_space/new_space_view.dart | 2 +- .../class_settings/class_settings_page.dart | 96 -------------- .../class_settings/class_settings_view.dart | 85 ------------ .../class_settings_button.dart | 41 ------ lib/pangea/pages/new_class/new_class.dart | 122 ------------------ .../pages/new_class/new_class_view.dart | 88 ------------- lib/pangea/utils/add_to_space.dart | 13 +- .../utils/chat_list_handle_space_tap.dart | 5 +- 16 files changed, 65 insertions(+), 481 deletions(-) delete mode 100644 lib/pangea/pages/class_settings/class_settings_page.dart delete mode 100644 lib/pangea/pages/class_settings/class_settings_view.dart delete mode 100644 lib/pangea/pages/class_settings/p_class_widgets/class_settings_button.dart delete mode 100644 lib/pangea/pages/new_class/new_class.dart delete mode 100644 lib/pangea/pages/new_class/new_class_view.dart diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 41eeb498d..f15a81fa4 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3674,7 +3674,7 @@ "bestAnswerFeedback": "That's correct!", "definitionDefaultPrompt": "What does this word mean?", "practiceDefaultPrompt": "What is the best answer?", - "correctionDefaultPrompt": "What is the best correction?", + "correctionDefaultPrompt": "What is the best replacement?", "itStartDefaultPrompt": "Do you want help translating?", "languageLevelWarning": "Please select a class language level", "lockedChatWarning": "🔒 This chat has been locked", diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 8b69aca1e..8d4d4f181 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -26,7 +26,6 @@ import 'package:fluffychat/pages/settings_security/settings_security.dart'; import 'package:fluffychat/pages/settings_style/settings_style.dart'; import 'package:fluffychat/pangea/guard/p_vguard.dart'; import 'package:fluffychat/pangea/pages/analytics/student_analytics/student_analytics.dart'; -import 'package:fluffychat/pangea/pages/class_settings/class_settings_page.dart'; import 'package:fluffychat/pangea/pages/exchange/add_exchange_to_class.dart'; import 'package:fluffychat/pangea/pages/find_partner/find_partner.dart'; import 'package:fluffychat/pangea/pages/p_user_age/p_user_age.dart'; @@ -150,19 +149,6 @@ abstract class AppRoutes { : child, ), routes: [ - // #Pangea - GoRoute( - path: '/spaces/:roomid', - pageBuilder: (context, state) => defaultPageBuilder( - context, - state, - ChatDetails( - roomId: state.pathParameters['roomid']!, - ), - ), - redirect: loggedOutRedirect, - ), - // Pangea# GoRoute( path: '/rooms', redirect: loggedOutRedirect, @@ -521,17 +507,6 @@ abstract class AppRoutes { ), redirect: loggedOutRedirect, ), - // #Pangea - GoRoute( - path: 'class_settings', - pageBuilder: (context, state) => defaultPageBuilder( - context, - state, - const ClassSettingsPage(), - ), - redirect: loggedOutRedirect, - ), - // Pangea# GoRoute( path: 'invite', pageBuilder: (context, state) => defaultPageBuilder( diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 40701e742..907f9c5bf 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -481,7 +481,16 @@ class ChatController extends State } // Do not send read markers when app is not in foreground - if (kIsWeb && !Matrix.of(context).webHasFocus) return; + // #Pangea + try { + // Pangea# + if (kIsWeb && !Matrix.of(context).webHasFocus) return; + // #Pangea + } catch (err, s) { + ErrorHandler.logError(e: err, s: s); + return; + } + // Pangea# if (!kIsWeb && WidgetsBinding.instance.lifecycleState != AppLifecycleState.resumed) { return; diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index 9dbdc640c..2d46df11d 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -61,11 +61,22 @@ class ChatDetailsView extends StatelessWidget { ); return Scaffold( appBar: AppBar( - leading: controller.widget.embeddedCloseButton ?? - const Center(child: BackButton()), + leading: + // #Pangea + !room.isSpace + ? + // Pangea# + controller.widget.embeddedCloseButton ?? + const Center(child: BackButton()) + // #Pangea + : BackButton( + onPressed: () => context.go("/rooms"), + ) + // Pangea# + , elevation: Theme.of(context).appBarTheme.elevation, actions: [ - // #Pangeas + // #Pangea //if (room.canonicalAlias.isNotEmpty) // IconButton( // tooltip: L10n.of(context)!.share, diff --git a/lib/pages/chat_list/chat_list_view.dart b/lib/pages/chat_list/chat_list_view.dart index dc8389db0..6ad9feef3 100644 --- a/lib/pages/chat_list/chat_list_view.dart +++ b/lib/pages/chat_list/chat_list_view.dart @@ -75,7 +75,12 @@ class ChatListView extends StatelessWidget { label: L10n.of(context)!.allChats, // Pangea# ), - if (controller.spaces.isNotEmpty) + if (controller.spaces.isNotEmpty + // #Pangea + && + !FluffyThemes.isColumnMode(context) + // Pangea# + ) // #Pangea // const NavigationDestination( // icon: Icon(Icons.workspaces_outlined), diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index e7d793e3d..fae04dcff 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:collection/collection.dart'; +import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat_list/chat_list.dart'; import 'package:fluffychat/pages/chat_list/chat_list_item.dart'; import 'package:fluffychat/pages/chat_list/search_title.dart'; @@ -173,7 +174,7 @@ class _SpaceViewState extends State { if (spaceChild.roomId == widget.controller.activeSpaceId) { // #Pangea // context.go('/rooms/${spaceChild.roomId}'); - context.push('/spaces/${spaceChild.roomId}'); + context.go('/rooms/${spaceChild.roomId}/details'); // Pangea# } else { widget.controller.setActiveSpace(spaceChild.roomId); @@ -545,12 +546,25 @@ class _SpaceViewState extends State { titleSpacing: 0, title: ListTile( leading: BackButton( - onPressed: () => - widget.controller.setActiveSpace(parentSpace?.id), + // #Pangea + onPressed: () { + !FluffyThemes.isColumnMode(context) || + parentSpace?.id != null + ? widget.controller.setActiveSpace(parentSpace?.id) + : widget.controller.onDestinationSelected(0); + }, + // onPressed: () => + // widget.controller.setActiveSpace(parentSpace?.id), + // Pangea# ), title: Text( parentSpace == null - ? L10n.of(context)!.allSpaces + // #Pangea + // ? L10n.of(context)!.allSpaces + ? !FluffyThemes.isColumnMode(context) + ? L10n.of(context)!.allSpaces + : L10n.of(context)!.allChats + // Pangea# : parentSpace.getLocalizedDisplayname( MatrixLocals(L10n.of(context)!), ), @@ -721,8 +735,8 @@ class _SpaceViewState extends State { ), // #Pangea // onTap: () => _onJoinSpaceChild(spaceChild), - onTap: () => context.push( - '/spaces/${spaceChild.roomId}', + onTap: () => context.go( + '/rooms/${spaceChild.roomId}/details', ), // Pangea# ), diff --git a/lib/pages/new_group/new_group_view.dart b/lib/pages/new_group/new_group_view.dart index 822b89214..ac3d9dacc 100644 --- a/lib/pages/new_group/new_group_view.dart +++ b/lib/pages/new_group/new_group_view.dart @@ -91,7 +91,7 @@ class NewGroupView extends StatelessWidget { const Divider(height: 1), AddToSpaceToggles( key: controller.addToSpaceKey, - startOpen: false, + startOpen: true, activeSpaceId: controller.activeSpaceId, mode: AddToClassMode.chat, ), diff --git a/lib/pages/new_space/new_space.dart b/lib/pages/new_space/new_space.dart index be3e32dc5..a310769cc 100644 --- a/lib/pages/new_space/new_space.dart +++ b/lib/pages/new_space/new_space.dart @@ -216,7 +216,7 @@ class NewSpaceController extends State { ); MatrixState.pangeaController.classController .setActiveSpaceIdInChatListController(spaceId); - context.push('/spaces/$spaceId'); + context.go("/rooms/$spaceId/details"); return; } @@ -245,7 +245,7 @@ class NewSpaceController extends State { // context.pop(spaceId); MatrixState.pangeaController.classController .setActiveSpaceIdInChatListController(spaceId); - context.push('/spaces/$spaceId'); + context.go("/rooms/$spaceId/details"); // Pangea# } catch (e) { setState(() { diff --git a/lib/pages/new_space/new_space_view.dart b/lib/pages/new_space/new_space_view.dart index 71f887ef6..e550d0019 100644 --- a/lib/pages/new_space/new_space_view.dart +++ b/lib/pages/new_space/new_space_view.dart @@ -138,7 +138,7 @@ class NewSpaceView extends StatelessWidget { if (!controller.newClassMode) AddToSpaceToggles( key: controller.addToSpaceKey, - startOpen: false, + startOpen: true, mode: !controller.newClassMode ? AddToClassMode.exchange : AddToClassMode.chat, diff --git a/lib/pangea/pages/class_settings/class_settings_page.dart b/lib/pangea/pages/class_settings/class_settings_page.dart deleted file mode 100644 index d0c2d385d..000000000 --- a/lib/pangea/pages/class_settings/class_settings_page.dart +++ /dev/null @@ -1,96 +0,0 @@ -import 'dart:async'; -import 'dart:developer'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; - -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:go_router/go_router.dart'; -import 'package:matrix/matrix.dart'; - -import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; -import 'package:fluffychat/widgets/layouts/empty_page.dart'; -import '../../../widgets/matrix.dart'; -import '../../utils/error_handler.dart'; -import '../../utils/set_class_name.dart'; -import '../../widgets/space/class_settings.dart'; -import 'class_settings_view.dart'; -import 'p_class_widgets/room_rules_editor.dart'; - -class ClassSettingsPage extends StatefulWidget { - const ClassSettingsPage({super.key}); - - @override - State createState() => ClassSettingsController(); -} - -class ClassSettingsController extends State { - PangeaController pangeaController = MatrixState.pangeaController; - - final GlobalKey rulesEditorKey = GlobalKey(); - final GlobalKey classSettingsKey = - GlobalKey(); - - Room? room; - - String? get roomId => GoRouterState.of(context).pathParameters['roomid']; - - Future handleSave(BuildContext context) async { - if (classSettingsKey.currentState!.sameLanguages) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(L10n.of(context)!.noIdenticalLanguages), - ), - ); - return; - } - if (rulesEditorKey.currentState != null) { - await rulesEditorKey.currentState?.setRoomRules(roomId!); - } else { - debugger(when: kDebugMode); - ErrorHandler.logError(m: "Null rules editor state"); - } - if (classSettingsKey.currentState != null) { - await classSettingsKey.currentState?.setClassSettings( - roomId!, - ); - } else { - debugger(when: kDebugMode); - ErrorHandler.logError(m: "Null class settings state"); - } - } - - void goback(BuildContext context) { - context.push("/spaces/$roomId"); - } - - String get className => - Matrix.of(context).client.getRoomById(roomId!)?.name ?? ''; - - @override - void initState() { - // TODO: implement initState - super.initState(); - - Future.delayed(Duration.zero, () { - room = Matrix.of(context).client.getRoomById(roomId!); - if (room == null) { - debugger(when: kDebugMode); - context.pop(); - } - setState(() {}); - }); - } - //PTODO - show loading widget - - void setDisplaynameAction() => setClassDisplayname(context, roomId); - - bool showEditNameIcon = false; - void hoverEditNameIcon(bool hovering) => - setState(() => showEditNameIcon = !showEditNameIcon); - - @override - Widget build(BuildContext context) => room != null - ? ClassSettingsPageView(controller: this) - : const EmptyPage(); -} diff --git a/lib/pangea/pages/class_settings/class_settings_view.dart b/lib/pangea/pages/class_settings/class_settings_view.dart deleted file mode 100644 index f6fa434e9..000000000 --- a/lib/pangea/pages/class_settings/class_settings_view.dart +++ /dev/null @@ -1,85 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:future_loading_dialog/future_loading_dialog.dart'; -import 'package:go_router/go_router.dart'; - -import 'package:fluffychat/pangea/pages/class_settings/class_settings_page.dart'; -import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_rules_editor.dart'; -import 'package:fluffychat/pangea/widgets/space/class_settings.dart'; -import '../../../widgets/layouts/max_width_body.dart'; - -class ClassSettingsPageView extends StatelessWidget { - final ClassSettingsController controller; - const ClassSettingsPageView({super.key, required this.controller}); - - @override - Widget build(BuildContext context) { - debugPrint("in class settings page with roomId ${controller.roomId}"); - // PTODO-Lala - make the page scrollable anywhere, not just in the area of the elements - // so like, the user should be able scroll using the mouse wheel from anywhere within this view - // currently, your cursor needs be horizontally within the tiles in order to scroll - return Scaffold( - appBar: AppBar( - leading: GoRouterState.of(context).path?.startsWith('/spaces/') ?? false - ? null - : IconButton( - icon: const Icon(Icons.close_outlined), - onPressed: () => controller.goback(context), - ), - centerTitle: true, - title: Text(L10n.of(context)!.classSettings), - ), - body: ListView( - children: [ - MaxWidthBody( - child: ListTile( - title: Center( - child: TextButton.icon( - onPressed: controller.setDisplaynameAction, - onHover: controller.hoverEditNameIcon, - style: TextButton.styleFrom( - padding: const EdgeInsets.symmetric(horizontal: 25), - ), - label: Visibility( - visible: controller.showEditNameIcon, - child: Icon( - Icons.edit, - color: Theme.of(context).colorScheme.onBackground, - ), - ), - icon: Text( - controller.className, - style: TextStyle( - color: Theme.of(context).colorScheme.secondary, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - ), - ), - MaxWidthBody( - child: Column( - children: [ - ClassSettings( - roomId: controller.roomId, - startOpen: true, - ), - RoomRulesEditor(roomId: controller.roomId), - ], - ), - ), - ], - ), - floatingActionButton: FloatingActionButton.extended( - onPressed: () => showFutureLoadingDialog( - context: context, - future: () => controller.handleSave(context), - ), - label: Text(L10n.of(context)!.saveChanges), - icon: const Icon(Icons.save_outlined), - ), - ); - } -} diff --git a/lib/pangea/pages/class_settings/p_class_widgets/class_settings_button.dart b/lib/pangea/pages/class_settings/p_class_widgets/class_settings_button.dart deleted file mode 100644 index 3915d0ca0..000000000 --- a/lib/pangea/pages/class_settings/p_class_widgets/class_settings_button.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:go_router/go_router.dart'; - -class ClassSettingsButton extends StatelessWidget { - const ClassSettingsButton({super.key}); - - // final PangeaController _pangeaController = MatrixState.pangeaController; - - @override - Widget build(BuildContext context) { - // final roomId = GoRouterState.of(context).pathParameters['roomid']; - - final iconColor = Theme.of(context).textTheme.bodyLarge!.color; - return Column( - children: [ - ListTile( - // enabled: roomId != null && - // _pangeaController.classController - // .getClassModelBySpaceIdLocal(roomId) != - // null, - title: Text( - L10n.of(context)!.classSettings, - style: TextStyle( - color: Theme.of(context).colorScheme.secondary, - fontWeight: FontWeight.bold, - ), - ), - subtitle: Text(L10n.of(context)!.classSettingsDesc), - leading: CircleAvatar( - backgroundColor: Theme.of(context).scaffoldBackgroundColor, - foregroundColor: iconColor, - child: const Icon(Icons.settings_outlined), - ), - onTap: () => context.go('/class_settings'), - ), - ], - ); - } -} diff --git a/lib/pangea/pages/new_class/new_class.dart b/lib/pangea/pages/new_class/new_class.dart deleted file mode 100644 index 55b7d083d..000000000 --- a/lib/pangea/pages/new_class/new_class.dart +++ /dev/null @@ -1,122 +0,0 @@ -import 'dart:developer'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; - -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:future_loading_dialog/future_loading_dialog.dart'; -import 'package:go_router/go_router.dart'; -import 'package:matrix/matrix.dart' as sdk; -import 'package:matrix/matrix.dart'; - -import 'package:fluffychat/pangea/pages/new_class/new_class_view.dart'; -import 'package:fluffychat/pangea/utils/class_code.dart'; -import 'package:fluffychat/pangea/utils/error_handler.dart'; -import 'package:fluffychat/widgets/matrix.dart'; -import '../../controllers/pangea_controller.dart'; -import '../../widgets/space/class_settings.dart'; -import '../class_settings/p_class_widgets/room_rules_editor.dart'; - -class NewClass extends StatefulWidget { - const NewClass({super.key}); - - @override - NewClassController createState() => NewClassController(); -} - -class NewClassController extends State { - TextEditingController controller = TextEditingController(); - - final PangeaController pangeaController = MatrixState.pangeaController; - final GlobalKey rulesEditorKey = GlobalKey(); - final GlobalKey classSettingsKey = - GlobalKey(); - - void submitAction([_]) async { - //TODO: validate that object is complete - final matrix = Matrix.of(context); - if (controller.text.isEmpty) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(L10n.of(context)!.classNameRequired), - ), - ); - return; - } - if (classSettingsKey.currentState == null) { - debugger(when: kDebugMode); - } - if (classSettingsKey.currentState!.sameLanguages) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(L10n.of(context)!.noIdenticalLanguages), - ), - ); - return; - } - - final roomID = await showFutureLoadingDialog( - context: context, - future: () async { - final String roomID = await matrix.client.createRoom( - //PTODO - investigate effects of changing visibility from public - preset: sdk.CreateRoomPreset.publicChat, - creationContent: { - 'type': RoomCreationTypes.mSpace, - }, - visibility: sdk.Visibility.public, - // roomAliasName: controller.text.isNotEmpty - // ? "${matrix.client.userID!.localpart}-${controller.text.trim().toLowerCase().replaceAll(' ', '_')}" - // : null, - roomAliasName: ClassCodeUtil.generateClassCode(), - name: controller.text.isNotEmpty ? controller.text : null, - ); - - if (rulesEditorKey.currentState != null) { - await rulesEditorKey.currentState!.setRoomRules(roomID); - } else { - debugger(when: kDebugMode); - ErrorHandler.logError(m: "Null rules editor state"); - } - if (classSettingsKey.currentState != null) { - await classSettingsKey.currentState!.setClassSettings( - roomID, - ); - } else { - debugger(when: kDebugMode); - ErrorHandler.logError(m: "Null class settings state"); - } - return roomID; - }, - onError: (e) { - debugger(when: kDebugMode); - return e; - }, - ); - - if (roomID.error == null && roomID.result is String) { - pangeaController.classController.setActiveSpaceIdInChatListController( - roomID.result!, - ); - context.push('/spaces/${roomID.result!}'); - } else { - debugger(when: kDebugMode); - ErrorHandler.logError(e: roomID.error, s: StackTrace.current); - } - } - - @override - void initState() { - // TODO: implement initState - super.initState(); - } - - @override - void dispose() { - controller.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) => NewSpaceView(this); -} diff --git a/lib/pangea/pages/new_class/new_class_view.dart b/lib/pangea/pages/new_class/new_class_view.dart deleted file mode 100644 index 13796e2d8..000000000 --- a/lib/pangea/pages/new_class/new_class_view.dart +++ /dev/null @@ -1,88 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -import 'package:flutter_gen/gen_l10n/l10n.dart'; - -import 'package:fluffychat/pangea/constants/class_default_values.dart'; -import 'package:fluffychat/pangea/pages/new_class/new_class.dart'; -import 'package:fluffychat/widgets/layouts/max_width_body.dart'; -import '../../widgets/space/class_settings.dart'; -import '../class_settings/p_class_widgets/room_rules_editor.dart'; - -class NewSpaceView extends StatelessWidget { - // #Pangea - // final NewSpaceController controller; - final NewClassController controller; - // Pangea# - - const NewSpaceView(this.controller, {super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - // #Pangea - centerTitle: true, - // Pangea# - title: Text(L10n.of(context)!.createNewClass), - ), - body: MaxWidthBody( - // #Pangea - child: ListView( - // child: Column( - // mainAxisSize: MainAxisSize.min, - // #Pangea - children: [ - Padding( - padding: const EdgeInsets.all(12.0), - child: TextField( - // #Pangea - maxLength: ClassDefaultValues.maxClassName, - maxLengthEnforcement: MaxLengthEnforcement.enforced, - // #Pangea - controller: controller.controller, - autofocus: true, - autocorrect: false, - textInputAction: TextInputAction.go, - onSubmitted: controller.submitAction, - decoration: InputDecoration( - labelText: L10n.of(context)!.spaceName, - prefixIcon: const Icon(Icons.people_outlined), - hintText: L10n.of(context)!.enterASpacepName, - ), - ), - ), - // #Pangea - ClassSettings( - key: controller.classSettingsKey, - roomId: null, - startOpen: true, - ), - RoomRulesEditor( - key: controller.rulesEditorKey, - roomId: null, - ), - const SizedBox(height: 45), - // SwitchListTile.adaptive( - // title: Text(L10n.of(context)!.spaceIsPublic), - // value: controller.publicGroup, - // onChanged: controller.setPublicGroup, - // ), - // ListTile( - // trailing: const Padding( - // padding: EdgeInsets.symmetric(horizontal: 16.0), - // child: Icon(Icons.info_outlined), - // ), - // subtitle: Text(L10n.of(context)!.newSpaceDescription), - // ), - // #Pangea - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: controller.submitAction, - child: const Icon(Icons.arrow_forward_outlined), - ), - ); - } -} diff --git a/lib/pangea/utils/add_to_space.dart b/lib/pangea/utils/add_to_space.dart index 92458856c..f35b8f308 100644 --- a/lib/pangea/utils/add_to_space.dart +++ b/lib/pangea/utils/add_to_space.dart @@ -1,11 +1,9 @@ +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/widgets/matrix.dart'; import 'package:flutter/material.dart'; - import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:matrix/matrix.dart'; -import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; -import 'package:fluffychat/widgets/matrix.dart'; - bool canAddToSpace(Room space, PangeaController pangeaController) { final bool pangeaPermission = pangeaController.permissionsController.canUserGroupChat(roomID: space.id); @@ -27,8 +25,9 @@ Future pangeaAddToSpace( Room space, List selectedRoomIds, BuildContext context, - PangeaController pangeaController, -) async { + PangeaController pangeaController, { + bool suggested = true, +}) async { if (!canAddToSpace(space, pangeaController)) { throw L10n.of(context)!.noAddToSpacePermissions; } @@ -37,6 +36,6 @@ Future pangeaAddToSpace( if (room != null && chatIsInSpace(room, space)) { throw L10n.of(context)!.alreadyInSpace; } - await space.setSpaceChild(roomId); + await space.setSpaceChild(roomId, suggested: suggested); } } diff --git a/lib/pangea/utils/chat_list_handle_space_tap.dart b/lib/pangea/utils/chat_list_handle_space_tap.dart index ef0865634..982800661 100644 --- a/lib/pangea/utils/chat_list_handle_space_tap.dart +++ b/lib/pangea/utils/chat_list_handle_space_tap.dart @@ -21,7 +21,7 @@ void chatListHandleSpaceTap( controller.setActiveSpace(space.id); if (FluffyThemes.isColumnMode(context)) { - context.push('/spaces/${space.id}'); + context.go('/rooms/${space.id}/details'); } else if (controller.activeChat != null && !space.isFirstOrSecondChild(controller.activeChat!)) { context.go("/rooms"); @@ -108,6 +108,9 @@ void chatListHandleSpaceTap( showAlertDialog(context); } break; + case Membership.leave: + autoJoin(space); + break; default: setActiveSpaceAndCloseChat(); ErrorHandler.logError( From 2d4e2892051a667e113b67a5c0d4b64e0ae07603 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Wed, 15 May 2024 15:07:01 -0400 Subject: [PATCH 13/17] updated spanish copy --- assets/l10n/intl_es.arb | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/assets/l10n/intl_es.arb b/assets/l10n/intl_es.arb index 795a83ef7..59f5719b0 100644 --- a/assets/l10n/intl_es.arb +++ b/assets/l10n/intl_es.arb @@ -4389,7 +4389,7 @@ "bestAnswerFeedback": "¡Correcto!", "definitionDefaultPrompt": "¿Qué significa esta palabra?", "practiceDefaultPrompt": "¿Cuál es la mejor respuesta?", - "correctionDefaultPrompt": "¿Cuál es la mejor corrección?", + "correctionDefaultPrompt": "¿Cuál es el mejor reemplazo?", "itStartDefaultPrompt": "¿Quiere ayuda para traducir?", "suggestTo": "Sugerir a {spaceName}", "suggestChatDesc": "Los chats sugeridos aparecerán en la lista de chats de {spaceName}.", @@ -4592,17 +4592,17 @@ "presencesToggle": "Mostrar mensajes de estado de otros usuarios", "writeAMessageFlag": "Escribe un mensaje en {l1flag} o {l2flag}...", "@writeAMessageFlag": { - "type": "text", - "placeholders": { - "l1flag": {}, - "l2flag": {} - } + "type": "text", + "placeholders": { + "l1flag": {}, + "l2flag": {} + } }, "youInvitedToBy": "📩 Has sido invitado a través de un enlace a:\n{alias}", "@youInvitedToBy": { - "placeholders": { - "alias": {} - } + "placeholders": { + "alias": {} + } }, "hidePresences": "¿Ocultar la lista de estados?", "sendReadReceipts": "Enviar recibos de lectura", @@ -4621,11 +4621,11 @@ "commandHint_unignore": "Designorar el ID de matriz dado", "unreadChatsInApp": "{appname}: {unread} chats no leídos", "@unreadChatsInApp": { - "type": "text", - "placeholders": { - "appname": {}, - "unread": {} - } + "type": "text", + "placeholders": { + "appname": {}, + "unread": {} + } }, "messageAnalytics": "Análisis de mensajes", "words": "Palabras", @@ -4635,4 +4635,4 @@ "noPaymentInfo": "No se necesitan datos de pago.", "updatePhoneOS": "Puede que necesites actualizar la versión del sistema operativo de tu dispositivo.", "wordsPerMinute": "Palabras por minuto" -} +} \ No newline at end of file From fa0639b5d63b1610996180d4dfd1ccdfd2609bdd Mon Sep 17 00:00:00 2001 From: William Jordan-Cooley Date: Wed, 15 May 2024 15:17:30 -0400 Subject: [PATCH 14/17] converting actually to words per hour so its an int --- lib/pangea/models/speech_to_text_models.dart | 11 +++-- macos/Flutter/GeneratedPluginRegistrant.swift | 4 +- pubspec.lock | 48 +++++++++++-------- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/lib/pangea/models/speech_to_text_models.dart b/lib/pangea/models/speech_to_text_models.dart index dd07f3fc6..3bcb4711c 100644 --- a/lib/pangea/models/speech_to_text_models.dart +++ b/lib/pangea/models/speech_to_text_models.dart @@ -148,18 +148,21 @@ class STTToken { class Transcript { final String text; final int confidence; - final int wordsPerMinute; final List sttTokens; final String langCode; + final int? wordsPerHr; Transcript({ required this.text, required this.confidence, required this.sttTokens, required this.langCode, - required this.wordsPerMinute, + required this.wordsPerHr, }); + /// Returns the number of words per minute rounded to one decimal place. + double? get wordsPerMinute => wordsPerHr != null ? wordsPerHr! / 60 : null; + factory Transcript.fromJson(Map json) => Transcript( text: json['transcript'], confidence: json['confidence'] <= 100 @@ -169,7 +172,7 @@ class Transcript { .map((e) => STTToken.fromJson(e)) .toList(), langCode: json['lang_code'], - wordsPerMinute: json['words_per_minute'].round(), + wordsPerHr: json['words_per_hr'], ); Map toJson() => { @@ -177,7 +180,7 @@ class Transcript { "confidence": confidence, "stt_tokens": sttTokens.map((e) => e.toJson()).toList(), "lang_code": langCode, - "words_per_minute": wordsPerMinute, + "words_per_hr": wordsPerHr, }; Color color(BuildContext context) { diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index ce6ae4707..09c588b29 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -28,7 +28,7 @@ import package_info_plus import pasteboard import path_provider_foundation import purchases_flutter -import record_macos +import record_darwin import sentry_flutter import share_plus import shared_preferences_foundation @@ -64,7 +64,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PurchasesFlutterPlugin.register(with: registry.registrar(forPlugin: "PurchasesFlutterPlugin")) - RecordMacosPlugin.register(with: registry.registrar(forPlugin: "RecordMacosPlugin")) + RecordPlugin.register(with: registry.registrar(forPlugin: "RecordPlugin")) SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 54e1ac6a7..8932ea070 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1841,50 +1841,58 @@ packages: dependency: "direct main" description: name: record - sha256: f703397f5a60d9b2b655b3acc94ba079b2d9a67dc0725bdb90ef2fee2441ebf7 + sha256: "113b368168c49c78902ab37c2b354dea30a0aec5bdeca434073826b6ea73eca1" url: "https://pub.dev" source: hosted - version: "4.4.4" - record_linux: + version: "5.0.5" + record_android: dependency: transitive description: - name: record_linux - sha256: "348db92c4ec1b67b1b85d791381c8c99d7c6908de141e7c9edc20dad399b15ce" + name: record_android + sha256: "0df98e05873b22b443309e289bf1eb3b5b9a60e7779134334e2073eb0763a992" url: "https://pub.dev" source: hosted - version: "0.4.1" - record_macos: + version: "1.1.0" + record_darwin: dependency: transitive description: - name: record_macos - sha256: d1d0199d1395f05e218207e8cacd03eb9dc9e256ddfe2cfcbbb90e8edea06057 + name: record_darwin + sha256: ee8cb1bb1712d7ce38140ecabe70e5c286c02f05296d66043bee865ace7eb1b9 url: "https://pub.dev" source: hosted - version: "0.2.2" + version: "1.0.1" + record_linux: + dependency: transitive + description: + name: record_linux + sha256: "7d0e70cd51635128fe9d37d89bafd6011d7cbba9af8dc323079ae60f23546aef" + url: "https://pub.dev" + source: hosted + version: "0.7.1" record_platform_interface: dependency: transitive description: name: record_platform_interface - sha256: "7a2d4ce7ac3752505157e416e4e0d666a54b1d5d8601701b7e7e5e30bec181b4" + sha256: "3a4b56e94ecd2a0b2b43eb1fa6f94c5b8484334f5d38ef43959c4bf97fb374cf" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "1.0.2" record_web: dependency: transitive description: name: record_web - sha256: "219ffb4ca59b4338117857db56d3ffadbde3169bcaf1136f5f4d4656f4a2372d" + sha256: "24847cdbcf999f7a5762170792f622ac844858766becd0f2370ec8ae22f7526e" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "1.0.5" record_windows: dependency: transitive description: name: record_windows - sha256: "42d545155a26b20d74f5107648dbb3382dbbc84dc3f1adc767040359e57a1345" + sha256: "39998b3ea7d8d28b04159d82220e6e5e32a7c357c6fb2794f5736beea272f6c3" url: "https://pub.dev" source: hosted - version: "0.7.1" + version: "1.0.2" remove_emoji: dependency: transitive description: @@ -1945,18 +1953,18 @@ packages: dependency: transitive description: name: sentry - sha256: e572d33a3ff1d69549f33ee828a8ff514047d43ca8eea4ab093d72461205aa3e + sha256: fd1fbfe860c05f5c52820ec4dbf2b6473789e83ead26cfc18bca4fe80bf3f008 url: "https://pub.dev" source: hosted - version: "7.20.1" + version: "8.2.0" sentry_flutter: dependency: "direct main" description: name: sentry_flutter - sha256: ac8cf6bb849f3560353ae33672e17b2713809a4e8de0d3cf372e9e9c42013757 + sha256: c64f0aec5332bec87083b61514d1b6b29e435b9045d03ce1575861192b9a5680 url: "https://pub.dev" source: hosted - version: "7.20.1" + version: "8.2.0" share_plus: dependency: "direct main" description: From 25daaad305761d1b5fd939587382ccfb53536549 Mon Sep 17 00:00:00 2001 From: Kelrap <99418823+Kelrap@users.noreply.github.com> Date: Wed, 15 May 2024 16:49:47 -0400 Subject: [PATCH 15/17] Change default value of autoplay option to false --- lib/pangea/pages/settings_learning/settings_learning_view.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pangea/pages/settings_learning/settings_learning_view.dart b/lib/pangea/pages/settings_learning/settings_learning_view.dart index 125b2ac99..d878dcb42 100644 --- a/lib/pangea/pages/settings_learning/settings_learning_view.dart +++ b/lib/pangea/pages/settings_learning/settings_learning_view.dart @@ -65,7 +65,7 @@ class SettingsLearningView extends StatelessWidget { defaultValue: controller.pangeaController.pStoreService.read( PLocalKey.autoPlayMessages, ) ?? - true, + false, title: L10n.of(context)!.autoPlayTitle, subtitle: L10n.of(context)!.autoPlayDesc, pStoreKey: PLocalKey.autoPlayMessages, From 00c90ec9a0d575033522c0987a7775169a1ff71d Mon Sep 17 00:00:00 2001 From: Kelrap Date: Thu, 16 May 2024 09:24:20 -0400 Subject: [PATCH 16/17] Checks that message is not redacted before opening toolbar --- lib/pages/chat/events/message.dart | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/pages/chat/events/message.dart b/lib/pages/chat/events/message.dart index 373689043..472ef4eb4 100644 --- a/lib/pages/chat/events/message.dart +++ b/lib/pages/chat/events/message.dart @@ -167,9 +167,10 @@ class Message extends StatelessWidget { // #Pangea ToolbarDisplayController? toolbarController; if (event.type == EventTypes.Message && - event.messageType == MessageTypes.Text || - event.messageType == MessageTypes.Notice || - event.messageType == MessageTypes.Audio) { + !event.redacted && + (event.messageType == MessageTypes.Text || + event.messageType == MessageTypes.Notice || + event.messageType == MessageTypes.Audio)) { toolbarController = controller.getToolbarDisplayController( event.eventId, nextEvent: nextEvent, From ed1a483184b8ad77e3612e26ef5a58fcafe2cdbc Mon Sep 17 00:00:00 2001 From: ggurdin Date: Thu, 16 May 2024 10:08:17 -0400 Subject: [PATCH 17/17] load accuracte number for num chats in space --- lib/pages/chat_list/space_view.dart | 175 ++++++++++++++++++++-------- 1 file changed, 129 insertions(+), 46 deletions(-) diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index fae04dcff..856bed7d1 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -8,6 +8,7 @@ import 'package:fluffychat/pages/chat_list/chat_list_item.dart'; import 'package:fluffychat/pages/chat_list/search_title.dart'; import 'package:fluffychat/pages/chat_list/utils/on_chat_tap.dart'; import 'package:fluffychat/pangea/constants/class_default_values.dart'; +import 'package:fluffychat/pangea/constants/pangea_room_types.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/pangea/extensions/sync_update_extension.dart'; import 'package:fluffychat/pangea/utils/archive_space.dart'; @@ -47,11 +48,23 @@ class _SpaceViewState extends State { // #Pangea StreamSubscription? _roomSubscription; bool refreshing = false; + + final String _chatCountsKey = 'chatCounts'; + Map get chatCounts => Map.from( + widget.controller.pangeaController.pStoreService.read( + _chatCountsKey, + local: true, + ) ?? + {}, + ); // Pangea# @override void initState() { loadHierarchy(); + // #Pangea + loadChatCounts(); + // Pangea# super.initState(); } @@ -74,9 +87,15 @@ class _SpaceViewState extends State { // Pangea# } - Future loadHierarchy([String? prevBatch]) async { + Future loadHierarchy([ + String? prevBatch, // #Pangea - if (widget.controller.activeSpaceId == null || loading) { + String? spaceId, + // Pangea# + ]) async { + // #Pangea + if ((widget.controller.activeSpaceId == null && spaceId == null) || + loading) { return GetSpaceHierarchyResponse( rooms: [], nextBatch: null, @@ -89,7 +108,10 @@ class _SpaceViewState extends State { }); // Pangea# - final activeSpaceId = widget.controller.activeSpaceId!; + // #Pangea + // final activeSpaceId = widget.controller.activeSpaceId!; + final activeSpaceId = (widget.controller.activeSpaceId ?? spaceId)!; + // Pangea# final client = Matrix.of(context).client; final activeSpace = client.getRoomById(activeSpaceId); @@ -122,6 +144,14 @@ class _SpaceViewState extends State { }); rethrow; } finally { + // #Pangea + if (activeSpace != null) { + await setChatCount( + activeSpace, + _lastResponse[activeSpaceId], + ); + } + // Pangea# setState(() { loading = false; }); @@ -387,6 +417,14 @@ class _SpaceViewState extends State { } // #Pangea + Future loadChatCounts() async { + for (final Room room in Matrix.of(context).client.rooms) { + if (room.isSpace && !chatCounts.containsKey(room.id)) { + await loadHierarchy(null, room.id); + } + } + } + Future refreshOnUpdate(SyncUpdate event) async { /* refresh on leave, invite, and space child update not join events, because there's already a listener on @@ -412,6 +450,90 @@ class _SpaceViewState extends State { } setState(() => refreshing = false); } + + bool includeSpaceChild(sc, matchingSpaceChildren) { + final bool isAnalyticsRoom = sc.roomType == PangeaRoomTypes.analytics; + final bool isMember = [Membership.join, Membership.invite] + .contains(Matrix.of(context).client.getRoomById(sc.roomId)?.membership); + final bool isSuggested = matchingSpaceChildren.any( + (matchingSpaceChild) => + matchingSpaceChild.roomId == sc.roomId && + matchingSpaceChild.suggested == true, + ); + return !isAnalyticsRoom && (isMember || isSuggested); + } + + List filterSpaceChildren( + Room space, + List spaceChildren, + ) { + final childIds = + spaceChildren.map((hierarchyMember) => hierarchyMember.roomId); + + final matchingSpaceChildren = space.spaceChildren + .where((spaceChild) => childIds.contains(spaceChild.roomId)) + .toList(); + + final filteredSpaceChildren = spaceChildren + .where( + (sc) => includeSpaceChild( + sc, + matchingSpaceChildren, + ), + ) + .toList(); + return filteredSpaceChildren; + } + + int sortSpaceChildren( + SpaceRoomsChunk a, + SpaceRoomsChunk b, + ) { + final bool aIsSpace = a.roomType == 'm.space'; + final bool bIsSpace = b.roomType == 'm.space'; + + if (aIsSpace && !bIsSpace) { + return -1; + } else if (!aIsSpace && bIsSpace) { + return 1; + } + return 0; + } + + Future setChatCount( + Room space, + GetSpaceHierarchyResponse? response, + ) async { + final Map updatedChatCounts = Map.from(chatCounts); + final List spaceChildren = response?.rooms ?? []; + final filteredChildren = filterSpaceChildren(space, spaceChildren) + .where((sc) => sc.roomId != space.id) + .toList(); + updatedChatCounts[space.id] = filteredChildren.length; + + await widget.controller.pangeaController.pStoreService.save( + _chatCountsKey, + updatedChatCounts, + local: true, + ); + } + + bool roomCountLoading(Room space) => + space.membership == Membership.join && !chatCounts.containsKey(space.id); + + Widget spaceSubtitle(Room space) { + if (roomCountLoading(space)) { + return const CircularProgressIndicator.adaptive(); + } + + return Text( + space.membership == Membership.join + ? L10n.of(context)!.numChats( + chatCounts[space.id].toString(), + ) + : L10n.of(context)!.youreInvited, + ); + } // Pangea# @override @@ -473,14 +595,8 @@ class _SpaceViewState extends State { // #Pangea subtitle: Row( children: [ - Text( - rootSpace.membership == Membership.join - ? L10n.of(context)!.numChats( - rootSpace.spaceChildren.length.toString(), - ) - : L10n.of(context)!.youreInvited, - ), - if (rootSpace.locked ?? false) + spaceSubtitle(rootSpace), + if (rootSpace.locked) const Padding( padding: EdgeInsets.only(left: 4.0), child: Icon( @@ -625,42 +741,9 @@ class _SpaceViewState extends State { final space = Matrix.of(context).client.getRoomById(activeSpaceId); if (space != null) { - final matchingSpaceChildren = space.spaceChildren - .where( - (spaceChild) => spaceChildren - .map((hierarchyMember) => hierarchyMember.roomId) - .contains(spaceChild.roomId), - ) - .toList(); - spaceChildren = spaceChildren - .where( - (spaceChild) => - matchingSpaceChildren.any( - (matchingSpaceChild) => - matchingSpaceChild.roomId == - spaceChild.roomId && - matchingSpaceChild.suggested == true, - ) || - [Membership.join, Membership.invite].contains( - Matrix.of(context) - .client - .getRoomById(spaceChild.roomId) - ?.membership, - ), - ) - .toList(); + spaceChildren = filterSpaceChildren(space, spaceChildren); } - spaceChildren.sort((a, b) { - final bool aIsSpace = a.roomType == 'm.space'; - final bool bIsSpace = b.roomType == 'm.space'; - - if (aIsSpace && !bIsSpace) { - return -1; - } else if (!aIsSpace && bIsSpace) { - return 1; - } - return 0; - }); + spaceChildren.sort(sortSpaceChildren); // Pangea# final canLoadMore = response.nextBatch != null; return SliverList(