From c4349babcfdbb75feb27e90157e2dc18a9d3099c Mon Sep 17 00:00:00 2001 From: Kelrap Date: Fri, 13 Jun 2025 13:04:06 -0400 Subject: [PATCH 01/19] Fix duplicate language warning overflow --- .../pages/settings_learning_view.dart | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/pangea/learning_settings/pages/settings_learning_view.dart b/lib/pangea/learning_settings/pages/settings_learning_view.dart index 74c8cb0c6..c521e9717 100644 --- a/lib/pangea/learning_settings/pages/settings_learning_view.dart +++ b/lib/pangea/learning_settings/pages/settings_learning_view.dart @@ -192,13 +192,15 @@ class SettingsLearningView extends StatelessWidget { .colorScheme .error, ), - Text( - L10n.of(context) - .noIdenticalLanguages, - style: TextStyle( - color: Theme.of(context) - .colorScheme - .error, + Flexible( + child: Text( + L10n.of(context) + .noIdenticalLanguages, + style: TextStyle( + color: Theme.of(context) + .colorScheme + .error, + ), ), ), ], From 01b8a4ff383cc6ba0724e058bc12fa2864005503 Mon Sep 17 00:00:00 2001 From: Kelrap Date: Fri, 13 Jun 2025 13:35:26 -0400 Subject: [PATCH 02/19] Stop overflow in language selection entries --- .../widgets/p_language_dropdown.dart | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/pangea/learning_settings/widgets/p_language_dropdown.dart b/lib/pangea/learning_settings/widgets/p_language_dropdown.dart index 462eaf650..c71fea714 100644 --- a/lib/pangea/learning_settings/widgets/p_language_dropdown.dart +++ b/lib/pangea/learning_settings/widgets/p_language_dropdown.dart @@ -239,15 +239,17 @@ class LanguageDropDownEntry extends StatelessWidget { Expanded( child: Row( children: [ - Text( - languageModel.getDisplayName(context) ?? "", - style: const TextStyle().copyWith( - color: enabled - ? Theme.of(context).textTheme.bodyLarge!.color - : Theme.of(context).disabledColor, - fontSize: 14, + Flexible( + child: Text( + languageModel.getDisplayName(context) ?? "", + style: const TextStyle().copyWith( + color: enabled + ? Theme.of(context).textTheme.bodyLarge!.color + : Theme.of(context).disabledColor, + fontSize: 14, + ), + overflow: TextOverflow.ellipsis, ), - overflow: TextOverflow.ellipsis, ), const SizedBox(width: 10), if (isL2List && languageModel.l2Support != L2SupportEnum.full) From 68b1382ba205fa2795a9f444d704201ed5a17999 Mon Sep 17 00:00:00 2001 From: wcjord <32568597+wcjord@users.noreply.github.com> Date: Fri, 13 Jun 2025 14:57:45 -0400 Subject: [PATCH 03/19] feat(phonetic_transcription): repo set up --- lib/pangea/common/network/urls.dart | 3 + .../phonetic_transcription_repo.dart | 66 +++++++++++++++++++ .../phonetic_transcription_request.dart | 33 ++++++++++ .../phonetic_transcription_response.dart | 55 ++++++++++++++++ .../test_phonetic_transcription_api.dart | 0 5 files changed, 157 insertions(+) create mode 100644 lib/pangea/phonetic_transcription/phonetic_transcription_repo.dart create mode 100644 lib/pangea/phonetic_transcription/phonetic_transcription_request.dart create mode 100644 lib/pangea/phonetic_transcription/phonetic_transcription_response.dart create mode 100644 lib/pangea/phonetic_transcription/test_phonetic_transcription_api.dart diff --git a/lib/pangea/common/network/urls.dart b/lib/pangea/common/network/urls.dart index a667066c8..5bb4f2c86 100644 --- a/lib/pangea/common/network/urls.dart +++ b/lib/pangea/common/network/urls.dart @@ -86,4 +86,7 @@ class PApiUrls { static String rcProductsTrial = "${PApiUrls.subscriptionEndpoint}/free_trial"; static String rcSubscription = PApiUrls.subscriptionEndpoint; + + static String phoneticTranscription = + "${PApiUrls.choreoEndpoint}/phonetic_transcription"; } diff --git a/lib/pangea/phonetic_transcription/phonetic_transcription_repo.dart b/lib/pangea/phonetic_transcription/phonetic_transcription_repo.dart new file mode 100644 index 000000000..30eac8302 --- /dev/null +++ b/lib/pangea/phonetic_transcription/phonetic_transcription_repo.dart @@ -0,0 +1,66 @@ +import 'dart:convert'; +import 'dart:developer'; + +import 'package:fluffychat/pangea/common/config/environment.dart'; +import 'package:fluffychat/pangea/common/network/requests.dart'; +import 'package:fluffychat/pangea/common/network/urls.dart'; +import 'package:fluffychat/pangea/common/utils/error_handler.dart'; +import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_request.dart'; +import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_response.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import 'package:flutter/foundation.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:http/http.dart'; + +class PhoneticTranscriptionRepo { + static final GetStorage _storage = + GetStorage('phonetic_transcription_storage'); + + static void set(PhoneticTranscriptionRequest request, + PhoneticTranscriptionResponse response) { + response.expireAt ??= DateTime.now().add(const Duration(days: 100)); + _storage.write(request.storageKey, response.toJson()); + } + + static Future _fetch( + PhoneticTranscriptionRequest request) async { + final cachedJson = _storage.read(request.storageKey); + final cached = cachedJson == null + ? null + : PhoneticTranscriptionResponse.fromJson(cachedJson); + + if (cached != null) { + if (DateTime.now().isBefore(cached.expireAt!)) { + return cached; + } else { + _storage.remove(request.storageKey); + } + } + + final Requests req = Requests( + choreoApiKey: Environment.choreoApiKey, + accessToken: MatrixState.pangeaController.userController.accessToken, + ); + + final Response res = await req.post( + url: PApiUrls.phoneticTranscription, + body: request.toJson(), + ); + + final decodedBody = jsonDecode(utf8.decode(res.bodyBytes)); + final response = PhoneticTranscriptionResponse.fromJson(decodedBody); + set(request, response); + return response; + } + + static Future get( + PhoneticTranscriptionRequest request) async { + try { + return await _fetch(request); + } catch (e) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: e, data: request.toJson()); + rethrow; + } + } +} diff --git a/lib/pangea/phonetic_transcription/phonetic_transcription_request.dart b/lib/pangea/phonetic_transcription/phonetic_transcription_request.dart new file mode 100644 index 000000000..02dfcb7c7 --- /dev/null +++ b/lib/pangea/phonetic_transcription/phonetic_transcription_request.dart @@ -0,0 +1,33 @@ +class PhoneticTranscriptionRequest { + final String l1; + final String l2; + final String content; + final bool requiresTokenization; + + PhoneticTranscriptionRequest({ + required this.l1, + required this.l2, + required this.content, + this.requiresTokenization = true, + }); + + factory PhoneticTranscriptionRequest.fromJson(Map json) { + return PhoneticTranscriptionRequest( + l1: json['l1'] as String, + l2: json['l2'] as String, + content: json['content'] as String, + requiresTokenization: json['requires_tokenization'] ?? true, + ); + } + + Map toJson() { + return { + 'l1': l1, + 'l2': l2, + 'content': content, + 'requires_tokenization': requiresTokenization, + }; + } + + String get storageKey => 'l1:$l1,l2:$l2,content:$content'; +} diff --git a/lib/pangea/phonetic_transcription/phonetic_transcription_response.dart b/lib/pangea/phonetic_transcription/phonetic_transcription_response.dart new file mode 100644 index 000000000..9efce60d4 --- /dev/null +++ b/lib/pangea/phonetic_transcription/phonetic_transcription_response.dart @@ -0,0 +1,55 @@ +class PhoneticTranscriptionResponse { + final Map arc; + final Map content; + final Map tokenization; + final Map phoneticTranscriptionResult; + DateTime? expireAt; + + PhoneticTranscriptionResponse({ + required this.arc, + required this.content, + required this.tokenization, + required this.phoneticTranscriptionResult, + this.expireAt, + }); + + factory PhoneticTranscriptionResponse.fromJson(Map json) { + return PhoneticTranscriptionResponse( + arc: Map.from(json['arc'] as Map), + content: Map.from(json['content'] as Map), + tokenization: Map.from(json['tokenization'] as Map), + phoneticTranscriptionResult: Map.from( + json['phonetic_transcription_result'] as Map), + expireAt: json['expireAt'] == null + ? null + : DateTime.parse(json['expireAt'] as String), + ); + } + + Map toJson() { + return { + 'arc': arc, + 'content': content, + 'tokenization': tokenization, + 'phonetic_transcription_result': phoneticTranscriptionResult, + 'expireAt': expireAt?.toIso8601String(), + }; + } + + @override + bool operator ==(Object other) => + identical(this, other) || + other is PhoneticTranscriptionResponse && + runtimeType == other.runtimeType && + arc == other.arc && + content == other.content && + tokenization == other.tokenization && + phoneticTranscriptionResult == other.phoneticTranscriptionResult; + + @override + int get hashCode => + arc.hashCode ^ + content.hashCode ^ + tokenization.hashCode ^ + phoneticTranscriptionResult.hashCode; +} diff --git a/lib/pangea/phonetic_transcription/test_phonetic_transcription_api.dart b/lib/pangea/phonetic_transcription/test_phonetic_transcription_api.dart new file mode 100644 index 000000000..e69de29bb From 742bc0d8decfccad572c39a29b2fcd13806a014f Mon Sep 17 00:00:00 2001 From: Kelrap Date: Mon, 16 Jun 2025 11:01:34 -0400 Subject: [PATCH 04/19] Make get started background grayer and more opaque --- lib/pangea/onboarding/onboarding_complete.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/pangea/onboarding/onboarding_complete.dart b/lib/pangea/onboarding/onboarding_complete.dart index cbc3c821b..796602d28 100644 --- a/lib/pangea/onboarding/onboarding_complete.dart +++ b/lib/pangea/onboarding/onboarding_complete.dart @@ -19,7 +19,10 @@ class OnboardingComplete extends StatelessWidget { children: [ Container( decoration: BoxDecoration( - color: Theme.of(context).colorScheme.onSurface.withAlpha(20), + color: Theme.of(context) + .colorScheme + .surfaceContainerHigh + .withAlpha(170), borderRadius: BorderRadius.circular( 10.0, ), From bf1b4397df0abc5b6aa6c886df7c91c14076311a Mon Sep 17 00:00:00 2001 From: Kelrap Date: Mon, 16 Jun 2025 11:15:08 -0400 Subject: [PATCH 05/19] Does not show option to start a conversation for the user's own profile popup --- .../member_actions_popup_menu_button.dart | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/widgets/member_actions_popup_menu_button.dart b/lib/widgets/member_actions_popup_menu_button.dart index 6502beedd..115ddb072 100644 --- a/lib/widgets/member_actions_popup_menu_button.dart +++ b/lib/widgets/member_actions_popup_menu_button.dart @@ -7,6 +7,7 @@ import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/pangea/analytics_misc/level_display_name.dart'; import 'package:fluffychat/pangea/bot/utils/bot_name.dart'; import 'package:fluffychat/widgets/avatar.dart'; +import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/permission_slider_dialog.dart'; import 'adaptive_dialogs/show_ok_cancel_alert_dialog.dart'; import 'adaptive_dialogs/user_dialog.dart'; @@ -90,20 +91,21 @@ void showMemberActionsPopupMenu({ ), const PopupMenuDivider(), // #Pangea - PopupMenuItem( - value: _MemberActions.chat, - child: Row( - children: [ - const Icon(Icons.forum_outlined), - const SizedBox(width: 18), - Text( - dmRoomId == null - ? L10n.of(context).startConversation - : L10n.of(context).sendAMessage, - ), - ], + if (Matrix.of(context).client.userID != user.id) + PopupMenuItem( + value: _MemberActions.chat, + child: Row( + children: [ + const Icon(Icons.forum_outlined), + const SizedBox(width: 18), + Text( + dmRoomId == null + ? L10n.of(context).startConversation + : L10n.of(context).sendAMessage, + ), + ], + ), ), - ), // Pangea# if (onMention != null) PopupMenuItem( From 007162ea0265b53507d4a943e8172467bb8483fa Mon Sep 17 00:00:00 2001 From: ggurdin Date: Mon, 16 Jun 2025 11:53:22 -0400 Subject: [PATCH 06/19] chore: update how client instance is accessed --- lib/widgets/member_actions_popup_menu_button.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/widgets/member_actions_popup_menu_button.dart b/lib/widgets/member_actions_popup_menu_button.dart index 115ddb072..f4ff7c3ca 100644 --- a/lib/widgets/member_actions_popup_menu_button.dart +++ b/lib/widgets/member_actions_popup_menu_button.dart @@ -7,7 +7,6 @@ import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/pangea/analytics_misc/level_display_name.dart'; import 'package:fluffychat/pangea/bot/utils/bot_name.dart'; import 'package:fluffychat/widgets/avatar.dart'; -import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/permission_slider_dialog.dart'; import 'adaptive_dialogs/show_ok_cancel_alert_dialog.dart'; import 'adaptive_dialogs/user_dialog.dart'; @@ -91,7 +90,7 @@ void showMemberActionsPopupMenu({ ), const PopupMenuDivider(), // #Pangea - if (Matrix.of(context).client.userID != user.id) + if (user.room.client.userID != user.id) PopupMenuItem( value: _MemberActions.chat, child: Row( From 9139c992acd46975cf78d8229371a549b21f50f7 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Mon, 16 Jun 2025 12:00:53 -0400 Subject: [PATCH 07/19] chore: update emojis when switching between different tokens --- lib/pangea/lemmas/lemma_reaction_picker.dart | 32 +++++++++++++++----- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/lib/pangea/lemmas/lemma_reaction_picker.dart b/lib/pangea/lemmas/lemma_reaction_picker.dart index b229f2396..92a3a70ef 100644 --- a/lib/pangea/lemmas/lemma_reaction_picker.dart +++ b/lib/pangea/lemmas/lemma_reaction_picker.dart @@ -28,17 +28,35 @@ class LemmaReactionPickerState extends State { @override void initState() { super.initState(); - widget.cId.getLemmaInfo().then((info) { - loading = false; - setState(() => displayEmoji = info.emoji); - }).catchError((e, s) { - ErrorHandler.logError(data: widget.cId.toJson(), e: e, s: s); - setState(() => loading = false); - }); + _refresh(); + } + + @override + void didUpdateWidget(LemmaReactionPicker oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.cId != widget.cId) { + _refresh(); + } } void setEmoji(String emoji) => widget.controller.sendEmojiAction(emoji); + Future _refresh() async { + setState(() { + loading = true; + displayEmoji = []; + }); + + try { + final info = await widget.cId.getLemmaInfo(); + displayEmoji = info.emoji; + } catch (e, s) { + ErrorHandler.logError(data: widget.cId.toJson(), e: e, s: s); + } finally { + setState(() => loading = false); + } + } + @override Widget build(BuildContext context) { return Container( From 40a6e5a10bb67fc05561cc8b37c3e380a8bd64e1 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Mon, 16 Jun 2025 13:52:32 -0400 Subject: [PATCH 08/19] chore: started adding widget to show phonetic transcription --- lib/l10n/intl_en.arb | 3 +- .../vocab_analytics_details_view.dart | 10 ++ .../phonetic_transcription_repo.dart | 20 ++-- .../phonetic_transcription_widget.dart | 106 ++++++++++++++++++ .../test_phonetic_transcription_api.dart | 0 5 files changed, 131 insertions(+), 8 deletions(-) create mode 100644 lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart delete mode 100644 lib/pangea/phonetic_transcription/test_phonetic_transcription_api.dart diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 50166f59f..a7e110b90 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -5016,5 +5016,6 @@ "directMessage": "Direct Message", "newDirectMessage": "New direct message", "speakingExercisesTooltip": "Speaking practice", - "noChatsFoundHereYet": "No chats found here yet" + "noChatsFoundHereYet": "No chats found here yet", + "phoneticTranscriptionError": "Phonetic transcription failed" } \ No newline at end of file diff --git a/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart b/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart index 56fabe42c..4f65589cc 100644 --- a/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart +++ b/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart @@ -11,6 +11,7 @@ import 'package:fluffychat/pangea/lemmas/lemma_emoji_row.dart'; import 'package:fluffychat/pangea/morphs/get_grammar_copy.dart'; import 'package:fluffychat/pangea/morphs/morph_features_enum.dart'; import 'package:fluffychat/pangea/morphs/morph_icon.dart'; +import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_widget.dart'; import 'package:fluffychat/pangea/toolbar/widgets/practice_activity/word_text_with_audio_button.dart'; import 'package:fluffychat/pangea/toolbar/widgets/word_zoom/lemma_meaning_widget.dart'; import 'package:fluffychat/widgets/matrix.dart'; @@ -26,6 +27,9 @@ class VocabDetailsView extends StatelessWidget { ConstructUses get _construct => constructId.constructUses; + String? get _userL1 => + MatrixState.pangeaController.languageController.userL1?.langCode; + /// Get the language code for the current lemma String? get _userL2 => MatrixState.pangeaController.languageController.userL2?.langCode; @@ -60,6 +64,12 @@ class VocabDetailsView extends StatelessWidget { ), subtitle: Column( children: [ + if (_userL1 != null && _userL2 != null) + PhoneticTranscription( + text: _construct.lemma, + l1: _userL1!, + l2: _userL2!, + ), Row( mainAxisSize: MainAxisSize.min, spacing: 8.0, diff --git a/lib/pangea/phonetic_transcription/phonetic_transcription_repo.dart b/lib/pangea/phonetic_transcription/phonetic_transcription_repo.dart index 30eac8302..124389eed 100644 --- a/lib/pangea/phonetic_transcription/phonetic_transcription_repo.dart +++ b/lib/pangea/phonetic_transcription/phonetic_transcription_repo.dart @@ -1,6 +1,11 @@ import 'dart:convert'; import 'dart:developer'; +import 'package:flutter/foundation.dart'; + +import 'package:get_storage/get_storage.dart'; +import 'package:http/http.dart'; + import 'package:fluffychat/pangea/common/config/environment.dart'; import 'package:fluffychat/pangea/common/network/requests.dart'; import 'package:fluffychat/pangea/common/network/urls.dart'; @@ -8,22 +13,22 @@ import 'package:fluffychat/pangea/common/utils/error_handler.dart'; import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_request.dart'; import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_response.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/foundation.dart'; -import 'package:get_storage/get_storage.dart'; -import 'package:http/http.dart'; class PhoneticTranscriptionRepo { static final GetStorage _storage = GetStorage('phonetic_transcription_storage'); - static void set(PhoneticTranscriptionRequest request, - PhoneticTranscriptionResponse response) { + static void set( + PhoneticTranscriptionRequest request, + PhoneticTranscriptionResponse response, + ) { response.expireAt ??= DateTime.now().add(const Duration(days: 100)); _storage.write(request.storageKey, response.toJson()); } static Future _fetch( - PhoneticTranscriptionRequest request) async { + PhoneticTranscriptionRequest request, + ) async { final cachedJson = _storage.read(request.storageKey); final cached = cachedJson == null ? null @@ -54,7 +59,8 @@ class PhoneticTranscriptionRepo { } static Future get( - PhoneticTranscriptionRequest request) async { + PhoneticTranscriptionRequest request, + ) async { try { return await _fetch(request); } catch (e) { diff --git a/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart b/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart new file mode 100644 index 000000000..b8d7f0d77 --- /dev/null +++ b/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart @@ -0,0 +1,106 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/l10n/l10n.dart'; +import 'package:fluffychat/pangea/common/utils/error_handler.dart'; +import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_repo.dart'; +import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_request.dart'; +import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_response.dart'; + +class PhoneticTranscription extends StatefulWidget { + final String text; + final String l1; + final String l2; + + const PhoneticTranscription({ + super.key, + required this.text, + required this.l1, + required this.l2, + }); + + @override + State createState() => PhoneticTranscriptionState(); +} + +class PhoneticTranscriptionState extends State { + bool _loading = false; + String? error; + + PhoneticTranscriptionResponse? _response; + + @override + void initState() { + super.initState(); + _fetchPhoneticTranscription(); + } + + @override + void didUpdateWidget(covariant PhoneticTranscription oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.text != widget.text || + oldWidget.l1 != widget.l1 || + oldWidget.l2 != widget.l2) { + _fetchPhoneticTranscription(); + } + } + + Future _fetchPhoneticTranscription() async { + final PhoneticTranscriptionRequest request = PhoneticTranscriptionRequest( + l1: widget.l1, + l2: widget.l2, + content: widget.text, + ); + + try { + setState(() { + _loading = true; + error = null; + }); + + _response = await PhoneticTranscriptionRepo.get(request); + } catch (e, s) { + ErrorHandler.logError( + e: e, + s: s, + data: request.toJson(), + ); + error = e.toString(); + } finally { + if (mounted) { + setState(() { + _loading = false; + }); + } + } + } + + @override + Widget build(BuildContext context) { + if (error != null) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + Icons.error_outline, + color: Theme.of(context).colorScheme.error, + size: 16.0, + ), + const SizedBox(width: 8), + Text( + L10n.of(context).phoneticTranscriptionError, + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ); + } + + if (_loading || _response == null) { + return const Center(child: CircularProgressIndicator.adaptive()); + } + + return Text( + 'Phonetic transcription for "${widget.text}" in ${widget.l2}', + style: Theme.of(context).textTheme.bodyLarge, + ); + } +} diff --git a/lib/pangea/phonetic_transcription/test_phonetic_transcription_api.dart b/lib/pangea/phonetic_transcription/test_phonetic_transcription_api.dart deleted file mode 100644 index e69de29bb..000000000 From a92237fc8bfb4816fd70540ebbde03b2eccf5377 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Mon, 16 Jun 2025 14:12:49 -0400 Subject: [PATCH 09/19] chore: update transcription error message --- lib/l10n/intl_en.arb | 3 ++- lib/pangea/toolbar/widgets/overlay_message.dart | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 50166f59f..09c40f998 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -5016,5 +5016,6 @@ "directMessage": "Direct Message", "newDirectMessage": "New direct message", "speakingExercisesTooltip": "Speaking practice", - "noChatsFoundHereYet": "No chats found here yet" + "noChatsFoundHereYet": "No chats found here yet", + "transcriptionFailed": "Failed to transcribe audio" } \ No newline at end of file diff --git a/lib/pangea/toolbar/widgets/overlay_message.dart b/lib/pangea/toolbar/widgets/overlay_message.dart index ed2f8b71e..b6633b0c6 100644 --- a/lib/pangea/toolbar/widgets/overlay_message.dart +++ b/lib/pangea/toolbar/widgets/overlay_message.dart @@ -160,7 +160,7 @@ class OverlayMessage extends StatelessWidget { ), const SizedBox(width: 8), Text( - L10n.of(context).oopsSomethingWentWrong, + L10n.of(context).transcriptionFailed, style: AppConfig.messageTextStyle( event, textColor, From 1a0061b35accffbd80b60a57f5d957df5ece4af0 Mon Sep 17 00:00:00 2001 From: Kelrap Date: Mon, 16 Jun 2025 14:50:02 -0400 Subject: [PATCH 10/19] Use translate tooltip for speech translation button --- lib/pangea/toolbar/widgets/select_mode_buttons.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/pangea/toolbar/widgets/select_mode_buttons.dart b/lib/pangea/toolbar/widgets/select_mode_buttons.dart index 0c353c3f4..07f5d3722 100644 --- a/lib/pangea/toolbar/widgets/select_mode_buttons.dart +++ b/lib/pangea/toolbar/widgets/select_mode_buttons.dart @@ -37,11 +37,10 @@ enum SelectMode { case SelectMode.audio: return l10n.playAudio; case SelectMode.translate: + case SelectMode.speechTranslation: return l10n.translationTooltip; case SelectMode.practice: return l10n.practice; - case SelectMode.speechTranslation: - return l10n.speechToTextTooltip; } } } From 20fab6a5d2d08b8088f506bf17a2d0eeadbdf150 Mon Sep 17 00:00:00 2001 From: Kelrap Date: Mon, 16 Jun 2025 15:04:37 -0400 Subject: [PATCH 11/19] Don't use space default image/description for joining chats in space --- .../public_spaces/public_room_bottom_sheet.dart | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/pangea/public_spaces/public_room_bottom_sheet.dart b/lib/pangea/public_spaces/public_room_bottom_sheet.dart index ba0b71fc7..89ed09700 100644 --- a/lib/pangea/public_spaces/public_room_bottom_sheet.dart +++ b/lib/pangea/public_spaces/public_room_bottom_sheet.dart @@ -200,12 +200,14 @@ class PublicRoomBottomSheetState extends State { Row( spacing: 16.0, children: [ - (chunk?.avatarUrl != null) + (chunk?.avatarUrl != null || chunk?.roomType != 'm.space') ? Avatar( mxContent: chunk?.avatarUrl, name: chunk?.name, size: 160.0, - borderRadius: BorderRadius.circular(24.0), + borderRadius: BorderRadius.circular( + chunk?.roomType != 'm.space' ? 80 : 24.0, + ), ) : ClipRRect( borderRadius: BorderRadius.circular(24.0), @@ -242,7 +244,11 @@ class PublicRoomBottomSheetState extends State { child: SingleChildScrollView( child: Text( chunk?.topic ?? - L10n.of(context).noSpaceDescriptionYet, + (chunk?.roomType != 'm.space' + ? L10n.of(context) + .noChatDescriptionYet + : L10n.of(context) + .noSpaceDescriptionYet), softWrap: true, textAlign: TextAlign.start, maxLines: null, From daeaf900f3da5eae705e87eb8f6b3255fecf1a31 Mon Sep 17 00:00:00 2001 From: wcjord <32568597+wcjord@users.noreply.github.com> Date: Mon, 16 Jun 2025 16:13:40 -0400 Subject: [PATCH 12/19] fix(phonetic_transcription): fixed models --- lib/main.dart | 17 +- .../vocab_analytics_details_view.dart | 37 +++-- .../models/pangea_token_text_model.dart | 8 + .../models/language_model.dart | 27 +++- .../phonetic_transcription_request.dart | 26 +-- .../phonetic_transcription_response.dart | 123 ++++++++++++-- .../phonetic_transcription_widget.dart | 153 ++++++++++++++++++ 7 files changed, 346 insertions(+), 45 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index d33e62b41..b7df5a61c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,13 +1,4 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - import 'package:collection/collection.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import 'package:get_storage/get_storage.dart'; -import 'package:matrix/matrix.dart'; -import 'package:shared_preferences/shared_preferences.dart'; - import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/common/config/environment.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; @@ -15,6 +6,14 @@ import 'package:fluffychat/pangea/common/utils/firebase_analytics.dart'; import 'package:fluffychat/pangea/learning_settings/utils/p_language_store.dart'; import 'package:fluffychat/utils/client_manager.dart'; import 'package:fluffychat/utils/platform_infos.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:matrix/matrix.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + import 'config/setting_keys.dart'; import 'utils/background_push.dart'; import 'widgets/fluffy_chat_app.dart'; diff --git a/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart b/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart index 4f65589cc..c00fb1176 100644 --- a/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart +++ b/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart @@ -1,7 +1,4 @@ -import 'package:flutter/material.dart'; - import 'package:collection/collection.dart'; - import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/pangea/analytics_details_popup/analytics_details_popup_content.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; @@ -15,6 +12,7 @@ import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_ import 'package:fluffychat/pangea/toolbar/widgets/practice_activity/word_text_with_audio_button.dart'; import 'package:fluffychat/pangea/toolbar/widgets/word_zoom/lemma_meaning_widget.dart'; import 'package:fluffychat/widgets/matrix.dart'; +import 'package:flutter/material.dart'; /// Displays information about selected lemma, and its usage class VocabDetailsView extends StatelessWidget { @@ -53,14 +51,33 @@ class VocabDetailsView extends StatelessWidget { : _construct.lemmaCategory.darkColor(context)); return AnalyticsDetailsViewContent( - title: WordTextWithAudioButton( - text: _construct.lemma, - style: Theme.of(context).textTheme.headlineLarge?.copyWith( - color: textColor, + title: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + WordTextWithAudioButton( + text: _construct.lemma, + style: Theme.of(context).textTheme.headlineLarge?.copyWith( + color: textColor, + ), + iconSize: _iconSize, + uniqueID: "${_construct.lemma}-${_construct.category}", + langCode: _userL2!, + ), + if (MatrixState.pangeaController.languageController.userL2 != null) + Padding( + padding: const EdgeInsets.only(top: 4.0), + child: PhoneticTranscriptionWidget( + text: _construct.lemma, + textLanguage: + MatrixState.pangeaController.languageController.userL2!, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + color: textColor.withAlpha((0.7 * 255).toInt()), + fontSize: 18, + ), + iconSize: _iconSize * 0.8, + ), ), - iconSize: _iconSize, - uniqueID: "${_construct.lemma}-${_construct.category}", - langCode: _userL2!, + ], ), subtitle: Column( children: [ diff --git a/lib/pangea/events/models/pangea_token_text_model.dart b/lib/pangea/events/models/pangea_token_text_model.dart index 7f7323cf6..efef9a712 100644 --- a/lib/pangea/events/models/pangea_token_text_model.dart +++ b/lib/pangea/events/models/pangea_token_text_model.dart @@ -22,6 +22,14 @@ class PangeaTokenText { ); } + static PangeaTokenText fromString(String content) { + return PangeaTokenText( + offset: 0, + content: content, + length: content.length, + ); + } + static const String _offsetKey = "offset"; static const String _contentKey = "content"; static const String _lengthKey = "length"; diff --git a/lib/pangea/learning_settings/models/language_model.dart b/lib/pangea/learning_settings/models/language_model.dart index 61f021e91..6d6a03380 100644 --- a/lib/pangea/learning_settings/models/language_model.dart +++ b/lib/pangea/learning_settings/models/language_model.dart @@ -1,8 +1,7 @@ -import 'package:flutter/material.dart'; - import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart'; import 'package:fluffychat/pangea/learning_settings/enums/l2_support_enum.dart'; +import 'package:flutter/material.dart'; class LanguageModel { final String langCode; @@ -80,3 +79,27 @@ class LanguageModel { @override int get hashCode => langCode.hashCode; } + +class LanguageArc { + final LanguageModel l1; + final LanguageModel l2; + + LanguageArc({ + required this.l1, + required this.l2, + }); + + factory LanguageArc.fromJson(Map json) { + return LanguageArc( + l1: LanguageModel.fromJson(json['l1'] as Map), + l2: LanguageModel.fromJson(json['l2'] as Map), + ); + } + + Map toJson() { + return { + 'l1': l1.toJson(), + 'l2': l2.toJson(), + }; + } +} diff --git a/lib/pangea/phonetic_transcription/phonetic_transcription_request.dart b/lib/pangea/phonetic_transcription/phonetic_transcription_request.dart index 02dfcb7c7..cbd22fc22 100644 --- a/lib/pangea/phonetic_transcription/phonetic_transcription_request.dart +++ b/lib/pangea/phonetic_transcription/phonetic_transcription_request.dart @@ -1,33 +1,33 @@ +import 'package:fluffychat/pangea/events/models/pangea_token_text_model.dart'; +import 'package:fluffychat/pangea/learning_settings/models/language_model.dart'; + class PhoneticTranscriptionRequest { - final String l1; - final String l2; - final String content; + final LanguageArc arc; + final PangeaTokenText content; final bool requiresTokenization; PhoneticTranscriptionRequest({ - required this.l1, - required this.l2, + required this.arc, required this.content, - this.requiresTokenization = true, + this.requiresTokenization = false, }); factory PhoneticTranscriptionRequest.fromJson(Map json) { return PhoneticTranscriptionRequest( - l1: json['l1'] as String, - l2: json['l2'] as String, - content: json['content'] as String, + arc: LanguageArc.fromJson(json['arc'] as Map), + content: + PangeaTokenText.fromJson(json['content'] as Map), requiresTokenization: json['requires_tokenization'] ?? true, ); } Map toJson() { return { - 'l1': l1, - 'l2': l2, - 'content': content, + 'arc': arc.toJson(), + 'content': content.toJson(), 'requires_tokenization': requiresTokenization, }; } - String get storageKey => 'l1:$l1,l2:$l2,content:$content'; + String get storageKey => '${arc.l1}-${arc.l2}-${content.hashCode}'; } diff --git a/lib/pangea/phonetic_transcription/phonetic_transcription_response.dart b/lib/pangea/phonetic_transcription/phonetic_transcription_response.dart index 9efce60d4..a4cd2b3a3 100644 --- a/lib/pangea/phonetic_transcription/phonetic_transcription_response.dart +++ b/lib/pangea/phonetic_transcription/phonetic_transcription_response.dart @@ -1,8 +1,107 @@ +import 'package:fluffychat/pangea/events/models/pangea_token_text_model.dart'; +import 'package:fluffychat/pangea/learning_settings/models/language_model.dart'; + +enum PhoneticTranscriptionDelimEnum { sp, noSp } + +extension PhoneticTranscriptionDelimEnumExt on PhoneticTranscriptionDelimEnum { + String get value { + switch (this) { + case PhoneticTranscriptionDelimEnum.sp: + return " "; + case PhoneticTranscriptionDelimEnum.noSp: + return ""; + } + } + + static PhoneticTranscriptionDelimEnum fromString(String s) { + switch (s) { + case " ": + return PhoneticTranscriptionDelimEnum.sp; + case "": + return PhoneticTranscriptionDelimEnum.noSp; + default: + return PhoneticTranscriptionDelimEnum.sp; + } + } +} + +class PhoneticTranscriptionToken { + final LanguageArc arc; + final PangeaTokenText tokenL2; + final PangeaTokenText phoneticL1Transcription; + + PhoneticTranscriptionToken({ + required this.arc, + required this.tokenL2, + required this.phoneticL1Transcription, + }); + + factory PhoneticTranscriptionToken.fromJson(Map json) { + return PhoneticTranscriptionToken( + arc: LanguageArc.fromJson(json['arc'] as Map), + tokenL2: + PangeaTokenText.fromJson(json['token_l2'] as Map), + phoneticL1Transcription: PangeaTokenText.fromJson( + json['phonetic_l1_transcription'] as Map, + ), + ); + } + + Map toJson() => { + 'arc': arc.toJson(), + 'token_l2': tokenL2.toJson(), + 'phonetic_l1_transcription': phoneticL1Transcription.toJson(), + }; +} + +class PhoneticTranscription { + final LanguageArc arc; + final PangeaTokenText transcriptionL2; + final List phoneticTranscription; + final PhoneticTranscriptionDelimEnum delim; + + PhoneticTranscription({ + required this.arc, + required this.transcriptionL2, + required this.phoneticTranscription, + this.delim = PhoneticTranscriptionDelimEnum.sp, + }); + + factory PhoneticTranscription.fromJson(Map json) { + return PhoneticTranscription( + arc: LanguageArc.fromJson(json['arc'] as Map), + transcriptionL2: PangeaTokenText.fromJson( + json['transcription_l2'] as Map, + ), + phoneticTranscription: (json['phonetic_transcription'] as List) + .map( + (e) => + PhoneticTranscriptionToken.fromJson(e as Map), + ) + .toList(), + delim: json['delim'] != null + ? PhoneticTranscriptionDelimEnumExt.fromString( + json['delim'] as String, + ) + : PhoneticTranscriptionDelimEnum.sp, + ); + } + + Map toJson() => { + 'arc': arc.toJson(), + 'transcription_l2': transcriptionL2.toJson(), + 'phonetic_transcription': + phoneticTranscription.map((e) => e.toJson()).toList(), + 'delim': delim.value, + }; +} + class PhoneticTranscriptionResponse { - final Map arc; - final Map content; - final Map tokenization; - final Map phoneticTranscriptionResult; + final LanguageArc arc; + final PangeaTokenText content; + final Map + tokenization; // You can define a typesafe model if needed + final PhoneticTranscription phoneticTranscriptionResult; DateTime? expireAt; PhoneticTranscriptionResponse({ @@ -15,11 +114,13 @@ class PhoneticTranscriptionResponse { factory PhoneticTranscriptionResponse.fromJson(Map json) { return PhoneticTranscriptionResponse( - arc: Map.from(json['arc'] as Map), - content: Map.from(json['content'] as Map), + arc: LanguageArc.fromJson(json['arc'] as Map), + content: + PangeaTokenText.fromJson(json['content'] as Map), tokenization: Map.from(json['tokenization'] as Map), - phoneticTranscriptionResult: Map.from( - json['phonetic_transcription_result'] as Map), + phoneticTranscriptionResult: PhoneticTranscription.fromJson( + json['phonetic_transcription_result'] as Map, + ), expireAt: json['expireAt'] == null ? null : DateTime.parse(json['expireAt'] as String), @@ -28,10 +129,10 @@ class PhoneticTranscriptionResponse { Map toJson() { return { - 'arc': arc, - 'content': content, + 'arc': arc.toJson(), + 'content': content.toJson(), 'tokenization': tokenization, - 'phonetic_transcription_result': phoneticTranscriptionResult, + 'phonetic_transcription_result': phoneticTranscriptionResult.toJson(), 'expireAt': expireAt?.toIso8601String(), }; } diff --git a/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart b/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart index b8d7f0d77..abf0c8bc2 100644 --- a/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart +++ b/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart @@ -1,3 +1,4 @@ +<<<<<<< Updated upstream import 'package:flutter/material.dart'; import 'package:fluffychat/l10n/l10n.dart'; @@ -27,10 +28,51 @@ class PhoneticTranscriptionState extends State { String? error; PhoneticTranscriptionResponse? _response; +======= +import 'dart:async'; + +import 'package:fluffychat/l10n/l10n.dart'; +import 'package:fluffychat/pangea/common/utils/error_handler.dart'; +import 'package:fluffychat/pangea/events/models/pangea_token_text_model.dart'; +import 'package:fluffychat/pangea/learning_settings/models/language_model.dart'; +import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_repo.dart'; +import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_request.dart'; +import 'package:fluffychat/pangea/toolbar/controllers/tts_controller.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import 'package:flutter/material.dart'; + +class PhoneticTranscriptionWidget extends StatefulWidget { + final String text; + final LanguageModel textLanguage; + final TextStyle? style; + final double? iconSize; + + const PhoneticTranscriptionWidget({ + super.key, + required this.text, + required this.textLanguage, + this.style, + this.iconSize, + }); + + @override + State createState() => + _PhoneticTranscriptionWidgetState(); +} + +class _PhoneticTranscriptionWidgetState + extends State { + late Future _transcriptionFuture; + bool _hovering = false; + bool _isPlaying = false; + bool _isLoading = false; + late final StreamSubscription _loadingChoreoSubscription; +>>>>>>> Stashed changes @override void initState() { super.initState(); +<<<<<<< Updated upstream _fetchPhoneticTranscription(); } @@ -71,11 +113,69 @@ class PhoneticTranscriptionState extends State { _loading = false; }); } +======= + _transcriptionFuture = _fetchTranscription(); + _loadingChoreoSubscription = + TtsController.loadingChoreoStream.stream.listen((val) { + if (mounted) setState(() => _isLoading = val); + }); + } + + @override + void dispose() { + TtsController.stop(); + _loadingChoreoSubscription.cancel(); + super.dispose(); + } + + Future _fetchTranscription() async { + if (MatrixState.pangeaController.languageController.userL1 == null) { + ErrorHandler.logError( + e: Exception('User L1 is not set'), + data: { + 'text': widget.text, + 'textLanguageCode': widget.textLanguage.langCode, + }, + ); + return widget.text; // Fallback to original text if no L1 is set + } + final req = PhoneticTranscriptionRequest( + arc: LanguageArc( + l1: MatrixState.pangeaController.languageController.userL1!, + l2: widget.textLanguage, + ), + content: PangeaTokenText.fromString(widget.text), + // arc can be omitted for default empty map + ); + final res = await PhoneticTranscriptionRepo.get(req); + return res.phoneticTranscriptionResult.phoneticTranscription.first + .phoneticL1Transcription.content; + } + + Future _handleAudioTap(BuildContext context) async { + if (_isPlaying) { + await TtsController.stop(); + setState(() => _isPlaying = false); + } else { + await TtsController.tryToSpeak( + widget.text, + context: context, + targetID: 'phonetic-transcription-${widget.text}', + langCode: widget.textLanguage.langCode, + onStart: () { + if (mounted) setState(() => _isPlaying = true); + }, + onStop: () { + if (mounted) setState(() => _isPlaying = false); + }, + ); +>>>>>>> Stashed changes } } @override Widget build(BuildContext context) { +<<<<<<< Updated upstream if (error != null) { return Row( mainAxisSize: MainAxisSize.min, @@ -101,6 +201,59 @@ class PhoneticTranscriptionState extends State { return Text( 'Phonetic transcription for "${widget.text}" in ${widget.l2}', style: Theme.of(context).textTheme.bodyLarge, +======= + return FutureBuilder( + future: _transcriptionFuture, + builder: (context, snapshot) { + final transcription = snapshot.data ?? ''; + return MouseRegion( + onEnter: (_) => setState(() => _hovering = true), + onExit: (_) => setState(() => _hovering = false), + child: GestureDetector( + onTap: () => _handleAudioTap(context), + child: AnimatedContainer( + duration: const Duration(milliseconds: 150), + decoration: BoxDecoration( + color: _hovering + ? Colors.grey.withAlpha((0.2 * 255).round()) + : Colors.transparent, + borderRadius: BorderRadius.circular(6), + ), + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + transcription.isNotEmpty ? transcription : widget.text, + style: + widget.style ?? Theme.of(context).textTheme.bodyMedium, + ), + const SizedBox(width: 8), + Tooltip( + message: _isPlaying + ? L10n.of(context).stop + : L10n.of(context).playAudio, + child: _isLoading + ? const SizedBox( + width: 16, + height: 16, + child: CircularProgressIndicator(strokeWidth: 3), + ) + : Icon( + _isPlaying ? Icons.pause_outlined : Icons.volume_up, + size: widget.iconSize ?? 24, + color: _isPlaying + ? Theme.of(context).colorScheme.primary + : Theme.of(context).iconTheme.color, + ), + ), + ], + ), + ), + ), + ); + }, +>>>>>>> Stashed changes ); } } From 7756f2fe9fa4f53324471d1a7107746b8b617fda Mon Sep 17 00:00:00 2001 From: ggurdin Date: Mon, 16 Jun 2025 16:32:13 -0400 Subject: [PATCH 13/19] chore: clean up vocab analytics details popup --- lib/main.dart | 17 +-- .../vocab_analytics_details_view.dart | 30 +++-- .../models/language_model.dart | 3 +- .../phonetic_transcription_widget.dart | 108 +----------------- 4 files changed, 28 insertions(+), 130 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index b7df5a61c..d33e62b41 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,13 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + import 'package:collection/collection.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:matrix/matrix.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/common/config/environment.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; @@ -6,14 +15,6 @@ import 'package:fluffychat/pangea/common/utils/firebase_analytics.dart'; import 'package:fluffychat/pangea/learning_settings/utils/p_language_store.dart'; import 'package:fluffychat/utils/client_manager.dart'; import 'package:fluffychat/utils/platform_infos.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import 'package:get_storage/get_storage.dart'; -import 'package:matrix/matrix.dart'; -import 'package:shared_preferences/shared_preferences.dart'; - import 'config/setting_keys.dart'; import 'utils/background_push.dart'; import 'widgets/fluffy_chat_app.dart'; diff --git a/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart b/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart index c00fb1176..d472a64b1 100644 --- a/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart +++ b/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart @@ -1,4 +1,7 @@ +import 'package:flutter/material.dart'; + import 'package:collection/collection.dart'; + import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/pangea/analytics_details_popup/analytics_details_popup_content.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; @@ -9,10 +12,10 @@ import 'package:fluffychat/pangea/morphs/get_grammar_copy.dart'; import 'package:fluffychat/pangea/morphs/morph_features_enum.dart'; import 'package:fluffychat/pangea/morphs/morph_icon.dart'; import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_widget.dart'; +import 'package:fluffychat/pangea/toolbar/utils/shrinkable_text.dart'; import 'package:fluffychat/pangea/toolbar/widgets/practice_activity/word_text_with_audio_button.dart'; import 'package:fluffychat/pangea/toolbar/widgets/word_zoom/lemma_meaning_widget.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/material.dart'; /// Displays information about selected lemma, and its usage class VocabDetailsView extends StatelessWidget { @@ -52,16 +55,17 @@ class VocabDetailsView extends StatelessWidget { return AnalyticsDetailsViewContent( title: Column( - crossAxisAlignment: CrossAxisAlignment.start, children: [ - WordTextWithAudioButton( - text: _construct.lemma, - style: Theme.of(context).textTheme.headlineLarge?.copyWith( - color: textColor, - ), - iconSize: _iconSize, - uniqueID: "${_construct.lemma}-${_construct.category}", - langCode: _userL2!, + LayoutBuilder( + builder: (context, constraints) { + return ShrinkableText( + text: _construct.lemma, + maxWidth: constraints.maxWidth - 40.0, + style: Theme.of(context).textTheme.headlineLarge?.copyWith( + color: textColor, + ), + ); + }, ), if (MatrixState.pangeaController.languageController.userL2 != null) Padding( @@ -81,12 +85,6 @@ class VocabDetailsView extends StatelessWidget { ), subtitle: Column( children: [ - if (_userL1 != null && _userL2 != null) - PhoneticTranscription( - text: _construct.lemma, - l1: _userL1!, - l2: _userL2!, - ), Row( mainAxisSize: MainAxisSize.min, spacing: 8.0, diff --git a/lib/pangea/learning_settings/models/language_model.dart b/lib/pangea/learning_settings/models/language_model.dart index 6d6a03380..1e1ef69b9 100644 --- a/lib/pangea/learning_settings/models/language_model.dart +++ b/lib/pangea/learning_settings/models/language_model.dart @@ -1,7 +1,8 @@ +import 'package:flutter/material.dart'; + import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart'; import 'package:fluffychat/pangea/learning_settings/enums/l2_support_enum.dart'; -import 'package:flutter/material.dart'; class LanguageModel { final String langCode; diff --git a/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart b/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart index abf0c8bc2..d55695dc2 100644 --- a/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart +++ b/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart @@ -1,36 +1,7 @@ -<<<<<<< Updated upstream -import 'package:flutter/material.dart'; - -import 'package:fluffychat/l10n/l10n.dart'; -import 'package:fluffychat/pangea/common/utils/error_handler.dart'; -import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_repo.dart'; -import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_request.dart'; -import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_response.dart'; - -class PhoneticTranscription extends StatefulWidget { - final String text; - final String l1; - final String l2; - - const PhoneticTranscription({ - super.key, - required this.text, - required this.l1, - required this.l2, - }); - - @override - State createState() => PhoneticTranscriptionState(); -} - -class PhoneticTranscriptionState extends State { - bool _loading = false; - String? error; - - PhoneticTranscriptionResponse? _response; -======= import 'dart:async'; +import 'package:flutter/material.dart'; + import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_text_model.dart'; @@ -39,7 +10,6 @@ import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_ import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_request.dart'; import 'package:fluffychat/pangea/toolbar/controllers/tts_controller.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/material.dart'; class PhoneticTranscriptionWidget extends StatefulWidget { final String text; @@ -67,53 +37,10 @@ class _PhoneticTranscriptionWidgetState bool _isPlaying = false; bool _isLoading = false; late final StreamSubscription _loadingChoreoSubscription; ->>>>>>> Stashed changes @override void initState() { super.initState(); -<<<<<<< Updated upstream - _fetchPhoneticTranscription(); - } - - @override - void didUpdateWidget(covariant PhoneticTranscription oldWidget) { - super.didUpdateWidget(oldWidget); - if (oldWidget.text != widget.text || - oldWidget.l1 != widget.l1 || - oldWidget.l2 != widget.l2) { - _fetchPhoneticTranscription(); - } - } - - Future _fetchPhoneticTranscription() async { - final PhoneticTranscriptionRequest request = PhoneticTranscriptionRequest( - l1: widget.l1, - l2: widget.l2, - content: widget.text, - ); - - try { - setState(() { - _loading = true; - error = null; - }); - - _response = await PhoneticTranscriptionRepo.get(request); - } catch (e, s) { - ErrorHandler.logError( - e: e, - s: s, - data: request.toJson(), - ); - error = e.toString(); - } finally { - if (mounted) { - setState(() { - _loading = false; - }); - } -======= _transcriptionFuture = _fetchTranscription(); _loadingChoreoSubscription = TtsController.loadingChoreoStream.stream.listen((val) { @@ -169,39 +96,11 @@ class _PhoneticTranscriptionWidgetState if (mounted) setState(() => _isPlaying = false); }, ); ->>>>>>> Stashed changes } } @override Widget build(BuildContext context) { -<<<<<<< Updated upstream - if (error != null) { - return Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon( - Icons.error_outline, - color: Theme.of(context).colorScheme.error, - size: 16.0, - ), - const SizedBox(width: 8), - Text( - L10n.of(context).phoneticTranscriptionError, - style: Theme.of(context).textTheme.bodyLarge, - ), - ], - ); - } - - if (_loading || _response == null) { - return const Center(child: CircularProgressIndicator.adaptive()); - } - - return Text( - 'Phonetic transcription for "${widget.text}" in ${widget.l2}', - style: Theme.of(context).textTheme.bodyLarge, -======= return FutureBuilder( future: _transcriptionFuture, builder: (context, snapshot) { @@ -224,7 +123,7 @@ class _PhoneticTranscriptionWidgetState mainAxisSize: MainAxisSize.min, children: [ Text( - transcription.isNotEmpty ? transcription : widget.text, + "/${transcription.isNotEmpty ? transcription : widget.text}/", style: widget.style ?? Theme.of(context).textTheme.bodyMedium, ), @@ -253,7 +152,6 @@ class _PhoneticTranscriptionWidgetState ), ); }, ->>>>>>> Stashed changes ); } } From c4b582c93f37272c839b45cf08f8c4a36eddc0b5 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Mon, 16 Jun 2025 16:51:18 -0400 Subject: [PATCH 14/19] chore: add phonetic transcription to audio message toolbar --- .../phonetic_transcription_widget.dart | 10 +++-- .../toolbar/widgets/overlay_message.dart | 39 +++++++++++++++---- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart b/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart index d55695dc2..0e7c69f74 100644 --- a/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart +++ b/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart @@ -122,10 +122,12 @@ class _PhoneticTranscriptionWidgetState child: Row( mainAxisSize: MainAxisSize.min, children: [ - Text( - "/${transcription.isNotEmpty ? transcription : widget.text}/", - style: - widget.style ?? Theme.of(context).textTheme.bodyMedium, + Flexible( + child: Text( + "/${transcription.isNotEmpty ? transcription : widget.text}/", + style: widget.style ?? + Theme.of(context).textTheme.bodyMedium, + ), ), const SizedBox(width: 8), Tooltip( diff --git a/lib/pangea/toolbar/widgets/overlay_message.dart b/lib/pangea/toolbar/widgets/overlay_message.dart index b6633b0c6..aa3300f3c 100644 --- a/lib/pangea/toolbar/widgets/overlay_message.dart +++ b/lib/pangea/toolbar/widgets/overlay_message.dart @@ -10,6 +10,9 @@ import 'package:fluffychat/pages/chat/events/message_content.dart'; import 'package:fluffychat/pages/chat/events/reply_content.dart'; import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart'; import 'package:fluffychat/pangea/events/extensions/pangea_event_extension.dart'; +import 'package:fluffychat/pangea/learning_settings/models/language_model.dart'; +import 'package:fluffychat/pangea/learning_settings/utils/p_language_store.dart'; +import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_widget.dart'; import 'package:fluffychat/pangea/toolbar/enums/reading_assistance_mode_enum.dart'; import 'package:fluffychat/pangea/toolbar/widgets/message_selection_overlay.dart'; import 'package:fluffychat/utils/date_time_extension.dart'; @@ -170,14 +173,34 @@ class OverlayMessage extends StatelessWidget { ) : overlayController.transcription != null ? SingleChildScrollView( - child: Text( - overlayController.transcription!.transcript.text, - style: AppConfig.messageTextStyle( - event, - textColor, - ).copyWith( - fontStyle: FontStyle.italic, - ), + child: Column( + spacing: 8.0, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + overlayController + .transcription!.transcript.text, + style: AppConfig.messageTextStyle( + event, + textColor, + ).copyWith( + fontStyle: FontStyle.italic, + ), + ), + PhoneticTranscriptionWidget( + text: overlayController + .transcription!.transcript.text, + textLanguage: PLanguageStore.byLangCode( + pangeaMessageEvent! + .messageDisplayLangCode, + ) ?? + LanguageModel.unknown, + style: AppConfig.messageTextStyle( + event, + textColor, + ), + ), + ], ), ) : Row( From 5f535a9d95d9fc8c3e56bbdbbd53e1628074b369 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Mon, 16 Jun 2025 16:56:29 -0400 Subject: [PATCH 15/19] chore: remove background color from emoji reactions --- lib/pages/chat/events/message_reactions.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/pages/chat/events/message_reactions.dart b/lib/pages/chat/events/message_reactions.dart index e34dad9a0..b3afbef60 100644 --- a/lib/pages/chat/events/message_reactions.dart +++ b/lib/pages/chat/events/message_reactions.dart @@ -158,7 +158,9 @@ class _Reaction extends StatelessWidget { borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2), child: Container( decoration: BoxDecoration( - color: color, + // #Pangea + // color: color, + // Pangea# borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2), ), padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2), From fdf30b3462d73e9f31f2ae073a53f2652b073308 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Tue, 17 Jun 2025 09:32:47 -0400 Subject: [PATCH 16/19] chore: update presence avatar when user ID changes, go right to knocking members filter from knocking users indicator --- lib/config/routes.dart | 3 ++ lib/l10n/intl_en.arb | 12 +++++- lib/pages/chat_members/chat_members.dart | 37 ++++++++++++++++++- .../widgets/knocking_users_indicator.dart | 8 ++-- .../widgets/leaderboard_participant_list.dart | 5 ++- lib/widgets/presence_builder.dart | 18 +++++++++ 6 files changed, 77 insertions(+), 6 deletions(-) diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 1b647b2ae..e7fb1d376 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -653,6 +653,9 @@ abstract class AppRoutes { state, ChatMembersPage( roomId: state.pathParameters['roomid']!, + // #Pangea + filter: state.uri.queryParameters['filter'], + // Pangea# ), ), redirect: loggedOutRedirect, diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 09c40f998..813eb9c76 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -5017,5 +5017,15 @@ "newDirectMessage": "New direct message", "speakingExercisesTooltip": "Speaking practice", "noChatsFoundHereYet": "No chats found here yet", - "transcriptionFailed": "Failed to transcribe audio" + "transcriptionFailed": "Failed to transcribe audio", + "aUserIsKnocking": "1 user is requesting to join your space", + "usersAreKnocking": "{users} users are requesting to join your space", + "@usersAreKnocking": { + "type": "int", + "placeholders": { + "users": { + "type": "int" + } + } + } } \ No newline at end of file diff --git a/lib/pages/chat_members/chat_members.dart b/lib/pages/chat_members/chat_members.dart index 6376a9b2c..8fd3df8be 100644 --- a/lib/pages/chat_members/chat_members.dart +++ b/lib/pages/chat_members/chat_members.dart @@ -9,8 +9,18 @@ import 'chat_members_view.dart'; class ChatMembersPage extends StatefulWidget { final String roomId; + // #Pangea + final String? filter; + // Pangea# - const ChatMembersPage({required this.roomId, super.key}); + // #Pangea + // const ChatMembersPage({required this.roomId, super.key}); + const ChatMembersPage({ + required this.roomId, + this.filter, + super.key, + }); + // Pangea# @override State createState() => ChatMembersController(); @@ -24,6 +34,22 @@ class ChatMembersController extends State { final TextEditingController filterController = TextEditingController(); + // #Pangea + @override + void didUpdateWidget(ChatMembersPage oldWidget) { + super.didUpdateWidget(oldWidget); + // Update the membership filter if the widget's filter changes + if (oldWidget.filter != widget.filter) { + setState(() { + membershipFilter = Membership.values.firstWhere( + (membership) => membership.name == widget.filter, + orElse: () => Membership.join, + ); + }); + } + } + // Pangea# + void setMembershipFilter(Membership membership) { membershipFilter = membership; setFilter(); @@ -110,6 +136,15 @@ class ChatMembersController extends State { false, ) .listen(refreshMembers); + + // #Pangea + if (widget.filter != null) { + membershipFilter = Membership.values.firstWhere( + (membership) => membership.name == widget.filter, + orElse: () => Membership.join, + ); + } + // Pangea# } @override diff --git a/lib/pangea/spaces/widgets/knocking_users_indicator.dart b/lib/pangea/spaces/widgets/knocking_users_indicator.dart index 76cc30959..b40519584 100644 --- a/lib/pangea/spaces/widgets/knocking_users_indicator.dart +++ b/lib/pangea/spaces/widgets/knocking_users_indicator.dart @@ -7,6 +7,7 @@ import 'package:matrix/matrix.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; +import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/utils/stream_extension.dart'; @@ -89,15 +90,16 @@ class KnockingUsersIndicatorState extends State { Expanded( child: Text( _knockingUsers.length == 1 - ? "1 user is requesting to join your space" - : "${_knockingUsers.length} users are requesting to join your space", + ? L10n.of(context).aUserIsKnocking + : L10n.of(context) + .usersAreKnocking(_knockingUsers.length), style: Theme.of(context).textTheme.bodyMedium, ), ), ], ), onTap: () => context.push( - "/rooms/${widget.room.id}/details/members", + "/rooms/${widget.room.id}/details/members?filter=knock", ), ), ), diff --git a/lib/pangea/spaces/widgets/leaderboard_participant_list.dart b/lib/pangea/spaces/widgets/leaderboard_participant_list.dart index 347d12cd2..c9906cea9 100644 --- a/lib/pangea/spaces/widgets/leaderboard_participant_list.dart +++ b/lib/pangea/spaces/widgets/leaderboard_participant_list.dart @@ -48,7 +48,10 @@ class LeaderboardParticipantListState return LoadParticipantsUtil( space: widget.space, builder: (participantsLoader) { - final participants = participantsLoader.filteredParticipants(""); + final participants = participantsLoader + .filteredParticipants("") + .where((p) => p.membership == Membership.join) + .toList(); return AnimatedSize( duration: FluffyThemes.animationDuration, diff --git a/lib/widgets/presence_builder.dart b/lib/widgets/presence_builder.dart index 2f1a66d77..4332485ab 100644 --- a/lib/widgets/presence_builder.dart +++ b/lib/widgets/presence_builder.dart @@ -48,6 +48,24 @@ class _PresenceBuilderState extends State { } } + // #Pangea + @override + void didUpdateWidget(PresenceBuilder oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.userId == widget.userId) return; + + final client = widget.client ?? Matrix.of(context).client; + final userId = widget.userId; + if (userId != null) { + client.fetchCurrentPresence(userId).then(_updatePresence); + _sub?.cancel(); + _sub = client.onPresenceChanged.stream + .where((presence) => presence.userid == userId) + .listen(_updatePresence); + } + } + // Pangea# + @override void dispose() { _sub?.cancel(); From 9e9d9d3b66e669eb6bda9c1c9fead78e997da167 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Tue, 17 Jun 2025 10:21:57 -0400 Subject: [PATCH 17/19] chore: prevent getting stuck in chat members with no filters --- lib/pages/chat_members/chat_members.dart | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/pages/chat_members/chat_members.dart b/lib/pages/chat_members/chat_members.dart index 8fd3df8be..971b538f4 100644 --- a/lib/pages/chat_members/chat_members.dart +++ b/lib/pages/chat_members/chat_members.dart @@ -105,6 +105,19 @@ class ChatMembersController extends State { if (!mounted) return; + // #Pangea + final availableFilters = (participants ?? []) + .map( + (p) => p.membership, + ) + .toSet(); + + if (availableFilters.length == 1 && + membershipFilter != availableFilters.first) { + membershipFilter = availableFilters.first; + } + // Pangea# + setState(() { members = participants; }); From 161fd570050154944dc8aa825f649879552e2b62 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Tue, 17 Jun 2025 10:41:00 -0400 Subject: [PATCH 18/19] chore: fix position of unread label in nav rail --- lib/pages/chat_list/navi_rail_item.dart | 68 ++++++++++++++----------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/lib/pages/chat_list/navi_rail_item.dart b/lib/pages/chat_list/navi_rail_item.dart index a68112cf8..492804381 100644 --- a/lib/pages/chat_list/navi_rail_item.dart +++ b/lib/pages/chat_list/navi_rail_item.dart @@ -89,39 +89,45 @@ class NaviRailItem extends StatelessWidget { // color: isSelected // ? theme.colorScheme.primaryContainer // : theme.colorScheme.surfaceContainerHigh, - child: Container( - alignment: Alignment.center, - decoration: BoxDecoration( - color: backgroundColor ?? - (isSelected - ? theme.colorScheme.primaryContainer - : theme.colorScheme.surfaceContainerHigh), - borderRadius: borderRadius, + child: UnreadRoomsBadge( + filter: unreadBadgeFilter ?? (_) => false, + badgePosition: BadgePosition.topEnd( + top: -4, + end: isColumnMode ? 8 : 4, ), - margin: EdgeInsets.symmetric( - horizontal: isColumnMode ? 16.0 : 12.0, - vertical: isColumnMode ? 8.0 : 6.0, - ), - // Pangea# - child: Tooltip( - message: toolTip, - child: InkWell( + child: Container( + alignment: Alignment.center, + decoration: BoxDecoration( + color: backgroundColor ?? + (isSelected + ? theme.colorScheme.primaryContainer + : theme.colorScheme.surfaceContainerHigh), borderRadius: borderRadius, - onTap: onTap, - child: unreadBadgeFilter == null - ? icon - : UnreadRoomsBadge( - filter: unreadBadgeFilter, - badgePosition: BadgePosition.topEnd( - // #Pangea - // top: -12, - // end: -8, - top: -20, - end: -16, - // Pangea# - ), - child: icon, - ), + ), + margin: EdgeInsets.symmetric( + horizontal: isColumnMode ? 16.0 : 12.0, + vertical: isColumnMode ? 8.0 : 6.0, + ), + // Pangea# + child: Tooltip( + message: toolTip, + child: InkWell( + borderRadius: borderRadius, + onTap: onTap, + // #Pangea + child: icon, + // child: unreadBadgeFilter == null + // ? icon + // : UnreadRoomsBadge( + // filter: unreadBadgeFilter, + // badgePosition: BadgePosition.topEnd( + // top: -12, + // end: -8, + // ), + // child: icon, + // ), + // Pangea# + ), ), ), ), From 684a9bd16e2dbf231b87568df10b83fad28119eb Mon Sep 17 00:00:00 2001 From: ggurdin Date: Tue, 17 Jun 2025 10:49:32 -0400 Subject: [PATCH 19/19] chore: make text size match for matrix pill widget --- lib/pages/chat/events/html_message.dart | 10 ++++++++-- lib/pangea/toolbar/utils/token_rendering_util.dart | 6 +++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/pages/chat/events/html_message.dart b/lib/pages/chat/events/html_message.dart index d7af1008f..ddfa041b3 100644 --- a/lib/pages/chat/events/html_message.dart +++ b/lib/pages/chat/events/html_message.dart @@ -407,7 +407,10 @@ class HtmlMessage extends StatelessWidget { avatar: user.avatarUrl, uri: href, outerContext: context, - fontSize: fontSize, + // #Pangea + // fontSize: fontSize, + fontSize: renderer.fontSize(context), + // Pangea# color: linkStyle.color, // #Pangea userId: user.id, @@ -428,7 +431,10 @@ class HtmlMessage extends StatelessWidget { avatar: room?.avatar, uri: href, outerContext: context, - fontSize: fontSize, + // #Pangea + // fontSize: fontSize, + fontSize: renderer.fontSize(context), + // Pangea# color: linkStyle.color, ), ); diff --git a/lib/pangea/toolbar/utils/token_rendering_util.dart b/lib/pangea/toolbar/utils/token_rendering_util.dart index d6d2cc27f..8efbeeedc 100644 --- a/lib/pangea/toolbar/utils/token_rendering_util.dart +++ b/lib/pangea/toolbar/utils/token_rendering_util.dart @@ -27,7 +27,7 @@ class TokenRenderingUtil { return readingAssistanceMode == ReadingAssistanceMode.transitionMode; } - double? _fontSize(BuildContext context) => showCenterStyling + double? fontSize(BuildContext context) => showCenterStyling ? overlayController != null && overlayController!.maxWidth > 600 ? Theme.of(context).textTheme.titleLarge?.fontSize : Theme.of(context).textTheme.bodyLarge?.fontSize @@ -38,14 +38,14 @@ class TokenRenderingUtil { Color? color, }) => existingStyle.copyWith( - fontSize: _fontSize(context), + fontSize: fontSize(context), decoration: TextDecoration.underline, decorationThickness: 4, decorationColor: color ?? Colors.white.withAlpha(0), ); double tokenTextWidthForContainer(BuildContext context, String text) { - final tokenSizeKey = "$text-${_fontSize(context)}"; + final tokenSizeKey = "$text-${fontSize(context)}"; if (_tokensWidthCache.containsKey(tokenSizeKey)) { return _tokensWidthCache[tokenSizeKey]!; }