mirror of
https://github.com/wger-project/flutter.git
synced 2026-02-18 23:42:00 +01:00
Render correct number of pages in gym mode
This commit is contained in:
@@ -75,6 +75,22 @@ class AppLocalizations {
|
||||
);
|
||||
}
|
||||
|
||||
String get rir {
|
||||
return Intl.message(
|
||||
'rir',
|
||||
name: 'RiR',
|
||||
desc: 'Shorthand for Repetitions In Reserve',
|
||||
);
|
||||
}
|
||||
|
||||
String get comment {
|
||||
return Intl.message(
|
||||
'Comment',
|
||||
name: 'comment',
|
||||
desc: 'Comment, additional information',
|
||||
);
|
||||
}
|
||||
|
||||
String get impression {
|
||||
return Intl.message(
|
||||
'Impression',
|
||||
|
||||
@@ -78,7 +78,7 @@ class MealItem {
|
||||
}
|
||||
|
||||
if (ingredientObj.sodium != null) {
|
||||
out.sodium + ingredientObj.sodium * weight / 100;
|
||||
out.sodium = ingredientObj.sodium * weight / 100;
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:wger/helpers/json.dart';
|
||||
|
||||
@@ -11,39 +9,42 @@ class Log {
|
||||
final int id;
|
||||
|
||||
@JsonKey(required: true)
|
||||
final int exercise;
|
||||
int exercise;
|
||||
|
||||
@JsonKey(required: true, name: 'workout')
|
||||
final int workoutPlan;
|
||||
int workoutPlan;
|
||||
|
||||
@JsonKey(required: true)
|
||||
final int reps;
|
||||
int reps;
|
||||
|
||||
@JsonKey(required: false)
|
||||
final double rir;
|
||||
double rir;
|
||||
|
||||
@JsonKey(required: true, name: 'repetition_unit')
|
||||
final int repetitionUnit;
|
||||
int repetitionUnit;
|
||||
|
||||
@JsonKey(required: true, fromJson: toNum, toJson: toString)
|
||||
final num weight;
|
||||
num weight;
|
||||
|
||||
@JsonKey(required: true, name: 'weight_unit')
|
||||
final int weightUnit;
|
||||
int weightUnit;
|
||||
|
||||
@JsonKey(required: true)
|
||||
final DateTime date;
|
||||
@JsonKey(required: true, toJson: toDate)
|
||||
DateTime date;
|
||||
|
||||
//@JsonKey(required: true)
|
||||
//String comment;
|
||||
|
||||
Log({
|
||||
@required this.id,
|
||||
@required this.exercise,
|
||||
@required this.workoutPlan,
|
||||
@required this.repetitionUnit,
|
||||
@required this.reps,
|
||||
@required this.rir,
|
||||
@required this.weight,
|
||||
@required this.weightUnit,
|
||||
@required this.date,
|
||||
this.id,
|
||||
this.exercise,
|
||||
this.workoutPlan,
|
||||
this.repetitionUnit,
|
||||
this.reps,
|
||||
this.rir,
|
||||
this.weight,
|
||||
this.weightUnit,
|
||||
this.date,
|
||||
});
|
||||
|
||||
// Boilerplate
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:wger/helpers/json.dart';
|
||||
@@ -10,28 +9,32 @@ const ImpressionMap = {1: 'bad', 2: 'neutral', 3: 'good'};
|
||||
@JsonSerializable()
|
||||
class WorkoutSession {
|
||||
@JsonKey(required: true)
|
||||
final int id;
|
||||
int id;
|
||||
|
||||
@JsonKey(required: true)
|
||||
final DateTime date;
|
||||
int workoutId;
|
||||
|
||||
@JsonKey(required: true, toJson: toDate)
|
||||
DateTime date;
|
||||
|
||||
@JsonKey(required: true, fromJson: toNum, toJson: toString)
|
||||
final num impression;
|
||||
num impression;
|
||||
|
||||
@JsonKey(required: false, defaultValue: '')
|
||||
final String notes;
|
||||
String notes;
|
||||
|
||||
@JsonKey(required: true, name: 'time_start', toJson: timeToString, fromJson: stringToTime)
|
||||
final TimeOfDay timeStart;
|
||||
TimeOfDay timeStart;
|
||||
|
||||
@JsonKey(required: true, name: 'time_end', toJson: timeToString, fromJson: stringToTime)
|
||||
final TimeOfDay timeEnd;
|
||||
TimeOfDay timeEnd;
|
||||
|
||||
WorkoutSession({
|
||||
@required this.id,
|
||||
@required this.date,
|
||||
@required this.impression,
|
||||
@required this.notes,
|
||||
this.id,
|
||||
this.workoutId,
|
||||
this.date,
|
||||
this.impression,
|
||||
this.notes,
|
||||
this.timeStart,
|
||||
this.timeEnd,
|
||||
});
|
||||
|
||||
@@ -29,6 +29,10 @@ class Set {
|
||||
@JsonKey(required: false)
|
||||
List<Setting> settings = [];
|
||||
|
||||
/// Computed settings
|
||||
@JsonKey(required: false)
|
||||
List<Setting> settingsComputed = [];
|
||||
|
||||
Set({
|
||||
this.id,
|
||||
sets,
|
||||
@@ -36,11 +40,13 @@ class Set {
|
||||
this.order,
|
||||
exercises,
|
||||
settings,
|
||||
settingsComputed,
|
||||
}) {
|
||||
this.sets = sets ?? DEFAULT_NR_SETS;
|
||||
this.exercisesObj = exercises ?? [];
|
||||
this.exercisesIds = exercisesObj.map((e) => e.id).toList();
|
||||
this.settings = settings ?? [];
|
||||
this.settingsComputed = settingsComputed ?? [];
|
||||
}
|
||||
|
||||
void addExercise(Exercise exercise) {
|
||||
|
||||
@@ -33,6 +33,9 @@ class Setting {
|
||||
@JsonKey(required: true, defaultValue: '')
|
||||
String comment = '';
|
||||
|
||||
@JsonKey(required: false, defaultValue: '')
|
||||
String rir = '';
|
||||
|
||||
// Generated by Server
|
||||
@JsonKey(required: false)
|
||||
String repsText;
|
||||
@@ -46,6 +49,7 @@ class Setting {
|
||||
this.weight,
|
||||
this.weightUnit,
|
||||
this.comment,
|
||||
this.rir,
|
||||
this.repsText,
|
||||
}) {
|
||||
if (exerciseObj != null) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import 'package:wger/models/http_exception.dart';
|
||||
import 'package:wger/models/workouts/day.dart';
|
||||
import 'package:wger/models/workouts/log.dart';
|
||||
import 'package:wger/models/workouts/repetition_unit.dart';
|
||||
import 'package:wger/models/workouts/session.dart';
|
||||
import 'package:wger/models/workouts/set.dart';
|
||||
import 'package:wger/models/workouts/setting.dart';
|
||||
import 'package:wger/models/workouts/weight_unit.dart';
|
||||
@@ -146,6 +147,7 @@ class WorkoutPlans extends WgerBaseProvider with ChangeNotifier {
|
||||
|
||||
for (final set in entry['set_list']) {
|
||||
List<Setting> settings = [];
|
||||
List<Setting> settingsComputed = [];
|
||||
List<Exercise> exercises = [];
|
||||
|
||||
for (final exerciseData in set['exercise_list']) {
|
||||
@@ -186,6 +188,11 @@ class WorkoutPlans extends WgerBaseProvider with ChangeNotifier {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Computed settings
|
||||
for (var setting in exerciseData['settings_computed']) {
|
||||
settingsComputed.add(Setting.fromJson(setting));
|
||||
}
|
||||
}
|
||||
|
||||
// Sets
|
||||
@@ -194,6 +201,7 @@ class WorkoutPlans extends WgerBaseProvider with ChangeNotifier {
|
||||
sets: set['obj']['sets'],
|
||||
order: set['obj']['order'],
|
||||
settings: settings,
|
||||
settingsComputed: settingsComputed,
|
||||
exercises: exercises,
|
||||
));
|
||||
}
|
||||
@@ -377,4 +385,23 @@ class WorkoutPlans extends WgerBaseProvider with ChangeNotifier {
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
Future<WorkoutSession> addSession(WorkoutSession session) async {
|
||||
print(session.toJson());
|
||||
final data = await post(session.toJson(), makeUrl(_sessionUrlPath));
|
||||
final newSession = WorkoutSession.fromJson(data);
|
||||
notifyListeners();
|
||||
return newSession;
|
||||
}
|
||||
|
||||
/*
|
||||
* Logs
|
||||
*/
|
||||
Future<Log> addLog(Log log) async {
|
||||
print(log.toJson());
|
||||
final data = await post(log.toJson(), makeUrl(_logsUrlPath));
|
||||
final newLog = Log.fromJson(data);
|
||||
notifyListeners();
|
||||
return newLog;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ class WorkoutDayWidget extends StatelessWidget {
|
||||
Widget getSetRow(Set set) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.baseline,
|
||||
textBaseline: TextBaseline.alphabetic,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
|
||||
@@ -21,10 +21,14 @@ import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:wger/helpers/ui.dart';
|
||||
import 'package:wger/locale/locales.dart';
|
||||
import 'package:wger/models/exercises/exercise.dart';
|
||||
import 'package:wger/models/http_exception.dart';
|
||||
import 'package:wger/models/workouts/day.dart';
|
||||
import 'package:wger/models/workouts/log.dart';
|
||||
import 'package:wger/models/workouts/session.dart';
|
||||
import 'package:wger/models/workouts/setting.dart';
|
||||
import 'package:wger/providers/exercises.dart';
|
||||
import 'package:wger/providers/workout_plans.dart';
|
||||
|
||||
@@ -52,22 +56,27 @@ class _GymModeState extends State<GymMode> {
|
||||
final exerciseProvider = Provider.of<Exercises>(context, listen: false);
|
||||
final workoutProvider = Provider.of<WorkoutPlans>(context, listen: false);
|
||||
|
||||
List<Widget> out = [];
|
||||
|
||||
for (var set in widget._workoutDay.sets) {
|
||||
var firstPage = true;
|
||||
for (var setting in set.settingsComputed) {
|
||||
if (firstPage) {
|
||||
out.add(ExerciseOverview(_controller, exerciseProvider.findById(setting.exerciseId)));
|
||||
}
|
||||
out.add(LogPage(_controller, setting, exerciseProvider.findById(setting.exerciseId)));
|
||||
out.add(TimerWidget(_controller));
|
||||
|
||||
firstPage = false;
|
||||
}
|
||||
}
|
||||
|
||||
return PageView(
|
||||
controller: _controller,
|
||||
children: [
|
||||
StartPage(_controller, widget._workoutDay),
|
||||
ExerciseOverview(_controller, exerciseProvider.findById(20)),
|
||||
LogPage(_controller),
|
||||
TimerWidget(_controller),
|
||||
LogPage(_controller),
|
||||
TimerWidget(_controller),
|
||||
ExerciseOverview(_controller, exerciseProvider.findById(30)),
|
||||
LogPage(_controller),
|
||||
TimerWidget(_controller),
|
||||
...out,
|
||||
SessionPage(),
|
||||
|
||||
//MyPage2Widget(),
|
||||
//MyPage3Widget(),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -132,11 +141,32 @@ class StartPage extends StatelessWidget {
|
||||
|
||||
class LogPage extends StatelessWidget {
|
||||
PageController _controller;
|
||||
Setting _setting;
|
||||
Exercise _exercise;
|
||||
Log _log = Log();
|
||||
|
||||
final _form = GlobalKey<FormState>();
|
||||
final _repsController = TextEditingController();
|
||||
final _weightController = TextEditingController();
|
||||
final _rirController = TextEditingController();
|
||||
final _commentController = TextEditingController();
|
||||
|
||||
LogPage(this._controller);
|
||||
LogPage(this._controller, this._setting, this._exercise) {
|
||||
if (_setting.reps != null) {
|
||||
_weightController.text = _setting.reps.toString();
|
||||
}
|
||||
|
||||
if (_setting.weight != null) {
|
||||
_weightController.text = _setting.weight.toString();
|
||||
}
|
||||
|
||||
if (_setting.rir != null) {
|
||||
_rirController.text = _setting.rir;
|
||||
}
|
||||
|
||||
_log.date = DateTime.now();
|
||||
_log.exercise = _exercise.id;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -148,7 +178,7 @@ class LogPage extends StatelessWidget {
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Text(
|
||||
'Log',
|
||||
_exercise.name,
|
||||
style: Theme.of(context).textTheme.headline5,
|
||||
),
|
||||
),
|
||||
@@ -164,18 +194,68 @@ class LogPage extends StatelessWidget {
|
||||
controller: _repsController,
|
||||
keyboardType: TextInputType.number,
|
||||
onFieldSubmitted: (_) {},
|
||||
onSaved: (newValue) {},
|
||||
onSaved: (newValue) {
|
||||
_log.reps = int.parse(newValue);
|
||||
},
|
||||
validator: (value) {
|
||||
try {
|
||||
double.parse(value);
|
||||
} catch (error) {
|
||||
return 'Please enter a valid number';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
TextFormField(
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).weight),
|
||||
controller: _weightController,
|
||||
keyboardType: TextInputType.number,
|
||||
onFieldSubmitted: (_) {},
|
||||
onSaved: (newValue) {
|
||||
_log.weight = double.parse(newValue);
|
||||
},
|
||||
),
|
||||
TextFormField(
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).rir),
|
||||
controller: _rirController,
|
||||
keyboardType: TextInputType.number,
|
||||
onFieldSubmitted: (_) {},
|
||||
onSaved: (newValue) {},
|
||||
),
|
||||
/*
|
||||
TextFormField(
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).comment),
|
||||
controller: _commentController,
|
||||
keyboardType: TextInputType.multiline,
|
||||
maxLines: 3,
|
||||
onFieldSubmitted: (_) {},
|
||||
onSaved: (newValue) {
|
||||
_log.
|
||||
},
|
||||
),
|
||||
|
||||
*/
|
||||
ElevatedButton(
|
||||
child: Text(AppLocalizations.of(context).save),
|
||||
onPressed: () async {},
|
||||
onPressed: () async {
|
||||
// Validate and save the current values to the weightEntry
|
||||
final isValid = _form.currentState.validate();
|
||||
if (!isValid) {
|
||||
return;
|
||||
}
|
||||
_form.currentState.save();
|
||||
|
||||
// Save the entry on the server
|
||||
try {
|
||||
await Provider.of<WorkoutPlans>(context, listen: false).addLog(_log);
|
||||
_controller.nextPage(
|
||||
duration: Duration(milliseconds: 200), curve: Curves.bounceIn);
|
||||
} on WgerHttpException catch (error) {
|
||||
showHttpExceptionErrorDialog(error, context);
|
||||
} catch (error) {
|
||||
showErrorDialog(error, context);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -209,7 +289,7 @@ class ExerciseOverview extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text('aa'),
|
||||
child: Text(_exercise.description),
|
||||
),
|
||||
NavigationFooter(_controller),
|
||||
],
|
||||
@@ -231,6 +311,7 @@ class _SessionPageState extends State<SessionPage> {
|
||||
final timeEndController = TextEditingController();
|
||||
|
||||
int impressionValue = 2;
|
||||
var _session = WorkoutSession();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -289,7 +370,9 @@ class _SessionPageState extends State<SessionPage> {
|
||||
controller: notesController,
|
||||
keyboardType: TextInputType.multiline,
|
||||
onFieldSubmitted: (_) {},
|
||||
onSaved: (newValue) {},
|
||||
onSaved: (newValue) {
|
||||
_session.notes = newValue;
|
||||
},
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
@@ -315,16 +398,37 @@ class _SessionPageState extends State<SessionPage> {
|
||||
),
|
||||
ElevatedButton(
|
||||
child: Text(AppLocalizations.of(context).save),
|
||||
onPressed: () async {},
|
||||
onPressed: () async {
|
||||
// Validate and save the current values to the weightEntry
|
||||
final isValid = _form.currentState.validate();
|
||||
if (!isValid) {
|
||||
return;
|
||||
}
|
||||
_form.currentState.save();
|
||||
_session.date = DateTime.now();
|
||||
|
||||
// Save the entry on the server
|
||||
try {
|
||||
await Provider.of<WorkoutPlans>(context, listen: false)
|
||||
.addSession(_session);
|
||||
Navigator.of(context).pop();
|
||||
} on WgerHttpException catch (error) {
|
||||
showHttpExceptionErrorDialog(error, context);
|
||||
} catch (error) {
|
||||
showErrorDialog(error, context);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.stop),
|
||||
onPressed: () {},
|
||||
)
|
||||
icon: Icon(Icons.exit_to_app),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -112,6 +112,7 @@ class DayLogWidget extends StatelessWidget {
|
||||
Widget getSetRow(Set set) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.baseline,
|
||||
textBaseline: TextBaseline.alphabetic,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
|
||||
Reference in New Issue
Block a user