diff --git a/lib/pangea/analytics_misc/level_up.dart b/lib/pangea/analytics_misc/level_up.dart index 3325089e4..872e8f450 100644 --- a/lib/pangea/analytics_misc/level_up.dart +++ b/lib/pangea/analytics_misc/level_up.dart @@ -1,19 +1,19 @@ import 'dart:async'; -import 'package:flutter/material.dart'; - import 'package:audioplayers/audioplayers.dart'; import 'package:cached_network_image/cached_network_image.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; - import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pangea/analytics_misc/analytics_constants.dart'; import 'package:fluffychat/pangea/analytics_misc/learning_skills_enum.dart'; +import 'package:fluffychat/pangea/analytics_summary/progress_bar/progress_bar.dart'; +import 'package:fluffychat/pangea/analytics_summary/progress_bar/progress_bar_details.dart'; import 'package:fluffychat/pangea/common/config/environment.dart'; import 'package:fluffychat/pangea/common/utils/overlay.dart'; import 'package:fluffychat/pangea/constructs/construct_repo.dart'; import 'package:fluffychat/widgets/matrix.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; class LevelUpConstants { static const String starFileName = "star.png"; @@ -88,6 +88,7 @@ class LevelUpBannerState extends State bool _showDetails = false; bool _showedDetails = false; + bool _showingLevelingAnimation = false; ConstructSummary? _constructSummary; String? _error; @@ -177,9 +178,15 @@ class LevelUpBannerState extends State if (!Environment.isStagingEnvironment) return; if (mounted) { + if (!_showedDetails) { + setState(() { + _showingLevelingAnimation = true; + }); + } + setState(() { _showDetails = !_showDetails; - if (_showDetails && !_showedDetails) { + if (_showDetails && _showedDetails) { _showedDetails = true; } }); @@ -188,6 +195,14 @@ class LevelUpBannerState extends State ? _sizeController.forward() : _sizeController.reverse()); + if (_showDetails && _showingLevelingAnimation) { + await Future.delayed(const Duration(seconds: 2)); + if (!mounted) return; + setState(() { + _showingLevelingAnimation = false; + }); + } + if (!_showDetails) { await Future.delayed( const Duration(milliseconds: 300), @@ -240,9 +255,10 @@ class LevelUpBannerState extends State top: 16, ), decoration: BoxDecoration( - color: Theme.of(context) - .colorScheme - .secondaryContainer, + color: + Theme.of(context).brightness == Brightness.dark + ? Colors.black + : Colors.white, borderRadius: BorderRadius.circular(8), ), padding: const EdgeInsets.symmetric( @@ -258,10 +274,8 @@ class LevelUpBannerState extends State text: TextSpan( children: [ TextSpan( - text: L10n.of(context) - .congratulationsOnReaching( - widget.level, - ), + //Hardcoded for now, put in translations later + text: "Level up", style: style, ), TextSpan( @@ -287,7 +301,7 @@ class LevelUpBannerState extends State duration: FluffyThemes.animationDuration, child: _error == null ? FluffyThemes.isColumnMode(context) - ? ElevatedButton( + ? IconButton( style: IconButton.styleFrom( padding: const EdgeInsets .symmetric( @@ -296,8 +310,11 @@ class LevelUpBannerState extends State ), ), onPressed: _toggleDetails, - child: Text( - L10n.of(context).details, + icon: Icon( + Icons.arrow_drop_down, + color: Theme.of(context) + .colorScheme + .onSurface, ), ) : SizedBox( @@ -337,10 +354,6 @@ class LevelUpBannerState extends State ], ), ), - IconButton( - icon: const Icon(Icons.close), - onPressed: _close, - ), ], ), ], @@ -350,156 +363,168 @@ class LevelUpBannerState extends State SizeTransition( sizeFactor: _sizeAnimation, child: Container( - constraints: BoxConstraints( - maxHeight: - MediaQuery.of(context).size.height * 0.75, - ), + height: MediaQuery.of(context).size.height * 0.75, + width: MediaQuery.of(context).size.width * .5, margin: const EdgeInsets.only( top: 4.0, ), decoration: BoxDecoration( - color: Colors.black, + color: + Theme.of(context).brightness == Brightness.dark + ? Colors.black + : Colors.white, borderRadius: BorderRadius.circular(8), ), padding: const EdgeInsets.all(16), - child: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - spacing: 24.0, - children: [ - Table( - columnWidths: const { - 0: IntrinsicColumnWidth(), - 1: FlexColumnWidth(), - 2: IntrinsicColumnWidth(), - }, - defaultVerticalAlignment: - TableCellVerticalAlignment.middle, - children: [ - ...LearningSkillsEnum.values - .where( - (v) => - v.isVisible && _skillsPoints(v) > -1, - ) - .map((skill) { - return TableRow( + child: _showingLevelingAnimation + ? const Expanded( + child: LevelUpBarAnimation(), + ) + : SingleChildScrollView( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + spacing: 24.0, + children: [ + Table( + columnWidths: const { + 0: IntrinsicColumnWidth(), + 1: FlexColumnWidth(), + 2: IntrinsicColumnWidth(), + }, + defaultVerticalAlignment: + TableCellVerticalAlignment.middle, children: [ - Padding( - padding: const EdgeInsets.symmetric( - vertical: 9.0, - horizontal: 18.0, - ), - child: Icon( - skill.icon, - size: 25, - color: Colors.white, - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - vertical: 9.0, - horizontal: 18.0, - ), - child: Text( - skill.tooltip(context), - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Colors.white, - ), - textAlign: TextAlign.center, - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - vertical: 9.0, - horizontal: 18.0, - ), - child: Text( - "+ ${_skillsPoints(skill)} XP", - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Colors.white, - ), - textAlign: TextAlign.center, - ), - ), + ...LearningSkillsEnum.values + .where( + (v) => + v.isVisible && + _skillsPoints(v) > -1, + ) + .map((skill) { + return TableRow( + children: [ + Padding( + padding: const EdgeInsets + .symmetric( + vertical: 9.0, + horizontal: 18.0, + ), + child: Icon( + skill.icon, + size: 25, + color: Theme.of(context) + .colorScheme + .onSurface, + ), + ), + Padding( + padding: const EdgeInsets + .symmetric( + vertical: 9.0, + horizontal: 18.0, + ), + child: Text( + skill.tooltip(context), + style: const TextStyle( + fontSize: 16, + fontWeight: + FontWeight.w600, + ), + textAlign: TextAlign.center, + ), + ), + Padding( + padding: const EdgeInsets + .symmetric( + vertical: 9.0, + horizontal: 18.0, + ), + child: Text( + "+ ${_skillsPoints(skill)} XP", + style: const TextStyle( + fontSize: 16, + fontWeight: + FontWeight.w600, + ), + textAlign: TextAlign.center, + ), + ), + ], + ); + }), ], - ); - }), - ], - ), - CachedNetworkImage( - imageUrl: - "${AppConfig.assetsBaseURL}/${LevelUpConstants.dinoLevelUPFileName}", - width: 400, - fit: BoxFit.cover, - ), - if (_constructSummary?.textSummary != null) - Container( - padding: const EdgeInsets.all(12), - decoration: BoxDecoration( - color: Theme.of(context) - .colorScheme - .secondaryContainer, - borderRadius: BorderRadius.circular(8), - ), - child: Text( - _constructSummary!.textSummary, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Theme.of(context) - .colorScheme - .onSecondaryContainer, ), - textAlign: TextAlign.center, - ), + CachedNetworkImage( + imageUrl: + "${AppConfig.assetsBaseURL}/${LevelUpConstants.dinoLevelUPFileName}", + width: 400, + fit: BoxFit.cover, + ), + if (_constructSummary?.textSummary != + null) + Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.transparent, + borderRadius: + BorderRadius.circular(8), + ), + child: Text( + _constructSummary!.textSummary, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w400, + color: Theme.of(context) + .colorScheme + .onSecondaryContainer, + ), + textAlign: TextAlign.center, + ), + ), + const SizedBox( + height: 24, + ), + // Share button, currently no functionality + // ElevatedButton( + // onPressed: () { + // // Add share functionality + // }, + // style: ElevatedButton.styleFrom( + // backgroundColor: Colors.white, + // foregroundColor: Colors.black, + // padding: const EdgeInsets.symmetric( + // vertical: 12, + // horizontal: 24, + // ), + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8), + // ), + // ), + // child: const Row( + // mainAxisSize: MainAxisSize + // .min, + // children: [ + // Text( + // "Share with Friends", + // style: TextStyle( + // fontSize: 16, + // fontWeight: FontWeight.bold, + // ), + // ), + // SizedBox( + // width: 8, + // ), + // Icon( + // Icons.ios_share, + // size: 20, + // ), + // ), + // ), + // ), + ], ), - const SizedBox( - height: 24, ), - // Share button, currently no functionality - // ElevatedButton( - // onPressed: () { - // // Add share functionality - // }, - // style: ElevatedButton.styleFrom( - // backgroundColor: Colors.white, - // foregroundColor: Colors.black, - // padding: const EdgeInsets.symmetric( - // vertical: 12, - // horizontal: 24, - // ), - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.circular(8), - // ), - // ), - // child: const Row( - // mainAxisSize: MainAxisSize - // .min, - // children: [ - // Text( - // "Share with Friends", - // style: TextStyle( - // fontSize: 16, - // fontWeight: FontWeight.bold, - // ), - // ), - // SizedBox( - // width: 8, - // ), - // Icon( - // Icons.ios_share, - // size: 20, - // ), - // ), - // ), - // ), - ], - ), - ), ), ), ], @@ -513,3 +538,61 @@ class LevelUpBannerState extends State ); } } + +//animated progress bar -- move to own file later +class LevelUpBarAnimation extends StatefulWidget { + const LevelUpBarAnimation({super.key}); + + @override + State createState() => _LevelUpBarAnimationState(); +} + +class _LevelUpBarAnimationState extends State + with SingleTickerProviderStateMixin { + late AnimationController _controller; + late Animation _animation; + + @override + void initState() { + super.initState(); + + _controller = AnimationController( + duration: const Duration(milliseconds: 1500), + vsync: this, + ); + + _animation = Tween(begin: 0, end: 1).animate( + CurvedAnimation(parent: _controller, curve: Curves.easeInOut), + ); + + _controller.forward(); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return AnimatedBuilder( + animation: _animation, + builder: (context, _) { + return Padding( + padding: const EdgeInsets.all(24), + child: ProgressBar( + levelBars: [ + LevelBarDetails( + widthMultiplier: _animation.value, + currentPoints: 0, + fillColor: AppConfig.goldLight, + ), + ], + height: 20, + ), + ); + }, + ); + } +}