Merge pull request #955 from GaecKo/feature/end_workout_button

Feature/end_workout_button in "jump to" section
This commit is contained in:
Roland Geider
2025-10-17 18:28:26 +02:00
committed by GitHub
6 changed files with 45 additions and 9 deletions

View File

@@ -1063,6 +1063,7 @@
"@indicatorAvg": { "@indicatorAvg": {
"description": "added for localization of Class Indicator's field text" "description": "added for localization of Class Indicator's field text"
}, },
"endWorkout": "End Workout",
"themeMode": "Theme mode", "themeMode": "Theme mode",
"darkMode": "Always dark mode", "darkMode": "Always dark mode",
"lightMode": "Always light mode", "lightMode": "Always light mode",

View File

@@ -25,12 +25,14 @@ class ExerciseOverview extends StatelessWidget {
final Exercise _exercise; final Exercise _exercise;
final double _ratioCompleted; final double _ratioCompleted;
final Map<Exercise, int> _exercisePages; final Map<Exercise, int> _exercisePages;
final int _totalPages;
const ExerciseOverview( const ExerciseOverview(
this._controller, this._controller,
this._exercise, this._exercise,
this._ratioCompleted, this._ratioCompleted,
this._exercisePages, this._exercisePages,
this._totalPages,
); );
@override @override
@@ -40,6 +42,7 @@ class ExerciseOverview extends StatelessWidget {
NavigationHeader( NavigationHeader(
_exercise.getTranslation(Localizations.localeOf(context).languageCode).name, _exercise.getTranslation(Localizations.localeOf(context).languageCode).name,
_controller, _controller,
totalPages: _totalPages,
exercisePages: _exercisePages, exercisePages: _exercisePages,
), ),
Expanded( Expanded(

View File

@@ -46,6 +46,7 @@ class GymMode extends ConsumerStatefulWidget {
class _GymModeState extends ConsumerState<GymMode> { class _GymModeState extends ConsumerState<GymMode> {
var _totalElements = 1; var _totalElements = 1;
var _totalPages = 1;
late Future<int> _initData; late Future<int> _initData;
bool _initialPageJumped = false; bool _initialPageJumped = false;
@@ -103,6 +104,12 @@ class _GymModeState extends ConsumerState<GymMode> {
void _calculatePages() { void _calculatePages() {
for (final slot in widget._dayDataGym.slots) { for (final slot in widget._dayDataGym.slots) {
_totalElements += slot.setConfigs.length; _totalElements += slot.setConfigs.length;
// add 1 for each exercise
_totalPages += 1;
for (final config in slot.setConfigs) {
// add nrOfSets * 2, 1 for log page and 1 for timer
_totalPages += (config.nrOfSets! * 2).toInt();
}
} }
_exercisePages.clear(); _exercisePages.clear();
var currentPage = 1; var currentPage = 1;
@@ -143,6 +150,7 @@ class _GymModeState extends ConsumerState<GymMode> {
exercise, exercise,
ratioCompleted, ratioCompleted,
state.exercisePages, state.exercisePages,
_totalPages,
), ),
); );
} }
@@ -156,6 +164,7 @@ class _GymModeState extends ConsumerState<GymMode> {
routinesProvider.findById(widget._dayDataGym.day!.routineId), routinesProvider.findById(widget._dayDataGym.day!.routineId),
ratioCompleted, ratioCompleted,
state.exercisePages, state.exercisePages,
_totalPages,
widget._iteration, widget._iteration,
), ),
); );
@@ -168,16 +177,16 @@ class _GymModeState extends ConsumerState<GymMode> {
config.restTime!.toInt(), config.restTime!.toInt(),
ratioCompleted, ratioCompleted,
state.exercisePages, state.exercisePages,
_totalPages,
), ),
); );
} else { } else {
out.add(TimerWidget(_controller, ratioCompleted, state.exercisePages)); out.add(TimerWidget(_controller, ratioCompleted, state.exercisePages, _totalPages));
} }
firstPage = false; firstPage = false;
} }
} }
return out; return out;
} }

View File

