All real data, confetti tweaks, remove test button, timing and animation tweaks, added copy to arb file
This commit is contained in:
parent
d49d08f67b
commit
fe22e2bcd2
5 changed files with 193 additions and 190 deletions
|
|
@ -4976,5 +4976,6 @@
|
|||
"canBeFoundViaCodeOrLink": "\u2022 code or link",
|
||||
"canBeFoundViaKnock": "\u2022 request to join and admin approval",
|
||||
"anyoneCanJoin": "Anyone can join! However, admin can kick and ban whoever misbehaves. Those who are banned may not return!",
|
||||
"createYourSpace": "Create your space"
|
||||
"createYourSpace": "Create your space",
|
||||
"youHaveLeveledUp": "You have leveled up!"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ import 'package:fluffychat/widgets/settings_switch_list_tile.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
//import for testing level up
|
||||
import '../../pangea/analytics_misc/level_up/level_up_banner.dart';
|
||||
import 'settings_chat.dart';
|
||||
|
||||
class SettingsChatView extends StatelessWidget {
|
||||
|
|
@ -30,17 +28,6 @@ class SettingsChatView extends StatelessWidget {
|
|||
child: MaxWidthBody(
|
||||
child: Column(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
// Test button for leveling up
|
||||
onPressed: () {
|
||||
LevelUpUtil.showLevelUpDialog(
|
||||
4,
|
||||
3,
|
||||
context,
|
||||
);
|
||||
},
|
||||
child: const Text("Test Level Up Dialog"),
|
||||
),
|
||||
// #Pangea
|
||||
// SettingsSwitchListTile.adaptive(
|
||||
// title: L10n.of(context).formattedMessages,
|
||||
|
|
|
|||
|
|
@ -23,29 +23,21 @@ class LevelUpUtil {
|
|||
int prevLevel,
|
||||
BuildContext context,
|
||||
) async {
|
||||
// Remove delay since GetAnalyticsController._onLevelUp is already async
|
||||
final player = AudioPlayer();
|
||||
|
||||
final snackbarRegex = RegExp(r'_snackbar$');
|
||||
// Wait for any existing snackbars to dismiss
|
||||
await _waitForSnackbars(context);
|
||||
|
||||
while (MatrixState.pAnyState.activeOverlays
|
||||
.any((overlayId) => snackbarRegex.hasMatch(overlayId))) {
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
}
|
||||
await player.play(
|
||||
UrlSource(
|
||||
"${AppConfig.assetsBaseURL}/${AnalyticsConstants.levelUpAudioFileName}",
|
||||
),
|
||||
);
|
||||
|
||||
player
|
||||
.play(
|
||||
UrlSource(
|
||||
"${AppConfig.assetsBaseURL}/${AnalyticsConstants.levelUpAudioFileName}",
|
||||
),
|
||||
)
|
||||
.then(
|
||||
(_) => Future.delayed(
|
||||
const Duration(seconds: 2),
|
||||
() => player.dispose(),
|
||||
),
|
||||
);
|
||||
if (!context.mounted) return;
|
||||
|
||||
OverlayUtil.showOverlay(
|
||||
await OverlayUtil.showOverlay(
|
||||
overlayKey: "level_up_notification",
|
||||
context: context,
|
||||
child: LevelUpBanner(
|
||||
|
|
@ -54,7 +46,7 @@ class LevelUpUtil {
|
|||
backButtonOverride: IconButton(
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
MatrixState.pAnyState.closeOverlay("level_up_notification");
|
||||
},
|
||||
),
|
||||
),
|
||||
|
|
@ -64,6 +56,17 @@ class LevelUpUtil {
|
|||
closePrevOverlay: false,
|
||||
canPop: false,
|
||||
);
|
||||
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
player.dispose();
|
||||
}
|
||||
|
||||
static Future<void> _waitForSnackbars(BuildContext context) async {
|
||||
final snackbarRegex = RegExp(r'_snackbar$');
|
||||
while (MatrixState.pAnyState.activeOverlays
|
||||
.any((id) => snackbarRegex.hasMatch(id))) {
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,15 +97,12 @@ class LevelUpBannerState extends State<LevelUpBanner>
|
|||
void initState() {
|
||||
super.initState();
|
||||
|
||||
LevelUpManager().preloadAnalytics(
|
||||
LevelUpManager.instance.preloadAnalytics(
|
||||
context,
|
||||
widget.level,
|
||||
widget.prevLevel,
|
||||
);
|
||||
|
||||
LevelUpManager().shouldAutoPopup = true;
|
||||
|
||||
LevelUpManager().printAnalytics();
|
||||
LevelUpManager.instance.printAnalytics();
|
||||
|
||||
_slideController = AnimationController(
|
||||
vsync: this,
|
||||
|
|
@ -122,8 +122,9 @@ class LevelUpBannerState extends State<LevelUpBanner>
|
|||
_slideController.forward();
|
||||
|
||||
Future.delayed(const Duration(seconds: 10), () async {
|
||||
if (mounted && !_showedDetails) {}
|
||||
_close();
|
||||
if (mounted && !_showedDetails) {
|
||||
_close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -140,12 +141,12 @@ class LevelUpBannerState extends State<LevelUpBanner>
|
|||
|
||||
Future<void> _toggleDetails() async {
|
||||
await _close();
|
||||
LevelUpManager().markPopupSeen();
|
||||
LevelUpManager.instance.markPopupSeen();
|
||||
_showedDetails = true;
|
||||
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) => LevelUpPopup(widget: widget),
|
||||
builder: (context) => const LevelUpPopup(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -228,7 +229,6 @@ class LevelUpBannerState extends State<LevelUpBanner>
|
|||
),
|
||||
),
|
||||
),
|
||||
// Optional staging-only dropdown icon
|
||||
SizedBox(
|
||||
width: constraints.maxWidth >= 600 ? 120.0 : 65.0,
|
||||
child: Row(
|
||||
|
|
|
|||
|
|
@ -1,22 +1,25 @@
|
|||
import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart';
|
||||
import 'package:fluffychat/pangea/analytics_misc/level_up/level_up_banner.dart';
|
||||
import 'package:fluffychat/pangea/constructs/construct_repo.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class LevelUpManager {
|
||||
// Singleton instance
|
||||
static final LevelUpManager instance = LevelUpManager._internal();
|
||||
|
||||
// Private constructor
|
||||
LevelUpManager._internal();
|
||||
factory LevelUpManager() {
|
||||
return _instance;
|
||||
}
|
||||
static final LevelUpManager _instance = LevelUpManager._internal();
|
||||
|
||||
int? prevLevel;
|
||||
int? level;
|
||||
int prevLevel = 0;
|
||||
int level = 0;
|
||||
|
||||
int? prevGrammar;
|
||||
int? nextGrammar;
|
||||
int? prevVocab;
|
||||
int? nextVocab;
|
||||
int prevGrammar = 0;
|
||||
int nextGrammar = 0;
|
||||
int prevVocab = 0;
|
||||
int nextVocab = 0;
|
||||
|
||||
String? userL2Code;
|
||||
|
||||
ConstructSummary? constructSummary;
|
||||
|
||||
|
|
@ -24,6 +27,13 @@ class LevelUpManager {
|
|||
bool shouldAutoPopup = false;
|
||||
String? error;
|
||||
|
||||
bool _isShowingLevelUp = false;
|
||||
|
||||
int get vocabCount =>
|
||||
MatrixState.pangeaController.getAnalytics.constructListModel
|
||||
.unlockedLemmas(ConstructTypeEnum.vocab)
|
||||
.length;
|
||||
|
||||
Future<void> preloadAnalytics(
|
||||
BuildContext context,
|
||||
int level,
|
||||
|
|
@ -32,22 +42,22 @@ class LevelUpManager {
|
|||
this.level = level;
|
||||
this.prevLevel = prevLevel;
|
||||
|
||||
//grammar and vocab
|
||||
nextGrammar = MatrixState.pangeaController.getAnalytics.constructListModel
|
||||
.unlockedLemmas(
|
||||
ConstructTypeEnum.morph,
|
||||
)
|
||||
.length;
|
||||
shouldAutoPopup = true;
|
||||
|
||||
nextVocab = MatrixState.pangeaController.getAnalytics.constructListModel
|
||||
.unlockedLemmas(
|
||||
ConstructTypeEnum.vocab,
|
||||
)
|
||||
.length;
|
||||
//grammar and vocab
|
||||
nextGrammar = MatrixState
|
||||
.pangeaController.getAnalytics.constructListModel.grammarLemmas;
|
||||
nextVocab = MatrixState
|
||||
.pangeaController.getAnalytics.constructListModel.vocabLemmas;
|
||||
|
||||
//for now idk how to get these
|
||||
prevGrammar = 0;
|
||||
prevVocab = 0;
|
||||
prevGrammar = nextGrammar < 20 ? 0 : nextGrammar - 20;
|
||||
|
||||
prevVocab = nextVocab < 20 ? 0 : nextVocab - 20;
|
||||
|
||||
userL2Code = MatrixState.pangeaController.languageController
|
||||
.activeL2Code()
|
||||
?.toUpperCase();
|
||||
|
||||
//fetch construct summary
|
||||
try {
|
||||
|
|
@ -72,6 +82,8 @@ class LevelUpManager {
|
|||
print('Previous Level: $prevLevel');
|
||||
print('Next Grammar: $nextGrammar');
|
||||
print('Next Vocab: $nextVocab');
|
||||
print("should show popup: $shouldAutoPopup");
|
||||
print("has seen popup: $hasSeenPopup");
|
||||
if (constructSummary != null) {
|
||||
print('Construct Summary: ${constructSummary!.toJson()}');
|
||||
} else {
|
||||
|
|
@ -79,17 +91,37 @@ class LevelUpManager {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> handleLevelUp(
|
||||
BuildContext context,
|
||||
int level,
|
||||
int prevLevel,
|
||||
) async {
|
||||
if (_isShowingLevelUp) return;
|
||||
_isShowingLevelUp = true;
|
||||
|
||||
await preloadAnalytics(context, level, prevLevel);
|
||||
|
||||
if (!context.mounted) {
|
||||
_isShowingLevelUp = false;
|
||||
return;
|
||||
}
|
||||
|
||||
await LevelUpUtil.showLevelUpDialog(level, prevLevel, context);
|
||||
_isShowingLevelUp = false;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
hasSeenPopup = false;
|
||||
shouldAutoPopup = false;
|
||||
prevLevel = null;
|
||||
level = null;
|
||||
prevGrammar = null;
|
||||
nextGrammar = null;
|
||||
prevVocab = null;
|
||||
nextVocab = null;
|
||||
prevLevel = 0;
|
||||
level = 0;
|
||||
prevGrammar = 0;
|
||||
nextGrammar = 0;
|
||||
prevVocab = 0;
|
||||
nextVocab = 0;
|
||||
constructSummary = null;
|
||||
error = null;
|
||||
_isShowingLevelUp = false;
|
||||
// Reset any other state if necessary
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ import 'dart:math';
|
|||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:confetti/confetti.dart';
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart';
|
||||
import 'package:fluffychat/pangea/analytics_misc/learning_skills_enum.dart';
|
||||
import 'package:fluffychat/pangea/analytics_misc/level_up/level_up_banner.dart';
|
||||
import 'package:fluffychat/pangea/analytics_summary/progress_bar/progress_bar.dart';
|
||||
import 'package:fluffychat/pangea/analytics_misc/level_up/level_up_manager.dart';
|
||||
import 'package:fluffychat/pangea/analytics_summary/progress_bar/level_bar.dart';
|
||||
import 'package:fluffychat/pangea/analytics_summary/progress_bar/progress_bar_details.dart';
|
||||
import 'package:fluffychat/pangea/common/widgets/full_width_dialog.dart';
|
||||
import 'package:fluffychat/pangea/constructs/construct_repo.dart';
|
||||
|
|
@ -22,11 +22,8 @@ import 'package:matrix/matrix_api_lite/generated/model.dart';
|
|||
class LevelUpPopup extends StatelessWidget {
|
||||
const LevelUpPopup({
|
||||
super.key,
|
||||
required this.widget,
|
||||
});
|
||||
|
||||
final LevelUpBanner widget;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FullWidthDialog(
|
||||
|
|
@ -36,18 +33,18 @@ class LevelUpPopup extends StatelessWidget {
|
|||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: kIsWeb
|
||||
? const Text(
|
||||
"You have leveled up!",
|
||||
style: TextStyle(
|
||||
? Text(
|
||||
L10n.of(context).youHaveLeveledUp,
|
||||
style: const TextStyle(
|
||||
color: AppConfig.gold,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
body: LevelUpBarAnimation(
|
||||
prevLevel: widget.prevLevel,
|
||||
level: widget.level,
|
||||
body: LevelUpPopupContent(
|
||||
prevLevel: LevelUpManager.instance.prevLevel ?? 0,
|
||||
level: LevelUpManager.instance.level ?? 0,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
@ -55,57 +52,55 @@ class LevelUpPopup extends StatelessWidget {
|
|||
}
|
||||
|
||||
//animated progress bar -- move to own file later
|
||||
class LevelUpBarAnimation extends StatefulWidget {
|
||||
class LevelUpPopupContent extends StatefulWidget {
|
||||
final int prevLevel;
|
||||
final int level;
|
||||
|
||||
const LevelUpBarAnimation({
|
||||
const LevelUpPopupContent({
|
||||
super.key,
|
||||
required this.prevLevel,
|
||||
required this.level,
|
||||
});
|
||||
|
||||
@override
|
||||
State<LevelUpBarAnimation> createState() => _LevelUpBarAnimationState();
|
||||
State<LevelUpPopupContent> createState() => _LevelUpPopupContentState();
|
||||
}
|
||||
|
||||
class _LevelUpBarAnimationState extends State<LevelUpBarAnimation>
|
||||
class _LevelUpPopupContentState extends State<LevelUpPopupContent>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late int _endGrammar;
|
||||
late int _endVocab;
|
||||
late final AnimationController _controller;
|
||||
late final Animation<double> _progressAnimation;
|
||||
late final Animation<int> _vocabAnimation;
|
||||
late final Animation<int> _grammarAnimation;
|
||||
late final Animation<double> _skillsOpacity;
|
||||
late final Animation<double> _shrinkMultiplier;
|
||||
|
||||
Uri? avatarUrl;
|
||||
late final Future<Profile> profile;
|
||||
|
||||
late final ConfettiController _confettiController;
|
||||
|
||||
ConstructSummary? _constructSummary;
|
||||
String? _error;
|
||||
|
||||
int displayedLevel = -1;
|
||||
bool _hasBlastedConfetti = false;
|
||||
|
||||
static const int _startGrammar = 0;
|
||||
static const int _startVocab = 0;
|
||||
static const String language = "ES";
|
||||
static final int _startGrammar = LevelUpManager.instance.prevGrammar ?? 0;
|
||||
static final int _startVocab = LevelUpManager.instance.prevVocab ?? 0;
|
||||
static final ConstructSummary? _constructSummary =
|
||||
LevelUpManager.instance.constructSummary;
|
||||
static final String? _error = LevelUpManager.instance.error;
|
||||
static final String language = LevelUpManager.instance.userL2Code ?? "N/A";
|
||||
|
||||
static const Duration _animationDuration = Duration(seconds: 6);
|
||||
static const Duration _animationDuration = Duration(seconds: 5);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
LevelUpManager.instance.markPopupSeen();
|
||||
|
||||
displayedLevel = widget.prevLevel;
|
||||
_confettiController =
|
||||
ConfettiController(duration: const Duration(seconds: 3));
|
||||
|
||||
_setConstructSummary();
|
||||
_setGrammarAndVocab();
|
||||
// Use LevelUpManager stats instead of fetching separately
|
||||
_endGrammar = LevelUpManager.instance.nextGrammar ?? 0;
|
||||
_endVocab = LevelUpManager.instance.nextVocab ?? 0;
|
||||
|
||||
final client = Matrix.of(context).client;
|
||||
client.fetchOwnProfile().then((profile) {
|
||||
|
|
@ -135,70 +130,10 @@ class _LevelUpBarAnimationState extends State<LevelUpBarAnimation>
|
|||
}
|
||||
});
|
||||
|
||||
_progressAnimation = Tween<double>(begin: 0, end: 1).animate(
|
||||
CurvedAnimation(parent: _controller, curve: Curves.easeOutBack),
|
||||
);
|
||||
|
||||
_vocabAnimation = IntTween(begin: _startVocab, end: _endVocab).animate(
|
||||
CurvedAnimation(
|
||||
parent: _controller,
|
||||
curve: const Interval(0.0, 0.5, curve: Curves.easeInOutQuad),
|
||||
),
|
||||
);
|
||||
|
||||
_grammarAnimation =
|
||||
IntTween(begin: _startGrammar, end: _endGrammar).animate(
|
||||
CurvedAnimation(
|
||||
parent: _controller,
|
||||
curve: const Interval(0.0, 0.5, curve: Curves.easeInOutQuad),
|
||||
),
|
||||
);
|
||||
|
||||
_skillsOpacity = Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||
CurvedAnimation(
|
||||
parent: _controller,
|
||||
curve: const Interval(0.7, 1.0, curve: Curves.easeIn),
|
||||
),
|
||||
);
|
||||
|
||||
_shrinkMultiplier = Tween<double>(begin: 1.0, end: 0.3).animate(
|
||||
CurvedAnimation(
|
||||
parent: _controller,
|
||||
curve: const Interval(0.7, 1.0, curve: Curves.easeInOut),
|
||||
),
|
||||
);
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_controller.forward(); // or start your animation
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _setConstructSummary() async {
|
||||
try {
|
||||
_constructSummary = await MatrixState.pangeaController.getAnalytics
|
||||
.generateLevelUpAnalytics(
|
||||
widget.level,
|
||||
widget.prevLevel,
|
||||
);
|
||||
} catch (e) {
|
||||
_error = e.toString();
|
||||
}
|
||||
}
|
||||
|
||||
void _setGrammarAndVocab() {
|
||||
_endGrammar = MatrixState.pangeaController.getAnalytics.constructListModel
|
||||
.unlockedLemmas(
|
||||
ConstructTypeEnum.morph,
|
||||
)
|
||||
.length;
|
||||
|
||||
_endVocab = MatrixState.pangeaController.getAnalytics.constructListModel
|
||||
.unlockedLemmas(
|
||||
ConstructTypeEnum.vocab,
|
||||
)
|
||||
.length;
|
||||
_controller.forward();
|
||||
}
|
||||
|
||||
// Use LevelUpManager's constructSummary instead of local _constructSummary
|
||||
int _getSkillXP(LearningSkillsEnum skill) {
|
||||
return switch (skill) {
|
||||
LearningSkillsEnum.writing =>
|
||||
|
|
@ -217,12 +152,50 @@ class _LevelUpBarAnimationState extends State<LevelUpBarAnimation>
|
|||
void dispose() {
|
||||
_controller.dispose();
|
||||
_confettiController.dispose();
|
||||
LevelUpManager.instance.reset();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Animation<double> progressAnimation =
|
||||
Tween<double>(begin: 0, end: 1).animate(
|
||||
CurvedAnimation(parent: _controller, curve: const Interval(0.0, 0.5)),
|
||||
);
|
||||
|
||||
final Animation<int> vocabAnimation =
|
||||
IntTween(begin: _startVocab, end: _endVocab).animate(
|
||||
CurvedAnimation(
|
||||
parent: _controller,
|
||||
curve: const Interval(0.0, 0.5, curve: Curves.easeInOutQuad),
|
||||
),
|
||||
);
|
||||
|
||||
final Animation<int> grammarAnimation =
|
||||
IntTween(begin: _startGrammar, end: _endGrammar).animate(
|
||||
CurvedAnimation(
|
||||
parent: _controller,
|
||||
curve: const Interval(0.0, 0.5, curve: Curves.easeInOutQuad),
|
||||
),
|
||||
);
|
||||
|
||||
final Animation<double> skillsOpacity =
|
||||
Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||
CurvedAnimation(
|
||||
parent: _controller,
|
||||
curve: const Interval(0.7, 1.0, curve: Curves.easeIn),
|
||||
),
|
||||
);
|
||||
|
||||
final Animation<double> shrinkMultiplier =
|
||||
Tween<double>(begin: 1.0, end: 0.3).animate(
|
||||
CurvedAnimation(
|
||||
parent: _controller,
|
||||
curve: const Interval(0.7, 1.0, curve: Curves.easeInOut),
|
||||
),
|
||||
);
|
||||
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final grammarVocabStyle = Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
|
|
@ -237,24 +210,26 @@ class _LevelUpBarAnimationState extends State<LevelUpBarAnimation>
|
|||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
AnimatedBuilder(
|
||||
animation: _progressAnimation,
|
||||
animation: _controller,
|
||||
builder: (_, __) => Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
avatarUrl == null
|
||||
? const CircularProgressIndicator()
|
||||
: Padding(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: MxcImage(
|
||||
uri: avatarUrl,
|
||||
width: 150 * _shrinkMultiplier.value,
|
||||
height: 150 * _shrinkMultiplier.value,
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: avatarUrl == null
|
||||
? const CircularProgressIndicator()
|
||||
: ClipOval(
|
||||
child: MxcImage(
|
||||
uri: avatarUrl,
|
||||
width: 150 * shrinkMultiplier.value,
|
||||
height: 150 * shrinkMultiplier.value,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
language,
|
||||
style: TextStyle(
|
||||
fontSize: 24 * _skillsOpacity.value,
|
||||
fontSize: 24 * skillsOpacity.value,
|
||||
color: AppConfig.goldLight,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
|
|
@ -264,19 +239,26 @@ class _LevelUpBarAnimationState extends State<LevelUpBarAnimation>
|
|||
),
|
||||
// Progress bar + Level
|
||||
AnimatedBuilder(
|
||||
animation: _progressAnimation,
|
||||
animation: _controller,
|
||||
builder: (_, __) => Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ProgressBar(
|
||||
levelBars: [
|
||||
LevelBarDetails(
|
||||
widthMultiplier: _progressAnimation.value,
|
||||
currentPoints: 0,
|
||||
fillColor: AppConfig.goldLight,
|
||||
),
|
||||
],
|
||||
height: 20,
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return LevelBar(
|
||||
details: const LevelBarDetails(
|
||||
fillColor: Colors.green,
|
||||
currentPoints: 0,
|
||||
widthMultiplier: 1,
|
||||
),
|
||||
progressBarDetails: ProgressBarDetails(
|
||||
totalWidth: constraints.maxWidth *
|
||||
progressAnimation.value,
|
||||
height: 20,
|
||||
borderColor: colorScheme.surface,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
|
|
@ -304,7 +286,7 @@ class _LevelUpBarAnimationState extends State<LevelUpBarAnimation>
|
|||
size: 35,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text('${_vocabAnimation.value}', style: grammarVocabStyle),
|
||||
Text('${vocabAnimation.value}', style: grammarVocabStyle),
|
||||
const SizedBox(width: 40),
|
||||
Icon(
|
||||
Symbols.toys_and_games,
|
||||
|
|
@ -313,7 +295,7 @@ class _LevelUpBarAnimationState extends State<LevelUpBarAnimation>
|
|||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'${_grammarAnimation.value}',
|
||||
'${grammarAnimation.value}',
|
||||
style: grammarVocabStyle,
|
||||
),
|
||||
],
|
||||
|
|
@ -323,9 +305,9 @@ class _LevelUpBarAnimationState extends State<LevelUpBarAnimation>
|
|||
|
||||
// Skills section
|
||||
AnimatedBuilder(
|
||||
animation: _skillsOpacity,
|
||||
animation: skillsOpacity,
|
||||
builder: (_, __) => Opacity(
|
||||
opacity: _skillsOpacity.value,
|
||||
opacity: skillsOpacity.value,
|
||||
child: _error == null
|
||||
? Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
|
|
@ -415,8 +397,9 @@ class _LevelUpBarAnimationState extends State<LevelUpBarAnimation>
|
|||
.explosive, // don't specify a direction, blast randomly
|
||||
shouldLoop:
|
||||
true, // start again as soon as the animation is finished
|
||||
emissionFrequency: 0.1,
|
||||
numberOfParticles: 7,
|
||||
emissionFrequency: 0.2,
|
||||
numberOfParticles: 15,
|
||||
gravity: 0.1,
|
||||
colors: const [
|
||||
AppConfig.goldLight,
|
||||
AppConfig.gold,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue