More refactoring of routine screens and widgets

This commit is contained in:
Roland Geider
2024-11-10 15:13:30 +01:00
parent 12f22d214a
commit 47e36eff48
18 changed files with 179 additions and 107 deletions

View File

@@ -3,7 +3,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:mockito/mockito.dart';
import 'package:provider/provider.dart';
import 'package:wger/providers/routines.dart';
import 'package:wger/screens/workout_plan_screen.dart';
import 'package:wger/screens/routine_screen.dart';
import 'package:wger/theme/theme.dart';
import '../test/workout/workout_form_test.mocks.dart';
@@ -35,7 +35,7 @@ Widget createWorkoutDetailScreen({locale = 'en'}) {
onPressed: () => key.currentState!.push(
MaterialPageRoute<void>(
settings: RouteSettings(arguments: workout),
builder: (_) => const WorkoutPlanScreen(),
builder: (_) => const RoutineScreen(),
),
),
child: const SizedBox(),

View File

@@ -5,7 +5,7 @@ import 'package:provider/provider.dart';
import 'package:wger/providers/exercises.dart';
import 'package:wger/providers/routines.dart';
import 'package:wger/screens/gym_mode.dart';
import 'package:wger/screens/workout_plan_screen.dart';
import 'package:wger/screens/routine_screen.dart';
import 'package:wger/theme/theme.dart';
import '../test/utils.dart';
@@ -50,7 +50,7 @@ Widget createGymModeScreen({locale = 'en'}) {
child: const SizedBox(),
),
routes: {
WorkoutPlanScreen.routeName: (ctx) => const WorkoutPlanScreen(),
RoutineScreen.routeName: (ctx) => const RoutineScreen(),
},
),
),

View File

