From 1689fda54f184ac86b8ee8d1beb73329fc837373 Mon Sep 17 00:00:00 2001 From: ggurdin <46800240+ggurdin@users.noreply.github.com> Date: Tue, 31 Dec 2024 16:01:04 -0500 Subject: [PATCH] 1337 feedback on word card (#1339) * fix: don't give word meaning activity if there are no distractors available * fix: center activity / answer text in word zoom card * fix: after completing hidden word activity, wait for savor the joy to end before showing word zoom card --- assets/l10n/intl_en.arb | 3 ++- .../choreographer/widgets/choice_array.dart | 1 + lib/pangea/repo/lemma_definition_repo.dart | 4 ++-- .../word_meaning_activity_generator.dart | 4 ++-- lib/pangea/widgets/chat/message_toolbar.dart | 16 +++++++++++++-- .../practice_activity_card.dart | 5 ++++- .../contextual_translation_widget.dart | 5 ++++- .../widgets/word_zoom/word_zoom_widget.dart | 20 ++++++++++++++----- 8 files changed, 44 insertions(+), 14 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index b82cca72c..dbedd75ec 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -4658,5 +4658,6 @@ "myBaseLanguage": "My base language", "publicProfileTitle": "Allow my profile to be found in search", "publicProfileDesc": "By enabling this option, I confirm that I am of legal age in my country of residence", - "clickWordsInstructions": "Click on individual words for more activities." + "clickWordsInstructions": "Click on individual words for more activities.", + "chooseBestDefinition": "Choose the best definition" } diff --git a/lib/pangea/choreographer/widgets/choice_array.dart b/lib/pangea/choreographer/widgets/choice_array.dart index 331616ec2..aeaf4b2dd 100644 --- a/lib/pangea/choreographer/widgets/choice_array.dart +++ b/lib/pangea/choreographer/widgets/choice_array.dart @@ -211,6 +211,7 @@ class ChoiceItem extends StatelessWidget { ? getDisplayCopy!(entry.value.text) : entry.value.text, style: BotStyle.text(context), + textAlign: TextAlign.center, ), ), ), diff --git a/lib/pangea/repo/lemma_definition_repo.dart b/lib/pangea/repo/lemma_definition_repo.dart index 7a6df90fd..7f458cd05 100644 --- a/lib/pangea/repo/lemma_definition_repo.dart +++ b/lib/pangea/repo/lemma_definition_repo.dart @@ -134,14 +134,14 @@ class LemmaDictionaryRepo { /// From the cache, get a random set of cached definitions that are not for a specific lemma static List getDistractorDefinitions( - LemmaDefinitionRequest req, + String lemma, int count, ) { _clearExpiredEntries(); final List definitions = []; for (final entry in _cache.entries) { - if (entry.key.lemma != req.lemma) { + if (entry.key.lemma != lemma) { definitions.add(entry.value.definition); } } diff --git a/lib/pangea/repo/practice/word_meaning_activity_generator.dart b/lib/pangea/repo/practice/word_meaning_activity_generator.dart index a97792dec..d180bcadd 100644 --- a/lib/pangea/repo/practice/word_meaning_activity_generator.dart +++ b/lib/pangea/repo/practice/word_meaning_activity_generator.dart @@ -30,7 +30,7 @@ class WordMeaningActivityGenerator { final res = await LemmaDictionaryRepo.get(lemmaDefReq); final choices = - LemmaDictionaryRepo.getDistractorDefinitions(lemmaDefReq, 3); + LemmaDictionaryRepo.getDistractorDefinitions(lemmaDefReq.lemma, 3); if (!choices.contains(res.definition)) { choices.add(res.definition); @@ -44,7 +44,7 @@ class WordMeaningActivityGenerator { langCode: req.userL2, activityType: ActivityTypeEnum.wordMeaning, content: ActivityContent( - question: "${L10n.of(context).definition}?", + question: L10n.of(context).chooseBestDefinition, choices: choices, answers: [res.definition], spanDisplayDetails: null, diff --git a/lib/pangea/widgets/chat/message_toolbar.dart b/lib/pangea/widgets/chat/message_toolbar.dart index b70fae677..8497e1739 100644 --- a/lib/pangea/widgets/chat/message_toolbar.dart +++ b/lib/pangea/widgets/chat/message_toolbar.dart @@ -74,11 +74,23 @@ class MessageToolbar extends StatelessWidget { messageEvent: pangeaMessageEvent, ); case MessageMode.noneSelected: - return Text(L10n.of(context).clickWordsInstructions); + return Padding( + padding: const EdgeInsets.all(16), + child: Text( + L10n.of(context).clickWordsInstructions, + textAlign: TextAlign.center, + ), + ); case MessageMode.practiceActivity: case MessageMode.wordZoom: if (overlayController.selectedToken == null) { - return Text(L10n.of(context).clickWordsInstructions); + return Padding( + padding: const EdgeInsets.all(16), + child: Text( + L10n.of(context).clickWordsInstructions, + textAlign: TextAlign.center, + ), + ); } return WordZoomWidget( token: overlayController.selectedToken!, diff --git a/lib/pangea/widgets/practice_activity/practice_activity_card.dart b/lib/pangea/widgets/practice_activity/practice_activity_card.dart index bcc7632f6..7d280a1de 100644 --- a/lib/pangea/widgets/practice_activity/practice_activity_card.dart +++ b/lib/pangea/widgets/practice_activity/practice_activity_card.dart @@ -260,12 +260,15 @@ class PracticeActivityCardState extends State { savorTheJoyDuration: _savorTheJoyDuration, ); - widget.overlayController.onActivityFinish(); pangeaController.activityRecordController.completeActivity( widget.pangeaMessageEvent.eventId, ); await _savorTheJoy(); + + // wait for savor the joy before popping from the activity queue + // to keep the completed activity on screen for a moment + widget.overlayController.onActivityFinish(); } catch (e, s) { _onError(); debugger(when: kDebugMode); diff --git a/lib/pangea/widgets/word_zoom/contextual_translation_widget.dart b/lib/pangea/widgets/word_zoom/contextual_translation_widget.dart index ad9efa77d..8b7f94f26 100644 --- a/lib/pangea/widgets/word_zoom/contextual_translation_widget.dart +++ b/lib/pangea/widgets/word_zoom/contextual_translation_widget.dart @@ -48,7 +48,10 @@ class ContextualTranslationWidget extends StatelessWidget { padding: 0, maxWidth: 500, ) - : Text(snapshot.data ?? "..."), + : Text( + snapshot.data ?? "...", + textAlign: TextAlign.center, + ), ), ); }, diff --git a/lib/pangea/widgets/word_zoom/word_zoom_widget.dart b/lib/pangea/widgets/word_zoom/word_zoom_widget.dart index ae82c9060..81b2da70c 100644 --- a/lib/pangea/widgets/word_zoom/word_zoom_widget.dart +++ b/lib/pangea/widgets/word_zoom/word_zoom_widget.dart @@ -3,6 +3,7 @@ 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/repo/lemma_definition_repo.dart'; import 'package:fluffychat/pangea/utils/grammar/get_grammar_copy.dart'; import 'package:fluffychat/pangea/widgets/chat/message_selection_overlay.dart'; import 'package:fluffychat/pangea/widgets/chat/tts_controller.dart'; @@ -72,7 +73,13 @@ class WordZoomWidgetState extends State { // The function to determine if lemma distractors can be generated // is computationally expensive, so we only do it once - bool canGenerateLemmaActivity = false; + bool _canGenerateLemmaActivity = false; + + bool get _canGenerateDefintionActivity => + LemmaDictionaryRepo.getDistractorDefinitions( + widget.token.lemma.text, + 1, + ).isNotEmpty; @override void initState() { @@ -101,7 +108,7 @@ class WordZoomWidgetState extends State { void _setCanGenerateLemmaActivity() { widget.token.canGenerateDistractors(ActivityTypeEnum.lemmaId).then((value) { - if (mounted) setState(() => canGenerateLemmaActivity = value); + if (mounted) setState(() => _canGenerateLemmaActivity = value); }); } @@ -152,7 +159,10 @@ class WordZoomWidgetState extends State { ? null : widget.token.morph[_selectedMorphFeature], ) && - (_selectionType != WordZoomSelection.lemma || canGenerateLemmaActivity); + (_selectionType != WordZoomSelection.lemma || + _canGenerateLemmaActivity) && + (_selectionType != WordZoomSelection.translation || + _canGenerateDefintionActivity); if (showActivity || _forceShowActivity) { return PracticeActivityCard( @@ -196,9 +206,9 @@ class WordZoomWidgetState extends State { lemma: morphTag, context: context, ); - return Text(copy ?? morphTag); + return Text(copy ?? morphTag, textAlign: TextAlign.center); case WordZoomSelection.lemma: - return Text(widget.token.lemma.text); + return Text(widget.token.lemma.text, textAlign: TextAlign.center); case WordZoomSelection.emoji: return widget.token.getEmoji() != null ? Text(widget.token.getEmoji()!)