@@ -49,6 +49,7 @@ class LogPage extends ConsumerStatefulWidget {
final double _ratioCompleted; final double _ratioCompleted;
final Map<Exercise, int> _exercisePages; final Map<Exercise, int> _exercisePages;
final Log _log; final Log _log;
final int _totalPages;
LogPage( LogPage(
this._controller, this._controller,
@@ -58,6 +59,7 @@ class LogPage extends ConsumerStatefulWidget {
this._workoutPlan, this._workoutPlan,
this._ratioCompleted, this._ratioCompleted,
this._exercisePages, this._exercisePages,
this._totalPages,
int? iteration, int? iteration,
) : _log = Log.fromSetConfigData(_configData) ) : _log = Log.fromSetConfigData(_configData)
..routineId = _workoutPlan.id! ..routineId = _workoutPlan.id!
@@ -93,6 +95,7 @@ class _LogPageState extends ConsumerState<LogPage> {
NavigationHeader( NavigationHeader(
widget._exercise.getTranslation(Localizations.localeOf(context).languageCode).name, widget._exercise.getTranslation(Localizations.localeOf(context).languageCode).name,
widget._controller, widget._controller,
totalPages: widget._totalPages,
exercisePages: widget._exercisePages, exercisePages: widget._exercisePages,
), ),

View File

@@ -15,6 +15,7 @@
* You should have received a copy of the GNU Affero General Public License * 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/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:wger/helpers/consts.dart'; import 'package:wger/helpers/consts.dart';
import 'package:wger/l10n/generated/app_localizations.dart'; import 'package:wger/l10n/generated/app_localizations.dart';
@@ -78,14 +79,31 @@ class NavigationHeader extends StatelessWidget {
final PageController _controller; final PageController _controller;
final String _title; final String _title;
final Map<Exercise, int> exercisePages; final Map<Exercise, int> exercisePages;
final int ?totalPages;
const NavigationHeader( const NavigationHeader(
this._title, this._title,
this._controller, { this._controller, {
required this.exercisePages, this.totalPages,
}); required this.exercisePages
});
Widget getDialog(BuildContext context) { Widget getDialog(BuildContext context) {
final TextButton? endWorkoutButton = totalPages != null
? 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( return AlertDialog(
title: Text( title: Text(
AppLocalizations.of(context).jumpTo, AppLocalizations.of(context).jumpTo,
@@ -113,6 +131,7 @@ class NavigationHeader extends StatelessWidget {
), ),
), ),
actions: [ actions: [
?endWorkoutButton,
TextButton( TextButton(
child: Text(MaterialLocalizations.of(context).closeButtonLabel), child: Text(MaterialLocalizations.of(context).closeButtonLabel),
onPressed: () { onPressed: () {

View File

@@ -28,12 +28,9 @@ class TimerWidget extends StatefulWidget {
final PageController _controller; final PageController _controller;
final double _ratioCompleted; final double _ratioCompleted;
final Map<Exercise, int> _exercisePages; final Map<Exercise, int> _exercisePages;
final _totalPages;
const TimerWidget( const TimerWidget(this._controller, this._ratioCompleted, this._exercisePages, this._totalPages);
this._controller,
this._ratioCompleted,
this._exercisePages,
);
@override @override
_TimerWidgetState createState() => _TimerWidgetState(); _TimerWidgetState createState() => _TimerWidgetState();
@@ -72,6 +69,7 @@ class _TimerWidgetState extends State<TimerWidget> {
NavigationHeader( NavigationHeader(
AppLocalizations.of(context).pause, AppLocalizations.of(context).pause,
widget._controller, widget._controller,
totalPages: widget._totalPages,
exercisePages: widget._exercisePages, exercisePages: widget._exercisePages,
), ),
Expanded( Expanded(
@@ -93,12 +91,14 @@ class TimerCountdownWidget extends StatefulWidget {
final double _ratioCompleted; final double _ratioCompleted;
final int _seconds; final int _seconds;
final Map<Exercise, int> _exercisePages; final Map<Exercise, int> _exercisePages;
final int _totalPages;
const TimerCountdownWidget( const TimerCountdownWidget(
this._controller, this._controller,
this._seconds, this._seconds,
this._ratioCompleted, this._ratioCompleted,
this._exercisePages, this._exercisePages,
this._totalPages,
); );
@override @override
@@ -137,6 +137,7 @@ class _TimerCountdownWidgetState extends State<TimerCountdownWidget> {
NavigationHeader( NavigationHeader(
AppLocalizations.of(context).pause, AppLocalizations.of(context).pause,
widget._controller, widget._controller,
totalPages: widget._totalPages,
exercisePages: widget._exercisePages, exercisePages: widget._exercisePages,
), ),
Expanded( Expanded(