diff --git a/lib/models/workouts/routine.dart b/lib/models/workouts/routine.dart index 7b7e197f..fdca5c97 100644 --- a/lib/models/workouts/routine.dart +++ b/lib/models/workouts/routine.dart @@ -1,19 +1,19 @@ /* * This file is part of wger Workout Manager . - * Copyright (C) 2020 wger Team + * Copyright (c) 2020 - 2026 wger Team * * wger Workout Manager is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * wger Workout Manager is distributed in the hope that it will be useful, + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ import 'package:json_annotation/json_annotation.dart'; @@ -130,6 +130,30 @@ class Routine { return dayData.where((data) => data.iteration == iteration).toList(); } + /// Filter out dayData entries with null days as well as duplicated days from + /// the "fixed weekly schedule" toggle. + List get dayDataCurrentIterationFiltered { + final sorted = List.from( + dayDataCurrentIteration.where((dd) => dd.day != null), + )..sort((a, b) => a.day!.order.compareTo(b.day!.order)); + + // Filter out entries where the day is the same as the previous one. This + // is necessary because if the user has the "Fixed weekly schedule" option + // enabled, there would be multiple entries for the same day. + final unique = []; + for (final dd in sorted) { + if (unique.isEmpty || unique.last.day!.id != dd.day!.id) { + unique.add(dd); + } else { + // If the day id is the same as the previous, replace the previous + // entry with the current one so the last occurrence is kept. + unique[unique.length - 1] = dd; + } + } + + return unique; + } + List get dayDataCurrentIterationGym { final iteration = getIteration(date: DateTime.now()) ?? 1; return dayDataGym.where((data) => data.iteration == iteration).toList(); diff --git a/lib/widgets/dashboard/widgets/routines.dart b/lib/widgets/dashboard/widgets/routines.dart index dba38045..20e21f8a 100644 --- a/lib/widgets/dashboard/widgets/routines.dart +++ b/lib/widgets/dashboard/widgets/routines.dart @@ -80,7 +80,7 @@ class _DashboardRoutineWidgetState extends State { if (_hasContent) ...[ Padding( padding: const EdgeInsets.symmetric(horizontal: 10), - child: DetailContentWidget(routine!.dayDataCurrentIteration, _showDetail), + child: DetailContentWidget(routine!.dayDataCurrentIterationFiltered, _showDetail), ), Row( mainAxisAlignment: MainAxisAlignment.start, diff --git a/lib/widgets/routines/routine_detail.dart b/lib/widgets/routines/routine_detail.dart index 57a34207..0d28303f 100644 --- a/lib/widgets/routines/routine_detail.dart +++ b/lib/widgets/routines/routine_detail.dart @@ -1,13 +1,13 @@ /* * This file is part of wger Workout Manager . - * Copyright (C) 2020, 2021 wger Team + * Copyright (c) 2026 wger Team * * wger Workout Manager is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * wger Workout Manager is distributed in the hope that it will be useful, + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. @@ -49,27 +49,9 @@ class RoutineDetail extends StatelessWidget { child: Text(i18n.edit), ), ), - ..._routine.dayDataCurrentIteration - .where((dayData) => dayData.day != null) - .map((dayData) => RoutineDayWidget(dayData, _routine.id!, viewMode)), - // if (_routine.fitInWeek) - // Padding( - // padding: const EdgeInsets.only(left: 8, right: 8, bottom: 12), - // child: Card( - // margin: EdgeInsets.zero, - // child: ListTile( - // tileColor: Theme.of(context).focusColor, - // contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), - // title: Text( - // i18n.tillEndOfWeek, - // style: Theme.of(context).textTheme.headlineSmall, - // overflow: TextOverflow.ellipsis, - // ), - // leading: const Icon(Icons.hotel), - // minLeadingWidth: 8, - // ), - // ), - // ), + ..._routine.dayDataCurrentIterationFiltered.map( + (dayData) => RoutineDayWidget(dayData, _routine.id!, viewMode), + ), ], ); } diff --git a/test/routine/models/routine_test.dart b/test/routine/models/routine_test.dart new file mode 100644 index 00000000..a5d9f69a --- /dev/null +++ b/test/routine/models/routine_test.dart @@ -0,0 +1,42 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (c) 2020 - 2026 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import 'package:flutter_test/flutter_test.dart'; + +import '../../../test_data/routines.dart'; + +void main() { + group('Routine model tests', () { + test('correctly filters out null days', () { + // Arrange + final routine = getTestRoutine(); + routine.dayData = [ + getTestRoutine().dayData[0], + getTestRoutine().dayData[0], + getTestRoutine().dayData[0], + ]; + routine.dayData[0].date = DateTime(2026, 1, 1); + routine.dayData[1].date = DateTime(2026, 1, 2); + routine.dayData[2].date = DateTime(2026, 1, 3); + + // Assert + expect(routine.dayDataCurrentIteration.length, equals(3)); + expect(routine.dayDataCurrentIterationFiltered.length, equals(1)); + }); + }); +}