@@ -45,10 +45,11 @@ import 'package:wger/screens/measurement_entries_screen.dart';
import 'package:wger/screens/nutritional_diary_screen.dart';
import 'package:wger/screens/nutritional_plan_screen.dart';
import 'package:wger/screens/nutritional_plans_screen.dart';
import 'package:wger/screens/routine_list_screen.dart';
import 'package:wger/screens/routine_logs_screen.dart';
import 'package:wger/screens/routine_screen.dart';
import 'package:wger/screens/splash_screen.dart';
import 'package:wger/screens/weight_screen.dart';
import 'package:wger/screens/workout_plan_screen.dart';
import 'package:wger/screens/workout_plans_screen.dart';
import 'package:wger/theme/theme.dart';
import 'package:wger/widgets/core/about.dart';
import 'package:wger/widgets/core/settings.dart';
@@ -164,8 +165,9 @@ class MyApp extends StatelessWidget {
LogMealsScreen.routeName: (ctx) => const LogMealsScreen(),
LogMealScreen.routeName: (ctx) => const LogMealScreen(),
WeightScreen.routeName: (ctx) => const WeightScreen(),
WorkoutPlanScreen.routeName: (ctx) => const WorkoutPlanScreen(),
WorkoutPlansScreen.routeName: (ctx) => const WorkoutPlansScreen(),
RoutineScreen.routeName: (ctx) => const RoutineScreen(),
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(),

View File

@@ -34,8 +34,8 @@ import 'package:wger/providers/user.dart';
import 'package:wger/screens/dashboard.dart';
import 'package:wger/screens/gallery_screen.dart';
import 'package:wger/screens/nutritional_plans_screen.dart';
import 'package:wger/screens/routine_list_screen.dart';
import 'package:wger/screens/weight_screen.dart';
import 'package:wger/screens/workout_plans_screen.dart';
class HomeTabsScreen extends StatefulWidget {
const HomeTabsScreen();
@@ -65,7 +65,7 @@ class _HomeTabsScreenState extends State<HomeTabsScreen> with SingleTickerProvid
final _screenList = [
const DashboardScreen(),
const WorkoutPlansScreen(),
const RoutineListScreen(),
const NutritionalPlansScreen(),
const WeightScreen(),
const GalleryScreen(),

View File

@@ -26,8 +26,8 @@ import 'package:wger/widgets/routines/app_bar.dart';
import 'package:wger/widgets/routines/forms.dart';
import 'package:wger/widgets/routines/workout_plans_list.dart';
class WorkoutPlansScreen extends StatelessWidget {
const WorkoutPlansScreen();
class RoutineListScreen extends StatelessWidget {
const RoutineListScreen();
static const routeName = '/workout-plans-list';

View File

@@ -25,51 +25,22 @@ import 'package:wger/screens/form_screen.dart';
import 'package:wger/theme/theme.dart';
import 'package:wger/widgets/routines/forms.dart';
import 'package:wger/widgets/routines/workout_logs.dart';
import 'package:wger/widgets/routines/workout_plan_detail.dart';
enum WorkoutScreenMode {
workout,
log,
}
enum WorkoutOptions {
edit,
delete,
}
class WorkoutPlanScreen extends StatefulWidget {
const WorkoutPlanScreen();
class WorkoutLogsScreen extends StatelessWidget {
const WorkoutLogsScreen();
static const routeName = '/workout-plan-detail';
@override
_WorkoutPlanScreenState createState() => _WorkoutPlanScreenState();
}
class _WorkoutPlanScreenState extends State<WorkoutPlanScreen> {
WorkoutScreenMode _mode = WorkoutScreenMode.workout;
void _changeMode(WorkoutScreenMode newMode) {
setState(() {
_mode = newMode;
});
}
static const routeName = '/workout-logs';
Future<Routine> _loadFullWorkout(BuildContext context, int routineId) {
return Provider.of<RoutinesProvider>(context, listen: false)
.fetchAndSetWorkoutPlanFull(routineId);
}
Widget getBody(Routine routine) {
switch (_mode) {
case WorkoutScreenMode.workout:
return WorkoutPlanDetail(routine, _changeMode);
case WorkoutScreenMode.log:
return WorkoutLogs(routine, _changeMode);
}
}
@override
Widget build(BuildContext context) {
const appBarForeground = Colors.white;
@@ -141,7 +112,7 @@ class _WorkoutPlanScreenState extends State<WorkoutPlanScreen> {
)
else
Consumer<RoutinesProvider>(
builder: (context, value, child) => getBody(routine),
builder: (context, value, child) => WorkoutLogs(routine),
),
],
),

View File

@@ -0,0 +1,135 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* Copyright (C) 2020, 2021 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,
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart';
import 'package:wger/models/workouts/routine.dart';
import 'package:wger/providers/routines.dart';
import 'package:wger/screens/form_screen.dart';
import 'package:wger/screens/routine_logs_screen.dart';
import 'package:wger/theme/theme.dart';
import 'package:wger/widgets/routines/forms.dart';
import 'package:wger/widgets/routines/routine_detail.dart';
enum WorkoutOptions {
edit,
delete,
logs,
}
class RoutineScreen extends StatelessWidget {
const RoutineScreen();
static const routeName = '/routine-detail';
Future<Routine> _loadFullWorkout(BuildContext context, int routineId) {
return Provider.of<RoutinesProvider>(context, listen: false)
.fetchAndSetWorkoutPlanFull(routineId);
}
@override
Widget build(BuildContext context) {
const appBarForeground = Colors.white;
final routine = ModalRoute.of(context)!.settings.arguments as Routine;
return Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar(
pinned: true,
iconTheme: const IconThemeData(color: appBarForeground),
backgroundColor: wgerPrimaryColor,
flexibleSpace: FlexibleSpaceBar(
titlePadding: const EdgeInsets.fromLTRB(56, 0, 56, 16),
title: Text(
routine.name,
style: Theme.of(context).textTheme.titleLarge?.copyWith(color: appBarForeground),
),
),
actions: [
PopupMenuButton<WorkoutOptions>(
icon: const Icon(Icons.more_vert, color: appBarForeground),
onSelected: (value) {
switch (value) {
case WorkoutOptions.edit:
Navigator.pushNamed(
context,
FormScreen.routeName,
arguments: FormScreenArguments(
AppLocalizations.of(context).edit,
WorkoutForm(routine),
),
);
case WorkoutOptions.logs:
Navigator.pushNamed(
context,
WorkoutLogsScreen.routeName,
arguments: routine,
);
case WorkoutOptions.delete:
Provider.of<RoutinesProvider>(context, listen: false)
.deleteWorkout(routine.id!);
Navigator.of(context).pop();
}
},
itemBuilder: (BuildContext context) {
return [
PopupMenuItem<WorkoutOptions>(
value: WorkoutOptions.logs,
child: Text(AppLocalizations.of(context).labelWorkoutLogs),
),
PopupMenuItem<WorkoutOptions>(
value: WorkoutOptions.edit,
child: Text(AppLocalizations.of(context).edit),
),
const PopupMenuDivider(),
PopupMenuItem<WorkoutOptions>(
value: WorkoutOptions.delete,
child: Text(AppLocalizations.of(context).delete),
),
];
},
),
],
),
FutureBuilder(
future: _loadFullWorkout(context, routine.id!),
builder: (context, AsyncSnapshot<Routine> snapshot) => SliverList(
delegate: SliverChildListDelegate(
[
if (snapshot.connectionState == ConnectionState.waiting)
const SizedBox(
height: 200,
child: Center(child: CircularProgressIndicator()),
)
else
Consumer<RoutinesProvider>(
builder: (context, value, child) => RoutineDetail(routine),
),
],
),
),
),
],
),
);
}
}

View File

@@ -35,8 +35,8 @@ import 'package:wger/screens/gym_mode.dart';
import 'package:wger/screens/log_meals_screen.dart';
import 'package:wger/screens/measurement_categories_screen.dart';
import 'package:wger/screens/nutritional_plan_screen.dart';
import 'package:wger/screens/routine_screen.dart';
import 'package:wger/screens/weight_screen.dart';
import 'package:wger/screens/workout_plan_screen.dart';
import 'package:wger/theme/theme.dart';
import 'package:wger/widgets/core/core.dart';
import 'package:wger/widgets/measurements/categories_card.dart';
@@ -503,7 +503,7 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
child: Text(AppLocalizations.of(context).goToDetailPage),
onPressed: () {
Navigator.of(context).pushNamed(
WorkoutPlanScreen.routeName,
RoutineScreen.routeName,
arguments: _workoutPlan,
);
},

View File

@@ -31,7 +31,7 @@ import 'package:wger/models/workouts/weight_unit.dart';
import 'package:wger/providers/exercises.dart';
import 'package:wger/providers/routines.dart';
import 'package:wger/screens/add_exercise_screen.dart';
import 'package:wger/screens/workout_plan_screen.dart';
import 'package:wger/screens/routine_screen.dart';
import 'package:wger/widgets/exercises/images.dart';
class WorkoutForm extends StatelessWidget {
@@ -114,7 +114,7 @@ class WorkoutForm extends StatelessWidget {
).addRoutine(_plan);
if (context.mounted) {
Navigator.of(context).pushReplacementNamed(
WorkoutPlanScreen.routeName,
RoutineScreen.routeName,
arguments: newPlan,
);
}

View File

@@ -20,48 +20,24 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:wger/models/workouts/routine.dart';
import 'package:wger/screens/form_screen.dart';
import 'package:wger/screens/workout_plan_screen.dart';
import 'package:wger/widgets/routines/day.dart';
import 'package:wger/widgets/routines/forms.dart';
class WorkoutPlanDetail extends StatefulWidget {
class RoutineDetail extends StatelessWidget {
final Routine _routine;
final Function _changeMode;
const WorkoutPlanDetail(this._routine, this._changeMode);
const RoutineDetail(this._routine);
@override
_WorkoutPlanDetailState createState() => _WorkoutPlanDetailState();
}
class _WorkoutPlanDetailState extends State<WorkoutPlanDetail> {
@override
Widget build(BuildContext context) {
return Column(
children: [
if (widget._routine.dayDataCurrentIteration.isNotEmpty)
Padding(
padding: const EdgeInsets.all(10),
child: ToggleButtons(
renderBorder: false,
onPressed: (int index) {
if (index == 1) {
widget._changeMode(WorkoutScreenMode.log);
}
},
isSelected: const [true, false],
children: const [
Icon(Icons.table_chart),
Icon(Icons.show_chart),
],
),
),
if (widget._routine.description != '')
if (_routine.description.isNotEmpty)
Padding(
padding: const EdgeInsets.all(15),
child: Text(widget._routine.description),
child: Text(_routine.description),
),
...widget._routine.dayDataCurrentIteration.map((dayData) => WorkoutDayWidget(dayData)),
..._routine.dayDataCurrentIteration.map((dayData) => WorkoutDayWidget(dayData)),
Column(
children: [
ElevatedButton(
@@ -72,7 +48,7 @@ class _WorkoutPlanDetailState extends State<WorkoutPlanDetail> {
FormScreen.routeName,
arguments: FormScreenArguments(
AppLocalizations.of(context).newDay,
DayFormWidget(widget._routine),
DayFormWidget(_routine),
hasListView: true,
),
);

View File

@@ -24,15 +24,13 @@ import 'package:wger/models/exercises/exercise.dart';
import 'package:wger/models/workouts/log.dart';
import 'package:wger/models/workouts/routine.dart';
import 'package:wger/models/workouts/session.dart';
import 'package:wger/screens/workout_plan_screen.dart';
import 'package:wger/theme/theme.dart';
import 'package:wger/widgets/routines/log.dart';
class WorkoutLogs extends StatefulWidget {
final Routine _workoutPlan;
final Function _changeMode;
const WorkoutLogs(this._workoutPlan, this._changeMode);
const WorkoutLogs(this._workoutPlan);
@override
_WorkoutLogsState createState() => _WorkoutLogsState();
@@ -51,16 +49,6 @@ class _WorkoutLogsState extends State<WorkoutLogs> {
Widget build(BuildContext context) {
return Column(
children: [
ToggleButtons(
renderBorder: false,
onPressed: (int index) {
if (index == 0) {
widget._changeMode(WorkoutScreenMode.workout);
}
},
isSelected: const [false, true],
children: const [Icon(Icons.table_chart), Icon(Icons.show_chart)],
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Text(

View File

@@ -21,7 +21,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:wger/providers/routines.dart';
import 'package:wger/screens/workout_plan_screen.dart';
import 'package:wger/screens/routine_screen.dart';
import 'package:wger/widgets/core/text_prompt.dart';
class WorkoutPlansList extends StatelessWidget {
@@ -48,7 +48,7 @@ class WorkoutPlansList extends StatelessWidget {
_workoutProvider.setCurrentPlan(currentWorkout.id!);
Navigator.of(context).pushNamed(
WorkoutPlanScreen.routeName,
RoutineScreen.routeName,
arguments: currentWorkout,
);
},

View File

@@ -26,7 +26,7 @@ import 'package:wger/providers/base_provider.dart';
import 'package:wger/providers/exercises.dart';
import 'package:wger/providers/routines.dart';
import 'package:wger/screens/gym_mode.dart';
import 'package:wger/screens/workout_plan_screen.dart';
import 'package:wger/screens/routine_screen.dart';
import 'package:wger/widgets/routines/forms.dart';
import 'package:wger/widgets/routines/gym_mode.dart';
@@ -67,7 +67,7 @@ void main() {
child: const SizedBox(),
),
routes: {
WorkoutPlanScreen.routeName: (ctx) => const WorkoutPlanScreen(),
RoutineScreen.routeName: (ctx) => const RoutineScreen(),
},
),
),

View File

@@ -25,7 +25,7 @@ import 'package:provider/provider.dart';
import 'package:wger/models/workouts/repetition_unit.dart';
import 'package:wger/models/workouts/slot_entry.dart';
import 'package:wger/providers/routines.dart';
import 'package:wger/screens/workout_plan_screen.dart';
import 'package:wger/screens/routine_screen.dart';
import 'package:wger/widgets/routines/forms.dart';
import 'repetition_unit_form_widget_test.mocks.dart';
@@ -67,7 +67,7 @@ void main() {
navigatorKey: key,
home: Scaffold(body: RepetitionUnitInputWidget(setting1)),
routes: {
WorkoutPlanScreen.routeName: (ctx) => const WorkoutPlanScreen(),
RoutineScreen.routeName: (ctx) => const RoutineScreen(),
},
),
);

View File

@@ -26,7 +26,7 @@ import 'package:wger/models/workouts/slot_entry.dart';
import 'package:wger/models/workouts/weight_unit.dart';
import 'package:wger/providers/body_weight.dart';
import 'package:wger/providers/routines.dart';
import 'package:wger/screens/workout_plan_screen.dart';
import 'package:wger/screens/routine_screen.dart';
import 'package:wger/widgets/routines/forms.dart';
import './workout_form_test.mocks.dart';
@@ -68,7 +68,7 @@ void main() {
navigatorKey: key,
home: Scaffold(body: WeightUnitInputWidget(setting1)),
routes: {
WorkoutPlanScreen.routeName: (ctx) => const WorkoutPlanScreen(),
RoutineScreen.routeName: (ctx) => const RoutineScreen(),
},
),
);

View File

@@ -25,7 +25,7 @@ import 'package:provider/provider.dart';
import 'package:wger/helpers/consts.dart';
import 'package:wger/models/workouts/routine.dart';
import 'package:wger/providers/routines.dart';
import 'package:wger/screens/workout_plan_screen.dart';
import 'package:wger/screens/routine_screen.dart';
import 'package:wger/widgets/routines/forms.dart';
import './workout_form_test.mocks.dart';
@@ -63,7 +63,7 @@ void main() {
navigatorKey: key,
home: Scaffold(body: WorkoutForm(workoutPlan)),
routes: {
WorkoutPlanScreen.routeName: (ctx) => const WorkoutPlanScreen(),
RoutineScreen.routeName: (ctx) => const RoutineScreen(),
},
),
);

View File

@@ -26,7 +26,7 @@ import 'package:wger/database/exercises/exercise_database.dart';
import 'package:wger/providers/base_provider.dart';
import 'package:wger/providers/exercises.dart';
import 'package:wger/providers/routines.dart';
import 'package:wger/screens/workout_plan_screen.dart';
import 'package:wger/screens/routine_screen.dart';
import '../../test_data/routines.dart';
import 'workout_plan_screen_test.mocks.dart';
@@ -52,13 +52,13 @@ void main() {
onPressed: () => key.currentState!.push(
MaterialPageRoute<void>(
settings: RouteSettings(arguments: getWorkout()),
builder: (_) => const WorkoutPlanScreen(),
builder: (_) => const RoutineScreen(),
),
),
child: const SizedBox(),
),
routes: {
WorkoutPlanScreen.routeName: (ctx) => const WorkoutPlanScreen(),
RoutineScreen.routeName: (ctx) => const RoutineScreen(),
},
),
);

View File

@@ -30,7 +30,7 @@ import 'package:wger/providers/base_provider.dart';
import 'package:wger/providers/exercises.dart';
import 'package:wger/providers/routines.dart';
import 'package:wger/screens/form_screen.dart';
import 'package:wger/screens/workout_plans_screen.dart';
import 'package:wger/screens/routine_list_screen.dart';
import 'package:wger/widgets/nutrition/forms.dart';
import 'package:wger/widgets/routines/forms.dart';
@@ -82,7 +82,7 @@ void main() {
locale: Locale(locale),
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
home: const WorkoutPlansScreen(),
home: const RoutineListScreen(),
routes: {FormScreen.routeName: (ctx) => const FormScreen()},
),
);