From e8fa2b574fc4945a3f60a99936ff7d412cff6be9 Mon Sep 17 00:00:00 2001 From: Jozys Date: Sun, 27 Apr 2025 17:27:40 +0200 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=90=9B=20Fix=20local=20time=20convers?= =?UTF-8?q?ion=20for=20workout=20start=20date?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activities/list/view_model/activities_view_model.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/presentation/activities/list/view_model/activities_view_model.dart b/lib/presentation/activities/list/view_model/activities_view_model.dart index ab7e222..7c690d2 100644 --- a/lib/presentation/activities/list/view_model/activities_view_model.dart +++ b/lib/presentation/activities/list/view_model/activities_view_model.dart @@ -53,6 +53,7 @@ class ActivitiesViewModel extends StateNotifier { for (int i = 0; i < workouts.length; i++) { ActivityPreview workout = workouts[i]; + state.icons ??= {}; if (state.icons!.containsKey(workout.sourceId)) { workouts[i].icon = state.icons?[workout.sourceId]; @@ -63,8 +64,10 @@ class ActivitiesViewModel extends StateNotifier { state.icons![workout.sourceId] = workouts[i].icon; state = state.copyWith(newIcons: state.icons); } + // Convert the start date to local time + final startDateLocal = toLocal(workout.start); DateTime day = DateTime( - workout.start.year, workout.start.month, workout.start.day); + startDateLocal.year, startDateLocal.month, startDateLocal.day); if (workoutsByDay[day] == null) { workoutsByDay[day] = []; } From f836097c1f67bb4db9fa09e6dcc9642a48297a1b Mon Sep 17 00:00:00 2001 From: Jozys Date: Sun, 27 Apr 2025 17:37:25 +0200 Subject: [PATCH 2/2] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20ListView=20?= =?UTF-8?q?in=20Activities=20for=20better=20refresh=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../list/screen/activities_screen.dart | 103 ++++++++++-------- 1 file changed, 60 insertions(+), 43 deletions(-) diff --git a/lib/presentation/activities/list/screen/activities_screen.dart b/lib/presentation/activities/list/screen/activities_screen.dart index a436e8e..430778c 100644 --- a/lib/presentation/activities/list/screen/activities_screen.dart +++ b/lib/presentation/activities/list/screen/activities_screen.dart @@ -1,4 +1,5 @@ import 'dart:io' show Platform; + import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; @@ -141,51 +142,67 @@ Widget _buildGroupedActivities( return seconds ~/ 60; } - return ListView.builder( - controller: scrollController, - physics: const ScrollPhysics(), - itemCount: activities?.length ?? 0, - itemBuilder: (context, index) { - final date = activities?.keys.elementAt(index); - final activityList = activities?[date]! ?? []; - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (date != null && activityList.isNotEmpty) - Padding( - padding: - const EdgeInsets.only(top: 16.0, left: 16.0, right: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - DateFormat("dd. MMMM yyyy").format(date), - style: const TextStyle(fontWeight: FontWeight.bold), - ), - Text( - getDuration(getActivityMinutes(activityList), context), - style: const TextStyle(fontWeight: FontWeight.bold), + return LayoutBuilder( + builder: (context, constraints) { + return SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + controller: scrollController, + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: constraints.maxHeight, + ), + child: ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: activities?.length ?? 0, + itemBuilder: (context, index) { + final date = activities?.keys.elementAt(index); + final activityList = activities?[date]! ?? []; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (date != null && activityList.isNotEmpty) + Padding( + padding: const EdgeInsets.only( + top: 16.0, left: 16.0, right: 16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + DateFormat("dd. MMMM yyyy").format(date), + style: + const TextStyle(fontWeight: FontWeight.bold), + ), + Text( + getDuration( + getActivityMinutes(activityList), context), + style: + const TextStyle(fontWeight: FontWeight.bold), + ), + ]), ), - ]), - ), - const Divider(), - ...activityList.map( - (activity) => _buildActivityItem(context, activity), + const Divider(), + ...activityList.map( + (activity) => _buildActivityItem(context, activity), + ), + // Add a loading indicator at the end of the list, + if (index == activities!.length - 1 && isLoading) + const Padding( + padding: EdgeInsets.symmetric(vertical: 8.0), + child: Center(child: CircularProgressIndicator()), + ) // Show loading + // Show no more entries text if end is reached + else if (index == activities.length - 1 && !isLoading) + const Padding( + padding: EdgeInsets.all(16.0), + child: Center( + child: Text("No more entries"), + )), + ], + ); + }, ), - // Add a loading indicator at the end of the list, - if (index == activities!.length - 1 && isLoading) - const Padding( - padding: EdgeInsets.symmetric(vertical: 8.0), - child: Center(child: CircularProgressIndicator()), - ) // Show loading - // Show no more entries text if end is reached - else if (index == activities.length - 1 && !isLoading) - const Padding( - padding: EdgeInsets.all(16.0), - child: Center( - child: Text("No more entries"), - )), - ], + ), ); }, );