From d2a539e4dd176d9a765e929313fb6c5cce56ba53 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Thu, 18 Dec 2025 12:49:56 -0500 Subject: [PATCH] chore: Swap seed for hyphen for not-yet-chosen emojis in analytics --- .../morph_details_view.dart | 16 +-- .../vocab_analytics_details_view.dart | 47 +++++-- .../constructs/construct_level_enum.dart | 4 +- lib/pangea/lemmas/construct_xp_widget.dart | 121 ++++-------------- 4 files changed, 61 insertions(+), 127 deletions(-) diff --git a/lib/pangea/analytics_details_popup/morph_details_view.dart b/lib/pangea/analytics_details_popup/morph_details_view.dart index 785cb5eb2..48a8d766a 100644 --- a/lib/pangea/analytics_details_popup/morph_details_view.dart +++ b/lib/pangea/analytics_details_popup/morph_details_view.dart @@ -44,18 +44,10 @@ class MorphDetailsView extends StatelessWidget { style: Theme.of(context).textTheme.bodyLarge, ), const Divider(), - Row( - spacing: 16.0, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ConstructXpWidget(id: constructId), - Text( - "${construct.points} XP", - style: Theme.of(context).textTheme.titleMedium?.copyWith( - color: textColor, - ), - ), - ], + ConstructXpWidget( + icon: construct.lemmaCategory.icon(30.0), + level: construct.lemmaCategory, + points: construct.points, ), Padding( padding: const EdgeInsets.all(20.0), diff --git a/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart b/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart index 743a9c1c1..7f5e4d1f4 100644 --- a/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart +++ b/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart @@ -8,11 +8,12 @@ import 'package:fluffychat/pangea/analytics_details_popup/word_text_with_audio_b import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; import 'package:fluffychat/pangea/constructs/construct_level_enum.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_text_model.dart'; +import 'package:fluffychat/pangea/lemmas/construct_xp_widget.dart'; import 'package:fluffychat/pangea/toolbar/word_card/word_zoom_widget.dart'; import 'package:fluffychat/widgets/matrix.dart'; /// Displays information about selected lemma, and its usage -class VocabDetailsView extends StatelessWidget { +class VocabDetailsView extends StatefulWidget { final ConstructIdentifier constructId; const VocabDetailsView({ @@ -20,6 +21,27 @@ class VocabDetailsView extends StatelessWidget { required this.constructId, }); + @override + State createState() => VocabDetailsViewState(); +} + +class VocabDetailsViewState extends State { + ConstructIdentifier get constructId => widget.constructId; + + final ValueNotifier _emojiNotifier = ValueNotifier(null); + + @override + void initState() { + super.initState(); + _emojiNotifier.value = constructId.userLemmaInfo.emojis?.firstOrNull; + } + + @override + void dispose() { + _emojiNotifier.dispose(); + super.dispose(); + } + List get forms => MatrixState.pangeaController.getAnalytics.constructListModel .getConstructUsesByLemma(constructId.lemma) @@ -30,8 +52,6 @@ class VocabDetailsView extends StatelessWidget { .whereType() .toList(); - final double _iconSize = 24.0; - @override Widget build(BuildContext context) { final construct = constructId.constructUses; @@ -47,23 +67,22 @@ class VocabDetailsView extends StatelessWidget { token: PangeaTokenText.fromString(constructId.lemma), langCode: MatrixState.pangeaController.userController.userL2Code!, construct: constructId, + setEmoji: (emoji) => _emojiNotifier.value = emoji, ), Column( children: [ Padding( padding: const EdgeInsets.all(20.0), - child: Row( - spacing: 16.0, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - construct.lemmaCategory.icon(_iconSize + 6.0), - Text( - "${construct.points} XP", - style: Theme.of(context).textTheme.titleMedium?.copyWith( - color: textColor, - ), + child: ConstructXpWidget( + icon: ValueListenableBuilder( + valueListenable: _emojiNotifier, + builder: (context, emoji, __) => Text( + emoji ?? "-", + style: const TextStyle(fontSize: 24.0), ), - ], + ), + level: construct.lemmaCategory, + points: construct.points, ), ), Padding( diff --git a/lib/pangea/constructs/construct_level_enum.dart b/lib/pangea/constructs/construct_level_enum.dart index 5874b37af..1fc003cf2 100644 --- a/lib/pangea/constructs/construct_level_enum.dart +++ b/lib/pangea/constructs/construct_level_enum.dart @@ -45,7 +45,7 @@ extension ConstructLevelEnumExt on ConstructLevelEnum { } } - String get svgURL { + String get _svgURL { switch (this) { case ConstructLevelEnum.seeds: return "${AppConfig.assetsBaseURL}/${AnalyticsConstants.seedSvgFileName}"; @@ -90,7 +90,7 @@ extension ConstructLevelEnumExt on ConstructLevelEnum { } Widget icon([double? size]) => CustomizedSvg( - svgUrl: svgURL, + svgUrl: _svgURL, colorReplacements: const {}, errorIcon: Text( emoji, diff --git a/lib/pangea/lemmas/construct_xp_widget.dart b/lib/pangea/lemmas/construct_xp_widget.dart index 9f2ce4720..093c33806 100644 --- a/lib/pangea/lemmas/construct_xp_widget.dart +++ b/lib/pangea/lemmas/construct_xp_widget.dart @@ -1,114 +1,37 @@ -import 'dart:async'; - import 'package:flutter/material.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; -import 'package:fluffychat/pangea/analytics_misc/get_analytics_controller.dart'; -import 'package:fluffychat/pangea/constructs/construct_identifier.dart'; import 'package:fluffychat/pangea/constructs/construct_level_enum.dart'; -import 'package:fluffychat/widgets/matrix.dart'; -/// display the construct xp widget -/// listen to analytics stream and, if the lemmaCategory has changed, -/// animate the constructSvg by making it animate in then rise up and float away - -class ConstructXpWidget extends StatefulWidget { - final ConstructIdentifier id; - final VoidCallback? onTap; - final double size; +class ConstructXpWidget extends StatelessWidget { + final ConstructLevelEnum level; + final int points; + final Widget icon; const ConstructXpWidget({ super.key, - required this.id, - this.onTap, - this.size = 24.0, + required this.level, + required this.points, + required this.icon, }); - @override - ConstructXpWidgetState createState() => ConstructXpWidgetState(); -} - -class ConstructXpWidgetState extends State - with SingleTickerProviderStateMixin { - ConstructLevelEnum? constructLemmaCategory; - bool didChange = false; - - late AnimationController _controller; - - StreamSubscription? _sub; - - @override - void initState() { - super.initState(); - - _controller = AnimationController( - duration: const Duration(milliseconds: 2000), - vsync: this, - ); - - setState(() => constructLemmaCategory = constructUse?.lemmaCategory); - - debugPrint('constructLemmaCategory: $constructLemmaCategory'); - - _sub = stream.listen((_) { - if (constructUse?.lemmaCategory != constructLemmaCategory) { - setState(() { - constructLemmaCategory = constructUse?.lemmaCategory; - didChange = true; - //_controller.reset(); - //_controller.forward(); - }); - } - }); - } - - ConstructUses? get constructUse => - MatrixState.pangeaController.getAnalytics.constructListModel - .getConstructUses(widget.id); - - Stream get stream => - MatrixState.pangeaController.getAnalytics.analyticsStream.stream; - - Widget? get svg => constructLemmaCategory?.icon(); - - @override - void dispose() { - _controller.dispose(); - _sub?.cancel(); - super.dispose(); - } - @override Widget build(BuildContext context) { - return SizedBox( - width: widget.size, - height: widget.size, - child: GestureDetector( - onTap: svg != null ? widget.onTap : null, - child: MouseRegion( - cursor: - svg != null ? SystemMouseCursors.click : SystemMouseCursors.basic, - child: Stack( - alignment: Alignment.center, - children: [ - //replaces rise animation, remove 116 and uncomment everything to revert - svg != null ? svg! : const SizedBox.shrink(), - // AnimatedSwitcher( - // duration: const Duration(milliseconds: 1000), - // child: svg, - // ), - // if (didChange) - // SlideTransition( - // position: _offsetAnimation, - // child: FadeTransition( - // opacity: _fadeAnimation, - // child: svg, - // ), - // ), - ], - ), + final Color textColor = Theme.of(context).brightness != Brightness.light + ? level.color(context) + : level.darkColor(context); + + return Row( + spacing: 16.0, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + icon, + Text( + "$points XP", + style: Theme.of(context).textTheme.titleMedium?.copyWith( + color: textColor, + ), ), - ), + ], ); } }