From 1da3ed16f71092c9d0fe298113a3786ec87b9cb2 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Tue, 16 Dec 2025 16:25:26 -0500 Subject: [PATCH] add shimmer background to match choices --- .../common/widgets/shimmer_background.dart | 44 ++++++++++++ .../lemmas/lemma_highlight_emoji_row.dart | 70 +++++++------------ .../message_practice/practice_match_card.dart | 40 ++++++----- 3 files changed, 93 insertions(+), 61 deletions(-) create mode 100644 lib/pangea/common/widgets/shimmer_background.dart diff --git a/lib/pangea/common/widgets/shimmer_background.dart b/lib/pangea/common/widgets/shimmer_background.dart new file mode 100644 index 000000000..8a2e59a3a --- /dev/null +++ b/lib/pangea/common/widgets/shimmer_background.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; + +import 'package:shimmer/shimmer.dart'; + +import 'package:fluffychat/config/app_config.dart'; + +class ShimmerBackground extends StatelessWidget { + final Widget child; + final Color shimmerColor; + final bool enabled; + + const ShimmerBackground({ + super.key, + required this.child, + this.shimmerColor = AppConfig.goldLight, + this.enabled = true, + }); + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + child, + if (enabled) + Positioned.fill( + child: ClipRRect( + borderRadius: BorderRadius.circular(AppConfig.borderRadius), + child: Shimmer.fromColors( + baseColor: shimmerColor.withValues(alpha: 0.1), + highlightColor: shimmerColor.withValues(alpha: 0.6), + direction: ShimmerDirection.ltr, + child: Container( + decoration: BoxDecoration( + color: shimmerColor.withValues(alpha: 0.3), + borderRadius: BorderRadius.circular(AppConfig.borderRadius), + ), + ), + ), + ), + ), + ], + ); + } +} diff --git a/lib/pangea/lemmas/lemma_highlight_emoji_row.dart b/lib/pangea/lemmas/lemma_highlight_emoji_row.dart index 45fe653c7..c036f6633 100644 --- a/lib/pangea/lemmas/lemma_highlight_emoji_row.dart +++ b/lib/pangea/lemmas/lemma_highlight_emoji_row.dart @@ -2,11 +2,10 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:shimmer/shimmer.dart'; - import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/analytics_misc/get_analytics_controller.dart'; import 'package:fluffychat/pangea/common/utils/overlay.dart'; +import 'package:fluffychat/pangea/common/widgets/shimmer_background.dart'; import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; import 'package:fluffychat/pangea/lemmas/lemma_meaning_builder.dart'; import 'package:fluffychat/widgets/hover_builder.dart'; @@ -158,55 +157,40 @@ class EmojiChoiceItemState extends State { @override Widget build(BuildContext context) { - final shimmerColor = (Theme.of(context).brightness == Brightness.dark) - ? Colors.white - : Theme.of(context).colorScheme.primary; return HoverBuilder( builder: (context, hovered) => GestureDetector( onTap: widget.onSelectEmoji, child: Stack( children: [ - CompositedTransformTarget( - link: layerLink, - child: AnimatedContainer( - duration: const Duration(milliseconds: 200), - padding: const EdgeInsets.all(8), - decoration: BoxDecoration( - color: hovered - ? Theme.of(context).colorScheme.primary.withAlpha(50) - : Colors.transparent, - borderRadius: BorderRadius.circular(AppConfig.borderRadius), - border: widget.selected - ? Border.all( - color: AppConfig.goldLight.withAlpha(200), - width: 2, - ) - : null, - ), - child: Text( - widget.emoji, - style: Theme.of(context).textTheme.headlineSmall, - ), - ), - ), - if (shimmer) - Positioned.fill( - child: ClipRRect( - borderRadius: BorderRadius.circular(AppConfig.borderRadius), - child: Shimmer.fromColors( - baseColor: shimmerColor.withValues(alpha: 0.1), - highlightColor: shimmerColor.withValues(alpha: 0.6), - direction: ShimmerDirection.ltr, - child: Container( - decoration: BoxDecoration( - color: shimmerColor.withValues(alpha: 0.3), - borderRadius: - BorderRadius.circular(AppConfig.borderRadius), - ), - ), + ShimmerBackground( + enabled: shimmer, + shimmerColor: (Theme.of(context).brightness == Brightness.dark) + ? Colors.white + : Theme.of(context).colorScheme.primary, + child: CompositedTransformTarget( + link: layerLink, + child: AnimatedContainer( + duration: const Duration(milliseconds: 200), + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: hovered + ? Theme.of(context).colorScheme.primary.withAlpha(50) + : Colors.transparent, + borderRadius: BorderRadius.circular(AppConfig.borderRadius), + border: widget.selected + ? Border.all( + color: AppConfig.goldLight.withAlpha(200), + width: 2, + ) + : null, + ), + child: Text( + widget.emoji, + style: Theme.of(context).textTheme.headlineSmall, ), ), ), + ), if (widget.badge != null) Positioned( right: 0, diff --git a/lib/pangea/toolbar/message_practice/practice_match_card.dart b/lib/pangea/toolbar/message_practice/practice_match_card.dart index 0b88a58ca..952f5fefa 100644 --- a/lib/pangea/toolbar/message_practice/practice_match_card.dart +++ b/lib/pangea/toolbar/message_practice/practice_match_card.dart @@ -7,6 +7,7 @@ import 'package:collection/collection.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pangea/common/widgets/choice_animation.dart'; +import 'package:fluffychat/pangea/common/widgets/shimmer_background.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'; @@ -37,26 +38,29 @@ class MatchActivityCard extends StatelessWidget { switch (activityType) { case ActivityTypeEnum.emoji: case ActivityTypeEnum.wordMeaning: - final text = Text( - choice, - style: TextStyle(fontSize: fontSize), - textAlign: TextAlign.center, + return ShimmerBackground( + enabled: controller.selectedChoice == null && + !currentActivity.practiceTarget.hasAnyCorrectChoices, + child: Padding( + padding: const EdgeInsets.all(8), + child: Text( + choice, + style: TextStyle(fontSize: fontSize), + textAlign: TextAlign.center, + ), + ), ); - - // if (controller.selectedChoice == null && - // !currentActivity.practiceTarget.hasAnyCorrectChoices) { - // return Shimmer.fromColors( - // baseColor: Theme.of(context).colorScheme.onSurface, - // highlightColor: AppConfig.goldLight, - // child: text, - // ); - // } - - return text; case ActivityTypeEnum.wordFocusListening: - return Icon( - Icons.volume_up, - size: fontSize, + return ShimmerBackground( + enabled: controller.selectedChoice == null && + !currentActivity.practiceTarget.hasAnyCorrectChoices, + child: Padding( + padding: const EdgeInsets.all(8), + child: Icon( + Icons.volume_up, + size: fontSize, + ), + ), ); default: debugger(when: kDebugMode);