diff --git a/lib/pangea/toolbar/message_practice/practice_controller.dart b/lib/pangea/toolbar/message_practice/practice_controller.dart index 1f572ada2..54ffcbbdf 100644 --- a/lib/pangea/toolbar/message_practice/practice_controller.dart +++ b/lib/pangea/toolbar/message_practice/practice_controller.dart @@ -40,29 +40,18 @@ class PracticeController with ChangeNotifier { bool? wasCorrectMatch(PracticeChoice choice) { if (_activity == null) return false; - final record = PracticeRecordController.recordByActivity(_activity!); - for (final response in record.responses) { - if (response.text == choice.choiceContent && response.isCorrect) { - return true; - } - } - for (final response in record.responses) { - if (response.text == choice.choiceContent) { - return false; - } - } - return null; + return PracticeRecordController.wasCorrectMatch( + _activity!.practiceTarget, + choice, + ); } bool? wasCorrectChoice(String choice) { if (_activity == null) return false; - final record = PracticeRecordController.recordByActivity(_activity!); - for (final response in record.responses) { - if (response.text == choice) { - return response.isCorrect; - } - } - return null; + return PracticeRecordController.wasCorrectChoice( + _activity!.practiceTarget, + choice, + ); } bool get isTotallyDone => @@ -107,28 +96,19 @@ class PracticeController with ChangeNotifier { bool get showChoiceShimmer { if (_activity == null) return false; - final record = PracticeRecordController.recordByActivity(_activity!); - if (_activity is MorphMatchPracticeActivityModel) { - return selectedMorph != null && record.responses.isEmpty; + return selectedMorph != null && + !PracticeRecordController.hasResponse( + _activity!.practiceTarget, + ); } - return selectedChoice == null && !record.responses.any((r) => r.isCorrect); + return selectedChoice == null && + !PracticeRecordController.hasAnyCorrectChoices( + _activity!.practiceTarget, + ); } - // PracticeTarget? get _target => _activity != null - // ? PracticeTarget( - // activityType: _activity!.activityType, - // tokens: _activity!.tokens, - // morphFeature: _activity is MorphPracticeActivityModel - // ? (_activity as MorphPracticeActivityModel).morphFeature - // : null, - // ) - // : null; - - // PracticeRecord? get _record => - // _target != null ? PracticeRecordRepo.get(_target!) : null; - Future _fetchPracticeSelection() async { if (pangeaMessageEvent.messageDisplayRepresentation?.tokens == null) return; practiceSelection = await PracticeSelectionRepo.get( @@ -193,7 +173,6 @@ class PracticeController with ChangeNotifier { void onMatch(PangeaToken token, PracticeChoice choice) { if (_activity == null) return; - final record = PracticeRecordController.recordByActivity(_activity!); final isCorrect = PracticeRecordController.onSelectChoice( choice.choiceContent, token, @@ -209,7 +188,8 @@ class PracticeController with ChangeNotifier { // we don't take off points for incorrect emoji matches if (_activity is! EmojiPracticeActivityModel || isCorrect) { final constructUseType = - record.responses.last.useType(_activity!.activityType); + PracticeRecordController.lastResponse(_activity!.practiceTarget)! + .useType(_activity!.activityType); final constructs = [ OneConstructUse( diff --git a/lib/pangea/toolbar/message_practice/practice_match_card.dart b/lib/pangea/toolbar/message_practice/practice_match_card.dart index 69b8f4a96..60506e821 100644 --- a/lib/pangea/toolbar/message_practice/practice_match_card.dart +++ b/lib/pangea/toolbar/message_practice/practice_match_card.dart @@ -21,8 +21,6 @@ class MatchActivityCard extends StatelessWidget { required this.controller, }); - // ActivityTypeEnum get activityType => currentActivity.activityType; - Widget choiceDisplayContent( BuildContext context, String choice, diff --git a/lib/pangea/toolbar/message_practice/practice_record_controller.dart b/lib/pangea/toolbar/message_practice/practice_record_controller.dart index 78716b89c..a32c01b27 100644 --- a/lib/pangea/toolbar/message_practice/practice_record_controller.dart +++ b/lib/pangea/toolbar/message_practice/practice_record_controller.dart @@ -2,22 +2,74 @@ import 'dart:developer'; import 'package:flutter/foundation.dart'; +import 'package:collection/collection.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_features_enum.dart'; import 'package:fluffychat/pangea/practice_activities/activity_type_enum.dart'; import 'package:fluffychat/pangea/practice_activities/practice_activity_model.dart'; +import 'package:fluffychat/pangea/practice_activities/practice_choice.dart'; import 'package:fluffychat/pangea/practice_activities/practice_record.dart'; import 'package:fluffychat/pangea/practice_activities/practice_record_repo.dart'; import 'package:fluffychat/pangea/practice_activities/practice_target.dart'; class PracticeRecordController { - static PracticeRecord recordByActivity(PracticeActivityModel activity) => - PracticeRecordRepo.get(activity.practiceTarget); + static PracticeRecord _recordByTarget(PracticeTarget target) => + PracticeRecordRepo.get(target); + + static bool hasResponse(PracticeTarget target) => + _recordByTarget(target).responses.isNotEmpty; + + static ActivityRecordResponse? lastResponse(PracticeTarget target) { + final record = _recordByTarget(target); + return record.responses.lastOrNull; + } + + static ActivityRecordResponse? correctResponse( + PracticeTarget target, + PangeaToken token, + ) { + final record = _recordByTarget(target); + return record.responses.firstWhereOrNull( + (res) => res.cId == token.vocabConstructID && res.isCorrect, + ); + } + + static bool? wasCorrectMatch( + PracticeTarget target, + PracticeChoice choice, + ) { + final record = _recordByTarget(target); + for (final response in record.responses) { + if (response.text == choice.choiceContent && response.isCorrect) { + return true; + } + } + for (final response in record.responses) { + if (response.text == choice.choiceContent) { + return false; + } + } + return null; + } + + static bool? wasCorrectChoice( + PracticeTarget target, + String choice, + ) { + final record = _recordByTarget(target); + for (final response in record.responses) { + if (response.text == choice) { + return response.isCorrect; + } + } + return null; + } static bool isCompleteByTarget(PracticeTarget target) { - final record = PracticeRecordRepo.get(target); + final record = _recordByTarget(target); if (target.activityType == ActivityTypeEnum.morphId) { return record.completeResponses > 0; } @@ -28,18 +80,6 @@ class PracticeRecordController { ); } - static bool isCompleteByActivity(PracticeActivityModel activity) { - final activityRecord = recordByActivity(activity); - if (activity.activityType == ActivityTypeEnum.morphId) { - return activityRecord.completeResponses > 0; - } - - return activity.tokens.every( - (t) => activityRecord.responses - .any((res) => res.cId == t.vocabConstructID && res.isCorrect), - ); - } - static bool isCompleteByToken( PracticeTarget target, PangeaToken token, [ @@ -60,7 +100,7 @@ class PracticeRecordController { return false; } - final record = PracticeRecordRepo.get(target); + final record = _recordByTarget(target); if (target.activityType == ActivityTypeEnum.morphId) { return record.responses.any( (res) => res.cId == token.morphIdByFeature(morph!) && res.isCorrect, @@ -73,7 +113,7 @@ class PracticeRecordController { } static bool hasAnyCorrectChoices(PracticeTarget target) { - final record = PracticeRecordRepo.get(target); + final record = _recordByTarget(target); return record.responses.any((response) => response.isCorrect); } @@ -82,8 +122,8 @@ class PracticeRecordController { PangeaToken token, PracticeActivityModel activity, ) { - final record = recordByActivity(activity); - if (isCompleteByActivity(activity) || + final record = _recordByTarget(activity.practiceTarget); + if (isCompleteByTarget(activity.practiceTarget) || record.alreadyHasMatchResponse( token.vocabConstructID, choice, diff --git a/lib/pangea/toolbar/message_practice/token_practice_button.dart b/lib/pangea/toolbar/message_practice/token_practice_button.dart index 46c1ceff1..a585e1290 100644 --- a/lib/pangea/toolbar/message_practice/token_practice_button.dart +++ b/lib/pangea/toolbar/message_practice/token_practice_button.dart @@ -2,7 +2,6 @@ import 'dart:math'; import 'package:flutter/material.dart'; -import 'package:collection/collection.dart'; import 'package:material_symbols_icons/symbols.dart'; import 'package:shimmer/shimmer.dart'; @@ -14,7 +13,6 @@ import 'package:fluffychat/pangea/morphs/get_grammar_copy.dart'; import 'package:fluffychat/pangea/morphs/morph_features_enum.dart'; import 'package:fluffychat/pangea/morphs/morph_icon.dart'; import 'package:fluffychat/pangea/practice_activities/practice_choice.dart'; -import 'package:fluffychat/pangea/practice_activities/practice_record_repo.dart'; import 'package:fluffychat/pangea/practice_activities/practice_target.dart'; import 'package:fluffychat/pangea/toolbar/message_practice/dotted_border_painter.dart'; import 'package:fluffychat/pangea/toolbar/message_practice/message_practice_mode_enum.dart'; @@ -258,14 +256,10 @@ class _NoActivityContentButton extends StatelessWidget { @override Widget build(BuildContext context) { if (practiceMode == MessagePracticeMode.wordEmoji && target != null) { - final record = PracticeRecordRepo.get(target!); - final displayEmoji = record.responses - .firstWhereOrNull( - (res) => res.cId == token.vocabConstructID && res.isCorrect, - ) - ?.text ?? - token.vocabConstructID.userSetEmoji ?? - ''; + final displayEmoji = + PracticeRecordController.correctResponse(target!, token)?.text ?? + token.vocabConstructID.userSetEmoji ?? + ''; return Text( displayEmoji, style: emojiStyle,