Allow day objects to load slots

This commit is contained in:
Roland Geider
2024-11-12 22:08:45 +01:00
parent bf73afd9fe
commit 056ed2b894
15 changed files with 97 additions and 67 deletions

View File

@@ -23,6 +23,13 @@ num stringToNum(String? e) {
return e == null ? 0 : num.parse(e);
}
num stringOrIntToNum(dynamic e) {
if (e is int) {
return e.toDouble(); // Convert int to double (a type of num)
}
return num.tryParse(e) ?? 0;
}
num? stringToNumNull(String? e) {
return e == null ? null : num.parse(e);
}

View File

@@ -17,6 +17,7 @@
*/
import 'package:json_annotation/json_annotation.dart';
import 'package:wger/helpers/json.dart';
part 'base_config.g.dart';
@@ -31,10 +32,10 @@ class BaseConfig {
@JsonKey(required: true)
late int iteration;
@JsonKey(required: true)
late String trigger;
// @JsonKey(required: true)
// late String trigger;
@JsonKey(required: true)
@JsonKey(required: true, fromJson: stringOrIntToNum)
late num value;
@JsonKey(required: true)
@@ -44,13 +45,13 @@ class BaseConfig {
late String step;
@JsonKey(required: true, name: 'need_log_to_apply')
late String needLogToApply;
late bool needLogToApply;
BaseConfig({
required this.id,
required this.slotEntryId,
required this.iteration,
required this.trigger,
// required this.trigger,
required this.value,
required this.operation,
required this.step,

View File

@@ -13,7 +13,6 @@ BaseConfig _$BaseConfigFromJson(Map<String, dynamic> json) {
'id',
'slot_entry',
'iteration',
'trigger',
'value',
'operation',
'step',
@@ -24,11 +23,10 @@ BaseConfig _$BaseConfigFromJson(Map<String, dynamic> json) {
id: (json['id'] as num).toInt(),
slotEntryId: (json['slot_entry'] as num).toInt(),
iteration: (json['iteration'] as num).toInt(),
trigger: json['trigger'] as String,
value: json['value'] as num,
value: stringOrIntToNum(json['value']),
operation: json['operation'] as String,
step: json['step'] as String,
needLogToApply: json['need_log_to_apply'] as String,
needLogToApply: json['need_log_to_apply'] as bool,
);
}
@@ -36,7 +34,6 @@ Map<String, dynamic> _$BaseConfigToJson(BaseConfig instance) => <String, dynamic
'id': instance.id,
'slot_entry': instance.slotEntryId,
'iteration': instance.iteration,
'trigger': instance.trigger,
'value': instance.value,
'operation': instance.operation,
'step': instance.step,

View File

@@ -21,13 +21,12 @@ import 'package:wger/models/workouts/slot.dart';
part 'day.g.dart';
const MIN_LENGTH_NAME = 3;
const MAX_LENGTH_NAME = 20;
const MAX_LENGTH_DESCRIPTION = 1000;
@JsonSerializable()
class Day {
static const MIN_LENGTH_NAME = 3;
static const MAX_LENGTH_NAME = 20;
static const MAX_LENGTH_DESCRIPTION = 1000;
@JsonKey(required: true)
int? id;
@@ -55,12 +54,9 @@ class Day {
@JsonKey(required: true)
late Object? config;
@JsonKey(includeFromJson: false, includeToJson: false)
@JsonKey(required: false, defaultValue: [], includeFromJson: true, includeToJson: false)
List<Slot> slots = [];
//@JsonKey(includeFromJson: false, includeToJson: false)
//late WorkoutPlan workout;
Day() {
slots = [];
}

View File

@@ -30,7 +30,11 @@ Day _$DayFromJson(Map<String, dynamic> json) {
..needLogsToAdvance = json['need_logs_to_advance'] as bool
..type = json['type'] as String
..order = json['order'] as num
..config = json['config'];
..config = json['config']
..slots = (json['slots'] as List<dynamic>?)
?.map((e) => Slot.fromJson(e as Map<String, dynamic>))
.toList() ??
[];
}
Map<String, dynamic> _$DayToJson(Day instance) => <String, dynamic>{

View File

@@ -25,20 +25,20 @@ import 'package:wger/models/workouts/log.dart';
part 'routine.g.dart';
const MIN_LENGTH_DESCRIPTION = 0;
const MAX_LENGTH_DESCRIPTION = 1000;
const MIN_LENGTH_NAME = 3;
const MAX_LENGTH_NAME = 25;
/// In weeks
const MIN_DURATION = 2;
/// In weeks
const MAX_DURATION = 16;
@JsonSerializable()
class Routine {
static const MIN_LENGTH_DESCRIPTION = 0;
static const MAX_LENGTH_DESCRIPTION = 1000;
static const MIN_LENGTH_NAME = 3;
static const MAX_LENGTH_NAME = 25;
/// In weeks
static const MIN_DURATION = 2;
/// In weeks
static const MAX_DURATION = 16;
@JsonKey(required: true)
int? id;

View File

@@ -47,7 +47,7 @@ class Slot {
@JsonKey(includeFromJson: false, includeToJson: false)
List<int> exercisesIds = [];
@JsonKey(includeFromJson: false, includeToJson: false)
@JsonKey(required: false, includeFromJson: true, defaultValue: [], includeToJson: false)
List<SlotEntry> entries = [];
/// Computed settings (instead of 4x10 this has [10, 10, 10, 10]), used for
@@ -67,7 +67,6 @@ class Slot {
Slot.withData({
this.id,
sets,
day,
comment,
order,
@@ -79,7 +78,7 @@ class Slot {
this.comment = comment ?? '';
exercisesObj = exercises ?? [];
exercisesIds = exercisesObj.map((e) => e.id!).toList();
this.entries = settings ?? [];
entries = settings ?? [];
this.settingsComputed = settingsComputed ?? [];
if (day != null) {
this.day = day;

View File

@@ -17,7 +17,9 @@ Slot _$SlotFromJson(Map<String, dynamic> json) {
comment: json['comment'] as String? ?? '',
order: (json['order'] as num).toInt(),
config: json['config'],
);
)..entries = (json['entries'] as List<dynamic>)
.map((e) => SlotEntry.fromJson(e as Map<String, dynamic>))
.toList();
}
Map<String, dynamic> _$SlotToJson(Slot instance) => <String, dynamic>{

View File

@@ -17,6 +17,7 @@
*/
import 'package:json_annotation/json_annotation.dart';
import 'package:wger/helpers/json.dart';
import 'package:wger/models/exercises/exercise.dart';
import 'package:wger/models/workouts/base_config.dart';
import 'package:wger/models/workouts/repetition_unit.dart';
@@ -40,6 +41,9 @@ class SlotEntry {
@JsonKey(required: true)
late int order;
@JsonKey(required: true)
late String comment;
@JsonKey(required: true)
late String type;
@@ -55,7 +59,7 @@ class SlotEntry {
@JsonKey(includeFromJson: false, includeToJson: false)
late RepetitionUnit repetitionUnitObj;
@JsonKey(required: true, name: 'repetition_rounding')
@JsonKey(required: true, name: 'repetition_rounding', fromJson: stringToNum)
late num repetitionRounding;
@JsonKey(required: true, name: 'reps_configs')
@@ -70,7 +74,7 @@ class SlotEntry {
@JsonKey(includeFromJson: false, includeToJson: false)
late WeightUnit weightUnitObj;
@JsonKey(required: true, name: 'weight_rounding')
@JsonKey(required: true, name: 'weight_rounding', fromJson: stringToNum)
late num weightRounding;
@JsonKey(required: true, name: 'weight_configs')
@@ -91,9 +95,6 @@ class SlotEntry {
@JsonKey(required: true, name: 'max_rest_configs')
late List<BaseConfig> maxRestTimeConfigs;
@JsonKey(required: true)
late String comment = '';
@JsonKey(required: true)
late Object? config;

View File

@@ -13,6 +13,7 @@ SlotEntry _$SlotEntryFromJson(Map<String, dynamic> json) {
'id',
'slot',
'order',
'comment',
'type',
'exercise',
'repetition_unit',
@@ -27,7 +28,6 @@ SlotEntry _$SlotEntryFromJson(Map<String, dynamic> json) {
'rir_configs',
'rest_configs',
'max_rest_configs',
'comment',
'config'
],
);
@@ -38,9 +38,9 @@ SlotEntry _$SlotEntryFromJson(Map<String, dynamic> json) {
type: json['type'] as String,
exerciseId: (json['exercise'] as num).toInt(),
repetitionUnitId: (json['repetition_unit'] as num).toInt(),
repetitionRounding: json['repetition_rounding'] as num,
repetitionRounding: stringToNum(json['repetition_rounding'] as String?),
weightUnitId: (json['weight_unit'] as num).toInt(),
weightRounding: json['weight_rounding'] as num,
weightRounding: stringToNum(json['weight_rounding'] as String?),
comment: json['comment'] as String,
)
..repsConfig = (json['reps_configs'] as List<dynamic>)
@@ -74,6 +74,7 @@ Map<String, dynamic> _$SlotEntryToJson(SlotEntry instance) => <String, dynamic>{
'id': instance.id,
'slot': instance.slotId,
'order': instance.order,
'comment': instance.comment,
'type': instance.type,
'exercise': instance.exerciseId,
'repetition_unit': instance.repetitionUnitId,
@@ -88,6 +89,5 @@ Map<String, dynamic> _$SlotEntryToJson(SlotEntry instance) => <String, dynamic>{
'rir_configs': instance.rirConfigs,
'rest_configs': instance.restTimeConfigs,
'max_rest_configs': instance.maxRestTimeConfigs,
'comment': instance.comment,
'config': instance.config,
};

View File

@@ -344,7 +344,7 @@ class RoutinesProvider with ChangeNotifier {
_routinesUrlPath,
id: workout.id,
objectMethod: 'log_data',
query: {'id': base.id.toString()},
query: {'id': base.id!.toString()},
),
);
return data;

View File

@@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
import 'package:wger/helpers/consts.dart';
import 'package:wger/models/workouts/day.dart';
import 'package:wger/providers/routines.dart';
import 'package:wger/widgets/routines/forms/slot.dart';
class ReorderableDaysList extends StatefulWidget {
final int routineId;
@@ -184,11 +185,11 @@ class _DayFormWidgetState extends State<DayFormWidget> {
},
validator: (value) {
if (value!.isEmpty ||
value.length < MIN_LENGTH_NAME ||
value.length > MAX_LENGTH_NAME) {
value.length < Day.MIN_LENGTH_NAME ||
value.length > Day.MAX_LENGTH_NAME) {
return AppLocalizations.of(context).enterCharacters(
MIN_LENGTH_NAME,
MAX_LENGTH_NAME,
Day.MIN_LENGTH_NAME,
Day.MAX_LENGTH_NAME,
);
}
@@ -209,8 +210,8 @@ class _DayFormWidgetState extends State<DayFormWidget> {
minLines: 2,
maxLines: 10,
validator: (value) {
if (value != null && value.length > MAX_LENGTH_DESCRIPTION) {
return AppLocalizations.of(context).enterCharacters(0, MAX_LENGTH_DESCRIPTION);
if (value != null && value.length > Day.MAX_LENGTH_DESCRIPTION) {
return AppLocalizations.of(context).enterCharacters(0, Day.MAX_LENGTH_DESCRIPTION);
}
return null;
@@ -258,6 +259,7 @@ class _DayFormWidgetState extends State<DayFormWidget> {
}
},
),
SlotFormWidgetNg(widget.day),
],
),
);

View File

@@ -53,11 +53,11 @@ class _RoutineFormState extends State<RoutineForm> {
controller: workoutNameController,
validator: (value) {
if (value!.isEmpty ||
value.length < MIN_LENGTH_NAME ||
value.length > MAX_LENGTH_NAME) {
value.length < Routine.MIN_LENGTH_NAME ||
value.length > Routine.MAX_LENGTH_NAME) {
return AppLocalizations.of(context).enterCharacters(
MIN_LENGTH_NAME,
MAX_LENGTH_NAME,
Routine.MIN_LENGTH_NAME,
Routine.MAX_LENGTH_NAME,
);
}
return null;
@@ -73,10 +73,10 @@ class _RoutineFormState extends State<RoutineForm> {
maxLines: 10,
controller: workoutDescriptionController,
validator: (value) {
if (value!.length > MAX_LENGTH_DESCRIPTION) {
if (value!.length > Routine.MAX_LENGTH_DESCRIPTION) {
return AppLocalizations.of(context).enterCharacters(
MIN_LENGTH_DESCRIPTION,
MAX_LENGTH_DESCRIPTION,
Routine.MIN_LENGTH_DESCRIPTION,
Routine.MAX_LENGTH_DESCRIPTION,
);
}
return null;
@@ -93,11 +93,11 @@ class _RoutineFormState extends State<RoutineForm> {
if (endDate.isBefore(startDate)) {
return 'End date must be after start date';
}
if (endDate.difference(startDate).inDays < MIN_DURATION * 7) {
return 'Duration of the routine must be more than $MIN_DURATION weeks';
if (endDate.difference(startDate).inDays < Routine.MIN_DURATION * 7) {
return 'Duration of the routine must be more than ${Routine.MIN_DURATION} weeks';
}
if (endDate.difference(startDate).inDays > MAX_DURATION * 7) {
return 'Duration of the routine must be less than $MAX_DURATION weeks';
if (endDate.difference(startDate).inDays > Routine.MAX_DURATION * 7) {
return 'Duration of the routine must be less than ${Routine.MAX_DURATION} weeks';
}
return null;
},

View File

@@ -31,12 +31,34 @@ import 'package:wger/screens/add_exercise_screen.dart';
import 'package:wger/widgets/exercises/images.dart';
import 'package:wger/widgets/routines/forms.dart';
class SlotFormWidgetNg extends StatefulWidget {
final Day _day;
SlotFormWidgetNg(this._day);
@override
_SlotFormWidgetStateNg createState() => _SlotFormWidgetStateNg();
}
class _SlotFormWidgetStateNg extends State<SlotFormWidgetNg> {
@override
Widget build(BuildContext context) {
return Form(
child: Column(
children: [
Text(widget._day.id!.toString()),
...widget._day.slots.map((slot) => Text(slot.id!.toString())).toList()
],
));
}
}
class SlotFormWidget extends StatefulWidget {
final Day _day;
late final Slot _slot;
SlotFormWidget(this._day, [Slot? set]) {
_slot = set ?? Slot.withData(day: _day.id, order: _day.slots.length, sets: 4);
_slot = set ?? Slot.withData(day: _day.id, order: _day.slots.length);
}
@override

View File

@@ -87,7 +87,6 @@ Routine getWorkout({List<Exercise>? exercises}) {
final setBenchPress = Slot.withData(
id: 1,
day: 1,
sets: 3,
order: 1,
comment: 'Make sure to warm up',
);
@@ -110,7 +109,7 @@ Routine getWorkout({List<Exercise>? exercises}) {
settingSquat.weightUnit = weightUnit1;
settingSquat.exercise = testBases[4];
final setSquat = Slot.withData(id: 2, day: 1, sets: 3, order: 1);
final setSquat = Slot.withData(id: 2, day: 1, order: 1);
setSquat.addExerciseBase(testBases[4]);
setSquat.entries.add(settingSquat);
setSquat.settingsComputed = [settingSquat, settingSquat];
@@ -131,7 +130,7 @@ Routine getWorkout({List<Exercise>? exercises}) {
settingSideRaises.exercise = testBases[5];
// settingSideRaises.weight = 6;
final setSideRaises = Slot.withData(id: 3, day: 1, sets: 3, order: 1);
final setSideRaises = Slot.withData(id: 3, day: 1, order: 1);
setSideRaises.addExerciseBase(testBases[5]);
setSideRaises.entries.add(settingSideRaises);
setSideRaises.settingsComputed = [settingSideRaises, settingSideRaises];