Allow opening the workout progress dialog from the progress indicator

This is easier to open with the thumbs and also makes logical sense. When
opening the workout menu from here, the default tab is the progress one, not
the overview.
This commit is contained in:
Roland Geider
2025-11-15 18:10:14 +01:00
parent 0bfb063552
commit 033213abbb
2 changed files with 113 additions and 88 deletions

View File

@@ -19,11 +19,51 @@
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/gym_state.dart';
import 'package:wger/theme/theme.dart';
import 'package:wger/widgets/routines/gym_mode/workout_menu.dart';
class NavigationHeader extends StatelessWidget {
final PageController _controller;
final String _title;
final bool showEndWorkoutButton;
const NavigationHeader(this._title, this._controller, {this.showEndWorkoutButton = true});
@override
Widget build(BuildContext context) {
return Row(
children: [
IconButton(
icon: const Icon(Icons.close),
onPressed: () {
Navigator.of(context).pop();
},
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Text(
_title,
style: Theme.of(context).textTheme.headlineSmall,
textAlign: TextAlign.center,
),
),
),
IconButton(
icon: const Icon(Icons.menu),
onPressed: () {
showDialog(
context: context,
builder: (ctx) => WorkoutMenuDialog(_controller),
);
},
),
],
);
}
}
class NavigationFooter extends ConsumerWidget {
final PageController _controller;
final bool showPrevious;
@@ -54,10 +94,19 @@ class NavigationFooter extends ConsumerWidget {
else
const SizedBox(width: 48),
Expanded(
child: LinearProgressIndicator(
minHeight: 3,
value: gymState.ratioCompleted,
valueColor: const AlwaysStoppedAnimation<Color>(wgerPrimaryColor),
child: GestureDetector(
onTap: () => showDialog(
context: context,
builder: (ctx) => WorkoutMenuDialog(_controller, initialIndex: 1),
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 15),
child: LinearProgressIndicator(
minHeight: 3,
value: gymState.ratioCompleted,
valueColor: const AlwaysStoppedAnimation<Color>(wgerPrimaryColor),
),
),
),
),
if (showNext)
@@ -76,85 +125,3 @@ class NavigationFooter extends ConsumerWidget {
);
}
}
class NavigationHeader extends ConsumerWidget {
final PageController _controller;
final String _title;
final bool showEndWorkoutButton;
const NavigationHeader(this._title, this._controller, {this.showEndWorkoutButton = true});
Widget getDialog(BuildContext context, int totalPages, List<PageEntry> pages) {
final endWorkoutButton = showEndWorkoutButton
? TextButton(
child: Text(AppLocalizations.of(context).endWorkout),
onPressed: () {
_controller.animateToPage(
totalPages,
duration: DEFAULT_ANIMATION_DURATION,
curve: DEFAULT_ANIMATION_CURVE,
);
Navigator.of(context).pop();
},
)
: null;
return AlertDialog(
title: Text(
AppLocalizations.of(context).jumpTo,
textAlign: TextAlign.center,
),
contentPadding: EdgeInsets.zero,
content: SizedBox(
height: double.maxFinite,
width: double.maxFinite,
child: WorkoutMenu(_controller),
),
actions: [
?endWorkoutButton,
TextButton(
child: Text(MaterialLocalizations.of(context).closeButtonLabel),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
}
@override
Widget build(BuildContext context, WidgetRef ref) {
final gymState = ref.watch(gymStateProvider);
return Row(
children: [
IconButton(
icon: const Icon(Icons.close),
onPressed: () {
Navigator.of(context).pop();
},
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Text(
_title,
style: Theme.of(context).textTheme.headlineSmall,
textAlign: TextAlign.center,
),
),
),
IconButton(
icon: const Icon(Icons.menu),
onPressed: () {
showDialog(
context: context,
builder: (ctx) => getDialog(ctx, gymState.totalPages, gymState.pages),
);
},
),
],
);
}
}

View File

@@ -20,17 +20,20 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:logging/logging.dart';
import 'package:wger/helpers/consts.dart';
import 'package:wger/l10n/generated/app_localizations.dart';
import 'package:wger/providers/gym_state.dart';
import 'package:wger/widgets/exercises/autocompleter.dart';
class WorkoutMenu extends StatelessWidget {
final PageController _controller;
final int initialIndex;
const WorkoutMenu(this._controller);
const WorkoutMenu(this._controller, {this.initialIndex = 0, super.key});
@override
Widget build(BuildContext context) {
return DefaultTabController(
initialIndex: initialIndex,
length: 2,
child: Column(
children: [
@@ -288,3 +291,58 @@ class ExerciseSwapWidget extends ConsumerWidget {
);
}
}
class WorkoutMenuDialog extends ConsumerWidget {
final PageController controller;
final bool showEndWorkoutButton;
final int initialIndex;
const WorkoutMenuDialog(
this.controller, {
super.key,
this.showEndWorkoutButton = true,
this.initialIndex = 0,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final gymState = ref.watch(gymStateProvider);
final endWorkoutButton = true
? TextButton(
child: Text(AppLocalizations.of(context).endWorkout),
onPressed: () {
controller.animateToPage(
gymState.totalPages,
duration: DEFAULT_ANIMATION_DURATION,
curve: DEFAULT_ANIMATION_CURVE,
);
Navigator.of(context).pop();
},
)
: null;
return AlertDialog(
title: Text(
AppLocalizations.of(context).jumpTo,
textAlign: TextAlign.center,
),
contentPadding: EdgeInsets.zero,
content: SizedBox(
height: double.maxFinite,
width: double.maxFinite,
child: WorkoutMenu(controller, initialIndex: initialIndex),
),
actions: [
?endWorkoutButton,
TextButton(
child: Text(MaterialLocalizations.of(context).closeButtonLabel),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
}
}