diff --git a/lib/main.dart b/lib/main.dart index 1cc80bcc9..938fdd632 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -33,6 +33,7 @@ import 'package:wger/providers/exercises.dart'; import 'package:wger/providers/gallery.dart'; import 'package:wger/providers/measurement.dart'; import 'package:wger/providers/nutrition.dart'; +import 'package:wger/providers/plate_weights.dart'; import 'package:wger/providers/routines.dart'; import 'package:wger/providers/user.dart'; import 'package:wger/providers/wger_base_riverpod.dart'; @@ -178,15 +179,6 @@ class MainApp extends StatelessWidget { update: (context, base, previous) => previous ?? ExercisesProvider(WgerBaseProvider(base)), ), - ChangeNotifierProxyProvider2( - create: (context) => RoutinesProvider( - WgerBaseProvider(Provider.of(context, listen: false)), - Provider.of(context, listen: false), - [], - ), - update: (context, auth, exercises, previous) => - previous ?? RoutinesProvider(WgerBaseProvider(auth), exercises, []), - ), ChangeNotifierProxyProvider( create: (context) => NutritionPlansProvider( WgerBaseProvider(Provider.of(context, listen: false)), @@ -240,47 +232,68 @@ class MainApp extends StatelessWidget { ], child: riverpod.Consumer( builder: (rpCtx, ref, _) { - return MaterialApp( - title: 'wger', - navigatorKey: navigatorKey, - theme: wgerLightTheme, - darkTheme: wgerDarkTheme, - highContrastTheme: wgerLightThemeHc, - highContrastDarkTheme: wgerDarkThemeHc, - themeMode: user.themeMode, - home: _getHomeScreen(auth), - routes: { - DashboardScreen.routeName: (ctx) => const DashboardScreen(), - FormScreen.routeName: (ctx) => const FormScreen(), - GalleryScreen.routeName: (ctx) => const GalleryScreen(), - GymModeScreen.routeName: (ctx) => const GymModeScreen(), - HomeTabsScreen.routeName: (ctx) => HomeTabsScreen(), - MeasurementCategoriesScreen.routeName: (ctx) => - const MeasurementCategoriesScreen(), - MeasurementEntriesScreen.routeName: (ctx) => const MeasurementEntriesScreen(), - NutritionalPlansScreen.routeName: (ctx) => const NutritionalPlansScreen(), - NutritionalDiaryScreen.routeName: (ctx) => const NutritionalDiaryScreen(), - NutritionalPlanScreen.routeName: (ctx) => const NutritionalPlanScreen(), - LogMealsScreen.routeName: (ctx) => const LogMealsScreen(), - LogMealScreen.routeName: (ctx) => const LogMealScreen(), - WeightScreen.routeName: (ctx) => const WeightScreen(), - RoutineScreen.routeName: (ctx) => const RoutineScreen(), - RoutineEditScreen.routeName: (ctx) => const RoutineEditScreen(), - WorkoutLogsScreen.routeName: (ctx) => const WorkoutLogsScreen(), - RoutineListScreen.routeName: (ctx) => const RoutineListScreen(), - ExercisesScreen.routeName: (ctx) => const ExercisesScreen(), - ExerciseDetailScreen.routeName: (ctx) => const ExerciseDetailScreen(), - AddExerciseScreen.routeName: (ctx) => const AddExerciseScreen(), - AboutPage.routeName: (ctx) => const AboutPage(), - SettingsPage.routeName: (ctx) => const SettingsPage(), - LogOverviewPage.routeName: (ctx) => const LogOverviewPage(), - ConfigurePlatesScreen.routeName: (ctx) => const ConfigurePlatesScreen(), - ConfigureDashboardWidgetsScreen.routeName: (ctx) => - const ConfigureDashboardWidgetsScreen(), - TrophyScreen.routeName: (ctx) => const TrophyScreen(), - }, - localizationsDelegates: AppLocalizations.localizationsDelegates, - supportedLocales: AppLocalizations.supportedLocales, + return ChangeNotifierProxyProvider2< + AuthProvider, + ExercisesProvider, + RoutinesProvider + >( + create: (context) => RoutinesProvider( + WgerBaseProvider(Provider.of(context, listen: false)), + Provider.of(context, listen: false), + ref.watch(plateCalculatorProvider.notifier), + [], + ), + update: (context, auth, exercises, previous) => + previous ?? + RoutinesProvider( + WgerBaseProvider(auth), + exercises, + ref.watch(plateCalculatorProvider.notifier), + [], + ), + child: MaterialApp( + title: 'wger', + navigatorKey: navigatorKey, + theme: wgerLightTheme, + darkTheme: wgerDarkTheme, + highContrastTheme: wgerLightThemeHc, + highContrastDarkTheme: wgerDarkThemeHc, + themeMode: user.themeMode, + home: _getHomeScreen(auth), + routes: { + DashboardScreen.routeName: (ctx) => const DashboardScreen(), + FormScreen.routeName: (ctx) => const FormScreen(), + GalleryScreen.routeName: (ctx) => const GalleryScreen(), + GymModeScreen.routeName: (ctx) => const GymModeScreen(), + HomeTabsScreen.routeName: (ctx) => HomeTabsScreen(), + MeasurementCategoriesScreen.routeName: (ctx) => + const MeasurementCategoriesScreen(), + MeasurementEntriesScreen.routeName: (ctx) => + const MeasurementEntriesScreen(), + NutritionalPlansScreen.routeName: (ctx) => const NutritionalPlansScreen(), + NutritionalDiaryScreen.routeName: (ctx) => const NutritionalDiaryScreen(), + NutritionalPlanScreen.routeName: (ctx) => const NutritionalPlanScreen(), + LogMealsScreen.routeName: (ctx) => const LogMealsScreen(), + LogMealScreen.routeName: (ctx) => const LogMealScreen(), + WeightScreen.routeName: (ctx) => const WeightScreen(), + RoutineScreen.routeName: (ctx) => const RoutineScreen(), + RoutineEditScreen.routeName: (ctx) => const RoutineEditScreen(), + WorkoutLogsScreen.routeName: (ctx) => const WorkoutLogsScreen(), + RoutineListScreen.routeName: (ctx) => const RoutineListScreen(), + ExercisesScreen.routeName: (ctx) => const ExercisesScreen(), + ExerciseDetailScreen.routeName: (ctx) => const ExerciseDetailScreen(), + AddExerciseScreen.routeName: (ctx) => const AddExerciseScreen(), + AboutPage.routeName: (ctx) => const AboutPage(), + SettingsPage.routeName: (ctx) => const SettingsPage(), + LogOverviewPage.routeName: (ctx) => const LogOverviewPage(), + ConfigurePlatesScreen.routeName: (ctx) => const ConfigurePlatesScreen(), + ConfigureDashboardWidgetsScreen.routeName: (ctx) => + const ConfigureDashboardWidgetsScreen(), + TrophyScreen.routeName: (ctx) => const TrophyScreen(), + }, + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, + ), ); }, ), diff --git a/lib/models/workouts/set_config_data.dart b/lib/models/workouts/set_config_data.dart index 38b8e1520..47435945c 100644 --- a/lib/models/workouts/set_config_data.dart +++ b/lib/models/workouts/set_config_data.dart @@ -107,7 +107,7 @@ class SetConfigData { this.maxNrOfSets, this.weight, this.maxWeight, - this.weightUnitId = WEIGHT_UNIT_KG, + this.weightUnitId, this.weightRounding, this.repetitions, this.maxRepetitions, diff --git a/lib/models/workouts/set_config_data.g.dart b/lib/models/workouts/set_config_data.g.dart index e415005b7..eba87c76a 100644 --- a/lib/models/workouts/set_config_data.g.dart +++ b/lib/models/workouts/set_config_data.g.dart @@ -40,7 +40,7 @@ SetConfigData _$SetConfigDataFromJson(Map json) { maxNrOfSets: json['max_sets'] as num?, weight: stringToNumNull(json['weight'] as String?), maxWeight: stringToNumNull(json['max_weight'] as String?), - weightUnitId: (json['weight_unit'] as num?)?.toInt() ?? WEIGHT_UNIT_KG, + weightUnitId: (json['weight_unit'] as num?)?.toInt(), weightRounding: stringToNumNull(json['weight_rounding'] as String?), repetitions: stringToNumNull(json['repetitions'] as String?), maxRepetitions: stringToNumNull(json['max_repetitions'] as String?), diff --git a/lib/models/workouts/slot_entry.dart b/lib/models/workouts/slot_entry.dart index 47f87bd08..5e46bc3c1 100644 --- a/lib/models/workouts/slot_entry.dart +++ b/lib/models/workouts/slot_entry.dart @@ -192,7 +192,7 @@ class SlotEntry { int? order, SlotEntryType? type, required Exercise exercise, - int? weightUnitId, + this.weightUnitId, this.weightRounding, int? repetitionUnitId, this.repetitionRounding, @@ -203,7 +203,6 @@ class SlotEntry { this.type = type ?? SlotEntryType.normal; exerciseObj = exercise; exerciseId = exercise.id!; - this.weightUnitId = weightUnitId ?? WEIGHT_UNIT_KG; this.repetitionUnitId = repetitionUnitId ?? REP_UNIT_REPETITIONS_ID; } diff --git a/lib/providers/plate_weights.dart b/lib/providers/plate_weights.dart index 493bad04c..a7fcededc 100644 --- a/lib/providers/plate_weights.dart +++ b/lib/providers/plate_weights.dart @@ -169,6 +169,10 @@ class PlateCalculatorNotifier extends Notifier { } } + bool isMetricSelected() { + return state.isMetric; + } + Future toggleSelection(num x) async { final newSelectedPlates = List.of(state.selectedPlates); if (newSelectedPlates.contains(x)) { diff --git a/lib/providers/routines.dart b/lib/providers/routines.dart index 692c36ceb..521b27751 100644 --- a/lib/providers/routines.dart +++ b/lib/providers/routines.dart @@ -37,6 +37,7 @@ import 'package:wger/models/workouts/slot_entry.dart'; import 'package:wger/models/workouts/weight_unit.dart'; import 'package:wger/providers/base_provider.dart'; import 'package:wger/providers/exercises.dart'; +import 'package:wger/providers/plate_weights.dart'; class RoutinesProvider with ChangeNotifier { final _logger = Logger('RoutinesProvider'); @@ -67,6 +68,7 @@ class RoutinesProvider with ChangeNotifier { Routine? activeRoutine; final ExercisesProvider _exerciseProvider; final WgerBaseProvider baseProvider; + final PlateCalculatorNotifier _plateCalculatorProvider; List _routines = []; List _weightUnits = []; List _repetitionUnits = []; @@ -74,6 +76,7 @@ class RoutinesProvider with ChangeNotifier { RoutinesProvider( this.baseProvider, this._exerciseProvider, + this._plateCalculatorProvider, List entries, { List? weightUnits, List? repetitionUnits, @@ -113,7 +116,8 @@ class RoutinesProvider with ChangeNotifier { /// Return the default weight unit (kg) WeightUnit get defaultWeightUnit { - return _weightUnits.firstWhere((element) => element.id == WEIGHT_UNIT_KG); + final id = _plateCalculatorProvider.isMetricSelected() ? WEIGHT_UNIT_KG : WEIGHT_UNIT_LB; + return _weightUnits.firstWhere((element) => element.id == id); } WeightUnit findWeightUnitById(int id) => _weightUnits.firstWhere((element) => element.id == id); @@ -203,9 +207,13 @@ class RoutinesProvider with ChangeNotifier { (e) => e.id == setConfig.repetitionsUnitId, ); - setConfig.weightUnit = _weightUnits.firstWhere( - (e) => e.id == setConfig.weightUnitId, - ); + if (setConfig.weightUnitId != null) { + setConfig.weightUnit = _weightUnits.firstWhere( + (e) => e.id == setConfig.weightUnitId, + ); + } else { + setConfig.weightUnit = defaultWeightUnit; + } } } } diff --git a/test/routine/routine_screen_test.dart b/test/routine/routine_screen_test.dart index 9d46b1d26..9687bfcaf 100644 --- a/test/routine/routine_screen_test.dart +++ b/test/routine/routine_screen_test.dart @@ -20,19 +20,26 @@ import 'dart:io'; import 'package:drift/native.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; import 'package:provider/provider.dart'; import 'package:wger/database/exercises/exercise_database.dart'; import 'package:wger/l10n/generated/app_localizations.dart'; import 'package:wger/providers/base_provider.dart'; import 'package:wger/providers/exercises.dart'; +import 'package:wger/providers/plate_weights.dart'; import 'package:wger/providers/routines.dart'; import 'package:wger/screens/routine_screen.dart'; import '../../test_data/routines.dart'; import 'routine_screen_test.mocks.dart'; +class PlateNotifierMock extends Notifier + with Mock + implements PlateCalculatorNotifier {} + @GenerateMocks([WgerBaseProvider]) void main() { final mockBaseProvider = MockWgerBaseProvider(); @@ -48,6 +55,7 @@ void main() { create: (context) => RoutinesProvider( mockBaseProvider, exercisesProvider, + PlateNotifierMock(), [getTestRoutine()], ), child: MaterialApp( diff --git a/test/routine/routines_provider_test.dart b/test/routine/routines_provider_test.dart index 4679985c5..ba4a290c2 100644 --- a/test/routine/routines_provider_test.dart +++ b/test/routine/routines_provider_test.dart @@ -19,6 +19,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:http/http.dart'; import 'package:mockito/annotations.dart'; @@ -34,6 +35,7 @@ import 'package:wger/models/workouts/routine.dart'; import 'package:wger/models/workouts/weight_unit.dart'; import 'package:wger/providers/base_provider.dart'; import 'package:wger/providers/exercises.dart'; +import 'package:wger/providers/plate_weights.dart'; import 'package:wger/providers/routines.dart'; import '../../test_data/exercises.dart'; @@ -41,6 +43,10 @@ import '../../test_data/routines.dart'; import '../fixtures/fixture_reader.dart'; import 'routines_provider_test.mocks.dart'; +class PlateNotifierMock extends Notifier + with Mock + implements PlateCalculatorNotifier {} + @GenerateMocks([WgerBaseProvider, ExercisesProvider]) void main() { final mockBaseProvider = MockWgerBaseProvider(); @@ -74,7 +80,12 @@ void main() { ); // Load the entries - final provider = RoutinesProvider(mockBaseProvider, exercisesProvider, []); + final provider = RoutinesProvider( + mockBaseProvider, + exercisesProvider, + PlateNotifierMock(), + [], + ); final plan = await provider.fetchAndSetRoutineSparse(325397); final plans = provider.getPlans(); @@ -102,7 +113,12 @@ void main() { ); // Load the entries - final provider = RoutinesProvider(mockBaseProvider, exercisesProvider, []); + final provider = RoutinesProvider( + mockBaseProvider, + exercisesProvider, + PlateNotifierMock(), + [], + ); await provider.fetchAndSetRoutineSparse(325397); await provider.deleteRoutine(325397); @@ -121,7 +137,12 @@ void main() { ).thenAnswer((_) => Future.value(tRepetitionUnits['results'])); // Load the entries - final provider = RoutinesProvider(mockBaseProvider, exercisesProvider, []); + final provider = RoutinesProvider( + mockBaseProvider, + exercisesProvider, + PlateNotifierMock(), + [], + ); await provider.fetchAndSetRepetitionUnits(); final repetitionUnits = provider.repetitionUnits; @@ -139,7 +160,12 @@ void main() { final ExercisesProvider testExercisesProvider = ExercisesProvider(mockBaseProvider); // Load the entries - final provider = RoutinesProvider(mockBaseProvider, testExercisesProvider, []); + final provider = RoutinesProvider( + mockBaseProvider, + testExercisesProvider, + PlateNotifierMock(), + [], + ); await provider.fetchAndSetWeightUnits(); final weightUnits = provider.weightUnits; @@ -168,7 +194,12 @@ void main() { final prefs = PreferenceHelper.asyncPref; // Load the entries - final provider = RoutinesProvider(mockBaseProvider, exercisesProvider, []); + final provider = RoutinesProvider( + mockBaseProvider, + exercisesProvider, + PlateNotifierMock(), + [], + ); await provider.fetchAndSetUnits(); final prefsJson = jsonDecode((await prefs.getString(PREFS_WORKOUT_UNITS))!); @@ -229,7 +260,12 @@ void main() { (_) async => Future.value(testCrunches), ); - final provider = RoutinesProvider(mockBaseProvider, mockExercisesProvider, []); + final provider = RoutinesProvider( + mockBaseProvider, + mockExercisesProvider, + PlateNotifierMock(), + [], + ); provider.repetitionUnits = testRepetitionUnits; provider.weightUnits = testWeightUnits; diff --git a/test/routine/routines_screen_test.dart b/test/routine/routines_screen_test.dart index 6c7740588..e6114b135 100644 --- a/test/routine/routines_screen_test.dart +++ b/test/routine/routines_screen_test.dart @@ -18,6 +18,7 @@ import 'package:drift/native.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:http/http.dart' as http; import 'package:mockito/annotations.dart'; @@ -28,6 +29,7 @@ import 'package:wger/l10n/generated/app_localizations.dart'; import 'package:wger/models/workouts/routine.dart'; import 'package:wger/providers/base_provider.dart'; import 'package:wger/providers/exercises.dart'; +import 'package:wger/providers/plate_weights.dart'; import 'package:wger/providers/routines.dart'; import 'package:wger/screens/form_screen.dart'; import 'package:wger/screens/routine_list_screen.dart'; @@ -36,6 +38,10 @@ import 'package:wger/widgets/routines/forms/routine.dart'; import 'routines_screen_test.mocks.dart'; +class PlateNotifierMock extends Notifier + with Mock + implements PlateCalculatorNotifier {} + @GenerateMocks([WgerBaseProvider]) void main() { var mockBaseProvider = MockWgerBaseProvider(); @@ -61,6 +67,7 @@ void main() { create: (context) => RoutinesProvider( mockBaseProvider, testExercisesProvider, + PlateNotifierMock(), [ Routine( id: 1,