From 02050d3006d0296b27f628522df70d383300a6d8 Mon Sep 17 00:00:00 2001 From: wcjord <32568597+wcjord@users.noreply.github.com> Date: Mon, 13 Jan 2025 10:23:40 -0500 Subject: [PATCH] 1407 bring back locking of tools (#1408) * dev: clean up isActivityBasicallyEligible and shouldDoActivity defs * feat: bring back locking of tools and highlight words with meaning activities * fix: exclude tokens that are not relevant for meaning activities from proportionOfActivitiesCompleted computation * fix: show yellow if token meaning activity has been done but shouldDoActivity is true --------- Co-authored-by: ggurdin --- lib/pages/chat/chat_event_list.dart | 8 ++-- lib/pages/chat/events/message.dart | 17 ++++++-- lib/pangea/choreographer/widgets/it_bar.dart | 6 +-- .../choreographer/widgets/it_bar_buttons.dart | 4 +- .../morph_categories_and_labels.dart | 2 + lib/pangea/controllers/pangea_controller.dart | 9 ++-- lib/pangea/enum/message_mode_enum.dart | 25 +++++++---- .../pangea_room_extension.dart | 19 +++++---- .../instructions/instructions_enum.dart | 6 ++- .../instructions_inline_tooltip.dart | 6 ++- .../instructions/instructions_show_popup.dart | 6 ++- .../instructions/instructions_toggle.dart | 6 ++- .../pangea_message_event.dart | 41 +++++++++++++++++-- lib/pangea/models/pangea_token_model.dart | 27 ++++++------ .../practice_activity_model.dart | 10 +++-- lib/pangea/models/user_model.dart | 4 +- .../repo/lemma_info/lemma_info_repo.dart | 7 ++-- .../word_meaning_activity_generator.dart | 6 ++- lib/pangea/utils/message_text_util.dart | 5 +-- .../chat/message_selection_overlay.dart | 3 +- .../chat/message_speech_to_text_card.dart | 13 +++--- .../widgets/chat/message_token_text.dart | 31 ++++++++++---- .../widgets/chat/message_toolbar_buttons.dart | 12 +++--- .../chat/message_translation_card.dart | 3 +- lib/pangea/widgets/chat/overlay_message.dart | 10 +++-- lib/pangea/widgets/chat/tts_controller.dart | 12 +++--- lib/pangea/widgets/igc/pangea_rich_text.dart | 9 ++-- .../no_more_practice_card.dart | 3 +- .../practice_activity_card.dart | 6 ++- .../word_zoom/lemma_meaning_widget.dart | 8 ++-- .../morphs/morphological_center_widget.dart | 6 ++- .../word_zoom/word_zoom_center_widget.dart | 5 ++- 32 files changed, 223 insertions(+), 112 deletions(-) diff --git a/lib/pages/chat/chat_event_list.dart b/lib/pages/chat/chat_event_list.dart index 8af90762c..599f5b821 100644 --- a/lib/pages/chat/chat_event_list.dart +++ b/lib/pages/chat/chat_event_list.dart @@ -1,3 +1,8 @@ +import 'package:flutter/material.dart'; + +import 'package:matrix/matrix.dart'; +import 'package:scroll_to_index/scroll_to_index.dart'; + import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat/chat.dart'; @@ -11,9 +16,6 @@ import 'package:fluffychat/utils/account_config.dart'; import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/filtered_timeline_extension.dart'; import 'package:fluffychat/utils/platform_infos.dart'; -import 'package:flutter/material.dart'; -import 'package:matrix/matrix.dart'; -import 'package:scroll_to_index/scroll_to_index.dart'; class ChatEventList extends StatelessWidget { final ChatController controller; diff --git a/lib/pages/chat/events/message.dart b/lib/pages/chat/events/message.dart index 92f9d5553..22e7eae49 100644 --- a/lib/pages/chat/events/message.dart +++ b/lib/pages/chat/events/message.dart @@ -154,8 +154,13 @@ class Message extends StatelessWidget { previousEvent!.senderId == event.senderId && previousEvent!.originServerTs.sameEnvironment(event.originServerTs); - final textColor = - ownMessage ? theme.colorScheme.onPrimary : theme.colorScheme.onSurface; + final textColor = ownMessage + ? + // #Pangea + // theme.colorScheme.onPrimary + ThemeData.dark().colorScheme.onPrimary + // Pangea# + : theme.colorScheme.onSurface; final rowMainAxisAlignment = ownMessage ? MainAxisAlignment.end : MainAxisAlignment.start; @@ -189,7 +194,13 @@ class Message extends StatelessWidget { if (ownMessage) { color = displayEvent.status.isError ? Colors.redAccent - : theme.colorScheme.primary; + // #Pangea + // : ThemeData.dark().colorScheme.primary; + : Color.alphaBlend( + Colors.white.withAlpha(180), + ThemeData.dark().colorScheme.primary, + ); + // Pangea# } final resetAnimateIn = this.resetAnimateIn; diff --git a/lib/pangea/choreographer/widgets/it_bar.dart b/lib/pangea/choreographer/widgets/it_bar.dart index 927411aa8..d5345f61b 100644 --- a/lib/pangea/choreographer/widgets/it_bar.dart +++ b/lib/pangea/choreographer/widgets/it_bar.dart @@ -1,6 +1,9 @@ import 'dart:async'; import 'dart:developer'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart'; import 'package:fluffychat/pangea/choreographer/controllers/it_controller.dart'; import 'package:fluffychat/pangea/choreographer/widgets/it_bar_buttons.dart'; @@ -14,9 +17,6 @@ import 'package:fluffychat/pangea/instructions/instructions_inline_tooltip.dart' import 'package:fluffychat/pangea/pages/settings_learning/settings_learning.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/pangea/widgets/animations/gain_points.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; - import '../../controllers/it_feedback_controller.dart'; import '../../models/it_response_model.dart'; import '../../utils/overlay.dart'; diff --git a/lib/pangea/choreographer/widgets/it_bar_buttons.dart b/lib/pangea/choreographer/widgets/it_bar_buttons.dart index c54518fc4..ae0fdefaf 100644 --- a/lib/pangea/choreographer/widgets/it_bar_buttons.dart +++ b/lib/pangea/choreographer/widgets/it_bar_buttons.dart @@ -1,9 +1,9 @@ +import 'package:flutter/material.dart'; + import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; import 'package:fluffychat/pangea/instructions/instructions_enum.dart'; import 'package:fluffychat/pangea/instructions/instructions_show_popup.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/material.dart'; - import '../../widgets/common/bot_face_svg.dart'; import '../controllers/choreographer.dart'; import '../controllers/it_controller.dart'; diff --git a/lib/pangea/constants/morph_categories_and_labels.dart b/lib/pangea/constants/morph_categories_and_labels.dart index 44e62440e..0ccf40ea0 100644 --- a/lib/pangea/constants/morph_categories_and_labels.dart +++ b/lib/pangea/constants/morph_categories_and_labels.dart @@ -220,6 +220,8 @@ IconData getIconForMorphFeature(String feature) { return Icons.check_circle_outline; case 'prepcase': return Icons.location_on_outlined; + case 'conjtype': + return Icons.compare_arrows; default: debugger(when: kDebugMode); return Icons.help_outline; diff --git a/lib/pangea/controllers/pangea_controller.dart b/lib/pangea/controllers/pangea_controller.dart index a1a6135b4..01fbef528 100644 --- a/lib/pangea/controllers/pangea_controller.dart +++ b/lib/pangea/controllers/pangea_controller.dart @@ -2,6 +2,11 @@ import 'dart:async'; import 'dart:developer'; import 'dart:math'; +import 'package:flutter/foundation.dart'; + +import 'package:matrix/matrix.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; + import 'package:fluffychat/pangea/constants/bot_mode.dart'; import 'package:fluffychat/pangea/constants/class_default_values.dart'; import 'package:fluffychat/pangea/constants/pangea_event_types.dart'; @@ -26,10 +31,6 @@ import 'package:fluffychat/pangea/models/bot_options_model.dart'; import 'package:fluffychat/pangea/utils/bot_name.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/foundation.dart'; -import 'package:matrix/matrix.dart'; -import 'package:sentry_flutter/sentry_flutter.dart'; - import '../../config/app_config.dart'; import '../utils/firebase_analytics.dart'; import '../utils/p_store.dart'; diff --git a/lib/pangea/enum/message_mode_enum.dart b/lib/pangea/enum/message_mode_enum.dart index 1f942b6be..2021f9941 100644 --- a/lib/pangea/enum/message_mode_enum.dart +++ b/lib/pangea/enum/message_mode_enum.dart @@ -81,23 +81,34 @@ extension MessageModeExtension on MessageMode { } bool isUnlocked( - int index, - int numActivitiesCompleted, + double proportionOfActivitiesCompleted, bool totallyDone, - ) => - numActivitiesCompleted >= index || totallyDone; + ) { + if (totallyDone) return true; + + switch (this) { + case MessageMode.translation: + return proportionOfActivitiesCompleted >= 1; + case MessageMode.textToSpeech: + return proportionOfActivitiesCompleted >= 0.5; + case MessageMode.speechToText: + case MessageMode.practiceActivity: + case MessageMode.wordZoom: + case MessageMode.noneSelected: + return true; + } + } bool get showButton => this != MessageMode.practiceActivity; Color iconButtonColor( BuildContext context, - int index, MessageMode currentMode, - int numActivitiesCompleted, + double proportionOfActivitiesUnlocked, bool totallyDone, ) { //locked - if (!isUnlocked(index, numActivitiesCompleted, totallyDone)) { + if (!isUnlocked(proportionOfActivitiesUnlocked, totallyDone)) { return barAndLockedButtonColor(context); } 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 c69d3863d..5265a4d1c 100644 --- a/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart @@ -4,8 +4,18 @@ import 'dart:async'; import 'dart:convert'; import 'dart:developer'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:collection/collection.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:html_unescape/html_unescape.dart'; +import 'package:matrix/matrix.dart' as matrix; +import 'package:matrix/matrix.dart'; +import 'package:matrix/src/utils/markdown.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; + import 'package:fluffychat/pangea/constants/bot_mode.dart'; import 'package:fluffychat/pangea/constants/class_code_constants.dart'; import 'package:fluffychat/pangea/constants/class_default_values.dart'; @@ -21,15 +31,6 @@ import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/widgets/future_loading_dialog.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:html_unescape/html_unescape.dart'; -import 'package:matrix/matrix.dart' as matrix; -import 'package:matrix/matrix.dart'; -import 'package:matrix/src/utils/markdown.dart'; -import 'package:sentry_flutter/sentry_flutter.dart'; - import '../../../config/app_config.dart'; import '../../constants/pangea_event_types.dart'; import '../../models/choreo_record.dart'; diff --git a/lib/pangea/instructions/instructions_enum.dart b/lib/pangea/instructions/instructions_enum.dart index 2465c33db..5ba657593 100644 --- a/lib/pangea/instructions/instructions_enum.dart +++ b/lib/pangea/instructions/instructions_enum.dart @@ -1,10 +1,12 @@ import 'dart:developer'; +import 'package:flutter/foundation.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; enum InstructionsEnum { itInstructions, diff --git a/lib/pangea/instructions/instructions_inline_tooltip.dart b/lib/pangea/instructions/instructions_inline_tooltip.dart index 6135624fb..6d659c2d0 100644 --- a/lib/pangea/instructions/instructions_inline_tooltip.dart +++ b/lib/pangea/instructions/instructions_inline_tooltip.dart @@ -1,8 +1,10 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pangea/instructions/instructions_enum.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; class InstructionsInlineTooltip extends StatefulWidget { final InstructionsEnum instructionsEnum; diff --git a/lib/pangea/instructions/instructions_show_popup.dart b/lib/pangea/instructions/instructions_show_popup.dart index baffc3863..0db555443 100644 --- a/lib/pangea/instructions/instructions_show_popup.dart +++ b/lib/pangea/instructions/instructions_show_popup.dart @@ -1,3 +1,7 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + import 'package:fluffychat/pangea/instructions/instructions_enum.dart'; import 'package:fluffychat/pangea/instructions/instructions_toggle.dart'; import 'package:fluffychat/pangea/utils/bot_style.dart'; @@ -5,8 +9,6 @@ import 'package:fluffychat/pangea/utils/overlay.dart'; import 'package:fluffychat/pangea/widgets/common/bot_face_svg.dart'; import 'package:fluffychat/pangea/widgets/igc/card_header.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; /// Instruction Card gives users tips on /// how to use Pangea Chat's features diff --git a/lib/pangea/instructions/instructions_toggle.dart b/lib/pangea/instructions/instructions_toggle.dart index 5c20233e0..7ae7543ca 100644 --- a/lib/pangea/instructions/instructions_toggle.dart +++ b/lib/pangea/instructions/instructions_toggle.dart @@ -1,9 +1,11 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; import 'package:fluffychat/pangea/instructions/instructions_enum.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; /// User can toggle on to prevent Instruction Card /// from appearing in future sessions diff --git a/lib/pangea/matrix_event_wrappers/pangea_message_event.dart b/lib/pangea/matrix_event_wrappers/pangea_message_event.dart index cfaf7daa6..1f4c04f36 100644 --- a/lib/pangea/matrix_event_wrappers/pangea_message_event.dart +++ b/lib/pangea/matrix_event_wrappers/pangea_message_event.dart @@ -9,6 +9,7 @@ import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:fluffychat/pangea/constants/model_keys.dart'; import 'package:fluffychat/pangea/controllers/text_to_speech_controller.dart'; +import 'package:fluffychat/pangea/enum/activity_type_enum.dart'; import 'package:fluffychat/pangea/enum/audio_encoding_enum.dart'; import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_representation_event.dart'; import 'package:fluffychat/pangea/matrix_event_wrappers/practice_activity_event.dart'; @@ -560,9 +561,43 @@ class PangeaMessageEvent { // return practiceActivities.any((activity) => !(activity.isComplete)); // } - int get numberOfActivitiesCompleted { - return MatrixState.pangeaController.activityRecordController - .getCompletedActivityCount(eventId); + /// value from 0 to 1 indicating the proportion of activities completed + double get proportionOfActivitiesCompleted { + if (messageDisplayRepresentation == null || + messageDisplayRepresentation?.tokens == null) { + return 1; + } + final int total = messageDisplayRepresentation!.tokens! + .where( + (token) => + token.isActivityBasicallyEligible(ActivityTypeEnum.wordMeaning), + ) + .length; + + final int toDo = messageDisplayRepresentation!.tokens! + .where( + (token) => + token.didActivitySuccessfully(ActivityTypeEnum.wordMeaning), + ) + .length; + + final double proportion = + (total - toDo) / messageDisplayRepresentation!.tokens!.length; + + if (proportion < 0) { + debugger(when: kDebugMode); + ErrorHandler.logError( + m: "proportion of activities completed is less than 0", + data: { + "proportion": proportion, + "total": total, + "toDo": toDo, + "tokens": messageDisplayRepresentation!.tokens, + }, + ); + } + + return proportion; } String? get l2Code => diff --git a/lib/pangea/models/pangea_token_model.dart b/lib/pangea/models/pangea_token_model.dart index b68b236da..16a7c6b51 100644 --- a/lib/pangea/models/pangea_token_model.dart +++ b/lib/pangea/models/pangea_token_model.dart @@ -1,7 +1,11 @@ import 'dart:developer'; import 'dart:math'; +import 'package:flutter/foundation.dart'; + import 'package:collection/collection.dart'; +import 'package:matrix/matrix.dart'; + import 'package:fluffychat/pangea/constants/language_constants.dart'; import 'package:fluffychat/pangea/constants/pangea_event_types.dart'; import 'package:fluffychat/pangea/enum/activity_type_enum.dart'; @@ -16,9 +20,6 @@ import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_repo.dart'; import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_request.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/foundation.dart'; -import 'package:matrix/matrix.dart'; - import '../constants/model_keys.dart'; import 'lemma.dart'; @@ -210,7 +211,10 @@ class PangeaToken { ); } - bool _isActivityBasicallyEligible(ActivityTypeEnum a) { + bool isActivityBasicallyEligible(ActivityTypeEnum a) { + if (!lemma.saveVocab) { + return false; + } switch (a) { case ActivityTypeEnum.wordMeaning: return canBeDefined; @@ -258,7 +262,7 @@ class PangeaToken { // } // } - bool _didActivitySuccessfully( + bool didActivitySuccessfully( ActivityTypeEnum a, [ String? morphFeature, String? morphTag, @@ -308,7 +312,7 @@ class PangeaToken { return false; } case ActivityTypeEnum.wordFocusListening: - return !_didActivitySuccessfully(a) || daysSinceLastUseByType(a) > 30; + return !didActivitySuccessfully(a) || daysSinceLastUseByType(a) > 30; case ActivityTypeEnum.hiddenWordListening: return daysSinceLastUseByType(a) > 7; case ActivityTypeEnum.lemmaId: @@ -402,8 +406,7 @@ class PangeaToken { required String? feature, required String? tag, }) { - return lemma.saveVocab && - _isActivityBasicallyEligible(a) && + return isActivityBasicallyEligible(a) && _isActivityProbablyLevelAppropriate(a, feature, tag); } @@ -428,13 +431,13 @@ class PangeaToken { .getConstructUses( ConstructIdentifier( lemma: lemma.text, - type: ConstructTypeEnum.morph, + type: ConstructTypeEnum.vocab, category: pos, ), ) ?? ConstructUses( lemma: lemma.text, - constructType: ConstructTypeEnum.morph, + constructType: ConstructTypeEnum.vocab, category: pos, uses: [], ); @@ -604,10 +607,10 @@ class PangeaToken { } String get xpEmoji { - if (xp < 30) { + if (vocabConstruct.points < 30) { // bean emoji return "🫛"; - } else if (xp < 100) { + } else if (vocabConstruct.points < 100) { // sprout emoji return "🌱"; } else { diff --git a/lib/pangea/models/practice_activities.dart/practice_activity_model.dart b/lib/pangea/models/practice_activities.dart/practice_activity_model.dart index d9aae9512..d7166e8bc 100644 --- a/lib/pangea/models/practice_activities.dart/practice_activity_model.dart +++ b/lib/pangea/models/practice_activities.dart/practice_activity_model.dart @@ -1,6 +1,12 @@ import 'dart:developer'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + import 'package:collection/collection.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; + import 'package:fluffychat/pangea/enum/activity_display_instructions_enum.dart'; import 'package:fluffychat/pangea/enum/activity_type_enum.dart'; import 'package:fluffychat/pangea/enum/analytics/morph_categories_enum.dart'; @@ -8,10 +14,6 @@ import 'package:fluffychat/pangea/enum/construct_type_enum.dart'; import 'package:fluffychat/pangea/models/pangea_token_model.dart'; import 'package:fluffychat/pangea/models/practice_activities.dart/multiple_choice_activity_model.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:sentry_flutter/sentry_flutter.dart'; class ConstructIdentifier { final String lemma; diff --git a/lib/pangea/models/user_model.dart b/lib/pangea/models/user_model.dart index d5dafffcc..19ce5f738 100644 --- a/lib/pangea/models/user_model.dart +++ b/lib/pangea/models/user_model.dart @@ -1,10 +1,10 @@ +import 'package:matrix/matrix.dart'; + import 'package:fluffychat/pangea/constants/model_keys.dart'; import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; import 'package:fluffychat/pangea/instructions/instruction_settings.dart'; import 'package:fluffychat/pangea/models/space_model.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:matrix/matrix.dart'; - import 'language_model.dart'; /// The user's settings learning settings. diff --git a/lib/pangea/repo/lemma_info/lemma_info_repo.dart b/lib/pangea/repo/lemma_info/lemma_info_repo.dart index a584201d6..d4cb65c28 100644 --- a/lib/pangea/repo/lemma_info/lemma_info_repo.dart +++ b/lib/pangea/repo/lemma_info/lemma_info_repo.dart @@ -1,15 +1,16 @@ import 'dart:convert'; import 'dart:developer'; +import 'package:flutter/foundation.dart'; + +import 'package:http/http.dart'; + import 'package:fluffychat/pangea/models/content_feedback.dart'; import 'package:fluffychat/pangea/network/urls.dart'; import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_request.dart'; import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_response.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/foundation.dart'; -import 'package:http/http.dart'; - import '../../config/environment.dart'; import '../../network/requests.dart'; diff --git a/lib/pangea/repo/practice/word_meaning_activity_generator.dart b/lib/pangea/repo/practice/word_meaning_activity_generator.dart index be0bec197..0d555d158 100644 --- a/lib/pangea/repo/practice/word_meaning_activity_generator.dart +++ b/lib/pangea/repo/practice/word_meaning_activity_generator.dart @@ -1,3 +1,7 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + import 'package:fluffychat/pangea/enum/activity_type_enum.dart'; import 'package:fluffychat/pangea/enum/construct_type_enum.dart'; import 'package:fluffychat/pangea/models/practice_activities.dart/message_activity_request.dart'; @@ -5,8 +9,6 @@ import 'package:fluffychat/pangea/models/practice_activities.dart/multiple_choic import 'package:fluffychat/pangea/models/practice_activities.dart/practice_activity_model.dart'; import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_repo.dart'; import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_request.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; class WordMeaningActivityGenerator { Future get( diff --git a/lib/pangea/utils/message_text_util.dart b/lib/pangea/utils/message_text_util.dart index 3e12ffe17..ef750f1b1 100644 --- a/lib/pangea/utils/message_text_util.dart +++ b/lib/pangea/utils/message_text_util.dart @@ -46,8 +46,7 @@ class MessageTextUtil { start: globalIndex, end: startIndex, hideContent: false, - highlight: - (isSelected?.call(token) ?? false) && !hasHiddenContent, + selected: (isSelected?.call(token) ?? false) && !hasHiddenContent, ), ); } @@ -58,7 +57,7 @@ class MessageTextUtil { end: endIndex, token: token, hideContent: hideContent, - highlight: (isSelected?.call(token) ?? false) && + selected: (isSelected?.call(token) ?? false) && !hideContent && !hasHiddenContent, ), diff --git a/lib/pangea/widgets/chat/message_selection_overlay.dart b/lib/pangea/widgets/chat/message_selection_overlay.dart index c9afa7f8c..aa0edaae6 100644 --- a/lib/pangea/widgets/chat/message_selection_overlay.dart +++ b/lib/pangea/widgets/chat/message_selection_overlay.dart @@ -76,7 +76,8 @@ class MessageOverlayController extends State int get activitiesLeftToComplete => messageAnalyticsEntry?.numActivities ?? 0; bool get isPracticeComplete => - activitiesLeftToComplete <= 0 || !messageInUserL2; + (pangeaMessageEvent?.proportionOfActivitiesCompleted ?? 1) >= 1 || + !messageInUserL2; /// Decides whether an _initialSelectedToken should be used /// for a first practice activity on the word meaning diff --git a/lib/pangea/widgets/chat/message_speech_to_text_card.dart b/lib/pangea/widgets/chat/message_speech_to_text_card.dart index dd2085cfe..75d5028ed 100644 --- a/lib/pangea/widgets/chat/message_speech_to_text_card.dart +++ b/lib/pangea/widgets/chat/message_speech_to_text_card.dart @@ -1,5 +1,12 @@ import 'dart:developer'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:material_symbols_icons/symbols.dart'; + import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/instructions/instructions_enum.dart'; import 'package:fluffychat/pangea/instructions/instructions_inline_tooltip.dart'; @@ -10,12 +17,6 @@ import 'package:fluffychat/pangea/widgets/chat/toolbar_content_loading_indicator import 'package:fluffychat/pangea/widgets/common/icon_number_widget.dart'; import 'package:fluffychat/pangea/widgets/igc/card_error_widget.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:material_symbols_icons/symbols.dart'; - import '../../utils/bot_style.dart'; class MessageSpeechToTextCard extends StatefulWidget { diff --git a/lib/pangea/widgets/chat/message_token_text.dart b/lib/pangea/widgets/chat/message_token_text.dart index b9e783f4a..1cf011152 100644 --- a/lib/pangea/widgets/chat/message_token_text.dart +++ b/lib/pangea/widgets/chat/message_token_text.dart @@ -3,7 +3,9 @@ import 'package:flutter/material.dart'; import 'package:collection/collection.dart'; +import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/controllers/message_analytics_controller.dart'; +import 'package:fluffychat/pangea/enum/activity_type_enum.dart'; import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart'; import 'package:fluffychat/pangea/models/pangea_token_model.dart'; import 'package:fluffychat/pangea/utils/message_text_util.dart'; @@ -69,7 +71,7 @@ class MessageTokenText extends StatelessWidget { class TokenPosition { final int start; final int end; - final bool highlight; + final bool selected; final bool hideContent; final PangeaToken? token; @@ -77,7 +79,7 @@ class TokenPosition { required this.start, required this.end, required this.hideContent, - required this.highlight, + required this.selected, this.token, }); } @@ -176,6 +178,19 @@ class MessageTextWidget extends StatelessWidget { text: TextSpan( children: tokenPositions.mapIndexed((int i, TokenPosition tokenPosition) { + final shouldDo = tokenPosition.token?.shouldDoActivity( + a: ActivityTypeEnum.wordMeaning, + feature: null, + tag: null, + ) ?? + false; + + final didMeaningActivity = + tokenPosition.token?.didActivitySuccessfully( + ActivityTypeEnum.wordMeaning, + ) ?? + true; + final substring = messageCharacters .skip(tokenPosition.start) .take(tokenPosition.end - tokenPosition.start) @@ -199,11 +214,13 @@ class MessageTextWidget extends StatelessWidget { text: substring, style: style.merge( TextStyle( - backgroundColor: tokenPosition.highlight - ? Theme.of(context).brightness == Brightness.light - ? Colors.black.withAlpha(100) - : Colors.white.withAlpha(100) - : Colors.transparent, + backgroundColor: tokenPosition.selected + ? AppConfig.primaryColor.withAlpha(80) + : (isSelected != null && shouldDo) + ? !didMeaningActivity + ? AppConfig.success.withAlpha(60) + : AppConfig.gold.withAlpha(60) + : Colors.transparent, ), ), ); diff --git a/lib/pangea/widgets/chat/message_toolbar_buttons.dart b/lib/pangea/widgets/chat/message_toolbar_buttons.dart index 8d056f0fd..15095eb1e 100644 --- a/lib/pangea/widgets/chat/message_toolbar_buttons.dart +++ b/lib/pangea/widgets/chat/message_toolbar_buttons.dart @@ -23,8 +23,8 @@ class ToolbarButtons extends StatelessWidget { super.key, }); - int? get activitiesCompleted => - overlayController.pangeaMessageEvent?.numberOfActivitiesCompleted; + double? get proportionOfActivitiesCompleted => + overlayController.pangeaMessageEvent?.proportionOfActivitiesCompleted; List get modes => MessageMode.values .where((mode) => mode.shouldShowAsToolbarButton(event)) @@ -62,7 +62,7 @@ class ToolbarButtons extends StatelessWidget { height: 12, width: overlayController.isPracticeComplete ? width - : min(width, (width / 2) * activitiesCompleted!), + : min(width, width * proportionOfActivitiesCompleted!), decoration: BoxDecoration( borderRadius: BorderRadius.circular(AppConfig.borderRadius), color: AppConfig.success, @@ -76,15 +76,13 @@ class ToolbarButtons extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.stretch, children: modes.mapIndexed((index, mode) { final enabled = mode.isUnlocked( - index, - activitiesCompleted!, + proportionOfActivitiesCompleted!, overlayController.isPracticeComplete, ); final color = mode.iconButtonColor( context, - index, overlayController.toolbarMode, - activitiesCompleted!, + proportionOfActivitiesCompleted!, overlayController.isPracticeComplete, ); return mode.showButton diff --git a/lib/pangea/widgets/chat/message_translation_card.dart b/lib/pangea/widgets/chat/message_translation_card.dart index adb012531..a1ba11571 100644 --- a/lib/pangea/widgets/chat/message_translation_card.dart +++ b/lib/pangea/widgets/chat/message_translation_card.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/instructions/instructions_enum.dart'; import 'package:fluffychat/pangea/instructions/instructions_inline_tooltip.dart'; @@ -9,7 +11,6 @@ import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/pangea/widgets/chat/toolbar_content_loading_indicator.dart'; import 'package:fluffychat/pangea/widgets/igc/card_error_widget.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/material.dart'; class MessageTranslationCard extends StatefulWidget { final PangeaMessageEvent messageEvent; diff --git a/lib/pangea/widgets/chat/overlay_message.dart b/lib/pangea/widgets/chat/overlay_message.dart index 12da4a663..aea2a00a0 100644 --- a/lib/pangea/widgets/chat/overlay_message.dart +++ b/lib/pangea/widgets/chat/overlay_message.dart @@ -82,7 +82,10 @@ class OverlayMessage extends StatelessWidget { if (ownMessage) { color = displayEvent.status.isError ? Colors.redAccent - : theme.colorScheme.primary; + : Color.alphaBlend( + Colors.white.withAlpha(180), + ThemeData.dark().colorScheme.primary, + ); } final noBubble = { @@ -96,8 +99,9 @@ class OverlayMessage extends StatelessWidget { MessageTypes.Audio, }.contains(event.messageType); - final textColor = - ownMessage ? theme.colorScheme.onPrimary : theme.colorScheme.onSurface; + final textColor = ownMessage + ? ThemeData.dark().colorScheme.onPrimary + : theme.colorScheme.onSurface; return Material( color: color, diff --git a/lib/pangea/widgets/chat/tts_controller.dart b/lib/pangea/widgets/chat/tts_controller.dart index 1a6701b6c..1bb393662 100644 --- a/lib/pangea/widgets/chat/tts_controller.dart +++ b/lib/pangea/widgets/chat/tts_controller.dart @@ -1,6 +1,13 @@ import 'dart:async'; import 'dart:developer'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_tts/flutter_tts.dart' as flutter_tts; +import 'package:matrix/matrix_api_lite/utils/logs.dart'; +import 'package:text_to_speech/text_to_speech.dart'; + import 'package:fluffychat/pangea/controllers/user_controller.dart'; import 'package:fluffychat/pangea/instructions/instructions_enum.dart'; import 'package:fluffychat/pangea/instructions/instructions_show_popup.dart'; @@ -8,11 +15,6 @@ import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/pangea/widgets/chat/missing_voice_button.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_tts/flutter_tts.dart' as flutter_tts; -import 'package:matrix/matrix_api_lite/utils/logs.dart'; -import 'package:text_to_speech/text_to_speech.dart'; class TtsController { String? get targetLanguage => diff --git a/lib/pangea/widgets/igc/pangea_rich_text.dart b/lib/pangea/widgets/igc/pangea_rich_text.dart index 4b7c5e9b2..f08f2bf65 100644 --- a/lib/pangea/widgets/igc/pangea_rich_text.dart +++ b/lib/pangea/widgets/igc/pangea_rich_text.dart @@ -1,6 +1,11 @@ import 'dart:developer'; import 'dart:ui'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:matrix/matrix.dart'; + import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pages/chat/chat.dart'; import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; @@ -11,10 +16,6 @@ import 'package:fluffychat/pangea/models/representation_content_model.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/pangea/widgets/chat/message_toolbar_selection_area.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:matrix/matrix.dart'; - import '../../models/pangea_match_model.dart'; class PangeaRichText extends StatefulWidget { diff --git a/lib/pangea/widgets/practice_activity/no_more_practice_card.dart b/lib/pangea/widgets/practice_activity/no_more_practice_card.dart index b124c6914..24f6152b3 100644 --- a/lib/pangea/widgets/practice_activity/no_more_practice_card.dart +++ b/lib/pangea/widgets/practice_activity/no_more_practice_card.dart @@ -1,7 +1,8 @@ +import 'package:flutter/material.dart'; + import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/instructions/instructions_enum.dart'; import 'package:fluffychat/pangea/instructions/instructions_inline_tooltip.dart'; -import 'package:flutter/material.dart'; class StarAnimationWidget extends StatefulWidget { const StarAnimationWidget({super.key}); diff --git a/lib/pangea/widgets/practice_activity/practice_activity_card.dart b/lib/pangea/widgets/practice_activity/practice_activity_card.dart index fe4818b52..06de7dce2 100644 --- a/lib/pangea/widgets/practice_activity/practice_activity_card.dart +++ b/lib/pangea/widgets/practice_activity/practice_activity_card.dart @@ -1,7 +1,11 @@ import 'dart:async'; import 'dart:developer'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + import 'package:collection/collection.dart'; + import 'package:fluffychat/pangea/controllers/message_analytics_controller.dart'; import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; import 'package:fluffychat/pangea/controllers/put_analytics_controller.dart'; @@ -22,8 +26,6 @@ import 'package:fluffychat/pangea/widgets/igc/card_error_widget.dart'; import 'package:fluffychat/pangea/widgets/practice_activity/multiple_choice_activity.dart'; import 'package:fluffychat/pangea/widgets/word_zoom/word_zoom_widget.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; /// The wrapper for practice activity content. /// Handles the activities associated with a message, diff --git a/lib/pangea/widgets/word_zoom/lemma_meaning_widget.dart b/lib/pangea/widgets/word_zoom/lemma_meaning_widget.dart index f07d9abb1..d925c1858 100644 --- a/lib/pangea/widgets/word_zoom/lemma_meaning_widget.dart +++ b/lib/pangea/widgets/word_zoom/lemma_meaning_widget.dart @@ -1,5 +1,10 @@ import 'dart:developer'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/choreographer/widgets/text_loading_shimmer.dart'; import 'package:fluffychat/pangea/constants/language_constants.dart'; @@ -7,9 +12,6 @@ import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_repo.dart'; import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_request.dart'; import 'package:fluffychat/pangea/repo/lemma_info/lemma_info_response.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; class LemmaMeaningWidget extends StatefulWidget { final String lemma; diff --git a/lib/pangea/widgets/word_zoom/morphs/morphological_center_widget.dart b/lib/pangea/widgets/word_zoom/morphs/morphological_center_widget.dart index f1268989c..e58c9fdb0 100644 --- a/lib/pangea/widgets/word_zoom/morphs/morphological_center_widget.dart +++ b/lib/pangea/widgets/word_zoom/morphs/morphological_center_widget.dart @@ -1,6 +1,10 @@ // stateful widget that displays morphological label and a shimmer effect while the text is loading // takes a token and morphological feature as input +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + import 'package:fluffychat/pangea/constants/model_keys.dart'; import 'package:fluffychat/pangea/constants/morph_categories_and_labels.dart'; import 'package:fluffychat/pangea/enum/analytics/morph_categories_enum.dart'; @@ -12,8 +16,6 @@ import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/pangea/utils/grammar/get_grammar_copy.dart'; import 'package:fluffychat/pangea/widgets/chat/message_selection_overlay.dart'; import 'package:fluffychat/widgets/future_loading_dialog.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; class MorphologicalCenterWidget extends StatefulWidget { final PangeaToken token; diff --git a/lib/pangea/widgets/word_zoom/word_zoom_center_widget.dart b/lib/pangea/widgets/word_zoom/word_zoom_center_widget.dart index aff842ed9..7093e2bda 100644 --- a/lib/pangea/widgets/word_zoom/word_zoom_center_widget.dart +++ b/lib/pangea/widgets/word_zoom/word_zoom_center_widget.dart @@ -1,5 +1,8 @@ import 'dart:developer'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + import 'package:fluffychat/pangea/controllers/message_analytics_controller.dart'; import 'package:fluffychat/pangea/models/pangea_token_model.dart'; import 'package:fluffychat/pangea/widgets/chat/message_selection_overlay.dart'; @@ -8,8 +11,6 @@ import 'package:fluffychat/pangea/widgets/practice_activity/practice_activity_ca import 'package:fluffychat/pangea/widgets/word_zoom/lemma_meaning_widget.dart'; import 'package:fluffychat/pangea/widgets/word_zoom/morphs/morphological_center_widget.dart'; import 'package:fluffychat/pangea/widgets/word_zoom/word_zoom_widget.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; class WordZoomCenterWidget extends StatelessWidget { final WordZoomSelection? selectionType;