diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 5da8185d0..32063d413 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -4134,5 +4134,6 @@ "canceledSend": "Canceled send", "morphsUsed": "Morphs Used", "translationChoicesBody": "Click and hold an option for a hint.", - "sendCanceled": "Sending canceled" + "sendCanceled": "Sending canceled", + "grammar": "Grammar" } \ No newline at end of file diff --git a/lib/pangea/constants/analytics_constants.dart b/lib/pangea/constants/analytics_constants.dart index 1608ef422..fb7c356f8 100644 --- a/lib/pangea/constants/analytics_constants.dart +++ b/lib/pangea/constants/analytics_constants.dart @@ -1,3 +1,5 @@ class AnalyticsConstants { static const int xpPerLevel = 2000; + static const int vocabUseMaxXP = 30; + static const int morphUseMaxXP = 500; } diff --git a/lib/pangea/enum/construct_type_enum.dart b/lib/pangea/enum/construct_type_enum.dart index 86c715fb6..2b346b235 100644 --- a/lib/pangea/enum/construct_type_enum.dart +++ b/lib/pangea/enum/construct_type_enum.dart @@ -1,3 +1,5 @@ +import 'package:fluffychat/pangea/constants/analytics_constants.dart'; + enum ConstructTypeEnum { grammar, vocab, @@ -15,6 +17,17 @@ extension ConstructExtension on ConstructTypeEnum { return 'morph'; } } + + int get maxXPPerLemma { + switch (this) { + case ConstructTypeEnum.grammar: + return 0; + case ConstructTypeEnum.vocab: + return AnalyticsConstants.vocabUseMaxXP; + case ConstructTypeEnum.morph: + return AnalyticsConstants.morphUseMaxXP; + } + } } class ConstructTypeUtil { diff --git a/lib/pangea/enum/progress_indicators_enum.dart b/lib/pangea/enum/progress_indicators_enum.dart index aa38230e2..ae37df389 100644 --- a/lib/pangea/enum/progress_indicators_enum.dart +++ b/lib/pangea/enum/progress_indicators_enum.dart @@ -5,7 +5,6 @@ import 'package:material_symbols_icons/symbols.dart'; enum ProgressIndicatorEnum { level, wordsUsed, - errorTypes, morphsUsed, } @@ -14,8 +13,6 @@ extension ProgressIndicatorsExtension on ProgressIndicatorEnum { switch (this) { case ProgressIndicatorEnum.wordsUsed: return Icons.text_fields_outlined; - case ProgressIndicatorEnum.errorTypes: - return Icons.error_outline; case ProgressIndicatorEnum.morphsUsed: return Symbols.toys_and_games; case ProgressIndicatorEnum.level: @@ -32,10 +29,10 @@ extension ProgressIndicatorsExtension on ProgressIndicatorEnum { return Theme.of(context).brightness == Brightness.dark ? const Color.fromARGB(255, 169, 183, 237) : const Color.fromARGB(255, 38, 59, 141); - case ProgressIndicatorEnum.errorTypes: - return Theme.of(context).brightness == Brightness.dark - ? const Color.fromARGB(255, 212, 144, 216) - : const Color.fromARGB(255, 163, 39, 169); + // case ProgressIndicatorEnum.errorTypes: + // return Theme.of(context).brightness == Brightness.dark + // ? const Color.fromARGB(255, 212, 144, 216) + // : const Color.fromARGB(255, 163, 39, 169); case ProgressIndicatorEnum.level: return Theme.of(context).brightness == Brightness.dark ? const Color.fromARGB(255, 250, 220, 129) @@ -50,13 +47,11 @@ extension ProgressIndicatorsExtension on ProgressIndicatorEnum { String tooltip(BuildContext context) { switch (this) { case ProgressIndicatorEnum.wordsUsed: - return L10n.of(context)!.wordsUsed; - case ProgressIndicatorEnum.errorTypes: - return L10n.of(context)!.errorTypes; + return L10n.of(context)!.vocab; case ProgressIndicatorEnum.level: return L10n.of(context)!.level; case ProgressIndicatorEnum.morphsUsed: - return L10n.of(context)!.morphsUsed; + return L10n.of(context)!.grammar; } } } diff --git a/lib/pangea/models/analytics/construct_list_model.dart b/lib/pangea/models/analytics/construct_list_model.dart index 8d8aeaff3..661fa9d0b 100644 --- a/lib/pangea/models/analytics/construct_list_model.dart +++ b/lib/pangea/models/analytics/construct_list_model.dart @@ -117,6 +117,14 @@ class ConstructUses { required this.constructType, required this.lemma, }); + + // Total points for all uses of this lemma + int get points { + return uses.fold( + 0, + (total, use) => total + use.useType.pointValue, + ); + } } /// One lemma, a use type, and a list of uses diff --git a/lib/pangea/widgets/chat_list/analytics_summary/analytics_popup.dart b/lib/pangea/widgets/chat_list/analytics_summary/analytics_popup.dart new file mode 100644 index 000000000..59859bb7b --- /dev/null +++ b/lib/pangea/widgets/chat_list/analytics_summary/analytics_popup.dart @@ -0,0 +1,67 @@ +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/enum/construct_type_enum.dart'; +import 'package:fluffychat/pangea/enum/progress_indicators_enum.dart'; +import 'package:fluffychat/pangea/models/analytics/construct_list_model.dart'; +import 'package:flutter/material.dart'; + +class AnalyticsPopup extends StatelessWidget { + final ProgressIndicatorEnum indicator; + final ConstructListModel constructsModel; + + const AnalyticsPopup({ + required this.indicator, + required this.constructsModel, + super.key, + }); + + @override + Widget build(BuildContext context) { + return Dialog( + child: ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 400, + maxHeight: 600, + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(20.0), + child: Scaffold( + appBar: AppBar( + title: Text(indicator.tooltip(context)), + leading: IconButton( + icon: const Icon(Icons.close), + onPressed: Navigator.of(context).pop, + ), + ), + body: Padding( + padding: const EdgeInsets.symmetric(vertical: 20), + child: ListView.builder( + itemCount: constructsModel.constructs.length, + itemBuilder: (context, index) { + return Tooltip( + message: + "${constructsModel.constructs[index].points} / ${constructsModel.type.maxXPPerLemma}", + child: ListTile( + onTap: () {}, + title: Text(constructsModel.constructs[index].lemma), + subtitle: LinearProgressIndicator( + value: constructsModel.constructs[index].points / + constructsModel.type.maxXPPerLemma, + minHeight: 20, + borderRadius: const BorderRadius.all( + Radius.circular(AppConfig.borderRadius), + ), + color: indicator.color(context), + ), + contentPadding: + const EdgeInsets.symmetric(horizontal: 20), + ), + ); + }, + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/pangea/widgets/chat_list/analytics_summary/learning_progress_indicators.dart b/lib/pangea/widgets/chat_list/analytics_summary/learning_progress_indicators.dart index 171f8ac64..39865aee9 100644 --- a/lib/pangea/widgets/chat_list/analytics_summary/learning_progress_indicators.dart +++ b/lib/pangea/widgets/chat_list/analytics_summary/learning_progress_indicators.dart @@ -9,6 +9,7 @@ import 'package:fluffychat/pangea/models/analytics/construct_list_model.dart'; import 'package:fluffychat/pangea/models/analytics/constructs_model.dart'; import 'package:fluffychat/pangea/widgets/animations/progress_bar/progress_bar.dart'; import 'package:fluffychat/pangea/widgets/animations/progress_bar/progress_bar_details.dart'; +import 'package:fluffychat/pangea/widgets/chat_list/analytics_summary/analytics_popup.dart'; import 'package:fluffychat/pangea/widgets/chat_list/analytics_summary/progress_indicator.dart'; import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/matrix.dart'; @@ -41,9 +42,6 @@ class LearningProgressIndicatorsState /// Vocabulary constructs model ConstructListModel? words; - /// Grammar constructs model - ConstructListModel? errors; - /// Morph constructs model ConstructListModel? morphs; @@ -87,10 +85,6 @@ class LearningProgressIndicatorsState type: ConstructTypeEnum.vocab, uses: constructs, ); - errors = ConstructListModel( - type: ConstructTypeEnum.grammar, - uses: constructs, - ); morphs = ConstructListModel( type: ConstructTypeEnum.morph, uses: constructs, @@ -101,13 +95,23 @@ class LearningProgressIndicatorsState if (mounted) setState(() {}); } + /// Get the number of points for a given progress indicator + ConstructListModel? getConstructsModel(ProgressIndicatorEnum indicator) { + switch (indicator) { + case ProgressIndicatorEnum.wordsUsed: + return words; + case ProgressIndicatorEnum.morphsUsed: + return morphs; + default: + return null; + } + } + /// Get the number of points for a given progress indicator int? getProgressPoints(ProgressIndicatorEnum indicator) { switch (indicator) { case ProgressIndicatorEnum.wordsUsed: return words?.lemmas.length; - case ProgressIndicatorEnum.errorTypes: - return errors?.lemmas.length; case ProgressIndicatorEnum.morphsUsed: return morphs?.lemmas.length; case ProgressIndicatorEnum.level: @@ -215,7 +219,17 @@ class LearningProgressIndicatorsState .map( (indicator) => ProgressIndicatorBadge( points: getProgressPoints(indicator), - onTap: () {}, + onTap: () { + final model = getConstructsModel(indicator); + if (model == null) return; + showDialog( + context: context, + builder: (c) => AnalyticsPopup( + indicator: indicator, + constructsModel: model, + ), + ); + }, progressIndicator: indicator, loading: loading, ),