Move ConfigureAvailablePlates to its own widget

This makes the corresponding screen to be much clearer
This commit is contained in:
Roland Geider
2025-05-27 17:56:33 +02:00
parent 4bcc268896
commit e470087f4c
6 changed files with 146 additions and 122 deletions

View File

@@ -37,6 +37,7 @@ import 'package:wger/providers/routines.dart';
import 'package:wger/providers/user.dart';
import 'package:wger/screens/add_exercise_screen.dart';
import 'package:wger/screens/auth_screen.dart';
import 'package:wger/screens/configure_plates_screen.dart';
import 'package:wger/screens/dashboard.dart';
import 'package:wger/screens/exercise_screen.dart';
import 'package:wger/screens/exercises_screen.dart';
@@ -244,6 +245,7 @@ class MainApp extends StatelessWidget {
AddExerciseScreen.routeName: (ctx) => const AddExerciseScreen(),
AboutPage.routeName: (ctx) => const AboutPage(),
SettingsPage.routeName: (ctx) => const SettingsPage(),
ConfigurePlatesScreen.routeName: (ctx) => const ConfigurePlatesScreen(),
},
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,

View File

@@ -1,119 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:wger/helpers/consts.dart';
import 'package:wger/l10n/generated/app_localizations.dart';
import 'package:wger/providers/plate_weights.dart';
import 'package:wger/widgets/routines/plate_calculator.dart';
class ConfigureAvailablePlates extends ConsumerStatefulWidget {
const ConfigureAvailablePlates({super.key});
@override
ConsumerState<ConfigureAvailablePlates> createState() => _AddPlateWeightsState();
}
class _AddPlateWeightsState extends ConsumerState<ConfigureAvailablePlates> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
ref.read(plateCalculatorProvider.notifier);
});
}
@override
Widget build(BuildContext context) {
final i18n = AppLocalizations.of(context);
final plateWeightsState = ref.watch(plateCalculatorProvider);
final plateWeightsNotifier = ref.read(plateCalculatorProvider.notifier);
// final userProvider = provider.Provider.of<UserProvider>(context);
return Scaffold(
appBar: AppBar(title: const Text('Select Available Plates')),
body: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: const EdgeInsets.all(10),
child: DropdownMenu<WeightUnitEnum>(
width: double.infinity,
initialSelection: plateWeightsState.isMetric ? WeightUnitEnum.kg : WeightUnitEnum.lb,
requestFocusOnTap: true,
label: Text(i18n.unit),
onSelected: (WeightUnitEnum? unit) {
if (unit == null) {
return;
}
plateWeightsNotifier.unitChange(unit: unit);
// userProvider.changeUnit(changeTo: unit.name);
// userProvider.saveProfile();
},
dropdownMenuEntries: WeightUnitEnum.values.map((unit) {
return DropdownMenuEntry<WeightUnitEnum>(
value: unit,
label: unit == WeightUnitEnum.kg ? i18n.kg : i18n.lb,
);
}).toList(),
),
),
Padding(
padding: const EdgeInsets.all(10),
child: DropdownMenu<num>(
width: double.infinity,
initialSelection: plateWeightsState.barWeight,
requestFocusOnTap: true,
label: Text(i18n.barWeight),
onSelected: (num? value) {
if (value == null) {
return;
}
plateWeightsNotifier.setBarWeight(value);
},
dropdownMenuEntries: plateWeightsState.availableBarsWeights.map((value) {
return DropdownMenuEntry<num>(
value: value,
label: value.toString(),
);
}).toList(),
),
),
SwitchListTile(
title: Text(i18n.useColors),
value: plateWeightsState.useColors,
onChanged: (state) => plateWeightsNotifier.setUseColors(state),
),
LayoutBuilder(
builder: (context, constraints) {
const double widthThreshold = 450.0;
final int crossAxisCount = constraints.maxWidth > widthThreshold ? 10 : 5;
return GridView.count(
crossAxisCount: crossAxisCount,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
children: plateWeightsState.availablePlates.map((number) {
final bool isSelected = plateWeightsState.selectedPlates.contains(number);
return GestureDetector(
onTap: () => plateWeightsNotifier.toggleSelection(number),
child: PlateWeight(
value: number,
isSelected: isSelected,
color: plateWeightsState.getColor(number),
),
);
}).toList(),
);
},
),
FilledButton(
onPressed: () {
plateWeightsNotifier.saveToSharedPrefs();
Navigator.pop(context);
},
child: Text(i18n.save),
),
],
),
);
}
}

View File

@@ -0,0 +1,19 @@
import 'package:flutter/material.dart';
import 'package:wger/l10n/generated/app_localizations.dart';
import 'package:wger/widgets/routines/plate_calculator.dart';
class ConfigurePlatesScreen extends StatelessWidget {
static const routeName = '/ConfigureAvailablePlates';
const ConfigurePlatesScreen({super.key});
@override
Widget build(BuildContext context) {
final i18n = AppLocalizations.of(context);
return Scaffold(
appBar: AppBar(title: Text(i18n.selectAvailablePlates)),
body: const ConfigureAvailablePlates(),
);
}
}

View File

