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
This commit is contained in:
ggurdin 2024-12-31 16:01:04 -05:00 committed by GitHub
parent dd2ccccaad
commit 1689fda54f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 44 additions and 14 deletions

View file

@ -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"
}

View file

@ -211,6 +211,7 @@ class ChoiceItem extends StatelessWidget {
? getDisplayCopy!(entry.value.text)
: entry.value.text,
style: BotStyle.text(context),
textAlign: TextAlign.center,
),
),
),

View file

@ -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<String> getDistractorDefinitions(
LemmaDefinitionRequest req,
String lemma,
int count,
) {
_clearExpiredEntries();
final List<String> definitions = [];
for (final entry in _cache.entries) {
if (entry.key.lemma != req.lemma) {
if (entry.key.lemma != lemma) {
definitions.add(entry.value.definition);
}
}

View file

@ -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,

View file

@ -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!,

View file

@ -260,12 +260,15 @@ class PracticeActivityCardState extends State<PracticeActivityCard> {
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);

View file

@ -48,7 +48,10 @@ class ContextualTranslationWidget extends StatelessWidget {
padding: 0,
maxWidth: 500,
)
: Text(snapshot.data ?? "..."),
: Text(
snapshot.data ?? "...",
textAlign: TextAlign.center,
),
),
);
},

View file

@ -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<WordZoomWidget> {
// 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<WordZoomWidget> {
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<WordZoomWidget> {
? 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<WordZoomWidget> {
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()!)