From dfaa2720107ba2eb72e08293ad9e17b5875187e2 Mon Sep 17 00:00:00 2001 From: Jesse Cheng Date: Tue, 5 Nov 2024 19:19:31 -0500 Subject: [PATCH 1/5] Make progress bar width dynamic based on digit count and shorten large numbers - Adjusted progress bar width to dynamically scale based on the number of digits in total points, achievements, etc., providing better visual alignment. - Implemented formatting to shorten large numbers (e.g., 1500 becomes 1.5K) for improved readability. --- game/lib/widget/progress_bar.dart | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/game/lib/widget/progress_bar.dart b/game/lib/widget/progress_bar.dart index 4318b7d1..c2fbed97 100644 --- a/game/lib/widget/progress_bar.dart +++ b/game/lib/widget/progress_bar.dart @@ -12,12 +12,33 @@ class LoadingBar extends StatelessWidget { this.totalTasks, ); + String formatNumber(int number) { + if (number < 1000) { + return number.toString(); + } else { + return (number / 1000).toStringAsFixed(1) + 'K'; + } + } + + double calculateWidthMultiplier(int number) { + int length = number.toString().length; + if (length == 1) { + return 0.5; + } else if (length == 2) { + return 0.47; + } else { + return 0.43; + } + } + @override Widget build(BuildContext context) { + double widthMultiplier = calculateWidthMultiplier(totalTasks); + return Row( children: [ Container( - width: MediaQuery.sizeOf(context).width * 0.5, + width: MediaQuery.sizeOf(context).width * widthMultiplier, child: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { return Stack(children: [ @@ -66,7 +87,7 @@ class LoadingBar extends StatelessWidget { Padding( padding: const EdgeInsets.only(left: 8.0), child: Text( - tasksFinished.toString() + "/" + totalTasks.toString(), + "${formatNumber(tasksFinished)}/${formatNumber(totalTasks)}", ), ), ], From f2b3bd8eddbc0618d1c017f299d704a26d2c4187 Mon Sep 17 00:00:00 2001 From: Jesse Cheng Date: Fri, 15 Nov 2024 16:22:19 -0500 Subject: [PATCH 2/5] Added SingleChildScrollView to fix overflow bug error and made small UI changes to profile page. --- game/lib/achievements/achievement_cell.dart | 3 +- game/lib/profile/completed_cell.dart | 12 +- game/lib/profile/profile_page.dart | 441 ++++++++++---------- 3 files changed, 237 insertions(+), 219 deletions(-) diff --git a/game/lib/achievements/achievement_cell.dart b/game/lib/achievements/achievement_cell.dart index 96c268c8..d7eebafc 100644 --- a/game/lib/achievements/achievement_cell.dart +++ b/game/lib/achievements/achievement_cell.dart @@ -40,7 +40,7 @@ class _AchievementCellState extends State { onTap: () async {}, child: Container( width: MediaQuery.sizeOf(context).width * 0.85, - height: MediaQuery.sizeOf(context).height * 0.11, + height: MediaQuery.sizeOf(context).height * 0.105, //padding: EdgeInsets.all(5), decoration: BoxDecoration( color: Colors.white, @@ -67,6 +67,7 @@ class _AchievementCellState extends State { alignment: Alignment.centerLeft, child: Container( width: MediaQuery.sizeOf(context).width * 0.45, + padding: EdgeInsets.only(top: 2), child: Text( description, maxLines: 2, diff --git a/game/lib/profile/completed_cell.dart b/game/lib/profile/completed_cell.dart index 1d145e82..6c652f41 100644 --- a/game/lib/profile/completed_cell.dart +++ b/game/lib/profile/completed_cell.dart @@ -22,7 +22,7 @@ Widget completedCell( int points) { return Container( width: MediaQuery.sizeOf(context).width * 0.85, - height: MediaQuery.sizeOf(context).height * 0.11, + height: MediaQuery.sizeOf(context).height * 0.105, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10.0), @@ -38,7 +38,7 @@ Widget completedCell( Padding( padding: const EdgeInsets.all(10), child: ClipRRect( - borderRadius: BorderRadius.circular(20), + borderRadius: BorderRadius.circular(10), child: Image( width: 64, height: 64, @@ -64,9 +64,13 @@ Widget completedCell( children: [ Text( "From " + type + " - ", - style: TextStyle(color: Colors.grey, fontSize: 12), + style: TextStyle( + color: Colors.grey, + fontSize: 12, + fontWeight: FontWeight.w600), ), - Text(date) + Text(date, + style: TextStyle(color: Colors.black, fontSize: 12)) ], ), Padding( diff --git a/game/lib/profile/profile_page.dart b/game/lib/profile/profile_page.dart index 557321e9..b5360f17 100644 --- a/game/lib/profile/profile_page.dart +++ b/game/lib/profile/profile_page.dart @@ -32,246 +32,259 @@ class _ProfilePageState extends State { Widget build(BuildContext context) { return Scaffold( backgroundColor: Color.fromARGB(255, 255, 245, 234), - body: SafeArea(child: Container( - child: Consumer5( - builder: (context, userModel, eventModel, trackerModel, - challengeModel, achModel, child) { - if (userModel.userData == null) { - return Center( - child: CircularProgressIndicator(), - ); - } + body: SafeArea( + child: SingleChildScrollView(child: Container( + child: Consumer5( + builder: (context, userModel, eventModel, trackerModel, + challengeModel, achModel, child) { + if (userModel.userData == null) { + return Center( + child: CircularProgressIndicator(), + ); + } - final achList = achModel.getAvailableTrackerPairs(); - var username = userModel.userData?.username; - var isGuest = userModel.userData?.authType == UserAuthTypeDto.device; - var score = userModel.userData?.score; + final achList = achModel.getAvailableTrackerPairs(); + var username = userModel.userData?.username; + var isGuest = + userModel.userData?.authType == UserAuthTypeDto.device; + var score = userModel.userData?.score; - List> completedEvents = []; + List> completedEvents = []; - //Get completed events - for (var eventId in userModel.userData!.trackedEvents!) { - if (completedEvents.length == 2) break; + //Get completed events + for (var eventId in userModel.userData!.trackedEvents!) { + if (completedEvents.length == 2) break; - var tracker = trackerModel.trackerByEventId(eventId); - EventDto? event = eventModel.getEventById(eventId); + var tracker = trackerModel.trackerByEventId(eventId); + EventDto? event = eventModel.getEventById(eventId); - if (tracker == null || event == null) { - continue; - } - if (tracker.prevChallenges.length != event.challenges!.length) { - continue; - } + if (tracker == null || event == null) { + continue; + } + if (tracker.prevChallenges.length != event.challenges!.length) { + continue; + } - try { - // prevChallenges.last will throw StateError if prevChallenges - // is empty, meaning the challenge was not completed properly - var completedDate = tracker.prevChallenges.last.dateCompleted; - DateTime date = - DateFormat("E, d MMM y HH:mm:ss").parse(completedDate); - int totalHintsUsed = 0; - for (var prev in tracker.prevChallenges) { - totalHintsUsed += prev.hintsUsed; + try { + // prevChallenges.last will throw StateError if prevChallenges + // is empty, meaning the challenge was not completed properly + var completedDate = tracker.prevChallenges.last.dateCompleted; + DateTime date = + DateFormat("E, d MMM y HH:mm:ss").parse(completedDate); + int totalHintsUsed = 0; + for (var prev in tracker.prevChallenges) { + totalHintsUsed += prev.hintsUsed; + } + completedEvents.add(Tuple3( + date, event, totalHintsUsed)); + } catch (e) { + displayToast("Error with completing challenge", Status.error); } - completedEvents.add( - Tuple3(date, event, totalHintsUsed)); - } catch (e) { - displayToast("Error with completing challenge", Status.error); } - } - //Sort so that the most recent events are first - completedEvents.sort((a, b) => b.item1.compareTo(a.item1)); - return Column( - children: [ - Stack(fit: StackFit.passthrough, children: [ - Center( - child: Container( - height: 160, - padding: EdgeInsets.only(top: 30), - child: Stack( - children: [ - Center( - child: SvgPicture.asset("assets/images/bear_prof.svg", - height: 100, width: 100), - ), - Align( - alignment: Alignment.bottomCenter, - child: Container( - height: 30, - width: 100, - padding: EdgeInsets.all(5.0), - decoration: BoxDecoration( - color: Color.fromARGB(255, 246, 228, 201), - borderRadius: BorderRadius.circular(15.0), - ), - child: Center( - child: Text( - score.toString() + " points", - style: TextStyle( - color: Colors.black, - fontWeight: FontWeight.w500, + //Sort so that the most recent events are first + completedEvents.sort((a, b) => b.item1.compareTo(a.item1)); + return Column( + children: [ + Stack(fit: StackFit.passthrough, children: [ + Center( + child: Container( + height: 180, + padding: EdgeInsets.only(top: 30), + child: Stack( + alignment: Alignment + .center, // Central alignment within the stack + children: [ + Positioned( + top: 0, // Adjust this value to move SVG up or down + child: SvgPicture.asset( + "assets/images/bear_prof.svg", + height: 100, + width: 100), + ), + Positioned( + bottom: 35, + child: Container( + height: 30, + width: 100, + padding: EdgeInsets.all(5.0), + decoration: BoxDecoration( + color: Color.fromARGB(255, 246, 228, 201), + borderRadius: BorderRadius.circular(15.0), + ), + child: Center( + child: Text( + score.toString() + " points", + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w500, + ), ), ), ), ), - ), - ], + Positioned( + bottom: 0, + child: Text( + username!, + style: TextStyle( + fontSize: 20, fontWeight: FontWeight.bold), + ), + ) + ], + ), ), ), - ), - Positioned.directional( - textDirection: TextDirection.rtl, - start: 10, - // top: 22, - child: Padding( - padding: const EdgeInsets.only(top: 10, right: 20), - child: IconButton( - alignment: Alignment.topRight, - icon: Icon(Icons.settings, size: 40), + Positioned.directional( + textDirection: TextDirection.rtl, + start: 10, + // top: 22, + child: Padding( + padding: const EdgeInsets.only(top: 0, right: 20), + child: IconButton( + alignment: Alignment.topRight, + icon: Icon(Icons.settings, size: 40), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + SettingsPage(isGuest))); + }), + ), + ), + ]), + //Completed Events + Padding( + padding: + const EdgeInsets.only(left: 28, right: 23.0, top: 14.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text("Completed", + style: TextStyle( + fontSize: 16, fontWeight: FontWeight.bold)), + TextButton( onPressed: () { Navigator.push( context, MaterialPageRoute( - builder: (context) => SettingsPage(isGuest))); - }), - ), - ), - ]), - Padding( - padding: const EdgeInsets.all(5.0), - child: Text( - username!, - style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), - ), - ), - //Completed Events - Padding( - padding: const EdgeInsets.only(left: 24, right: 24.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text("Completed", - style: TextStyle( - fontSize: 16, fontWeight: FontWeight.bold)), - TextButton( - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => CompletedFeedWidget())); - }, - child: Text( - 'View More →', - style: TextStyle( - color: Colors.black, - fontSize: 14.0, + builder: (context) => CompletedFeedWidget())); + }, + child: Text( + 'View All →', + style: TextStyle( + color: Colors.black, + fontSize: 14.0, + ), ), - ), - ) - ], + ) + ], + ), ), - ), - SizedBox( - height: MediaQuery.sizeOf(context).height * 0.25, - width: MediaQuery.sizeOf(context).width * 0.85, - child: ListView.separated( - itemCount: 2, - itemBuilder: (context, index) { - if (index >= completedEvents.length) { - return Container(); - } - var date = completedEvents[index].item1; - var event = completedEvents[index].item2; - var hintsUsed = completedEvents[index].item3; - String formattedDate = DateFormat("MMMM d, y").format(date); - var type = - event.challenges!.length > 1 ? "Journeys" : "Challenge"; + SizedBox( + height: MediaQuery.sizeOf(context).height * 0.24, + width: MediaQuery.sizeOf(context).width * 0.85, + child: ListView.separated( + itemCount: 2, + itemBuilder: (context, index) { + if (index >= completedEvents.length) { + return Container(); + } + var date = completedEvents[index].item1; + var event = completedEvents[index].item2; + var hintsUsed = completedEvents[index].item3; + String formattedDate = + DateFormat("MMMM d, y").format(date); + var type = event.challenges!.length > 1 + ? "Journeys" + : "Challenge"; - // Calculate totalPoints. - var totalPoints = 0; - var locationImage; - for (var challengeId in event.challenges ?? []) { - var challenge = - challengeModel.getChallengeById(challengeId); - locationImage = challenge?.imageUrl; - if (locationImage == null || locationImage.length == 0) - locationImage = - "https://upload.wikimedia.org/wikipedia/commons/b/b1/Missing-image-232x150.png"; - if (challenge != null) { - totalPoints += challenge.points ?? 0; + // Calculate totalPoints. + var totalPoints = 0; + var locationImage; + for (var challengeId in event.challenges ?? []) { + var challenge = + challengeModel.getChallengeById(challengeId); + locationImage = challenge?.imageUrl; + if (locationImage == null || locationImage.length == 0) + locationImage = + "https://upload.wikimedia.org/wikipedia/commons/b/b1/Missing-image-232x150.png"; + if (challenge != null) { + totalPoints += challenge.points ?? 0; + } } - } - return completedCell( - context, - event.name!, - locationImage, - type, - formattedDate, - friendlyDifficulty[event.difficulty]!, - hintsUsed, - totalPoints); - }, - physics: BouncingScrollPhysics(), - separatorBuilder: (context, index) { - return SizedBox(height: 10); - }, + return completedCell( + context, + event.name!, + locationImage, + type, + formattedDate, + friendlyDifficulty[event.difficulty]!, + hintsUsed, + totalPoints); + }, + physics: BouncingScrollPhysics(), + separatorBuilder: (context, index) { + return SizedBox(height: 10); + }, + ), ), - ), - Padding( - padding: const EdgeInsets.only(left: 24, right: 24), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text("Achievements", - style: TextStyle( - fontSize: 16, fontWeight: FontWeight.bold)), - TextButton( - onPressed: () { - // Handle button press, e.g., navigate to details page - Navigator.of(context).push(MaterialPageRoute( - builder: (context) => AchievementsPage())); - }, - child: Text( - 'View Details →', - style: TextStyle( - color: Colors.black, - fontSize: 14.0, + Padding( + padding: const EdgeInsets.only(left: 30, right: 23), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text("Achievements", + style: TextStyle( + fontSize: 16, fontWeight: FontWeight.bold)), + TextButton( + onPressed: () { + // Handle button press, e.g., navigate to details page + Navigator.of(context).push(MaterialPageRoute( + builder: (context) => AchievementsPage())); + }, + child: Text( + 'View Details →', + style: TextStyle( + color: Colors.black, + fontSize: 14.0, + ), ), - ), - ) - ], + ) + ], + ), ), - ), - //To be replaced with real data - Padding( - padding: EdgeInsets.only(left: 30, right: 30), - child: Column( - children: (achList - .sortedBy((a, b) => (a - .$1.progress / // least completed first - (a.$2.requiredPoints ?? 1)) - .compareTo( - b.$1.progress / (b.$2.requiredPoints ?? 1))) - .take(2) - .map((e) => ([ - AchievementCell( - e.$2.description ?? "", - SvgPicture.asset( - "assets/icons/achievementsilver.svg"), - e.$1.progress, - e.$2.requiredPoints ?? 0), - SizedBox(height: 10), - ])) - .expand((el) => el) - .toList()))), - ], - ); - }), - )), + //To be replaced with real data + Padding( + padding: EdgeInsets.only(left: 30, right: 30), + child: Column( + children: (achList + .sortedBy((a, b) => (a + .$1.progress / // least completed first + (a.$2.requiredPoints ?? 1)) + .compareTo( + b.$1.progress / (b.$2.requiredPoints ?? 1))) + .take(2) + .map((e) => ([ + AchievementCell( + e.$2.description ?? "", + SvgPicture.asset( + "assets/icons/achievementsilver.svg"), + e.$1.progress, + e.$2.requiredPoints ?? 0), + SizedBox(height: 10), + ])) + .expand((el) => el) + .toList()))), + ], + ); + }), + )), + ), ); } } From 7ce3be0bd924904329231e2250c1ea259975d8b8 Mon Sep 17 00:00:00 2001 From: Jesse Cheng Date: Sun, 17 Nov 2024 18:19:57 -0500 Subject: [PATCH 3/5] Changed progress bar width and points formatting --- game/lib/widget/progress_bar.dart | 42 ++++++++++++++++--------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/game/lib/widget/progress_bar.dart b/game/lib/widget/progress_bar.dart index c2fbed97..332235c4 100644 --- a/game/lib/widget/progress_bar.dart +++ b/game/lib/widget/progress_bar.dart @@ -16,29 +16,27 @@ class LoadingBar extends StatelessWidget { if (number < 1000) { return number.toString(); } else { - return (number / 1000).toStringAsFixed(1) + 'K'; - } - } - - double calculateWidthMultiplier(int number) { - int length = number.toString().length; - if (length == 1) { - return 0.5; - } else if (length == 2) { - return 0.47; - } else { - return 0.43; + if (number == 1000) { + return "1K"; + } else if (number > 1000 && number < 10000) { + return (number / 1000).toStringAsFixed(1) + 'K'; + } else if (number == 10000) { + return "10K"; + } else if (number > 10000 && number < 100000) { + return (number / 1000).toStringAsFixed(0) + 'K'; + } else { + // Throw an exception for numbers greater than 100,000 + throw FormatException('Number too large to format'); + } } } @override Widget build(BuildContext context) { - double widthMultiplier = calculateWidthMultiplier(totalTasks); - return Row( children: [ Container( - width: MediaQuery.sizeOf(context).width * widthMultiplier, + width: MediaQuery.sizeOf(context).width * 0.415, child: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { return Stack(children: [ @@ -85,11 +83,15 @@ class LoadingBar extends StatelessWidget { ]); })), Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Text( - "${formatNumber(tasksFinished)}/${formatNumber(totalTasks)}", - ), - ), + padding: EdgeInsets.only(left: 2.0), + child: Container( + // Explicit container for the text + // color: Colors.cyan, + width: MediaQuery.sizeOf(context).width * 0.16, + alignment: Alignment.center, // Center text within the container + child: Text( + "${formatNumber(tasksFinished)}/${formatNumber(totalTasks)}", + ))) ], ); } From 3b8ffd552ca1ab403927c262e8d584da5951ab40 Mon Sep 17 00:00:00 2001 From: Jesse Cheng Date: Sun, 17 Nov 2024 19:19:31 -0500 Subject: [PATCH 4/5] Added documentation for formatting number change --- game/lib/widget/progress_bar.dart | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/game/lib/widget/progress_bar.dart b/game/lib/widget/progress_bar.dart index 332235c4..8e9b0155 100644 --- a/game/lib/widget/progress_bar.dart +++ b/game/lib/widget/progress_bar.dart @@ -12,6 +12,17 @@ class LoadingBar extends StatelessWidget { this.totalTasks, ); +/** + * Formats a number into a readable string with a "K" suffix for thousands. + * + * Converts numbers to a string format using different precision based on their size to ensure readability in UI displays. + * For numbers between 1,000 and 9,999, one decimal is shown; numbers exactly at 1,000 or 10,000 are shown without decimals. + * Numbers above 10,000 and up to 99,999 are rounded to the nearest thousand. The function throws an exception for numbers exceeding 100,000. + * + * @param number - The number to format. + * @returns A string representing the formatted number or throws a FormatException for numbers above 100,000. + * + */ String formatNumber(int number) { if (number < 1000) { return number.toString(); From c89d851fa2eaf90f1939e1897b9436e7a3804cbc Mon Sep 17 00:00:00 2001 From: Jesse Cheng Date: Mon, 2 Dec 2024 23:01:48 -0500 Subject: [PATCH 5/5] Made progress bar dynamic --- game/lib/widget/progress_bar.dart | 121 +++++++++++++++++------------- 1 file changed, 67 insertions(+), 54 deletions(-) diff --git a/game/lib/widget/progress_bar.dart b/game/lib/widget/progress_bar.dart index 8e9b0155..60aa43ac 100644 --- a/game/lib/widget/progress_bar.dart +++ b/game/lib/widget/progress_bar.dart @@ -44,66 +44,79 @@ class LoadingBar extends StatelessWidget { @override Widget build(BuildContext context) { - return Row( - children: [ - Container( - width: MediaQuery.sizeOf(context).width * 0.415, - child: LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - return Stack(children: [ - Container( - width: constraints.maxWidth, - height: 13, - alignment: Alignment.centerLeft, - child: Container( - decoration: new BoxDecoration( - color: Color.fromARGB(255, 241, 241, 241), - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(16.0)), + return Container( + constraints: + BoxConstraints(maxWidth: MediaQuery.sizeOf(context).width * 0.53), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + flex: 3, + child: LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + return Stack(children: [ + Container( + width: constraints.maxWidth, + height: 13, + alignment: Alignment.centerLeft, + child: Container( + decoration: new BoxDecoration( + color: Color.fromARGB(255, 241, 241, 241), + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all(Radius.circular(16.0)), + ), ), ), - ), - Container( - width: (totalTasks > 0 ? tasksFinished / totalTasks : 0) * - constraints.maxWidth, - height: 13, - alignment: Alignment.centerLeft, - child: Container( + Container( + width: (totalTasks > 0 ? tasksFinished / totalTasks : 0) * + constraints.maxWidth, + height: 13, + alignment: Alignment.centerLeft, + child: Container( + decoration: new BoxDecoration( + color: Color.fromARGB(197, 237, 86, 86), + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all(Radius.circular(16.0)), + ), + ), + ), + Container( + height: 3, + width: max( + (totalTasks > 0 ? tasksFinished / totalTasks : 0) * + constraints.maxWidth - + 16, + 0), + margin: EdgeInsets.only(left: 8, top: 3), + alignment: Alignment.centerLeft, decoration: new BoxDecoration( - color: Color.fromARGB(197, 237, 86, 86), + color: Color(0x99F3C6C6), shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(16.0)), + borderRadius: BorderRadius.all(Radius.circular(5.0)), ), ), - ), - Container( - height: 3, - width: max( - (totalTasks > 0 ? tasksFinished / totalTasks : 0) * - constraints.maxWidth - - 16, - 0), - margin: EdgeInsets.only(left: 8, top: 3), - alignment: Alignment.centerLeft, - decoration: new BoxDecoration( - color: Color(0x99F3C6C6), - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(5.0)), - ), - ), - ]); - })), - Padding( - padding: EdgeInsets.only(left: 2.0), - child: Container( - // Explicit container for the text - // color: Colors.cyan, - width: MediaQuery.sizeOf(context).width * 0.16, - alignment: Alignment.center, // Center text within the container - child: Text( - "${formatNumber(tasksFinished)}/${formatNumber(totalTasks)}", - ))) - ], + ]); + })), + const SizedBox(width: 10), + Row( + children: [ + // current points + Container( + alignment: Alignment.centerRight, + child: Text("${formatNumber(tasksFinished)}", + style: const TextStyle(fontSize: 12))), + const Text( + "/", + style: TextStyle(fontSize: 12), + ), + Text( + "${formatNumber(totalTasks)}", + style: const TextStyle(fontSize: 12), + ), + ], + ), + ], + ), ); } }