@@ -23,6 +23,7 @@ import 'package:wger/l10n/generated/app_localizations.dart';
import 'package:wger/providers/exercises.dart';
import 'package:wger/providers/nutrition.dart';
import 'package:wger/providers/user.dart';
import 'package:wger/screens/configure_plates_screen.dart';
class SettingsPage extends StatelessWidget {
static String routeName = '/SettingsPage';
@@ -111,6 +112,13 @@ class SettingsPage extends StatelessWidget {
}).toList(),
),
),
ListTile(
title: Text(i18n.selectAvailablePlates),
onTap: () {
Navigator.of(context).pushNamed(ConfigurePlatesScreen.routeName);
},
trailing: const Icon(Icons.chevron_right),
),
],
),
);

View File

@@ -29,7 +29,7 @@ import 'package:wger/models/workouts/set_config_data.dart';
import 'package:wger/models/workouts/slot_data.dart';
import 'package:wger/providers/plate_weights.dart';
import 'package:wger/providers/routines.dart';
import 'package:wger/screens/configure_plates.dart';
import 'package:wger/screens/configure_plates_screen.dart';
import 'package:wger/widgets/core/core.dart';
import 'package:wger/widgets/core/progress_indicator.dart';
import 'package:wger/widgets/routines/forms/reps_unit.dart';
@@ -418,8 +418,7 @@ class _LogPageState extends ConsumerState<LogPage> {
// ),
GestureDetector(
onTap: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => const ConfigureAvailablePlates()));
Navigator.of(context).pushNamed(ConfigurePlatesScreen.routeName);
},
child: SizedBox(
child: plateWeightsState.hasPlates

View File

@@ -1,4 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:wger/helpers/consts.dart';
import 'package:wger/l10n/generated/app_localizations.dart';
import 'package:wger/providers/plate_weights.dart';
class PlateWeight extends StatelessWidget {
final num value;
@@ -21,6 +25,7 @@ class PlateWeight extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SizedBox(
key: ValueKey('plateWeight-$value'),
height: size,
width: size,
child: Padding(
@@ -46,3 +51,113 @@ class PlateWeight extends StatelessWidget {
);
}
}
class ConfigureAvailablePlates extends ConsumerStatefulWidget {
const ConfigureAvailablePlates({super.key});
@override
ConsumerState<ConfigureAvailablePlates> createState() => _AddPlateWeightsState();
}
class _AddPlateWeightsState extends ConsumerState<ConfigureAvailablePlates> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
ref.read(plateCalculatorProvider.notifier);
});
}
@override
Widget build(BuildContext context) {
final i18n = AppLocalizations.of(context);
final plateWeightsState = ref.watch(plateCalculatorProvider);
final plateWeightsNotifier = ref.read(plateCalculatorProvider.notifier);
// final userProvider = provider.Provider.of<UserProvider>(context);
return Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: const EdgeInsets.all(10),
child: DropdownMenu<WeightUnitEnum>(
width: double.infinity,
initialSelection: plateWeightsState.isMetric ? WeightUnitEnum.kg : WeightUnitEnum.lb,
requestFocusOnTap: true,
label: Text(i18n.unit),
onSelected: (WeightUnitEnum? unit) {
if (unit == null) {
return;
}
plateWeightsNotifier.unitChange(unit: unit);
// userProvider.changeUnit(changeTo: unit.name);
// userProvider.saveProfile();
},
dropdownMenuEntries: WeightUnitEnum.values.map((unit) {
return DropdownMenuEntry<WeightUnitEnum>(
value: unit,
label: unit == WeightUnitEnum.kg ? i18n.kg : i18n.lb,
);
}).toList(),
),
),
Padding(
padding: const EdgeInsets.all(10),
child: DropdownMenu<num>(
width: double.infinity,
initialSelection: plateWeightsState.barWeight,
requestFocusOnTap: true,
label: Text(i18n.barWeight),
onSelected: (num? value) {
if (value == null) {
return;
}
plateWeightsNotifier.setBarWeight(value);
},
dropdownMenuEntries: plateWeightsState.availableBarsWeights.map((value) {
return DropdownMenuEntry<num>(
value: value,
label: value.toString(),
);
}).toList(),
),
),
SwitchListTile(
title: Text(i18n.useColors),
value: plateWeightsState.useColors,
onChanged: (state) => plateWeightsNotifier.setUseColors(state),
),
LayoutBuilder(
builder: (context, constraints) {
const double widthThreshold = 450.0;
final int crossAxisCount = constraints.maxWidth > widthThreshold ? 10 : 5;
return GridView.count(
crossAxisCount: crossAxisCount,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
children: plateWeightsState.availablePlates.map((number) {
final bool isSelected = plateWeightsState.selectedPlates.contains(number);
return GestureDetector(
onTap: () => plateWeightsNotifier.toggleSelection(number),
child: PlateWeight(
value: number,
isSelected: isSelected,
color: plateWeightsState.getColor(number),
),
);
}).toList(),
);
},
),
FilledButton(
onPressed: () {
plateWeightsNotifier.saveToSharedPrefs();
Navigator.pop(context);
},
child: Text(i18n.save),
),
],
);
}
}