diff --git a/lib/pangea/practice_activities/practice_target.dart b/lib/pangea/practice_activities/practice_target.dart index 12353edbd..00bfcd671 100644 --- a/lib/pangea/practice_activities/practice_target.dart +++ b/lib/pangea/practice_activities/practice_target.dart @@ -154,6 +154,8 @@ class PracticeTarget { return null; } + bool get hasAnyResponses => record.responses.isNotEmpty; + bool get hasAnyCorrectChoices { for (final response in record.responses) { if (response.isCorrect) { diff --git a/lib/pangea/toolbar/message_practice/message_morph_choice.dart b/lib/pangea/toolbar/message_practice/message_morph_choice.dart index 851589f93..99d025a4e 100644 --- a/lib/pangea/toolbar/message_practice/message_morph_choice.dart +++ b/lib/pangea/toolbar/message_practice/message_morph_choice.dart @@ -146,6 +146,7 @@ class MessageMorphInputBarContentState }, isSelected: selectedTag == choice, isGold: wasCorrect, + shimmer: widget.controller.showChoiceShimmer, ), ); }, diff --git a/lib/pangea/toolbar/message_practice/message_morph_choice_item.dart b/lib/pangea/toolbar/message_practice/message_morph_choice_item.dart index 555b56b4f..7aa99a354 100644 --- a/lib/pangea/toolbar/message_practice/message_morph_choice_item.dart +++ b/lib/pangea/toolbar/message_practice/message_morph_choice_item.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; +import 'package:fluffychat/pangea/common/widgets/shimmer_background.dart'; import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; import 'package:fluffychat/pangea/morphs/get_grammar_copy.dart'; import 'package:fluffychat/pangea/morphs/morph_features_enum.dart'; @@ -14,12 +15,14 @@ class MessageMorphChoiceItem extends StatefulWidget { required this.isSelected, required this.isGold, required this.cId, + this.shimmer = false, }); final ConstructIdentifier cId; final void Function() onTap; final bool isSelected; final bool? isGold; + final bool shimmer; @override MessageMorphChoiceItemState createState() => MessageMorphChoiceItemState(); @@ -69,50 +72,53 @@ class MessageMorphChoiceItemState extends State { onHover: (isHovered) => setState(() => _isHovered = isHovered), borderRadius: BorderRadius.circular(AppConfig.borderRadius), onTap: onTap, - child: IntrinsicWidth( - child: Container( - alignment: Alignment.center, - decoration: BoxDecoration( - color: color, - borderRadius: BorderRadius.circular(AppConfig.borderRadius), - border: Border.all( - color: widget.isSelected || _isHovered - ? color.withAlpha(255) - : Colors.transparent, - width: 2.0, + child: ShimmerBackground( + enabled: widget.shimmer, + child: IntrinsicWidth( + child: Container( + alignment: Alignment.center, + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(AppConfig.borderRadius), + border: Border.all( + color: widget.isSelected || _isHovered + ? color.withAlpha(255) + : Colors.transparent, + width: 2.0, + ), ), - ), - padding: const EdgeInsets.symmetric( - vertical: 8.0, - horizontal: 12.0, - ), - child: Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - spacing: 8.0, - children: [ - SizedBox( - width: iconSize, - height: iconSize, - child: MorphIcon( - morphFeature: MorphFeaturesEnumExtension.fromString( - widget.cId.category, + padding: const EdgeInsets.symmetric( + vertical: 8.0, + horizontal: 12.0, + ), + child: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + spacing: 8.0, + children: [ + SizedBox( + width: iconSize, + height: iconSize, + child: MorphIcon( + morphFeature: MorphFeaturesEnumExtension.fromString( + widget.cId.category, + ), + morphTag: widget.cId.lemma, + size: Size(iconSize, iconSize), + showTooltip: false, ), - morphTag: widget.cId.lemma, - size: Size(iconSize, iconSize), - showTooltip: false, ), - ), - Text( - getGrammarCopy( - category: widget.cId.category, - lemma: widget.cId.lemma, - context: context, - ) ?? - widget.cId.lemma, - style: style, - ), - ], + Text( + getGrammarCopy( + category: widget.cId.category, + lemma: widget.cId.lemma, + context: context, + ) ?? + widget.cId.lemma, + style: style, + ), + ], + ), ), ), ), diff --git a/lib/pangea/toolbar/message_practice/practice_controller.dart b/lib/pangea/toolbar/message_practice/practice_controller.dart index f712924b0..4abf261fc 100644 --- a/lib/pangea/toolbar/message_practice/practice_controller.dart +++ b/lib/pangea/toolbar/message_practice/practice_controller.dart @@ -78,6 +78,18 @@ class PracticeController with ChangeNotifier { true; } + bool get showChoiceShimmer { + if (_activity == null) return false; + + if (_activity!.activityType == ActivityTypeEnum.morphId) { + return selectedMorph != null && + !_activity!.practiceTarget.hasAnyResponses; + } + + return selectedChoice == null && + !_activity!.practiceTarget.hasAnyCorrectChoices; + } + Future> fetchActivityModel( PracticeTarget target, ) async { diff --git a/lib/pangea/toolbar/message_practice/practice_match_card.dart b/lib/pangea/toolbar/message_practice/practice_match_card.dart index b71d25589..317be572a 100644 --- a/lib/pangea/toolbar/message_practice/practice_match_card.dart +++ b/lib/pangea/toolbar/message_practice/practice_match_card.dart @@ -104,8 +104,7 @@ class MatchActivityCard extends StatelessWidget { ? cf.choiceContent : null, controller: controller, - shimmer: controller.selectedChoice == null && - !currentActivity.practiceTarget.hasAnyCorrectChoices, + shimmer: controller.showChoiceShimmer, ), ); },