From af9ffe79d79c97d45d8623f22df470d373e460c0 Mon Sep 17 00:00:00 2001 From: WilsonLe Date: Thu, 10 Oct 2024 15:23:34 +1100 Subject: [PATCH 01/16] fix multiple empty chat --- lib/pangea/constants/bot_mode.dart | 1 + lib/pangea/controllers/pangea_controller.dart | 55 +++++++++++++++---- .../pangea_room_extension.dart | 3 +- .../room_information_extension.dart | 5 +- .../conversation_bot_settings.dart | 4 +- 5 files changed, 51 insertions(+), 17 deletions(-) diff --git a/lib/pangea/constants/bot_mode.dart b/lib/pangea/constants/bot_mode.dart index 96aa51e72..fbdd24b6f 100644 --- a/lib/pangea/constants/bot_mode.dart +++ b/lib/pangea/constants/bot_mode.dart @@ -1,4 +1,5 @@ class BotMode { + static const direct = "direct"; static const discussion = "discussion"; static const custom = "custom"; static const storyGame = "story_game"; diff --git a/lib/pangea/controllers/pangea_controller.dart b/lib/pangea/controllers/pangea_controller.dart index 87552955f..fbb23845c 100644 --- a/lib/pangea/controllers/pangea_controller.dart +++ b/lib/pangea/controllers/pangea_controller.dart @@ -20,7 +20,6 @@ import 'package:fluffychat/pangea/controllers/subscription_controller.dart'; import 'package:fluffychat/pangea/controllers/text_to_speech_controller.dart'; import 'package:fluffychat/pangea/controllers/user_controller.dart'; import 'package:fluffychat/pangea/controllers/word_net_controller.dart'; -import 'package:fluffychat/pangea/extensions/client_extension/client_extension.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; import 'package:fluffychat/pangea/guard/p_vguard.dart'; import 'package:fluffychat/pangea/utils/bot_name.dart'; @@ -193,19 +192,53 @@ class PangeaController { void startChatWithBotIfNotPresent() { Future.delayed(const Duration(milliseconds: 10000), () async { // check if user is logged in - if (!matrixState.client.isLogged() || - (await matrixState.client.hasBotDM)) { + if (!matrixState.client.isLogged()) { return; } - try { - await matrixState.client.startDirectChat( - BotName.byEnvironment, - enableEncryption: false, - ); - } catch (err, stack) { - debugger(when: kDebugMode); - ErrorHandler.logError(e: err, s: stack); + const List botDMs = []; + for (final room in matrixState.client.rooms) { + if (await room.isBotDM) { + botDMs.add(room); + } + } + + if (botDMs.isEmpty) { + try { + await matrixState.client.startDirectChat( + BotName.byEnvironment, + enableEncryption: false, + ); + } catch (err, stack) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: stack); + } + return; + } + + final Room botDMWithLatestActivity = botDMs.reduce((a, b) { + if (a.timeline == null || b.timeline == null) { + return a; + } + final aLastEvent = a.timeline!.events.last; + final bLastEvent = b.timeline!.events.last; + return aLastEvent.originServerTs.isAfter(bLastEvent.originServerTs) + ? a + : b; + }); + + for (final room in botDMs) { + if (room.id != botDMWithLatestActivity.id) { + await room.leave(); + continue; + } + } + + final participants = await botDMWithLatestActivity.requestParticipants(); + final joinedParticipants = + participants.where((e) => e.membership == Membership.join).toList(); + if (joinedParticipants.length < 2) { + await botDMWithLatestActivity.invite(BotName.byEnvironment); } }); } diff --git a/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart b/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart index bf9e10953..813fb7f1c 100644 --- a/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart @@ -4,6 +4,7 @@ import 'dart:developer'; import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:collection/collection.dart'; +import 'package:fluffychat/pangea/constants/bot_mode.dart'; import 'package:fluffychat/pangea/constants/class_default_values.dart'; import 'package:fluffychat/pangea/constants/language_constants.dart'; import 'package:fluffychat/pangea/constants/model_keys.dart'; @@ -253,7 +254,7 @@ extension PangeaRoom on Room { // bool isMadeForLang(String langCode) => _isMadeForLang(langCode); - Future get isBotRoom async => await _isBotRoom; + Future get botIsInRoom async => await _botIsInRoom; Future get isBotDM async => await _isBotDM; diff --git a/lib/pangea/extensions/pangea_room_extension/room_information_extension.dart b/lib/pangea/extensions/pangea_room_extension/room_information_extension.dart index 857ac26e0..a88551336 100644 --- a/lib/pangea/extensions/pangea_room_extension/room_information_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/room_information_extension.dart @@ -49,15 +49,14 @@ extension RoomInformationRoomExtension on Room { // creationContent?.tryGet(ModelKey.oldLangCode) == langCode; // } - Future get _isBotRoom async { + Future get _botIsInRoom async { final List participants = await requestParticipants(); return participants.any( (User user) => user.id == BotName.byEnvironment, ); } - Future get _isBotDM async => - (await isBotRoom) && getParticipants().length == 2; + Future get _isBotDM async => botOptions?.mode == BotMode.direct; bool get _isLocked { if (isDirectChat) return false; diff --git a/lib/pangea/widgets/conversation_bot/conversation_bot_settings.dart b/lib/pangea/widgets/conversation_bot/conversation_bot_settings.dart index 288149d76..fe85b48c7 100644 --- a/lib/pangea/widgets/conversation_bot/conversation_bot_settings.dart +++ b/lib/pangea/widgets/conversation_bot/conversation_bot_settings.dart @@ -46,7 +46,7 @@ class ConversationBotSettingsState extends State { botOptions = widget.room?.botOptions != null ? BotOptionsModel.fromJson(widget.room?.botOptions?.toJson()) : BotOptionsModel(); - widget.room?.isBotRoom.then((bool isBotRoom) { + widget.room?.botIsInRoom.then((bool isBotRoom) { setState(() { addBot = isBotRoom; }); @@ -260,7 +260,7 @@ class ConversationBotSettingsState extends State { botOptions = botOptions; }); final bool isBotRoomMember = - await widget.room?.isBotRoom ?? false; + await widget.room?.botIsInRoom ?? false; if (addBot && !isBotRoomMember) { await widget.room?.invite(BotName.byEnvironment); } else if (!addBot && isBotRoomMember) { From 18d2399c542b936c3257612722f482e82522af80 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Fri, 11 Oct 2024 10:53:42 -0400 Subject: [PATCH 02/16] add activity feedback to activity request hashcode to ensure new activity is fetched after giving feedback --- .../message_activity_request.dart | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/pangea/models/practice_activities.dart/message_activity_request.dart b/lib/pangea/models/practice_activities.dart/message_activity_request.dart index db57d01aa..458619d20 100644 --- a/lib/pangea/models/practice_activities.dart/message_activity_request.dart +++ b/lib/pangea/models/practice_activities.dart/message_activity_request.dart @@ -156,6 +156,20 @@ class ActivityQualityFeedback { 'bad_activity': badActivity.toJson(), }; } + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is ActivityQualityFeedback && + other.feedbackText == feedbackText && + other.badActivity == badActivity; + } + + @override + int get hashCode { + return feedbackText.hashCode ^ badActivity.hashCode; + } } class MessageActivityRequest { @@ -231,7 +245,9 @@ class MessageActivityRequest { @override int get hashCode { - return messageId.hashCode ^ const ListEquality().hash(tokensWithXP); + return messageId.hashCode ^ + const ListEquality().hash(tokensWithXP) ^ + activityQualityFeedback.hashCode; } } From 86dcf2241181addb2b5f126128f39193054ea26b Mon Sep 17 00:00:00 2001 From: ggurdin Date: Fri, 11 Oct 2024 12:21:09 -0400 Subject: [PATCH 03/16] center text in inline tooltip --- lib/pangea/utils/inline_tooltip.dart | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/pangea/utils/inline_tooltip.dart b/lib/pangea/utils/inline_tooltip.dart index f0d95c6f7..bef617b98 100644 --- a/lib/pangea/utils/inline_tooltip.dart +++ b/lib/pangea/utils/inline_tooltip.dart @@ -40,13 +40,15 @@ class InlineTooltip extends StatelessWidget { const SizedBox(width: 8), // Text in the middle Expanded( - child: Text( - instructionsEnum.body(context), - style: TextStyle( - color: Theme.of(context).colorScheme.onSurface, - height: 1.5, + child: Center( + child: Text( + instructionsEnum.body(context), + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface, + height: 1.5, + ), + textAlign: TextAlign.left, ), - textAlign: TextAlign.left, ), ), // Close button on the right From e5da017cc055364ae61e316d0251672e529e0598 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Fri, 11 Oct 2024 13:19:10 -0400 Subject: [PATCH 04/16] preset all new room to public to disable encryption --- lib/pages/chat_list/space_view.dart | 9 ++++++--- lib/pages/new_space/new_space.dart | 9 ++++++--- lib/pages/user_bottom_sheet/user_bottom_sheet.dart | 7 ++++++- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index 589c0341c..12d38b1fc 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -384,9 +384,12 @@ class _SpaceViewState extends State { } else { roomId = await client.createGroupChat( groupName: names.first, - preset: activeSpace.joinRules == JoinRules.public - ? CreateRoomPreset.publicChat - : CreateRoomPreset.privateChat, + // #Pangea + // preset: activeSpace.joinRules == JoinRules.public + // ? CreateRoomPreset.publicChat + // : CreateRoomPreset.privateChat, + preset: CreateRoomPreset.publicChat, + // Pangea# visibility: activeSpace.joinRules == JoinRules.public ? sdk.Visibility.public : sdk.Visibility.private, diff --git a/lib/pages/new_space/new_space.dart b/lib/pages/new_space/new_space.dart index a9a051063..0b1faf674 100644 --- a/lib/pages/new_space/new_space.dart +++ b/lib/pages/new_space/new_space.dart @@ -152,9 +152,12 @@ class NewSpaceController extends State { avatarUrl ??= avatar == null ? null : await client.uploadContent(avatar); final spaceId = await client.createRoom( - preset: publicGroup - ? sdk.CreateRoomPreset.publicChat - : sdk.CreateRoomPreset.privateChat, + // #Pangea + // preset: publicGroup + // ? sdk.CreateRoomPreset.publicChat + // : sdk.CreateRoomPreset.privateChat, + preset: sdk.CreateRoomPreset.publicChat, + // Pangea# creationContent: {'type': RoomCreationTypes.mSpace}, visibility: publicGroup ? sdk.Visibility.public : null, // #Pangea diff --git a/lib/pages/user_bottom_sheet/user_bottom_sheet.dart b/lib/pages/user_bottom_sheet/user_bottom_sheet.dart index 7a19043e8..786727cf8 100644 --- a/lib/pages/user_bottom_sheet/user_bottom_sheet.dart +++ b/lib/pages/user_bottom_sheet/user_bottom_sheet.dart @@ -255,7 +255,12 @@ class UserBottomSheetController extends State { sendError = null; }); try { - final roomId = await client.startDirectChat(userId); + final roomId = await client.startDirectChat( + userId, + // #Pangea + enableEncryption: false, + // Pangea# + ); if (!mounted) return; final room = client.getRoomById(roomId); if (room == null) { From b630d5f1d21604e55a4228ac3f73ce0b2c9c439b Mon Sep 17 00:00:00 2001 From: ggurdin Date: Fri, 11 Oct 2024 15:37:02 -0400 Subject: [PATCH 05/16] if send transcription file fails, don't show error audio message in timeline --- .../matrix_sdk_extensions/filtered_timeline_extension.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/utils/matrix_sdk_extensions/filtered_timeline_extension.dart b/lib/utils/matrix_sdk_extensions/filtered_timeline_extension.dart index 612f18f57..a1ed7b230 100644 --- a/lib/utils/matrix_sdk_extensions/filtered_timeline_extension.dart +++ b/lib/utils/matrix_sdk_extensions/filtered_timeline_extension.dart @@ -21,6 +21,9 @@ extension IsStateExtension on Event { (isState || !AppConfig.hideAllStateEvents) && // #Pangea content.tryGet(ModelKey.transcription) == null && + ((unsigned?['extra_content'] + as Map?)?[ModelKey.transcription] == + null) && // hide unimportant state events (!AppConfig.hideUnimportantStateEvents || !isState || From 061fd361a66a2499084827bba4ce8ace62409af8 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Fri, 11 Oct 2024 15:38:30 -0400 Subject: [PATCH 06/16] added comment explaining purpose of filter --- .../matrix_sdk_extensions/filtered_timeline_extension.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/utils/matrix_sdk_extensions/filtered_timeline_extension.dart b/lib/utils/matrix_sdk_extensions/filtered_timeline_extension.dart index a1ed7b230..a98209ce0 100644 --- a/lib/utils/matrix_sdk_extensions/filtered_timeline_extension.dart +++ b/lib/utils/matrix_sdk_extensions/filtered_timeline_extension.dart @@ -21,6 +21,8 @@ extension IsStateExtension on Event { (isState || !AppConfig.hideAllStateEvents) && // #Pangea content.tryGet(ModelKey.transcription) == null && + // if sending of transcription fails, + // don't show it as a errored audio event in timeline. ((unsigned?['extra_content'] as Map?)?[ModelKey.transcription] == null) && From fe6836d627a0848aeca1281924462dab969e741a Mon Sep 17 00:00:00 2001 From: ggurdin Date: Fri, 11 Oct 2024 15:40:18 -0400 Subject: [PATCH 07/16] exit getPracticeActivity early if finished is true --- .../controllers/practice_activity_generation_controller.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/pangea/controllers/practice_activity_generation_controller.dart b/lib/pangea/controllers/practice_activity_generation_controller.dart index 0e021f205..1d3c7f7ae 100644 --- a/lib/pangea/controllers/practice_activity_generation_controller.dart +++ b/lib/pangea/controllers/practice_activity_generation_controller.dart @@ -118,6 +118,11 @@ class PracticeGenerationController { requestModel: req, ); + if (res.finished) { + debugPrint('Activity generation finished'); + return null; + } + // if the server points to an existing event, return that event if (res.existingActivityEventId != null) { final Event? existingEvent = From e7781786382c1ac57131c4655face0e1fa059ca2 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Fri, 11 Oct 2024 15:41:01 -0400 Subject: [PATCH 08/16] in submitFeedback, only set currentActivity to null on error --- .../practice_activity/practice_activity_card.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/pangea/widgets/practice_activity/practice_activity_card.dart b/lib/pangea/widgets/practice_activity/practice_activity_card.dart index ab4f59451..7e80e2aaa 100644 --- a/lib/pangea/widgets/practice_activity/practice_activity_card.dart +++ b/lib/pangea/widgets/practice_activity/practice_activity_card.dart @@ -248,12 +248,13 @@ class MessagePracticeActivityCardState extends State { 'record': currentCompletionRecord, }, ); + + // clear the current activity and record + currentActivity = null; + currentCompletionRecord = null; + widget.overlayController.exitPracticeFlow(); }); - - // clear the current activity and record - currentActivity = null; - currentCompletionRecord = null; } RepresentationEvent? get representation => From eed898719613b1ed08a0adec7d74b2deec61cf72 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Fri, 11 Oct 2024 15:41:48 -0400 Subject: [PATCH 09/16] make MessageToolbar stateless --- lib/pangea/widgets/chat/message_toolbar.dart | 55 +++++++------------- 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/lib/pangea/widgets/chat/message_toolbar.dart b/lib/pangea/widgets/chat/message_toolbar.dart index 704338764..006b4e98d 100644 --- a/lib/pangea/widgets/chat/message_toolbar.dart +++ b/lib/pangea/widgets/chat/message_toolbar.dart @@ -19,7 +19,7 @@ import 'package:flutter/material.dart'; const double minCardHeight = 70; -class MessageToolbar extends StatefulWidget { +class MessageToolbar extends StatelessWidget { final PangeaMessageEvent pangeaMessageEvent; final MessageOverlayController overLayController; @@ -29,55 +29,45 @@ class MessageToolbar extends StatefulWidget { required this.overLayController, }); - @override - MessageToolbarState createState() => MessageToolbarState(); -} - -class MessageToolbarState extends State { - @override - void initState() { - super.initState(); - } - Widget get toolbarContent { final bool subscribed = MatrixState.pangeaController.subscriptionController.isSubscribed; if (!subscribed) { return MessageUnsubscribedCard( - controller: widget.overLayController, + controller: overLayController, ); } - switch (widget.overLayController.toolbarMode) { + switch (overLayController.toolbarMode) { case MessageMode.translation: return MessageTranslationCard( - messageEvent: widget.pangeaMessageEvent, - selection: widget.overLayController.selectedSpan, + messageEvent: pangeaMessageEvent, + selection: overLayController.selectedSpan, ); case MessageMode.textToSpeech: return MessageAudioCard( - messageEvent: widget.pangeaMessageEvent, - overlayController: widget.overLayController, + messageEvent: pangeaMessageEvent, + overlayController: overLayController, ); case MessageMode.speechToText: return MessageSpeechToTextCard( - messageEvent: widget.pangeaMessageEvent, + messageEvent: pangeaMessageEvent, ); case MessageMode.definition: - if (!widget.overLayController.isSelection) { + if (!overLayController.isSelection) { return const SelectToDefine(); } else { try { - final selectedText = widget.overLayController.targetText; + final selectedText = overLayController.targetText; return WordDataCard( word: selectedText, - wordLang: widget.pangeaMessageEvent.messageDisplayLangCode, - fullText: widget.pangeaMessageEvent.messageDisplayText, - fullTextLang: widget.pangeaMessageEvent.messageDisplayLangCode, + wordLang: pangeaMessageEvent.messageDisplayLangCode, + fullText: pangeaMessageEvent.messageDisplayText, + fullTextLang: pangeaMessageEvent.messageDisplayLangCode, hasInfo: true, - room: widget.overLayController.widget.chatController.room, + room: overLayController.widget.chatController.room, ); } catch (e, s) { debugger(when: kDebugMode); @@ -85,8 +75,8 @@ class MessageToolbarState extends State { e: "Error in WordDataCard", s: s, data: { - "word": widget.overLayController.targetText, - "fullText": widget.pangeaMessageEvent.messageDisplayText, + "word": overLayController.targetText, + "fullText": pangeaMessageEvent.messageDisplayText, }, ); return const SizedBox(); @@ -94,30 +84,25 @@ class MessageToolbarState extends State { } case MessageMode.practiceActivity: return PracticeActivityCard( - pangeaMessageEvent: widget.pangeaMessageEvent, - overlayController: widget.overLayController, + pangeaMessageEvent: pangeaMessageEvent, + overlayController: overLayController, ); default: debugger(when: kDebugMode); ErrorHandler.logError( e: "Invalid toolbar mode", s: StackTrace.current, - data: {"newMode": widget.overLayController.toolbarMode}, + data: {"newMode": overLayController.toolbarMode}, ); return const SizedBox(); } } - @override - void dispose() { - super.dispose(); - } - @override Widget build(BuildContext context) { return Material( key: MatrixState.pAnyState - .layerLinkAndKey('${widget.pangeaMessageEvent.eventId}-toolbar') + .layerLinkAndKey('${pangeaMessageEvent.eventId}-toolbar') .key, type: MaterialType.transparency, child: Column( From 19d8f5c0138a75a99275d46f0d3d14c0e7afd445 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Fri, 11 Oct 2024 15:57:32 -0400 Subject: [PATCH 10/16] prevent audio player text from being split onto multiple lines --- lib/pages/chat/events/audio_player.dart | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/pages/chat/events/audio_player.dart b/lib/pages/chat/events/audio_player.dart index d848cb6cc..3213d085f 100644 --- a/lib/pages/chat/events/audio_player.dart +++ b/lib/pages/chat/events/audio_player.dart @@ -391,18 +391,19 @@ class AudioPlayerState extends State { // #Pangea // const SizedBox(width: 8), const SizedBox(width: 5), + // SizedBox( + // width: 36, + // child: // Pangea# - SizedBox( - width: 36, - child: Text( - statusText, - style: TextStyle( - color: widget.color, - fontSize: 12, - ), + Text( + statusText, + style: TextStyle( + color: widget.color, + fontSize: 12, ), ), // #Pangea + // ), // const SizedBox(width: 8), // Badge( // isLabelVisible: audioPlayer != null, From 6a968110769c376b0c0e4637844655addaa11a77 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Mon, 14 Oct 2024 10:49:22 -0400 Subject: [PATCH 11/16] on app close, close toolbar overlay --- lib/pages/chat/chat.dart | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index ed223b061..a51a86b37 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -470,6 +470,14 @@ class ChatController extends State @override void didChangeAppLifecycleState(AppLifecycleState state) { + // #Pangea + // On iOS, if the toolbar is open and the app is closed, then the user goes + // back to do more toolbar activities, the toolbar buttons / selection don't + // update properly. So, when the user closes the app, close the toolbar overlay. + if (state == AppLifecycleState.paused) { + clearSelectedEvents(); + } + // Pangea# if (state != AppLifecycleState.resumed) return; setReadMarker(); } From 8e204c95e4ca7dc40005217c0aa876db0901f146 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Mon, 14 Oct 2024 11:13:20 -0400 Subject: [PATCH 12/16] shrink spancard width to not overflow screen --- lib/pangea/choreographer/controllers/igc_controller.dart | 2 +- lib/pangea/widgets/igc/pangea_text_controller.dart | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pangea/choreographer/controllers/igc_controller.dart b/lib/pangea/choreographer/controllers/igc_controller.dart index 4beea095f..470f7a45a 100644 --- a/lib/pangea/choreographer/controllers/igc_controller.dart +++ b/lib/pangea/choreographer/controllers/igc_controller.dart @@ -124,7 +124,7 @@ class IgcController { ), roomId: choreographer.roomId, ), - cardSize: match.isITStart ? const Size(350, 260) : const Size(400, 400), + cardSize: match.isITStart ? const Size(325, 260) : const Size(400, 400), transformTargetId: choreographer.inputTransformTargetKey, ); } diff --git a/lib/pangea/widgets/igc/pangea_text_controller.dart b/lib/pangea/widgets/igc/pangea_text_controller.dart index 63c5b3f94..314c19ee1 100644 --- a/lib/pangea/widgets/igc/pangea_text_controller.dart +++ b/lib/pangea/widgets/igc/pangea_text_controller.dart @@ -114,8 +114,8 @@ class PangeaTextController extends TextEditingController { context: context, cardSize: matchIndex != -1 && choreographer.igc.igcTextData!.matches[matchIndex].isITStart - ? const Size(350, 260) - : const Size(350, 400), + ? const Size(325, 260) + : const Size(325, 400), cardToShow: cardToShow, transformTargetId: choreographer.inputTransformTargetKey, ); From 07cc5b9c329ec5686a27fba346ef2348824bcb12 Mon Sep 17 00:00:00 2001 From: William Jordan-Cooley Date: Mon, 14 Oct 2024 14:56:37 -0400 Subject: [PATCH 13/16] show beta and alpha tags on l2s --- assets/l10n/intl_en.arb | 6 +- lib/main.dart | 2 +- lib/pangea/enum/l2_support_enum.dart | 98 +++++++++++++++++++ lib/pangea/models/language_model.dart | 18 ++-- .../pages/find_partner/find_partner_view.dart | 1 + .../practice_activity_card.dart | 4 + .../user_settings/p_language_dialog.dart | 2 + .../user_settings/p_language_dropdown.dart | 10 ++ pubspec.yaml | 2 +- 9 files changed, 131 insertions(+), 12 deletions(-) create mode 100644 lib/pangea/enum/l2_support_enum.dart diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 437b6d075..282acab40 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -4233,5 +4233,9 @@ "reportContentIssueTitle": "Report content issue", "feedback": "Optional feedback", "reportContentIssueDescription": "Uh oh! AI can faciliate personalized learning experiences but... also hallucinates. Please provide any feedback you have and we'll try again.", - "clickTheWordAgainToDeselect": "Click the selected word to deselect it." + "clickTheWordAgainToDeselect": "Click the selected word to deselect it.", + "l2SupportNa": "Not Available", + "l2SupportAlpha": "Alpha", + "l2SupportBeta": "Beta", + "l2SupportFull": "Full" } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 6be6edc91..36add47dc 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -22,7 +22,7 @@ void main() async { // #Pangea try { - await dotenv.load(fileName: ".env"); + await dotenv.load(fileName: ".env.local_choreo"); } catch (e) { Logs().e('Failed to load .env file', e); } diff --git a/lib/pangea/enum/l2_support_enum.dart b/lib/pangea/enum/l2_support_enum.dart new file mode 100644 index 000000000..c75534ea7 --- /dev/null +++ b/lib/pangea/enum/l2_support_enum.dart @@ -0,0 +1,98 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +enum L2SupportEnum { + na, + alpha, + beta, + full, +} + +extension L2SupportEnumExtension on L2SupportEnum { + String get storageString { + switch (this) { + case L2SupportEnum.na: + return 'na'; + case L2SupportEnum.alpha: + return 'alpha'; + case L2SupportEnum.beta: + return 'beta'; + case L2SupportEnum.full: + return 'full'; + } + } + + L2SupportEnum fromStorageString(String storageString) { + switch (storageString) { + case 'na': + case 'L2SupportEnum.na': + return L2SupportEnum.na; + case 'alpha': + case 'L2SupportEnum.alpha': + return L2SupportEnum.alpha; + case 'beta': + case 'L2SupportEnum.beta': + return L2SupportEnum.beta; + case 'full': + case 'L2SupportEnum.full': + return L2SupportEnum.full; + default: + throw Exception('Unknown L2SupportEnum storage string: $storageString'); + } + } + + String toLocalizedString(BuildContext context) { + final l10n = L10n.of(context)!; + + switch (this) { + case L2SupportEnum.na: + return l10n.l2SupportNa; + case L2SupportEnum.alpha: + return l10n.l2SupportAlpha; + case L2SupportEnum.beta: + return l10n.l2SupportBeta; + case L2SupportEnum.full: + return l10n.l2SupportFull; + } + } + + Badge toBadge(BuildContext context) { + final theme = Theme.of(context); + Color color; + String label; + + switch (this) { + case L2SupportEnum.na: + color = theme.colorScheme.onSurface.withOpacity(0.4); // Muted grey + label = toLocalizedString(context); + break; + case L2SupportEnum.alpha: + color = theme.colorScheme.primary.withOpacity(0.4); // Subtle primary + label = toLocalizedString(context); + break; + case L2SupportEnum.beta: + color = + theme.colorScheme.secondary.withOpacity(0.4); // Subtle secondary + label = toLocalizedString(context); + break; + case L2SupportEnum.full: + color = theme.colorScheme.tertiary.withOpacity(0.4); // Subtle tertiary + label = toLocalizedString(context); + break; + } + + return Badge( + label: Text( + label, + style: theme.textTheme.bodySmall?.copyWith( + color: theme.colorScheme.onSurface.withOpacity(0.8), // Dimmed text + fontWeight: FontWeight.w500, + ), + ), + backgroundColor: color, + alignment: Alignment.center, + padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), + smallSize: 20, // A smaller badge for subtlety + ); + } +} diff --git a/lib/pangea/models/language_model.dart b/lib/pangea/models/language_model.dart index be3cc71ba..37c93f504 100644 --- a/lib/pangea/models/language_model.dart +++ b/lib/pangea/models/language_model.dart @@ -1,6 +1,7 @@ import 'dart:developer'; import 'package:fluffychat/pangea/constants/language_constants.dart'; +import 'package:fluffychat/pangea/enum/l2_support_enum.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -12,15 +13,15 @@ class LanguageModel { final String languageFlag; final String displayName; final String? languageEmoji; - final bool l2; final bool l1; + final L2SupportEnum l2Support; LanguageModel({ required this.langCode, required this.languageFlag, required this.displayName, - required this.l2, required this.l1, + this.l2Support = L2SupportEnum.na, this.languageEmoji, }); @@ -37,9 +38,11 @@ class LanguageModel { displayName: _LanguageLocal.getDisplayName( code != LanguageKeys.unknownLanguage ? code : json['language_name'], ), - l2: json["l2"] ?? code.contains("es") || code.contains("en"), l1: json["l1"] ?? !code.contains("es") && !code.contains("en"), languageEmoji: json['language_emoji'], + l2Support: json['l2_support'] != null + ? L2SupportEnum.na.fromStorageString(json['l2_support']) + : L2SupportEnum.na, ); } @@ -47,11 +50,13 @@ class LanguageModel { 'language_code': langCode, 'language_name': displayName, 'language_flag': languageFlag, - 'l2': l2, 'l1': l1, 'language_emoji': languageEmoji, + 'l2_support': l2Support.storageString, }; + bool get l2 => l2Support != L2SupportEnum.na; + // Discuss with Jordan - adding langCode field to language objects as separate from displayName static String codeFromNameOrCode(String codeOrName, [String? url]) { if (codeOrName.isEmpty) return LanguageKeys.unknownLanguage; @@ -73,7 +78,6 @@ class LanguageModel { langCode: LanguageKeys.unknownLanguage, languageFlag: "", displayName: "Unknown", - l2: false, l1: false, ); @@ -81,16 +85,12 @@ class LanguageModel { displayName: context != null ? L10n.of(context)!.multiLingualSpace : "Multilingual Space", - l2: false, l1: false, langCode: LanguageKeys.multiLanguage, languageFlag: 'assets/colors.png', languageEmoji: "🌎", ); - // Discuss with Jordan - bool get hasContextualDefinitionSupport => l2; - String? getDisplayName(BuildContext context) { switch (langCode) { case 'ab': diff --git a/lib/pangea/pages/find_partner/find_partner_view.dart b/lib/pangea/pages/find_partner/find_partner_view.dart index 032ed7daf..092c6eee1 100644 --- a/lib/pangea/pages/find_partner/find_partner_view.dart +++ b/lib/pangea/pages/find_partner/find_partner_view.dart @@ -234,6 +234,7 @@ class LanguageSelectionRow extends StatelessWidget { targetLanguage: isSource ? null : language, ); }, + isL2List: !isSource, initialLanguage: isSource ? controller.sourceLanguageSearch : controller.targetLanguageSearch, diff --git a/lib/pangea/widgets/practice_activity/practice_activity_card.dart b/lib/pangea/widgets/practice_activity/practice_activity_card.dart index 7e80e2aaa..442b1cf64 100644 --- a/lib/pangea/widgets/practice_activity/practice_activity_card.dart +++ b/lib/pangea/widgets/practice_activity/practice_activity_card.dart @@ -231,6 +231,10 @@ class MessagePracticeActivityCardState extends State { return; } + // clear the current activity and record + currentActivity = null; + currentCompletionRecord = null; + _fetchNewActivity( ActivityQualityFeedback( feedbackText: feedback, diff --git a/lib/pangea/widgets/user_settings/p_language_dialog.dart b/lib/pangea/widgets/user_settings/p_language_dialog.dart index b04b0e435..80dd7fa9d 100644 --- a/lib/pangea/widgets/user_settings/p_language_dialog.dart +++ b/lib/pangea/widgets/user_settings/p_language_dialog.dart @@ -63,6 +63,7 @@ Future pLanguageDialog( setState(() => selectedSourceLanguage = p0), initialLanguage: selectedSourceLanguage, languages: pangeaController.pLanguageStore.baseOptions, + isL2List: false, ), PQuestionContainer( title: L10n.of(parentContext)!.whatLanguageYouWantToLearn, @@ -72,6 +73,7 @@ Future pLanguageDialog( setState(() => selectedTargetLanguage = p0), initialLanguage: selectedTargetLanguage, languages: pangeaController.pLanguageStore.targetOptions, + isL2List: true, ), ], ), diff --git a/lib/pangea/widgets/user_settings/p_language_dropdown.dart b/lib/pangea/widgets/user_settings/p_language_dropdown.dart index 0793efdc2..19c2e71a5 100644 --- a/lib/pangea/widgets/user_settings/p_language_dropdown.dart +++ b/lib/pangea/widgets/user_settings/p_language_dropdown.dart @@ -1,5 +1,6 @@ // Flutter imports: +import 'package:fluffychat/pangea/enum/l2_support_enum.dart'; import 'package:fluffychat/pangea/models/language_model.dart'; import 'package:flutter/material.dart'; @@ -10,6 +11,7 @@ class PLanguageDropdown extends StatefulWidget { final LanguageModel initialLanguage; final Function(LanguageModel) onChange; final bool showMultilingual; + final bool isL2List; const PLanguageDropdown({ super.key, @@ -17,6 +19,7 @@ class PLanguageDropdown extends StatefulWidget { required this.onChange, required this.initialLanguage, this.showMultilingual = false, + required this.isL2List, }); @override @@ -98,6 +101,7 @@ class _PLanguageDropdownState extends State { value: LanguageModel.multiLingual(context), child: LanguageDropDownEntry( languageModel: LanguageModel.multiLingual(context), + isL2List: widget.isL2List, ), ), ...sortedLanguages.map( @@ -105,6 +109,7 @@ class _PLanguageDropdownState extends State { value: languageModel, child: LanguageDropDownEntry( languageModel: languageModel, + isL2List: widget.isL2List, ), ), ), @@ -118,9 +123,11 @@ class _PLanguageDropdownState extends State { class LanguageDropDownEntry extends StatelessWidget { final LanguageModel languageModel; + final bool isL2List; const LanguageDropDownEntry({ super.key, required this.languageModel, + required this.isL2List, }); @override @@ -144,6 +151,9 @@ class LanguageDropDownEntry extends StatelessWidget { overflow: TextOverflow.clip, textAlign: TextAlign.center, ), + const SizedBox(width: 10), + if (isL2List && languageModel.l2Support != L2SupportEnum.full) + languageModel.l2Support.toBadge(context), ], ), ); diff --git a/pubspec.yaml b/pubspec.yaml index d15833a5a..173fef435 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -6,7 +6,7 @@ description: Learn a language while texting your friends. # Pangea# publish_to: none # On version bump also increase the build number for F-Droid -version: 1.21.4+3539 +version: 1.21.4+3540 environment: sdk: ">=3.0.0 <4.0.0" From 5f0439d0d42e02070aacd19a14924b191dde81f4 Mon Sep 17 00:00:00 2001 From: wcjord <32568597+wcjord@users.noreply.github.com> Date: Mon, 14 Oct 2024 14:59:15 -0400 Subject: [PATCH 14/16] Update main.dart Remove change to env path... --- lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/main.dart b/lib/main.dart index 36add47dc..6be6edc91 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -22,7 +22,7 @@ void main() async { // #Pangea try { - await dotenv.load(fileName: ".env.local_choreo"); + await dotenv.load(fileName: ".env"); } catch (e) { Logs().e('Failed to load .env file', e); } From b463558b1a35f7bdaff7e44e27ea0c29cbda7062 Mon Sep 17 00:00:00 2001 From: William Jordan-Cooley Date: Mon, 14 Oct 2024 17:00:15 -0400 Subject: [PATCH 15/16] fixing edge case of no l2s --- lib/pangea/controllers/language_list_controller.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/pangea/controllers/language_list_controller.dart b/lib/pangea/controllers/language_list_controller.dart index 77f4ae9e2..7380f3e3f 100644 --- a/lib/pangea/controllers/language_list_controller.dart +++ b/lib/pangea/controllers/language_list_controller.dart @@ -27,7 +27,9 @@ class PangeaLanguage { static Future initialize() async { try { _langList = await _getCachedFlags(); - if (await _shouldFetch || _langList.isEmpty) { + if (await _shouldFetch || + _langList.isEmpty || + _langList.every((lang) => !lang.l2)) { _langList = await LanguageRepo.fetchLanguages(); await _saveFlags(_langList); From ac586e0a4db36b416a42e124d8023b876e1227dd Mon Sep 17 00:00:00 2001 From: ggurdin Date: Tue, 15 Oct 2024 10:40:02 -0400 Subject: [PATCH 16/16] position overlay cards via tranform follower instead of manually calculating offset, close keyboard when showing span card --- .../controllers/igc_controller.dart | 3 +- lib/pangea/choreographer/widgets/it_bar.dart | 2 + lib/pangea/utils/overlay.dart | 221 +++++++++--------- .../widgets/igc/pangea_text_controller.dart | 4 +- 4 files changed, 112 insertions(+), 118 deletions(-) diff --git a/lib/pangea/choreographer/controllers/igc_controller.dart b/lib/pangea/choreographer/controllers/igc_controller.dart index 470f7a45a..9eeee47b4 100644 --- a/lib/pangea/choreographer/controllers/igc_controller.dart +++ b/lib/pangea/choreographer/controllers/igc_controller.dart @@ -105,6 +105,7 @@ class IgcController { return; } + choreographer.chatController.inputFocus.unfocus(); OverlayUtil.showPositionedCard( context: context, cardToShow: SpanCard( @@ -124,7 +125,7 @@ class IgcController { ), roomId: choreographer.roomId, ), - cardSize: match.isITStart ? const Size(325, 260) : const Size(400, 400), + cardSize: match.isITStart ? const Size(350, 260) : const Size(350, 350), transformTargetId: choreographer.inputTransformTargetKey, ); } diff --git a/lib/pangea/choreographer/widgets/it_bar.dart b/lib/pangea/choreographer/widgets/it_bar.dart index bfc4a174d..0c6a07498 100644 --- a/lib/pangea/choreographer/widgets/it_bar.dart +++ b/lib/pangea/choreographer/widgets/it_bar.dart @@ -308,6 +308,8 @@ class ITChoices extends StatelessWidget { ); return; } + + controller.choreographer.chatController.inputFocus.unfocus(); OverlayUtil.showPositionedCard( context: context, cardToShow: choiceFeedback == null diff --git a/lib/pangea/utils/overlay.dart b/lib/pangea/utils/overlay.dart index cb6ed626a..c15d8e945 100644 --- a/lib/pangea/utils/overlay.dart +++ b/lib/pangea/utils/overlay.dart @@ -1,8 +1,6 @@ import 'dart:developer'; -import 'dart:math'; import 'dart:ui'; -import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/utils/any_state_holder.dart'; import 'package:fluffychat/pangea/widgets/common_widgets/overlay_container.dart'; import 'package:flutter/foundation.dart'; @@ -22,7 +20,6 @@ class OverlayUtil { required BuildContext context, required Widget child, required String transformTargetId, - // Size? size, double? width, double? height, Offset? offset, @@ -63,13 +60,13 @@ class OverlayUtil { child: (position != OverlayPositionEnum.transform) ? child : CompositedTransformFollower( - targetAnchor: targetAnchor ?? Alignment.topLeft, - followerAnchor: followerAnchor ?? Alignment.topLeft, + targetAnchor: targetAnchor ?? Alignment.topCenter, + followerAnchor: + followerAnchor ?? Alignment.bottomCenter, link: MatrixState.pAnyState .layerLinkAndKey(transformTargetId) .link, showWhenUnlinked: false, - offset: offset ?? Offset.zero, child: child, ), ), @@ -103,11 +100,6 @@ class OverlayUtil { return; } - final Offset cardOffset = _calculateCardOffset( - cardSize: cardSize, - transformTargetContext: layerLinkAndKey.key.currentContext!, - ); - final Widget child = Material( borderOnForeground: false, color: Colors.transparent, @@ -124,7 +116,6 @@ class OverlayUtil { width: cardSize.width, height: cardSize.height, transformTargetId: transformTargetId, - offset: cardOffset, backDropToDismiss: backDropToDismiss, borderColor: borderColor, closePrevOverlay: closePrevOverlay, @@ -135,73 +126,73 @@ class OverlayUtil { } } - /// calculates the card offset relative to the target - /// identified by [transformTargetKey] - static Offset _calculateCardOffset({ - required Size cardSize, - required BuildContext transformTargetContext, - final double minPadding = 10.0, - }) { - // debugger(when: kDebugMode); - //Note: assumes overlay in chatview - final OverlayConstraints constraints = - ChatViewConstraints(transformTargetContext); + // /// calculates the card offset relative to the target + // /// identified by [transformTargetKey] + // static Offset _calculateCardOffset({ + // required Size cardSize, + // required BuildContext transformTargetContext, + // final double minPadding = 10.0, + // }) { + // // debugger(when: kDebugMode); + // //Note: assumes overlay in chatview + // final OverlayConstraints constraints = + // ChatViewConstraints(transformTargetContext); - final RenderObject? targetRenderBox = - transformTargetContext.findRenderObject(); - if (targetRenderBox == null) return Offset.zero; - final Offset transformTargetOffset = - (targetRenderBox as RenderBox).localToGlobal(Offset.zero); - final Size transformTargetSize = targetRenderBox.size; + // final RenderObject? targetRenderBox = + // transformTargetContext.findRenderObject(); + // if (targetRenderBox == null) return Offset.zero; + // final Offset transformTargetOffset = + // (targetRenderBox as RenderBox).localToGlobal(Offset.zero); + // final Size transformTargetSize = targetRenderBox.size; - // ideally horizontally centered on target - double dx = transformTargetSize.width / 2 - cardSize.width / 2; - // make sure it's not off the left edge of the screen - // if transformTargetOffset.dx + dc < constraints.x0 + minPadding + // // ideally horizontally centered on target + // double dx = transformTargetSize.width / 2 - cardSize.width / 2; + // // make sure it's not off the left edge of the screen + // // if transformTargetOffset.dx + dc < constraints.x0 + minPadding - if (transformTargetOffset.dx + dx < minPadding + constraints.x0) { - debugPrint("setting dx"); - dx = minPadding + constraints.x0 - transformTargetOffset.dx; - } - // make sure it's not off the right edge of the screen - if (transformTargetOffset.dx + dx + cardSize.width + minPadding > - constraints.x1) { - dx = constraints.x1 - - transformTargetOffset.dx - - cardSize.width - - minPadding; - } + // if (transformTargetOffset.dx + dx < minPadding + constraints.x0) { + // debugPrint("setting dx"); + // dx = minPadding + constraints.x0 - transformTargetOffset.dx; + // } + // // make sure it's not off the right edge of the screen + // if (transformTargetOffset.dx + dx + cardSize.width + minPadding > + // constraints.x1) { + // dx = constraints.x1 - + // transformTargetOffset.dx - + // cardSize.width - + // minPadding; + // } - // if there's more room above target, - // put the card there - // else, - // put it below - // debugPrint( - // "transformTargetOffset.dx ${transformTargetOffset.dx} transformTargetOffset.dy ${transformTargetOffset.dy}"); - // debugPrint( - // "transformTargetSize.width ${transformTargetSize.width} transformTargetSize.height ${transformTargetSize.height}"); - double dy = transformTargetOffset.dy > - constraints.y1 - - transformTargetOffset.dy - - transformTargetSize.height - ? -cardSize.height - minPadding - : transformTargetSize.height + minPadding; - // make sure it's not off the top edge of the screen - if (dy < minPadding + constraints.y0 - transformTargetOffset.dy) { - dy = minPadding + constraints.y0 - transformTargetOffset.dy; - } - // make sure it's not off the bottom edge of the screen - if (transformTargetOffset.dy + dy + cardSize.height + minPadding > - constraints.y1) { - dy = constraints.y1 - - transformTargetOffset.dy - - cardSize.height - - minPadding; - } - // debugPrint("dx $dx dy $dy"); + // // if there's more room above target, + // // put the card there + // // else, + // // put it below + // // debugPrint( + // // "transformTargetOffset.dx ${transformTargetOffset.dx} transformTargetOffset.dy ${transformTargetOffset.dy}"); + // // debugPrint( + // // "transformTargetSize.width ${transformTargetSize.width} transformTargetSize.height ${transformTargetSize.height}"); + // double dy = transformTargetOffset.dy > + // constraints.y1 - + // transformTargetOffset.dy - + // transformTargetSize.height + // ? -cardSize.height - minPadding + // : transformTargetSize.height + minPadding; + // // make sure it's not off the top edge of the screen + // if (dy < minPadding + constraints.y0 - transformTargetOffset.dy) { + // dy = minPadding + constraints.y0 - transformTargetOffset.dy; + // } + // // make sure it's not off the bottom edge of the screen + // if (transformTargetOffset.dy + dy + cardSize.height + minPadding > + // constraints.y1) { + // dy = constraints.y1 - + // transformTargetOffset.dy - + // cardSize.height - + // minPadding; + // } + // // debugPrint("dx $dx dy $dy"); - return Offset(dx, dy); - } + // return Offset(dx, dy); + // } static bool get isOverlayOpen => MatrixState.pAnyState.entries.isNotEmpty; } @@ -250,48 +241,48 @@ class TransparentBackdrop extends StatelessWidget { } } -/// global coordinates that the overlay should stay inside -abstract class OverlayConstraints { - late double x0; - late double y0; - late double x1; - late double y1; -} +// /// global coordinates that the overlay should stay inside +// abstract class OverlayConstraints { +// late double x0; +// late double y0; +// late double x1; +// late double y1; +// } -class ChatViewConstraints implements OverlayConstraints { - @override - late double x0; - @override - late double y0; - @override - late double x1; - @override - late double y1; +// class ChatViewConstraints implements OverlayConstraints { +// @override +// late double x0; +// @override +// late double y0; +// @override +// late double x1; +// @override +// late double y1; - ChatViewConstraints(BuildContext context) { - final MediaQueryData mediaQueryData = - MediaQuery.of(Scaffold.of(context).context); - final bool isColumnMode = FluffyThemes.isColumnMode(context); +// ChatViewConstraints(BuildContext context) { +// final MediaQueryData mediaQueryData = +// MediaQuery.of(Scaffold.of(context).context); +// final bool isColumnMode = FluffyThemes.isColumnMode(context); - x0 = isColumnMode - ? AppConfig.columnWidth + 70.0 - : max(mediaQueryData.viewPadding.left, mediaQueryData.viewInsets.left); - y0 = max(mediaQueryData.viewPadding.top, mediaQueryData.viewInsets.top); - x1 = mediaQueryData.size.width - - max(mediaQueryData.viewPadding.right, mediaQueryData.viewInsets.right); - y1 = mediaQueryData.size.height - - max( - mediaQueryData.viewPadding.bottom, - mediaQueryData.viewInsets.bottom, - ); +// x0 = isColumnMode +// ? AppConfig.columnWidth + 70.0 +// : max(mediaQueryData.viewPadding.left, mediaQueryData.viewInsets.left); +// y0 = max(mediaQueryData.viewPadding.top, mediaQueryData.viewInsets.top); +// x1 = mediaQueryData.size.width - +// max(mediaQueryData.viewPadding.right, mediaQueryData.viewInsets.right); +// y1 = mediaQueryData.size.height - +// max( +// mediaQueryData.viewPadding.bottom, +// mediaQueryData.viewInsets.bottom, +// ); - // https://medium.com/flutter-community/a-flutter-guide-to-visual-overlap-padding-viewpadding-and-viewinsets-a63e214be6e8 - // debugPrint( - // "viewInsets ${mediaQueryData.viewInsets.left} ${mediaQueryData.viewInsets.top} ${mediaQueryData.viewInsets.right} ${mediaQueryData.viewInsets.bottom}"); - // debugPrint( - // "padding ${mediaQueryData.padding.left} ${mediaQueryData.padding.top} ${mediaQueryData.padding.right} ${mediaQueryData.padding.bottom}"); - // debugPrint( - // "viewPadding ${mediaQueryData.viewPadding.left} ${mediaQueryData.viewPadding.top} ${mediaQueryData.viewPadding.right} ${mediaQueryData.viewPadding.bottom}"); - // debugPrint("chatViewConstraints x0: $x0 y0: $y0 x1: $x1 y1: $y1"); - } -} +// // https://medium.com/flutter-community/a-flutter-guide-to-visual-overlap-padding-viewpadding-and-viewinsets-a63e214be6e8 +// // debugPrint( +// // "viewInsets ${mediaQueryData.viewInsets.left} ${mediaQueryData.viewInsets.top} ${mediaQueryData.viewInsets.right} ${mediaQueryData.viewInsets.bottom}"); +// // debugPrint( +// // "padding ${mediaQueryData.padding.left} ${mediaQueryData.padding.top} ${mediaQueryData.padding.right} ${mediaQueryData.padding.bottom}"); +// // debugPrint( +// // "viewPadding ${mediaQueryData.viewPadding.left} ${mediaQueryData.viewPadding.top} ${mediaQueryData.viewPadding.right} ${mediaQueryData.viewPadding.bottom}"); +// // debugPrint("chatViewConstraints x0: $x0 y0: $y0 x1: $x1 y1: $y1"); +// } +// } diff --git a/lib/pangea/widgets/igc/pangea_text_controller.dart b/lib/pangea/widgets/igc/pangea_text_controller.dart index 314c19ee1..63c5b3f94 100644 --- a/lib/pangea/widgets/igc/pangea_text_controller.dart +++ b/lib/pangea/widgets/igc/pangea_text_controller.dart @@ -114,8 +114,8 @@ class PangeaTextController extends TextEditingController { context: context, cardSize: matchIndex != -1 && choreographer.igc.igcTextData!.matches[matchIndex].isITStart - ? const Size(325, 260) - : const Size(325, 400), + ? const Size(350, 260) + : const Size(350, 400), cardToShow: cardToShow, transformTargetId: choreographer.inputTransformTargetKey, );