diff --git a/lib/pangea/choreographer/widgets/choice_array.dart b/lib/pangea/choreographer/widgets/choice_array.dart index aeaf4b2dd..f1bfbec34 100644 --- a/lib/pangea/choreographer/widgets/choice_array.dart +++ b/lib/pangea/choreographer/widgets/choice_array.dart @@ -36,6 +36,10 @@ class ChoicesArray extends StatefulWidget { final String Function(String)? getDisplayCopy; + /// activity has multiple correct answers, so user can still + /// select choices once the correct choice has been selected + final bool enableMultiSelect; + const ChoicesArray({ super.key, required this.isLoading, @@ -50,6 +54,7 @@ class ChoicesArray extends StatefulWidget { this.onLongPress, this.getDisplayCopy, this.id, + this.enableMultiSelect = false, }); @override @@ -66,7 +71,7 @@ class ChoicesArrayState extends State { } void enableInteractions() { - if (_hasSelectedCorrectChoice) return; + if (_hasSelectedCorrectChoice && !widget.enableMultiSelect) return; WidgetsBinding.instance.addPostFrameCallback((_) { if (mounted) setState(() => interactionDisabled = false); }); diff --git a/lib/pangea/controllers/put_analytics_controller.dart b/lib/pangea/controllers/put_analytics_controller.dart index fbc689299..66359db4a 100644 --- a/lib/pangea/controllers/put_analytics_controller.dart +++ b/lib/pangea/controllers/put_analytics_controller.dart @@ -131,8 +131,6 @@ class PutAnalyticsController extends BaseController { } } - if (constructs.isEmpty) return; - final level = _pangeaController.getAnalytics.constructListModel.level; _addLocalMessage(eventID, constructs).then( diff --git a/lib/pangea/models/pangea_token_model.dart b/lib/pangea/models/pangea_token_model.dart index 0cee9e5ea..c380aad67 100644 --- a/lib/pangea/models/pangea_token_model.dart +++ b/lib/pangea/models/pangea_token_model.dart @@ -313,7 +313,7 @@ class PangeaToken { return _didActivitySuccessfully(ActivityTypeEnum.wordMeaning) && daysSinceLastUseByType(a) > 7; case ActivityTypeEnum.emoji: - return getEmoji() == null; + return true; case ActivityTypeEnum.morphId: if (morphFeature == null || morphTag == null) { debugger(when: kDebugMode); diff --git a/lib/pangea/models/practice_activities.dart/practice_activity_record_model.dart b/lib/pangea/models/practice_activities.dart/practice_activity_record_model.dart index 586620417..d84911568 100644 --- a/lib/pangea/models/practice_activities.dart/practice_activity_record_model.dart +++ b/lib/pangea/models/practice_activities.dart/practice_activity_record_model.dart @@ -81,6 +81,10 @@ class PracticeActivityRecordModel { } } + void clearResponses() { + responses.clear(); + } + /// Returns a list of [OneConstructUse] objects representing the uses of the practice activity. /// /// The [practiceActivity] parameter is the parent event, representing the activity itself. @@ -172,6 +176,8 @@ class ActivityRecordResponse { if (practiceActivity.activityType == ActivityTypeEnum.emoji) { final token = practiceActivity.targetTokens!.first; + // if the emoji is already set, don't give points + if (token.getEmoji() != null) return []; return [ OneConstructUse( lemma: token.lemma.text, diff --git a/lib/pangea/repo/practice/emoji_activity_generator.dart b/lib/pangea/repo/practice/emoji_activity_generator.dart index 54a5ed65d..5b6867907 100644 --- a/lib/pangea/repo/practice/emoji_activity_generator.dart +++ b/lib/pangea/repo/practice/emoji_activity_generator.dart @@ -1,4 +1,5 @@ import 'dart:developer'; +import 'dart:math'; import 'package:fluffychat/pangea/enum/activity_type_enum.dart'; import 'package:fluffychat/pangea/models/pangea_token_model.dart'; @@ -16,6 +17,12 @@ class EmojiActivityGenerator { final PangeaToken token = req.targetTokens.first; final List emojis = await token.getEmojiChoices(); + final tokenEmoji = token.getEmoji(); + if (tokenEmoji != null && !emojis.contains(tokenEmoji)) { + final Random random = Random(); + final int randomIndex = random.nextInt(emojis.length); + emojis[randomIndex] = tokenEmoji; + } // TODO - modify MultipleChoiceActivity flow to allow no correct answer return MessageActivityResponse( diff --git a/lib/pangea/widgets/practice_activity/emoji_practice_button.dart b/lib/pangea/widgets/practice_activity/emoji_practice_button.dart index f415ee4db..cda8df4bb 100644 --- a/lib/pangea/widgets/practice_activity/emoji_practice_button.dart +++ b/lib/pangea/widgets/practice_activity/emoji_practice_button.dart @@ -31,7 +31,6 @@ class EmojiPracticeButton extends StatelessWidget { : Text(emoji), isSelected: isSelected, onPressed: onPressed, - opacity: _shouldDoActivity ? 0.5 : 1, ) : const SizedBox(width: 40); } diff --git a/lib/pangea/widgets/practice_activity/multiple_choice_activity.dart b/lib/pangea/widgets/practice_activity/multiple_choice_activity.dart index a50fd6d68..adaae3869 100644 --- a/lib/pangea/widgets/practice_activity/multiple_choice_activity.dart +++ b/lib/pangea/widgets/practice_activity/multiple_choice_activity.dart @@ -25,6 +25,8 @@ class MultipleChoiceActivity extends StatefulWidget { final Event event; final VoidCallback? onError; final MessageOverlayController overlayController; + final String? initialSelectedChoice; + final bool clearResponsesOnUpdate; const MultipleChoiceActivity({ super.key, @@ -32,6 +34,8 @@ class MultipleChoiceActivity extends StatefulWidget { required this.currentActivity, required this.event, required this.overlayController, + this.initialSelectedChoice, + this.clearResponsesOnUpdate = false, this.onError, }); @@ -45,6 +49,17 @@ class MultipleChoiceActivityState extends State { PracticeActivityRecordModel? get currentRecordModel => widget.practiceCardController.currentCompletionRecord; + @override + void initState() { + super.initState(); + if (widget.initialSelectedChoice != null) { + currentRecordModel?.addResponse( + text: widget.initialSelectedChoice, + score: 1, + ); + } + } + @override void didUpdateWidget(covariant MultipleChoiceActivity oldWidget) { super.didUpdateWidget(oldWidget); @@ -89,6 +104,10 @@ class MultipleChoiceActivityState extends State { return; } + if (widget.clearResponsesOnUpdate) { + currentRecordModel?.clearResponses(); + } + currentRecordModel?.addResponse( text: value, score: isCorrect ? 1 : 0, @@ -229,6 +248,8 @@ class MultipleChoiceActivityState extends State { tts: practiceActivity.activityType.includeTTSOnClick ? tts : null, enableAudio: !widget.overlayController.isPlayingAudio, getDisplayCopy: _getDisplayCopy, + enableMultiSelect: + widget.currentActivity.activityType == ActivityTypeEnum.emoji, ), ], ); diff --git a/lib/pangea/widgets/practice_activity/practice_activity_card.dart b/lib/pangea/widgets/practice_activity/practice_activity_card.dart index 7d280a1de..a491aa13a 100644 --- a/lib/pangea/widgets/practice_activity/practice_activity_card.dart +++ b/lib/pangea/widgets/practice_activity/practice_activity_card.dart @@ -303,12 +303,20 @@ class PracticeActivityCardState extends State { case ActivityTypeEnum.lemmaId: case ActivityTypeEnum.emoji: case ActivityTypeEnum.morphId: + final selectedChoice = + currentActivity?.activityType == ActivityTypeEnum.emoji && + (currentActivity?.targetTokens?.isNotEmpty ?? false) + ? currentActivity?.targetTokens?.first.getEmoji() + : null; return MultipleChoiceActivity( practiceCardController: this, currentActivity: currentActivity!, event: widget.pangeaMessageEvent.event, onError: _onError, overlayController: widget.overlayController, + initialSelectedChoice: selectedChoice, + clearResponsesOnUpdate: + currentActivity?.activityType == ActivityTypeEnum.emoji, ); } }