From 0128ac42cd82dead35fcfd0ad725e85d1a58768a Mon Sep 17 00:00:00 2001 From: wcjord <32568597+wcjord@users.noreply.github.com> Date: Mon, 10 Mar 2025 10:33:39 -0400 Subject: [PATCH] Vocab-details-v2 (#2093) * started activity in chat creation * starting vocab tile display * refactor(vocab_analytics_list): made into little tiles that show the user chosen emoji * chore: comment out unused file * chore: remove unused variable * chore: make eventID nullable for constructs so users can set emoji from vocab details popup --------- Co-authored-by: ggurdin Co-authored-by: ggurdin <46800240+ggurdin@users.noreply.github.com> --- assets/l10n/intl_en.arb | 4 +- .../activity_plan_search_repo.dart | 46 +++++ .../activity_search_request.dart | 38 ++++ .../activity_suggestions_area.dart | 45 +++++ .../analytics_details_popup.dart | 12 +- .../analytics_details_popup_content.dart | 4 +- .../lemma_usage_dots.dart | 2 +- .../lemma_use_example_messages.dart | 5 +- ...ew.dart => morph_analytics_list_view.dart} | 56 ++++-- .../morph_details_view.dart | 4 +- ...dart => vocab_analytics_details_view.dart} | 16 +- .../vocab_analytics_list_tile.dart | 84 ++++++++ .../vocab_analytics_list_view.dart | 69 +++++++ .../vocab_analytics_view.dart | 182 ------------------ .../analytics_misc/construct_list_model.dart | 2 +- .../analytics_misc/construct_use_model.dart | 4 +- .../analytics_misc/constructs_model.dart | 9 +- .../message_analytics_controller.dart | 2 +- .../put_analytics_controller.dart | 22 ++- lib/pangea/common/network/urls.dart | 2 + lib/pangea/common/widgets/customized_svg.dart | 18 +- .../construct_identifier.dart | 50 +++++ .../construct_level_enum.dart | 14 ++ .../events/models/pangea_token_model.dart | 54 +----- .../instructions/instructions_enum.dart | 8 + .../instructions_inline_tooltip.dart | 2 +- lib/pangea/lemmas/construct_xp_widget.dart | 17 +- .../toolbar/enums/activity_type_enum.dart | 2 +- .../models/practice_activity_model.dart | 2 +- .../message_emoji_choice.dart | 23 +-- .../message_emoji_choice_item.dart | 13 +- .../reading_assistance_input_bar.dart | 6 +- .../word_emoji_choice.dart | 42 ++-- .../lemma_meaning_activity_generator.dart | 2 +- .../repo/morph_activity_generator.dart | 2 +- ...eaning_static_practice_activity_model.dart | 2 +- lib/pangea/toolbar/utils/shrinkable_text.dart | 33 ++++ .../widgets/message_selection_overlay.dart | 28 --- .../morphs/morphological_center_widget.dart | 4 +- .../widgets/word_zoom/word_zoom_widget.dart | 2 - lib/pangea/word_bank/vocab_bank_repo.dart | 2 +- lib/pangea/word_bank/vocab_response.dart | 2 +- .../writing_assistance_input_row.dart | 4 +- 43 files changed, 544 insertions(+), 396 deletions(-) create mode 100644 lib/pangea/activity_suggestions/activity_plan_search_repo.dart create mode 100644 lib/pangea/activity_suggestions/activity_search_request.dart create mode 100644 lib/pangea/activity_suggestions/activity_suggestions_area.dart rename lib/pangea/analytics_details_popup/{morph_analytics_view.dart => morph_analytics_list_view.dart} (82%) rename lib/pangea/analytics_details_popup/{vocab_details_view.dart => vocab_analytics_details_view.dart} (92%) create mode 100644 lib/pangea/analytics_details_popup/vocab_analytics_list_tile.dart create mode 100644 lib/pangea/analytics_details_popup/vocab_analytics_list_view.dart delete mode 100644 lib/pangea/analytics_details_popup/vocab_analytics_view.dart rename lib/pangea/{analytics_misc => constructs}/construct_identifier.dart (66%) rename lib/pangea/{analytics_misc => constructs}/construct_level_enum.dart (87%) create mode 100644 lib/pangea/toolbar/utils/shrinkable_text.dart diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 62f704245..bf0c096f6 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -4782,7 +4782,7 @@ }, "cancelInSubscriptionSettings": "• Cancel at any time in subscription settings", "cancelToAvoidCharges": "• Cancel before {trialEnds} to avoid charges", - "@cancelToAvoidCharges": { + "@cancelToAvoidCharges": { "type": "String", "placeholders": { "trialEnds": { @@ -4803,6 +4803,8 @@ } } }, + "analyticsVocabListBody": "This is all your vocabulary! As you earn XP for each word, they'll go from seedling to full bloom. Click on any word to see more details.", + "morphAnalyticsListBody": "These are all the grammar concepts in the language you're learning! You'll unlock them as you encounter them while chatting. Click for details.", "knockSpaceSuccess": "You have requested to join this space! An admin will respond to your request when they receive it 😀", "joinByCode": "Join by code", "createASpace": "Create a space" diff --git a/lib/pangea/activity_suggestions/activity_plan_search_repo.dart b/lib/pangea/activity_suggestions/activity_plan_search_repo.dart new file mode 100644 index 000000000..5006c4617 --- /dev/null +++ b/lib/pangea/activity_suggestions/activity_plan_search_repo.dart @@ -0,0 +1,46 @@ +import 'dart:convert'; + +import 'package:get_storage/get_storage.dart'; +import 'package:http/http.dart'; + +import 'package:fluffychat/pangea/activity_planner/activity_plan_request.dart'; +import 'package:fluffychat/pangea/activity_planner/activity_plan_response.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'; +import 'package:fluffychat/widgets/matrix.dart'; + +class ActivitySearchRepo { + static final GetStorage _activityPlanStorage = + GetStorage('activity_plan_search_storage'); + + static void set(ActivityPlanRequest request, ActivityPlanResponse response) { + _activityPlanStorage.write(request.storageKey, response.toJson()); + } + + static Future get(ActivityPlanRequest request) async { + final cachedJson = _activityPlanStorage.read(request.storageKey); + if (cachedJson != null) { + final cached = ActivityPlanResponse.fromJson(cachedJson); + + return cached; + } + + final Requests req = Requests( + choreoApiKey: Environment.choreoApiKey, + accessToken: MatrixState.pangeaController.userController.accessToken, + ); + + final Response res = await req.post( + url: PApiUrls.activityPlanSearch, + body: request.toJson(), + ); + + final decodedBody = jsonDecode(utf8.decode(res.bodyBytes)); + final response = ActivityPlanResponse.fromJson(decodedBody); + + set(request, response); + + return response; + } +} diff --git a/lib/pangea/activity_suggestions/activity_search_request.dart b/lib/pangea/activity_suggestions/activity_search_request.dart new file mode 100644 index 000000000..35b66fc70 --- /dev/null +++ b/lib/pangea/activity_suggestions/activity_search_request.dart @@ -0,0 +1,38 @@ +import 'package:fluffychat/pangea/activity_planner/media_enum.dart'; +import 'package:fluffychat/pangea/learning_settings/enums/language_level_type_enum.dart'; + +class ActivitySearchRequest { + final String targetLanguage; + final String languageOfInstructions; + final LanguageLevelTypeEnum? languageLevel; + + final String? mode; + final String? learningObjective; + final String? topic; + final MediaEnum? media; + final int? numberOfParticipants; + + ActivitySearchRequest({ + required this.targetLanguage, + required this.languageOfInstructions, + this.mode, + this.learningObjective, + this.topic, + this.media, + this.numberOfParticipants = 2, + this.languageLevel = LanguageLevelTypeEnum.preA1, + }); + + Map toJson() { + return { + 'target_language': targetLanguage, + 'language_of_instructions': languageOfInstructions, + 'language_level': languageLevel, + 'mode': mode, + 'objective': learningObjective, + 'topic': topic, + 'media': media, + 'number_of_participants': numberOfParticipants, + }; + } +} diff --git a/lib/pangea/activity_suggestions/activity_suggestions_area.dart b/lib/pangea/activity_suggestions/activity_suggestions_area.dart new file mode 100644 index 000000000..01a3f462e --- /dev/null +++ b/lib/pangea/activity_suggestions/activity_suggestions_area.dart @@ -0,0 +1,45 @@ +// // shows n rows of activity suggestions vertically, where n is the number of rows +// // as the user tries to scroll horizontally to the right, the client will fetch more activity suggestions + +// import 'package:flutter/material.dart'; + +// import 'package:fluffychat/pangea/activity_planner/activity_plan_request.dart'; +// import 'package:fluffychat/pangea/activity_suggestions/activity_plan_search_repo.dart'; + +// class ActivitySuggestionsArea extends StatefulWidget { +// const ActivitySuggestionsArea({super.key}); + +// @override +// ActivitySuggestionsAreaState createState() => ActivitySuggestionsAreaState(); +// } + +// class ActivitySuggestionsAreaState extends State { +// @override +// void initState() { +// super.initState(); +// } + +// Future fetchMoreSuggestions() async { +// ActivitySearchRepo.get( +// ActivityPlanRequest(), +// ); +// } + +// @override +// Widget build(BuildContext context) { +// return Container( +// child: ListView.builder( +// scrollDirection: Axis.vertical, +// itemCount: 5, +// itemBuilder: (context, index) { +// return Container( +// height: 100, +// width: 100, +// color: Colors.blue, +// margin: const EdgeInsets.all(10), +// ); +// }, +// ), +// ); +// } +// } diff --git a/lib/pangea/analytics_details_popup/analytics_details_popup.dart b/lib/pangea/analytics_details_popup/analytics_details_popup.dart index ae757c6f8..f22d77195 100644 --- a/lib/pangea/analytics_details_popup/analytics_details_popup.dart +++ b/lib/pangea/analytics_details_popup/analytics_details_popup.dart @@ -4,15 +4,15 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:material_symbols_icons/symbols.dart'; -import 'package:fluffychat/pangea/analytics_details_popup/morph_analytics_view.dart'; +import 'package:fluffychat/pangea/analytics_details_popup/morph_analytics_list_view.dart'; import 'package:fluffychat/pangea/analytics_details_popup/morph_details_view.dart'; -import 'package:fluffychat/pangea/analytics_details_popup/vocab_analytics_view.dart'; -import 'package:fluffychat/pangea/analytics_details_popup/vocab_details_view.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; +import 'package:fluffychat/pangea/analytics_details_popup/vocab_analytics_details_view.dart'; +import 'package:fluffychat/pangea/analytics_details_popup/vocab_analytics_list_view.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; import 'package:fluffychat/pangea/analytics_summary/progress_indicators_enum.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; import 'package:fluffychat/pangea/common/widgets/full_width_dialog.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; import 'package:fluffychat/pangea/morphs/default_morph_mapping.dart'; import 'package:fluffychat/pangea/morphs/morph_models.dart'; import 'package:fluffychat/pangea/morphs/morph_repo.dart'; @@ -135,13 +135,13 @@ class AnalyticsPopupWrapperState extends State { ), body: localView == ConstructTypeEnum.morph ? localConstructZoom == null - ? MorphAnalyticsView( + ? MorphAnalyticsListView( onConstructZoom: _setConstructZoom, controller: this, ) : MorphDetailsView(constructId: localConstructZoom!) : localConstructZoom == null - ? VocabAnalyticsView(onConstructZoom: _setConstructZoom) + ? VocabAnalyticsListView(onConstructZoom: _setConstructZoom) : VocabDetailsView(constructId: localConstructZoom!), ), maxWidth: 600, diff --git a/lib/pangea/analytics_details_popup/analytics_details_popup_content.dart b/lib/pangea/analytics_details_popup/analytics_details_popup_content.dart index 25df216ed..173e9fc2f 100644 --- a/lib/pangea/analytics_details_popup/analytics_details_popup_content.dart +++ b/lib/pangea/analytics_details_popup/analytics_details_popup_content.dart @@ -8,10 +8,10 @@ import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/analytics_details_popup/lemma_usage_dots.dart'; import 'package:fluffychat/pangea/analytics_details_popup/lemma_use_example_messages.dart'; import 'package:fluffychat/pangea/analytics_misc/analytics_constants.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_level_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; import 'package:fluffychat/pangea/analytics_misc/learning_skills_enum.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; +import 'package:fluffychat/pangea/constructs/construct_level_enum.dart'; class AnalyticsDetailsViewContent extends StatelessWidget { final Widget title; diff --git a/lib/pangea/analytics_details_popup/lemma_usage_dots.dart b/lib/pangea/analytics_details_popup/lemma_usage_dots.dart index b572b7db8..ee8b350cc 100644 --- a/lib/pangea/analytics_details_popup/lemma_usage_dots.dart +++ b/lib/pangea/analytics_details_popup/lemma_usage_dots.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:fluffychat/config/app_config.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_level_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart'; import 'package:fluffychat/pangea/analytics_misc/learning_skills_enum.dart'; +import 'package:fluffychat/pangea/constructs/construct_level_enum.dart'; class LemmaUsageDots extends StatelessWidget { final ConstructUses construct; diff --git a/lib/pangea/analytics_details_popup/lemma_use_example_messages.dart b/lib/pangea/analytics_details_popup/lemma_use_example_messages.dart index 3c5b0b379..8ae797f23 100644 --- a/lib/pangea/analytics_details_popup/lemma_use_example_messages.dart +++ b/lib/pangea/analytics_details_popup/lemma_use_example_messages.dart @@ -6,11 +6,11 @@ import 'package:collection/collection.dart'; import 'package:matrix/matrix.dart'; import 'package:fluffychat/config/app_config.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_level_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart'; import 'package:fluffychat/pangea/analytics_misc/learning_skills_enum.dart'; +import 'package:fluffychat/pangea/constructs/construct_level_enum.dart'; import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; import 'package:fluffychat/widgets/matrix.dart'; @@ -49,8 +49,9 @@ class LemmaUseExampleMessages extends StatelessWidget { continue; } + if (use.metadata.roomId == null) continue; final Room? room = MatrixState.pangeaController.matrixState.client - .getRoomById(use.metadata.roomId); + .getRoomById(use.metadata.roomId!); if (room == null) continue; Timeline? timeline = room.timeline; diff --git a/lib/pangea/analytics_details_popup/morph_analytics_view.dart b/lib/pangea/analytics_details_popup/morph_analytics_list_view.dart similarity index 82% rename from lib/pangea/analytics_details_popup/morph_analytics_view.dart rename to lib/pangea/analytics_details_popup/morph_analytics_list_view.dart index d6aff43ed..9d6ae3209 100644 --- a/lib/pangea/analytics_details_popup/morph_analytics_view.dart +++ b/lib/pangea/analytics_details_popup/morph_analytics_list_view.dart @@ -5,20 +5,22 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/analytics_details_popup/analytics_details_popup.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_level_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; +import 'package:fluffychat/pangea/constructs/construct_level_enum.dart'; +import 'package:fluffychat/pangea/instructions/instructions_enum.dart'; +import 'package:fluffychat/pangea/instructions/instructions_inline_tooltip.dart'; import 'package:fluffychat/pangea/morphs/get_grammar_copy.dart'; import 'package:fluffychat/pangea/morphs/morph_icon.dart'; import 'package:fluffychat/pangea/user/client_extension.dart'; import 'package:fluffychat/widgets/matrix.dart'; -class MorphAnalyticsView extends StatelessWidget { +class MorphAnalyticsListView extends StatelessWidget { final void Function(ConstructIdentifier) onConstructZoom; final AnalyticsPopupWrapperState controller; - const MorphAnalyticsView({ + const MorphAnalyticsListView({ required this.onConstructZoom, required this.controller, super.key, @@ -27,23 +29,35 @@ class MorphAnalyticsView extends StatelessWidget { @override Widget build(BuildContext context) { return Padding( - padding: const EdgeInsets.symmetric(vertical: 20), - child: ListView.builder( - key: const PageStorageKey('morph-analytics'), - itemCount: controller.features.length, - itemBuilder: (context, index) { - final feature = controller.features[index]; - return feature.displayTags.isNotEmpty - ? MorphFeatureBox( - morphFeature: feature.feature, - allTags: controller.morphs - .getDisplayTags(feature.feature) - .map((tag) => tag.toLowerCase()) - .toSet(), - onConstructZoom: onConstructZoom, - ) - : const SizedBox.shrink(); - }, + padding: const EdgeInsets.symmetric(vertical: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + // spacing: 16.0, + children: [ + // Add your text widget here + const InstructionsInlineTooltip( + instructionsEnum: InstructionsEnum.morphAnalyticsList, + ), + Expanded( + child: ListView.builder( + key: const PageStorageKey('morph-analytics'), + itemCount: controller.features.length, + itemBuilder: (context, index) { + final feature = controller.features[index]; + return feature.displayTags.isNotEmpty + ? MorphFeatureBox( + morphFeature: feature.feature, + allTags: controller.morphs + .getDisplayTags(feature.feature) + .map((tag) => tag.toLowerCase()) + .toSet(), + onConstructZoom: onConstructZoom, + ) + : const SizedBox.shrink(); + }, + ), + ), + ], ), ); } diff --git a/lib/pangea/analytics_details_popup/morph_details_view.dart b/lib/pangea/analytics_details_popup/morph_details_view.dart index f645b7758..1b90d6bab 100644 --- a/lib/pangea/analytics_details_popup/morph_details_view.dart +++ b/lib/pangea/analytics_details_popup/morph_details_view.dart @@ -4,10 +4,10 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:fluffychat/pangea/analytics_details_popup/analytics_details_popup_content.dart'; import 'package:fluffychat/pangea/analytics_details_popup/morph_meaning_widget.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_level_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; import 'package:fluffychat/pangea/analytics_misc/text_loading_shimmer.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; +import 'package:fluffychat/pangea/constructs/construct_level_enum.dart'; import 'package:fluffychat/pangea/lemmas/construct_xp_widget.dart'; import 'package:fluffychat/pangea/morphs/morph_feature_display.dart'; import 'package:fluffychat/pangea/morphs/morph_meaning/morph_info_repo.dart'; diff --git a/lib/pangea/analytics_details_popup/vocab_details_view.dart b/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart similarity index 92% rename from lib/pangea/analytics_details_popup/vocab_details_view.dart rename to lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart index 5b321365e..d90acf55f 100644 --- a/lib/pangea/analytics_details_popup/vocab_details_view.dart +++ b/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart @@ -4,11 +4,10 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:material_symbols_icons/symbols.dart'; import 'package:fluffychat/pangea/analytics_details_popup/analytics_details_popup_content.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_level_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_type_enum.dart'; -import 'package:fluffychat/pangea/common/widgets/customized_svg.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; +import 'package:fluffychat/pangea/constructs/construct_level_enum.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_text_model.dart'; import 'package:fluffychat/pangea/lemmas/lemma.dart'; @@ -178,16 +177,7 @@ class VocabDetailsView extends StatelessWidget { ], ), ), - xpIcon: CustomizedSvg( - svgUrl: _construct.lemmaCategory.svgURL, - colorReplacements: const {}, - errorIcon: Text( - _construct.lemmaCategory.emoji, - style: const TextStyle( - fontSize: 20, - ), - ), - ), + xpIcon: _construct.lemmaCategory.icon(12), constructId: constructId, ); } diff --git a/lib/pangea/analytics_details_popup/vocab_analytics_list_tile.dart b/lib/pangea/analytics_details_popup/vocab_analytics_list_tile.dart new file mode 100644 index 000000000..2e56cb8c4 --- /dev/null +++ b/lib/pangea/analytics_details_popup/vocab_analytics_list_tile.dart @@ -0,0 +1,84 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; +import 'package:fluffychat/pangea/constructs/construct_level_enum.dart'; +import 'package:fluffychat/pangea/toolbar/utils/shrinkable_text.dart'; + +class VocabAnalyticsListTile extends StatefulWidget { + const VocabAnalyticsListTile({ + super.key, + required this.constructUse, + required this.onTap, + }); + + final void Function() onTap; + final ConstructUses constructUse; + + @override + VocabAnalyticsListTileState createState() => VocabAnalyticsListTileState(); +} + +class VocabAnalyticsListTileState extends State { + bool _isHovered = false; + + final double maxWidth = 100; + final double padding = 8.0; + + @override + Widget build(BuildContext context) { + return MouseRegion( + onEnter: (_) => setState(() => _isHovered = true), + onExit: (_) => setState(() => _isHovered = false), + child: InkWell( + borderRadius: BorderRadius.circular(AppConfig.borderRadius), + onTap: widget.onTap, + child: Container( + height: maxWidth, + width: maxWidth, + padding: EdgeInsets.all(padding), + decoration: BoxDecoration( + color: _isHovered + ? widget.constructUse.constructLevel.color.withAlpha(30) + : Colors.transparent, + borderRadius: BorderRadius.circular(AppConfig.borderRadius), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + alignment: Alignment.center, + height: (maxWidth - padding * 2) * 0.6, + child: Opacity( + opacity: + widget.constructUse.id.userSetEmoji == null ? 0.2 : 1, + child: widget.constructUse.id.userSetEmoji != null + ? Text( + widget.constructUse.id.userSetEmoji!, + style: const TextStyle( + fontSize: 22, + ), + ) + : widget.constructUse.constructLevel.icon(10), + ), + ), + Container( + alignment: Alignment.topCenter, + padding: const EdgeInsets.only(top: 4), + height: (maxWidth - padding * 2) * 0.4, + child: ShrinkableText( + text: widget.constructUse.lemma, + maxWidth: maxWidth - padding * 2, + style: TextStyle( + fontSize: 16, + color: widget.constructUse.constructLevel.color, + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/pangea/analytics_details_popup/vocab_analytics_list_view.dart b/lib/pangea/analytics_details_popup/vocab_analytics_list_view.dart new file mode 100644 index 000000000..bfd45071f --- /dev/null +++ b/lib/pangea/analytics_details_popup/vocab_analytics_list_view.dart @@ -0,0 +1,69 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/analytics_details_popup/vocab_analytics_list_tile.dart'; +import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; +import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; +import 'package:fluffychat/pangea/constructs/construct_level_enum.dart'; +import 'package:fluffychat/pangea/instructions/instructions_enum.dart'; +import 'package:fluffychat/pangea/instructions/instructions_inline_tooltip.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +/// Displays vocab analytics, sorted into categories +/// (flowers, greens, and seeds) by points +class VocabAnalyticsListView extends StatelessWidget { + final void Function(ConstructIdentifier) onConstructZoom; + + List get vocab => MatrixState + .pangeaController.getAnalytics.constructListModel + .constructList(type: ConstructTypeEnum.vocab) + ..sort((a, b) => a.lemma.toLowerCase().compareTo(b.lemma.toLowerCase())); + + const VocabAnalyticsListView({ + super.key, + required this.onConstructZoom, + }); + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: Column( + children: [ + const InstructionsInlineTooltip( + instructionsEnum: InstructionsEnum.analyticsVocabList, + ), + Padding( + padding: const EdgeInsets.all(16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 50, + children: ConstructLevelEnum.values.reversed + .map((constructLevelCategory) { + final int count = vocab + .where((e) => e.lemmaCategory == constructLevelCategory) + .length; + + return Badge( + label: Text(count.toString()), + child: constructLevelCategory.icon(24), + ); + }).toList(), + ), + ), + Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + runAlignment: WrapAlignment.start, + children: vocab + .map( + (vocab) => VocabAnalyticsListTile( + onTap: () => onConstructZoom(vocab.id), + constructUse: vocab, + ), + ) + .toList(), + ), + ], + ), + ); + } +} diff --git a/lib/pangea/analytics_details_popup/vocab_analytics_view.dart b/lib/pangea/analytics_details_popup/vocab_analytics_view.dart deleted file mode 100644 index 828bc1eac..000000000 --- a/lib/pangea/analytics_details_popup/vocab_analytics_view.dart +++ /dev/null @@ -1,182 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:collection/collection.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:matrix/matrix.dart'; - -import 'package:fluffychat/pangea/analytics_misc/analytics_constants.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_level_enum.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; -import 'package:fluffychat/pangea/common/widgets/customized_svg.dart'; -import 'package:fluffychat/pangea/morphs/get_grammar_copy.dart'; -import 'package:fluffychat/widgets/matrix.dart'; - -/// Displays vocab analytics, sorted into categories -/// (flowers, greens, and seeds) by points -class VocabAnalyticsView extends StatelessWidget { - final void Function(ConstructIdentifier) onConstructZoom; - - const VocabAnalyticsView({ - super.key, - required this.onConstructZoom, - }); - - @override - Widget build(BuildContext context) { - final lemmas = MatrixState.pangeaController.getAnalytics.constructListModel - .constructList(type: ConstructTypeEnum.vocab) - ..sort((a, b) => a.lemma.toLowerCase().compareTo(b.lemma.toLowerCase())); - - final flowerLemmas = []; - final greenLemmas = []; - final seedLemmas = []; - for (int i = 0; i < lemmas.length; i++) { - final construct = lemmas[i]; - if (construct.lemma.isEmpty) continue; - final int points = construct.points; - String? displayText; - // Check if previous or next entry has same lemma as this entry - if ((i > 0 && lemmas[i - 1].lemma.equals(construct.lemma)) || - (i < lemmas.length - 1 && - lemmas[i + 1].lemma.equals(construct.lemma))) { - final pos = getGrammarCopy( - category: "pos", - lemma: construct.category, - context: context, - ) ?? - construct.category; - displayText = "${construct.lemma} (${pos.toLowerCase()})"; - } - final lemma = VocabChip( - construct: construct, - displayText: displayText, - ); - // Sort lemmas into categories - if (points < AnalyticsConstants.xpForGreens) { - seedLemmas.add(lemma); - } else if (points >= AnalyticsConstants.xpForFlower) { - flowerLemmas.add(lemma); - } else { - greenLemmas.add(lemma); - } - } - - final flowers = LemmaListSection( - type: ConstructLevelEnum.flowers, - lemmas: flowerLemmas, - onTap: onConstructZoom, - ); - final greens = LemmaListSection( - type: ConstructLevelEnum.greens, - lemmas: greenLemmas, - onTap: onConstructZoom, - ); - final seeds = LemmaListSection( - type: ConstructLevelEnum.seeds, - lemmas: seedLemmas, - onTap: onConstructZoom, - ); - - return Padding( - padding: const EdgeInsets.symmetric(vertical: 20), - child: ListView( - key: const PageStorageKey('vocab-analytics'), - children: [flowers, greens, seeds], - ), - ); - } -} - -class VocabChip { - final ConstructUses construct; - final String? displayText; - - VocabChip({ - required this.construct, - this.displayText, - }); -} - -class LemmaListSection extends StatelessWidget { - final ConstructLevelEnum type; - final List lemmas; - final Function(ConstructIdentifier) onTap; - - const LemmaListSection({ - super.key, - required this.type, - required this.lemmas, - required this.onTap, - }); - - @override - Widget build(BuildContext context) { - final theme = Theme.of(context); - final fontColor = - theme.brightness == Brightness.dark ? type.color : type.darkColor; - return Container( - padding: const EdgeInsets.all(16.0), - margin: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(16.0), - border: Border.all(color: type.color, width: 2), - ), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - CustomizedSvg( - svgUrl: type.svgURL, - colorReplacements: const {}, - errorIcon: Text(type.emoji), - ), - ], - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: lemmas.isEmpty - ? Text( - L10n.of(context).noLemmasFound(type.xpNeeded), - style: TextStyle( - color: fontColor, - fontStyle: FontStyle.italic, - ), - ) - : Wrap( - spacing: 0, - runSpacing: 0, - children: lemmas.mapIndexed((index, lemma) { - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - onTap: () => onTap(lemma.construct.id), - child: Text( - "${lemma.displayText ?? lemma.construct.lemma}${index < lemmas.length - 1 ? ', ' : ''}", - style: TextStyle( - shadows: [ - Shadow( - color: fontColor, - offset: const Offset(0, -2.5), - ), - ], - color: Colors.transparent, - decoration: TextDecoration.underline, - decorationStyle: TextDecorationStyle.dotted, - decorationColor: fontColor, - decorationThickness: 1, - fontSize: theme.textTheme.bodyLarge?.fontSize, - ), - ), - ), - ); - }).toList(), - ), - ), - ], - ), - ); - } -} diff --git a/lib/pangea/analytics_misc/construct_list_model.dart b/lib/pangea/analytics_misc/construct_list_model.dart index 08b442de6..28e17fc2c 100644 --- a/lib/pangea/analytics_misc/construct_list_model.dart +++ b/lib/pangea/analytics_misc/construct_list_model.dart @@ -5,11 +5,11 @@ import 'package:flutter/material.dart'; import 'package:collection/collection.dart'; import 'package:fluffychat/pangea/analytics_misc/analytics_constants.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; import 'package:fluffychat/pangea/morphs/get_grammar_copy.dart'; /// A wrapper around a list of [OneConstructUse]s, used to simplify diff --git a/lib/pangea/analytics_misc/construct_use_model.dart b/lib/pangea/analytics_misc/construct_use_model.dart index b27c890e0..c244f87ef 100644 --- a/lib/pangea/analytics_misc/construct_use_model.dart +++ b/lib/pangea/analytics_misc/construct_use_model.dart @@ -1,9 +1,9 @@ import 'package:fluffychat/pangea/analytics_misc/analytics_constants.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_level_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; +import 'package:fluffychat/pangea/constructs/construct_level_enum.dart'; /// One lemma and a list of construct uses for that lemma class ConstructUses { diff --git a/lib/pangea/analytics_misc/constructs_model.dart b/lib/pangea/analytics_misc/constructs_model.dart index f744ff8e0..756da3ad0 100644 --- a/lib/pangea/analytics_misc/constructs_model.dart +++ b/lib/pangea/analytics_misc/constructs_model.dart @@ -4,9 +4,9 @@ import 'package:flutter/foundation.dart'; import 'package:matrix/matrix.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_type_enum.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; import 'package:fluffychat/pangea/morphs/default_morph_mapping.dart'; import 'package:fluffychat/pangea/morphs/morph_models.dart'; import 'construct_type_enum.dart'; @@ -97,7 +97,7 @@ class OneConstructUse { this.id, }) : _category = category ?? "other"; - String get chatId => metadata.roomId; + String? get chatId => metadata.roomId; String get msgId => metadata.eventId!; DateTime get timeStamp => metadata.timeStamp; @@ -177,7 +177,8 @@ class OneConstructUse { } Room? getRoom(Client client) { - return client.getRoomById(metadata.roomId); + if (metadata.roomId == null) return null; + return client.getRoomById(metadata.roomId!); } Future getEvent(Client client) async { @@ -197,7 +198,7 @@ class OneConstructUse { class ConstructUseMetaData { String? eventId; - String roomId; + String? roomId; DateTime timeStamp; ConstructUseMetaData({ diff --git a/lib/pangea/analytics_misc/message_analytics_controller.dart b/lib/pangea/analytics_misc/message_analytics_controller.dart index acb9f6314..3a51dbf52 100644 --- a/lib/pangea/analytics_misc/message_analytics_controller.dart +++ b/lib/pangea/analytics_misc/message_analytics_controller.dart @@ -1,7 +1,7 @@ import 'package:flutter/foundation.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; import 'package:fluffychat/pangea/analytics_misc/get_analytics_controller.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; import 'package:fluffychat/pangea/toolbar/enums/activity_type_enum.dart'; diff --git a/lib/pangea/analytics_misc/put_analytics_controller.dart b/lib/pangea/analytics_misc/put_analytics_controller.dart index 694b8d7e9..06aab4ce8 100644 --- a/lib/pangea/analytics_misc/put_analytics_controller.dart +++ b/lib/pangea/analytics_misc/put_analytics_controller.dart @@ -119,13 +119,16 @@ class PutAnalyticsController extends BaseController { /// the data locally and reset the update timer /// Decide whether to update the analytics room void _onNewAnalyticsData(AnalyticsStream data) { - final List constructs = _getDraftUses(data.roomId); + final String? eventID = data.eventId; + final String? roomID = data.roomId; + + List constructs = []; + if (roomID != null) { + constructs = _getDraftUses(roomID); + } constructs.addAll(data.constructs); - final String eventID = data.eventId; - final String roomID = data.roomId; - if (kDebugMode) { for (final use in constructs) { debugPrint( @@ -138,7 +141,7 @@ class PutAnalyticsController extends BaseController { _addLocalMessage(eventID, constructs).then( (_) { - _clearDraftUses(roomID); + if (roomID != null) _clearDraftUses(roomID); _decideWhetherToUpdateAnalyticsRoom( level, data.origin, @@ -245,7 +248,7 @@ class PutAnalyticsController extends BaseController { /// Add a list of construct uses for a new message to the local /// cache of recently sent messages Future _addLocalMessage( - String cacheKey, + String? cacheKey, List constructs, ) async { try { @@ -254,7 +257,7 @@ class PutAnalyticsController extends BaseController { // if this is not a draft message, add the eventId to the metadata // if it's missing (it will be missing for draft constructs) - if (!cacheKey.startsWith('draft')) { + if (cacheKey != null && !cacheKey.startsWith('draft')) { constructs = constructs.map((construct) { if (construct.metadata.eventId != null) return construct; construct.metadata.eventId = cacheKey; @@ -262,6 +265,7 @@ class PutAnalyticsController extends BaseController { }).toList(); } + cacheKey ??= Object.hashAll(constructs).toString(); currentCache[cacheKey] = constructs; await _setMessagesSinceUpdate(currentCache); @@ -425,8 +429,8 @@ class PutAnalyticsController extends BaseController { } class AnalyticsStream { - final String eventId; - final String roomId; + final String? eventId; + final String? roomId; final AnalyticsUpdateOrigin? origin; final List constructs; diff --git a/lib/pangea/common/network/urls.dart b/lib/pangea/common/network/urls.dart index 6851369a9..72335b64d 100644 --- a/lib/pangea/common/network/urls.dart +++ b/lib/pangea/common/network/urls.dart @@ -72,6 +72,8 @@ class PApiUrls { static String activityModeList = "${PApiUrls.choreoEndpoint}/modes"; static String objectiveList = "${PApiUrls.choreoEndpoint}/objectives"; static String topicList = "${PApiUrls.choreoEndpoint}/topics"; + static String activityPlanSearch = + "${PApiUrls.choreoEndpoint}/activity_plan/search"; static String morphFeaturesAndTags = "${PApiUrls.choreoEndpoint}/morphs"; diff --git a/lib/pangea/common/widgets/customized_svg.dart b/lib/pangea/common/widgets/customized_svg.dart index 08f1ad53a..b326b9d6d 100644 --- a/lib/pangea/common/widgets/customized_svg.dart +++ b/lib/pangea/common/widgets/customized_svg.dart @@ -16,12 +16,24 @@ class CustomizedSvg extends StatelessWidget { /// Icon to show in case of error final Widget errorIcon; + /// Width of the SVG + /// Default is 24 + /// If you want to keep the aspect ratio, set only the height + final double? width; + + /// Height of the SVG + /// Default is 24 + /// If you want to keep the aspect ratio, set only the width + final double? height; + static final GetStorage _svgStorage = GetStorage('svg_cache'); const CustomizedSvg({ super.key, required this.svgUrl, required this.colorReplacements, this.errorIcon = const Icon(Icons.error_outline), + this.width = 24, + this.height = 24, }); Future _fetchSvg() async { @@ -110,7 +122,11 @@ class CustomizedSvg extends StatelessWidget { } else if (snapshot.hasError || snapshot.data == null) { return errorIcon; } else if (snapshot.hasData) { - return SvgPicture.string(snapshot.data!); + return SvgPicture.string( + snapshot.data!, + width: width, + height: height, + ); } else { return const SizedBox.shrink(); } diff --git a/lib/pangea/analytics_misc/construct_identifier.dart b/lib/pangea/constructs/construct_identifier.dart similarity index 66% rename from lib/pangea/analytics_misc/construct_identifier.dart rename to lib/pangea/constructs/construct_identifier.dart index 893def0c7..823ce429e 100644 --- a/lib/pangea/analytics_misc/construct_identifier.dart +++ b/lib/pangea/constructs/construct_identifier.dart @@ -12,6 +12,9 @@ import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; import 'package:fluffychat/pangea/common/constants/model_keys.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart'; +import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart'; +import 'package:fluffychat/pangea/lemmas/lemma_info_repo.dart'; +import 'package:fluffychat/pangea/lemmas/lemma_info_request.dart'; import 'package:fluffychat/widgets/matrix.dart'; class ConstructIdentifier { @@ -126,4 +129,51 @@ class ConstructIdentifier { } return null; } + + /// [setEmoji] sets the emoji for the lemma + /// NOTE: assumes that the language of the lemma is the same as the user's current l2 + Future setEmoji(String emoji) async { + final analyticsRoom = + MatrixState.pangeaController.matrixState.client.analyticsRoomLocal(); + if (analyticsRoom == null) return; + try { + final client = MatrixState.pangeaController.matrixState.client; + final syncFuture = client.onRoomState.stream.firstWhere((event) { + return event.roomId == analyticsRoom.id && + event.state.type == PangeaEventTypes.userChosenEmoji; + }); + client.setRoomStateWithKey( + analyticsRoom.id, + PangeaEventTypes.userChosenEmoji, + string, + {ModelKey.emoji: emoji}, + ); + await syncFuture; + } catch (err, s) { + debugger(when: kDebugMode); + ErrorHandler.logError( + e: err, + data: { + "construct": string, + "emoji": emoji, + }, + s: s, + ); + } + } + + // [getEmojiChoices] gets the emoji choices for the lemma + // assumes that the language of the lemma is the same as the user's current l2 + Future> getEmojiChoices() => LemmaInfoRepo.get( + LemmaInfoRequest( + lemma: lemma, + partOfSpeech: category, + lemmaLang: MatrixState + .pangeaController.languageController.userL2?.langCode ?? + LanguageKeys.unknownLanguage, + userL1: MatrixState + .pangeaController.languageController.userL1?.langCode ?? + LanguageKeys.defaultLanguage, + ), + ).then((onValue) => onValue.emoji); } diff --git a/lib/pangea/analytics_misc/construct_level_enum.dart b/lib/pangea/constructs/construct_level_enum.dart similarity index 87% rename from lib/pangea/analytics_misc/construct_level_enum.dart rename to lib/pangea/constructs/construct_level_enum.dart index 2cac70791..e263bbc1a 100644 --- a/lib/pangea/analytics_misc/construct_level_enum.dart +++ b/lib/pangea/constructs/construct_level_enum.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/analytics_misc/analytics_constants.dart'; +import 'package:fluffychat/pangea/common/widgets/customized_svg.dart'; enum ConstructLevelEnum { flowers, @@ -79,4 +80,17 @@ extension ConstructLevelEnumExt on ConstructLevelEnum { return 0; } } + + Widget icon([double? size]) => CustomizedSvg( + svgUrl: svgURL, + colorReplacements: const {}, + errorIcon: Text( + emoji, + style: TextStyle( + fontSize: size ?? 24, + ), + ), + width: size, + height: size, + ); } diff --git a/lib/pangea/events/models/pangea_token_model.dart b/lib/pangea/events/models/pangea_token_model.dart index 6141e87c4..7ac8b341c 100644 --- a/lib/pangea/events/models/pangea_token_model.dart +++ b/lib/pangea/events/models/pangea_token_model.dart @@ -5,19 +5,14 @@ import 'package:flutter/foundation.dart'; import 'package:collection/collection.dart'; import 'package:fluffychat/pangea/analytics_misc/analytics_constants.dart'; -import 'package:fluffychat/pangea/analytics_misc/client_analytics_extension.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_level_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; -import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; +import 'package:fluffychat/pangea/constructs/construct_level_enum.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_text_model.dart'; -import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart'; -import 'package:fluffychat/pangea/lemmas/lemma_info_repo.dart'; -import 'package:fluffychat/pangea/lemmas/lemma_info_request.dart'; import 'package:fluffychat/pangea/morphs/morph_repo.dart'; import 'package:fluffychat/pangea/toolbar/enums/activity_type_enum.dart'; import 'package:fluffychat/pangea/toolbar/enums/message_mode_enum.dart'; @@ -543,18 +538,7 @@ class PangeaToken { .cast() .toList(); - Future> getEmojiChoices() => LemmaInfoRepo.get( - LemmaInfoRequest( - lemma: lemma.text, - partOfSpeech: pos, - lemmaLang: MatrixState - .pangeaController.languageController.userL2?.langCode ?? - LanguageKeys.unknownLanguage, - userL1: MatrixState - .pangeaController.languageController.userL1?.langCode ?? - LanguageKeys.defaultLanguage, - ), - ).then((onValue) => onValue.emoji); + Future> getEmojiChoices() => vocabConstructID.getEmojiChoices(); ConstructIdentifier get vocabConstructID => ConstructIdentifier( lemma: lemma.text, @@ -562,37 +546,7 @@ class PangeaToken { category: pos, ); - /// [setEmoji] sets the emoji for the lemma - /// NOTE: assumes that the language of the lemma is the same as the user's current l2 - Future setEmoji(String emoji) async { - final analyticsRoom = - MatrixState.pangeaController.matrixState.client.analyticsRoomLocal(); - if (analyticsRoom == null) return; - try { - final client = MatrixState.pangeaController.matrixState.client; - final syncFuture = client.onRoomState.stream.firstWhere((event) { - return event.roomId == analyticsRoom.id && - event.state.type == PangeaEventTypes.userChosenEmoji; - }); - client.setRoomStateWithKey( - analyticsRoom.id, - PangeaEventTypes.userChosenEmoji, - vocabConstructID.string, - {ModelKey.emoji: emoji}, - ); - await syncFuture; - } catch (err, s) { - debugger(when: kDebugMode); - ErrorHandler.logError( - e: err, - data: { - "construct": vocabConstructID.string, - "emoji": emoji, - }, - s: s, - ); - } - } + Future setEmoji(String emoji) => vocabConstructID.setEmoji(emoji); /// [getEmoji] gets the emoji for the lemma /// NOTE: assumes that the language of the lemma is the same as the user's current l2 diff --git a/lib/pangea/instructions/instructions_enum.dart b/lib/pangea/instructions/instructions_enum.dart index bd97ebb20..587b0c29e 100644 --- a/lib/pangea/instructions/instructions_enum.dart +++ b/lib/pangea/instructions/instructions_enum.dart @@ -24,6 +24,8 @@ enum InstructionsEnum { activityPlannerOverview, ttsDisabled, chooseEmoji, + analyticsVocabList, + morphAnalyticsList, } extension InstructionsEnumExtension on InstructionsEnum { @@ -50,6 +52,8 @@ extension InstructionsEnumExtension on InstructionsEnum { case InstructionsEnum.clickBestOption: case InstructionsEnum.completeActivitiesToUnlock: case InstructionsEnum.lemmaMeaning: + case InstructionsEnum.analyticsVocabList: + case InstructionsEnum.morphAnalyticsList: ErrorHandler.logError( e: Exception("No title for this instruction"), m: 'InstructionsEnumExtension.title', @@ -96,6 +100,10 @@ extension InstructionsEnumExtension on InstructionsEnum { return l10n.chooseEmojiInstructionsBody; case InstructionsEnum.ttsDisabled: return l10n.ttsDisabledBody; + case InstructionsEnum.analyticsVocabList: + return l10n.analyticsVocabListBody; + case InstructionsEnum.morphAnalyticsList: + return l10n.morphAnalyticsListBody; } } diff --git a/lib/pangea/instructions/instructions_inline_tooltip.dart b/lib/pangea/instructions/instructions_inline_tooltip.dart index 48cc4a0a4..7943df3d3 100644 --- a/lib/pangea/instructions/instructions_inline_tooltip.dart +++ b/lib/pangea/instructions/instructions_inline_tooltip.dart @@ -69,7 +69,7 @@ class InstructionsInlineTooltipState extends State child: DecoratedBox( decoration: BoxDecoration( borderRadius: BorderRadius.circular(AppConfig.borderRadius), - color: Theme.of(context).colorScheme.primary.withAlpha(20), + color: Theme.of(context).colorScheme.primary.withAlpha(5), ), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8), diff --git a/lib/pangea/lemmas/construct_xp_widget.dart b/lib/pangea/lemmas/construct_xp_widget.dart index 39874040a..e4a5ebd92 100644 --- a/lib/pangea/lemmas/construct_xp_widget.dart +++ b/lib/pangea/lemmas/construct_xp_widget.dart @@ -2,11 +2,10 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_level_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; import 'package:fluffychat/pangea/analytics_misc/get_analytics_controller.dart'; -import 'package:fluffychat/pangea/common/widgets/customized_svg.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; +import 'package:fluffychat/pangea/constructs/construct_level_enum.dart'; import 'package:fluffychat/widgets/matrix.dart'; /// display the construct xp widget @@ -90,17 +89,7 @@ class ConstructXpWidgetState extends State Stream get stream => MatrixState.pangeaController.getAnalytics.analyticsStream.stream; - Widget get svg => CustomizedSvg( - svgUrl: - constructLemmaCategory?.svgURL ?? ConstructLevelEnum.seeds.svgURL, - colorReplacements: const {}, - errorIcon: Text( - constructLemmaCategory?.emoji ?? ConstructLevelEnum.seeds.svgURL, - style: const TextStyle( - fontSize: 20, - ), - ), - ); + Widget get svg => constructLemmaCategory?.icon() ?? const SizedBox(); @override void dispose() { diff --git a/lib/pangea/toolbar/enums/activity_type_enum.dart b/lib/pangea/toolbar/enums/activity_type_enum.dart index 6512edb7c..6ef056369 100644 --- a/lib/pangea/toolbar/enums/activity_type_enum.dart +++ b/lib/pangea/toolbar/enums/activity_type_enum.dart @@ -2,9 +2,9 @@ import 'package:flutter/material.dart'; import 'package:material_symbols_icons/symbols.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_type_enum.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; enum ActivityTypeEnum { wordMeaning, diff --git a/lib/pangea/toolbar/models/practice_activity_model.dart b/lib/pangea/toolbar/models/practice_activity_model.dart index 35862abe4..53b3a2105 100644 --- a/lib/pangea/toolbar/models/practice_activity_model.dart +++ b/lib/pangea/toolbar/models/practice_activity_model.dart @@ -7,8 +7,8 @@ import 'package:collection/collection.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; import 'package:fluffychat/pangea/morphs/morph_categories_enum.dart'; import 'package:fluffychat/pangea/toolbar/enums/activity_display_instructions_enum.dart'; diff --git a/lib/pangea/toolbar/reading_assistance_input_row/message_emoji_choice.dart b/lib/pangea/toolbar/reading_assistance_input_row/message_emoji_choice.dart index 17eaab29f..4126ab1c5 100644 --- a/lib/pangea/toolbar/reading_assistance_input_row/message_emoji_choice.dart +++ b/lib/pangea/toolbar/reading_assistance_input_row/message_emoji_choice.dart @@ -5,9 +5,9 @@ import 'package:matrix/matrix.dart'; import 'package:fluffychat/config/app_emojis.dart'; import 'package:fluffychat/pages/chat/chat.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_level_enum.dart'; -import 'package:fluffychat/pangea/common/widgets/customized_svg.dart'; +import 'package:fluffychat/pangea/constructs/construct_level_enum.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; +import 'package:fluffychat/pangea/toolbar/enums/activity_type_enum.dart'; import 'package:fluffychat/pangea/toolbar/reading_assistance_input_row/message_emoji_choice_item.dart'; import 'package:fluffychat/pangea/toolbar/widgets/message_selection_overlay.dart'; import 'package:fluffychat/widgets/future_loading_dialog.dart'; @@ -82,13 +82,18 @@ class MessageEmojiChoice extends StatelessWidget { isSelected: false, onDoubleTap: () => onDoubleTapOrLongPress(context, emoji), onLongPress: () => onDoubleTapOrLongPress(context, emoji), - token: null, + greenHighlight: false, ), ) .toList(); List perTokenEmoji(BuildContext context) => tokens!.where((token) => token.lemma.saveVocab).map((token) { + final bool greenHighlight = token.shouldDoActivity( + a: ActivityTypeEnum.wordMeaning, + feature: null, + tag: null, + ); if (!token.lemma.saveVocab) { return MessageEmojiChoiceItem( content: token.text.content, @@ -96,7 +101,7 @@ class MessageEmojiChoice extends StatelessWidget { isSelected: overlayController.isTokenSelected(token), onDoubleTap: null, onLongPress: null, - token: token, + greenHighlight: greenHighlight, ); } @@ -104,18 +109,14 @@ class MessageEmojiChoice extends StatelessWidget { if (emoji == null) { return MessageEmojiChoiceItem( - topContent: CustomizedSvg( - svgUrl: token.vocabConstruct.constructLevel.svgURL, - colorReplacements: const {}, - errorIcon: Text(token.xpEmoji), - ), + topContent: token.vocabConstruct.constructLevel.icon(), content: token.text.content, onTap: () => overlayController.onClickOverlayMessageToken(token), onDoubleTap: null, onLongPress: null, isSelected: overlayController.isTokenSelected(token), contentOpacity: 0.1, - token: token, + greenHighlight: greenHighlight, ); } @@ -129,7 +130,7 @@ class MessageEmojiChoice extends StatelessWidget { onDoubleTap: () => onDoubleTapOrLongPress(context, emoji), onLongPress: () => onDoubleTapOrLongPress(context, emoji), isSelected: overlayController.isTokenSelected(token), - token: token, + greenHighlight: greenHighlight, ); }).toList(); diff --git a/lib/pangea/toolbar/reading_assistance_input_row/message_emoji_choice_item.dart b/lib/pangea/toolbar/reading_assistance_input_row/message_emoji_choice_item.dart index e80060741..2642e05cc 100644 --- a/lib/pangea/toolbar/reading_assistance_input_row/message_emoji_choice_item.dart +++ b/lib/pangea/toolbar/reading_assistance_input_row/message_emoji_choice_item.dart @@ -1,8 +1,6 @@ import 'package:flutter/material.dart'; import 'package:fluffychat/config/app_config.dart'; -import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; -import 'package:fluffychat/pangea/toolbar/enums/activity_type_enum.dart'; class MessageEmojiChoiceItem extends StatefulWidget { const MessageEmojiChoiceItem({ @@ -15,7 +13,7 @@ class MessageEmojiChoiceItem extends StatefulWidget { this.onLongPress, required this.isSelected, this.contentOpacity = 1.0, - required this.token, + required this.greenHighlight, }); final Widget? topContent; @@ -26,7 +24,7 @@ class MessageEmojiChoiceItem extends StatefulWidget { final bool isSelected; final double textSize; final double contentOpacity; - final PangeaToken? token; + final bool greenHighlight; @override MessageEmojiChoiceItemState createState() => MessageEmojiChoiceItemState(); @@ -54,12 +52,7 @@ class MessageEmojiChoiceItemState extends State { ? AppConfig.primaryColor.withAlpha((0.2 * 255).toInt()) : _isHovered ? AppConfig.primaryColor.withAlpha((0.1 * 255).toInt()) - : widget.token?.shouldDoActivity( - a: ActivityTypeEnum.wordMeaning, - feature: null, - tag: null, - ) ?? - false + : widget.greenHighlight ? AppConfig.success.withAlpha((0.1 * 255).toInt()) : Colors.transparent, borderRadius: BorderRadius.circular(AppConfig.borderRadius), diff --git a/lib/pangea/toolbar/reading_assistance_input_row/reading_assistance_input_bar.dart b/lib/pangea/toolbar/reading_assistance_input_row/reading_assistance_input_bar.dart index 811051dc5..7fafcbdda 100644 --- a/lib/pangea/toolbar/reading_assistance_input_row/reading_assistance_input_bar.dart +++ b/lib/pangea/toolbar/reading_assistance_input_row/reading_assistance_input_bar.dart @@ -87,8 +87,10 @@ class ReadingAssistanceInputBar extends StatelessWidget { case MessageMode.wordEmoji: return WordEmojiChoice( - overlayController: overlayController, - token: overlayController.selectedToken!, + form: overlayController.selectedToken!.text.content, + onEmojiChosen: () => + overlayController.onActivityFinish(ActivityTypeEnum.emoji), + constructID: overlayController.selectedToken!.vocabConstructID, ); case MessageMode.wordMeaning: diff --git a/lib/pangea/toolbar/reading_assistance_input_row/word_emoji_choice.dart b/lib/pangea/toolbar/reading_assistance_input_row/word_emoji_choice.dart index 47a7dd6d0..47e633d85 100644 --- a/lib/pangea/toolbar/reading_assistance_input_row/word_emoji_choice.dart +++ b/lib/pangea/toolbar/reading_assistance_input_row/word_emoji_choice.dart @@ -9,22 +9,26 @@ import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart'; import 'package:fluffychat/pangea/analytics_misc/put_analytics_controller.dart'; import 'package:fluffychat/pangea/choreographer/widgets/choice_array.dart'; import 'package:fluffychat/pangea/choreographer/widgets/it_shimmer.dart'; -import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; import 'package:fluffychat/pangea/instructions/instructions_enum.dart'; import 'package:fluffychat/pangea/instructions/instructions_inline_tooltip.dart'; -import 'package:fluffychat/pangea/toolbar/enums/activity_type_enum.dart'; -import 'package:fluffychat/pangea/toolbar/widgets/message_selection_overlay.dart'; import 'package:fluffychat/widgets/matrix.dart'; class WordEmojiChoice extends StatefulWidget { const WordEmojiChoice({ super.key, - required this.overlayController, - required this.token, + required this.constructID, + required this.onEmojiChosen, + required this.form, + this.roomId, + this.eventId, }); - final MessageOverlayController overlayController; - final PangeaToken token; + final ConstructIdentifier constructID; + final String form; + final String? roomId; + final String? eventId; + final void Function() onEmojiChosen; @override WordEmojiChoiceState createState() => WordEmojiChoiceState(); @@ -36,7 +40,7 @@ class WordEmojiChoiceState extends State { @override void initState() { super.initState(); - localSelected = widget.token.getEmoji(); + localSelected = widget.constructID.userSetEmoji; } Future onChoice(BuildContext context, emoji) async { @@ -44,33 +48,33 @@ class WordEmojiChoiceState extends State { MatrixState.pangeaController.putAnalytics.setState( AnalyticsStream( - eventId: widget.overlayController.pangeaMessageEvent!.eventId, - roomId: widget.overlayController.pangeaMessageEvent!.room.id, + eventId: widget.eventId, + roomId: widget.roomId, constructs: [ OneConstructUse( useType: ConstructUseTypeEnum.em, - lemma: widget.token.text.content, + lemma: widget.constructID.lemma, constructType: ConstructTypeEnum.vocab, metadata: ConstructUseMetaData( - roomId: widget.overlayController.pangeaMessageEvent!.room.id, + roomId: widget.roomId, timeStamp: DateTime.now(), - eventId: widget.overlayController.pangeaMessageEvent!.eventId, + eventId: widget.eventId, ), - category: widget.token.pos, - form: widget.token.text.content, + category: widget.constructID.category, + form: widget.form, ), ], origin: AnalyticsUpdateOrigin.wordZoom, ), ); - await widget.token.setEmoji(emoji); + await widget.constructID.setEmoji(emoji); await Future.delayed( const Duration(milliseconds: choiceArrayAnimationDuration), ); - widget.overlayController.onActivityFinish(ActivityTypeEnum.emoji); + widget.onEmojiChosen(); setState(() => {}); } @@ -83,7 +87,7 @@ class WordEmojiChoiceState extends State { mainAxisSize: MainAxisSize.max, children: [ FutureBuilder( - future: widget.token.getEmojiChoices(), + future: widget.constructID.getEmojiChoices(), builder: (context, snapshot) { if (snapshot.hasError) { return Text(L10n.of(context).oopsSomethingWentWrong); @@ -111,7 +115,7 @@ class WordEmojiChoiceState extends State { originalSpan: "😀", uniqueKeyForLayerLink: (int index) => "emojiChoice$index", selectedChoiceIndex: snapshot.data!.indexWhere( - (element) => element == widget.token.getEmoji(), + (element) => element == widget.constructID.userSetEmoji, ), tts: null, fontSize: 26, diff --git a/lib/pangea/toolbar/repo/lemma_meaning_activity_generator.dart b/lib/pangea/toolbar/repo/lemma_meaning_activity_generator.dart index b2bb65575..2ea835be1 100644 --- a/lib/pangea/toolbar/repo/lemma_meaning_activity_generator.dart +++ b/lib/pangea/toolbar/repo/lemma_meaning_activity_generator.dart @@ -2,9 +2,9 @@ import 'dart:async'; import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; import 'package:fluffychat/pangea/lemmas/lemma_info_repo.dart'; import 'package:fluffychat/pangea/lemmas/lemma_info_request.dart'; import 'package:fluffychat/pangea/lemmas/lemma_info_response.dart'; diff --git a/lib/pangea/toolbar/repo/morph_activity_generator.dart b/lib/pangea/toolbar/repo/morph_activity_generator.dart index 2b3e195e9..bcc5d1e7e 100644 --- a/lib/pangea/toolbar/repo/morph_activity_generator.dart +++ b/lib/pangea/toolbar/repo/morph_activity_generator.dart @@ -4,9 +4,9 @@ import 'package:flutter/foundation.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; import 'package:fluffychat/pangea/morphs/morph_categories_enum.dart'; import 'package:fluffychat/pangea/toolbar/enums/activity_type_enum.dart'; diff --git a/lib/pangea/toolbar/repo/word_meaning_static_practice_activity_model.dart b/lib/pangea/toolbar/repo/word_meaning_static_practice_activity_model.dart index ada7a2371..f840df254 100644 --- a/lib/pangea/toolbar/repo/word_meaning_static_practice_activity_model.dart +++ b/lib/pangea/toolbar/repo/word_meaning_static_practice_activity_model.dart @@ -1,5 +1,5 @@ -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_text_model.dart'; import 'package:fluffychat/pangea/lemmas/lemma.dart'; diff --git a/lib/pangea/toolbar/utils/shrinkable_text.dart b/lib/pangea/toolbar/utils/shrinkable_text.dart new file mode 100644 index 000000000..18968ec48 --- /dev/null +++ b/lib/pangea/toolbar/utils/shrinkable_text.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; + +class ShrinkableText extends StatelessWidget { + final String text; + final double maxWidth; + final TextStyle? style; + + const ShrinkableText({ + super.key, + required this.text, + required this.maxWidth, + this.style, + }); + + @override + Widget build(BuildContext context) { + return LayoutBuilder( + builder: (context, constraints) { + return Container( + constraints: BoxConstraints(maxWidth: maxWidth), + child: FittedBox( + fit: BoxFit.scaleDown, + alignment: Alignment.centerLeft, + child: Text( + text, + style: style, + ), + ), + ); + }, + ); + } +} diff --git a/lib/pangea/toolbar/widgets/message_selection_overlay.dart b/lib/pangea/toolbar/widgets/message_selection_overlay.dart index b8600e48e..a4565dc11 100644 --- a/lib/pangea/toolbar/widgets/message_selection_overlay.dart +++ b/lib/pangea/toolbar/widgets/message_selection_overlay.dart @@ -65,14 +65,6 @@ class MessageOverlayController extends State bool initialized = false; bool isPlayingAudio = false; - /// If non-null and not complete, the activity will be shown regardless of shouldDoActivity. - /// Used to show the practice activity card's savor the joy animation. - /// (Analytics sending triggers the point gain animation, do also - /// causes shouldDoActivity to be false. This is a workaround.) - Completer? _activityLock; - - // final bool _hideCenterContent = false; - /// The text that the toolbar should target /// If there is no selectedSpan, then the whole message is the target /// If there is a selectedSpan, then the target is the selected text @@ -326,10 +318,6 @@ class MessageOverlayController extends State selectedMorphFeature = null; break; case MessageMode.practiceActivity: - if (messageAnalyticsEntry?.nextActivity?.activityType == - ActivityTypeEnum.hiddenWordListening) { - _lockActivity(); - } break; case MessageMode.messageTextToSpeech: if (isPlayingAudio) { @@ -432,18 +420,6 @@ class MessageOverlayController extends State /// Functions ///////////////////////////////////// - ///@ggurdin - is this still needed? - void _lockActivity() { - if (mounted) setState(() => _activityLock = Completer()); - } - - void _unlockActivity() { - if (_activityLock == null) return; - _activityLock!.complete(); - _activityLock = null; - if (mounted) setState(() {}); - } - /// If sentence TTS is playing a word, highlight that word in message overlay void highlightCurrentText(int currentPosition, List ttsTokens) { final List textToSelect = []; @@ -485,10 +461,6 @@ class MessageOverlayController extends State /// When an activity is completed, we need to update the state /// and check if the toolbar should be unlocked void onActivityFinish(ActivityTypeEnum activityType) { - if (activityType == ActivityTypeEnum.hiddenWordListening) { - _unlockActivity(); - } - messageAnalyticsEntry!.onActivityComplete(); if (selectedToken == null) { diff --git a/lib/pangea/toolbar/widgets/word_zoom/morphs/morphological_center_widget.dart b/lib/pangea/toolbar/widgets/word_zoom/morphs/morphological_center_widget.dart index 28276b2b3..3005938b7 100644 --- a/lib/pangea/toolbar/widgets/word_zoom/morphs/morphological_center_widget.dart +++ b/lib/pangea/toolbar/widgets/word_zoom/morphs/morphological_center_widget.dart @@ -6,11 +6,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:fluffychat/pangea/analytics_details_popup/analytics_details_popup.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_level_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; import 'package:fluffychat/pangea/common/constants/model_keys.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; +import 'package:fluffychat/pangea/constructs/construct_level_enum.dart'; import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart'; diff --git a/lib/pangea/toolbar/widgets/word_zoom/word_zoom_widget.dart b/lib/pangea/toolbar/widgets/word_zoom/word_zoom_widget.dart index 4322d4fa8..34e245038 100644 --- a/lib/pangea/toolbar/widgets/word_zoom/word_zoom_widget.dart +++ b/lib/pangea/toolbar/widgets/word_zoom/word_zoom_widget.dart @@ -63,8 +63,6 @@ class WordZoomWidget extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisSize: MainAxisSize.min, - // crossAxisAlignment: CrossAxisAlignment.stretch, - // spacing: 4.0, children: [ Container( constraints: const BoxConstraints( diff --git a/lib/pangea/word_bank/vocab_bank_repo.dart b/lib/pangea/word_bank/vocab_bank_repo.dart index 69be552ee..ebabab373 100644 --- a/lib/pangea/word_bank/vocab_bank_repo.dart +++ b/lib/pangea/word_bank/vocab_bank_repo.dart @@ -6,12 +6,12 @@ import 'package:flutter/foundation.dart'; import 'package:get_storage/get_storage.dart'; import 'package:http/http.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.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'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart'; import 'package:fluffychat/pangea/learning_settings/models/language_model.dart'; import 'package:fluffychat/pangea/learning_settings/utils/p_language_store.dart'; diff --git a/lib/pangea/word_bank/vocab_response.dart b/lib/pangea/word_bank/vocab_response.dart index 951777cea..a66e4fe26 100644 --- a/lib/pangea/word_bank/vocab_response.dart +++ b/lib/pangea/word_bank/vocab_response.dart @@ -1,4 +1,4 @@ -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; class VocabResponse { List vocab; diff --git a/lib/pangea/writing_assistance/writing_assistance_input_row.dart b/lib/pangea/writing_assistance/writing_assistance_input_row.dart index 5dc14c5c9..40a14616e 100644 --- a/lib/pangea/writing_assistance/writing_assistance_input_row.dart +++ b/lib/pangea/writing_assistance/writing_assistance_input_row.dart @@ -9,8 +9,8 @@ import 'package:flutter/material.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat/chat.dart'; import 'package:fluffychat/pangea/analytics_misc/analytics_constants.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart'; import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart'; +import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart'; import 'package:fluffychat/pangea/toolbar/reading_assistance_input_row/message_emoji_choice_item.dart'; import 'package:fluffychat/pangea/word_bank/vocab_bank_repo.dart'; @@ -102,7 +102,7 @@ class WritingAssistanceInputRowState extends State { }, isSelected: false, textSize: 16, - token: null, + greenHighlight: false, ), ) .toList(),