mirror of
https://github.com/wger-project/flutter.git
synced 2026-02-18 00:17:48 +01:00
Workout logs and settings now have a reference to an exercise base
This puts this code in sync with the backend and is logically better, since the translations can be displayed when needed and are not hard coded
This commit is contained in:
@@ -201,7 +201,7 @@ void main() {
|
||||
creationDate: DateTime(2021, 1, 15),
|
||||
name: 'Squats',
|
||||
description: 'add clever text',
|
||||
base: tBase1,
|
||||
baseId: tBase1,
|
||||
language: tLanguage1,
|
||||
);
|
||||
|
||||
@@ -211,7 +211,7 @@ void main() {
|
||||
creationDate: DateTime(2021, 1, 15),
|
||||
name: 'Bench press',
|
||||
description: 'add clever text',
|
||||
base: tBase1,
|
||||
baseId: tBase1,
|
||||
language: tLanguage1,
|
||||
);
|
||||
|
||||
@@ -221,7 +221,7 @@ void main() {
|
||||
creationDate: DateTime(2021, 1, 15),
|
||||
name: 'deadLift',
|
||||
description: 'add clever text',
|
||||
base: tBase1,
|
||||
baseId: tBase1,
|
||||
language: tLanguage1,
|
||||
);
|
||||
|
||||
@@ -231,7 +231,7 @@ void main() {
|
||||
creationDate: DateTime(2021, 1, 15),
|
||||
name: 'Crunches',
|
||||
description: 'add clever text',
|
||||
base: tBase1,
|
||||
baseId: tBase1,
|
||||
language: tLanguage1,
|
||||
);
|
||||
|
||||
@@ -243,7 +243,7 @@ void main() {
|
||||
final setting1 = Setting(
|
||||
setId: 1,
|
||||
order: 1,
|
||||
exerciseId: 1,
|
||||
exerciseBaseId: 1,
|
||||
repetitionUnitId: 1,
|
||||
reps: 5,
|
||||
weightUnitId: 1,
|
||||
@@ -252,13 +252,13 @@ void main() {
|
||||
);
|
||||
setting1.repetitionUnit = repetitionUnit1;
|
||||
setting1.weightUnit = weightUnit1;
|
||||
setting1.exercise = squats;
|
||||
setting1.exerciseBase = squats;
|
||||
setting1.weight = 100;
|
||||
|
||||
final setting2 = Setting(
|
||||
setId: 1,
|
||||
order: 1,
|
||||
exerciseId: 2,
|
||||
exerciseBaseId: 2,
|
||||
repetitionUnitId: 1,
|
||||
reps: 6,
|
||||
weightUnitId: 1,
|
||||
@@ -267,13 +267,13 @@ void main() {
|
||||
);
|
||||
setting2.repetitionUnit = repetitionUnit1;
|
||||
setting2.weightUnit = weightUnit1;
|
||||
setting2.exercise = benchPress;
|
||||
setting2.exerciseBase = benchPress;
|
||||
setting2.weight = 80;
|
||||
|
||||
final setting2b = Setting(
|
||||
setId: 1,
|
||||
order: 1,
|
||||
exerciseId: 2,
|
||||
exerciseBaseId: 2,
|
||||
repetitionUnitId: 1,
|
||||
reps: 8,
|
||||
weightUnitId: 1,
|
||||
@@ -282,13 +282,13 @@ void main() {
|
||||
);
|
||||
setting2b.repetitionUnit = repetitionUnit1;
|
||||
setting2b.weightUnit = weightUnit1;
|
||||
setting2b.exercise = benchPress;
|
||||
setting2b.exerciseBase = benchPress;
|
||||
setting2b.weight = 60;
|
||||
|
||||
final setting3 = Setting(
|
||||
setId: 1,
|
||||
order: 1,
|
||||
exerciseId: 2,
|
||||
exerciseBaseId: 2,
|
||||
repetitionUnitId: 1,
|
||||
reps: 20,
|
||||
weightUnitId: 1,
|
||||
@@ -297,12 +297,12 @@ void main() {
|
||||
);
|
||||
setting3.repetitionUnit = repetitionUnit1;
|
||||
setting3.weightUnit = weightUnit1;
|
||||
setting3.exercise = crunches;
|
||||
setting3.exerciseBase = crunches;
|
||||
|
||||
final setting4 = Setting(
|
||||
setId: 1,
|
||||
order: 1,
|
||||
exerciseId: 2,
|
||||
exerciseBaseId: 2,
|
||||
repetitionUnitId: 1,
|
||||
reps: 8,
|
||||
weightUnitId: 1,
|
||||
@@ -311,7 +311,7 @@ void main() {
|
||||
);
|
||||
setting4.repetitionUnit = repetitionUnit1;
|
||||
setting4.weightUnit = weightUnit1;
|
||||
setting4.exercise = deadLift;
|
||||
setting4.exerciseBase = deadLift;
|
||||
setting4.weight = 120;
|
||||
|
||||
final set1 = Set.withData(
|
||||
@@ -320,7 +320,7 @@ void main() {
|
||||
sets: 3,
|
||||
order: 1,
|
||||
);
|
||||
set1.addExercise(squats);
|
||||
set1.addExerciseBase(squats);
|
||||
set1.settings.add(setting1);
|
||||
set1.settings.add(setting1);
|
||||
set1.settings.add(setting1);
|
||||
@@ -332,7 +332,7 @@ void main() {
|
||||
sets: 3,
|
||||
order: 1,
|
||||
);
|
||||
set2.addExercise(benchPress);
|
||||
set2.addExerciseBase(benchPress);
|
||||
set2.settings.add(setting2);
|
||||
set2.settings.add(setting2);
|
||||
set2.settings.add(setting2b);
|
||||
@@ -344,7 +344,7 @@ void main() {
|
||||
sets: 3,
|
||||
order: 1,
|
||||
);
|
||||
set3.addExercise(crunches);
|
||||
set3.addExerciseBase(crunches);
|
||||
set3.settings.add(setting3);
|
||||
|
||||
final set4 = Set.withData(
|
||||
@@ -353,7 +353,7 @@ void main() {
|
||||
sets: 3,
|
||||
order: 1,
|
||||
);
|
||||
set4.addExercise(deadLift);
|
||||
set4.addExerciseBase(deadLift);
|
||||
set4.settings.add(setting4);
|
||||
set4.settings.add(setting4);
|
||||
set4.settings.add(setting4);
|
||||
|
||||
@@ -121,7 +121,7 @@ class ExerciseBase extends Equatable {
|
||||
/// translation in English. This is something that should never happen,
|
||||
/// but we can't make sure that no local installation hasn't deleted
|
||||
/// the entry in English.
|
||||
Exercise getExercises(String language) {
|
||||
Exercise getExercise(String language) {
|
||||
return exercises.firstWhere(
|
||||
(e) => e.languageObj.shortName == language,
|
||||
orElse: () => exercises.firstWhere(
|
||||
|
||||
@@ -20,12 +20,8 @@ import 'package:equatable/equatable.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:wger/models/exercises/alias.dart';
|
||||
import 'package:wger/models/exercises/base.dart';
|
||||
import 'package:wger/models/exercises/category.dart';
|
||||
import 'package:wger/models/exercises/comment.dart';
|
||||
import 'package:wger/models/exercises/equipment.dart';
|
||||
import 'package:wger/models/exercises/image.dart';
|
||||
import 'package:wger/models/exercises/language.dart';
|
||||
import 'package:wger/models/exercises/muscle.dart';
|
||||
|
||||
part 'exercise.g.dart';
|
||||
|
||||
@@ -49,9 +45,6 @@ class Exercise extends Equatable {
|
||||
@JsonKey(required: true, name: 'exercise_base')
|
||||
late int? baseId;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
late ExerciseBase baseObj;
|
||||
|
||||
@JsonKey(required: true)
|
||||
final String name;
|
||||
|
||||
@@ -70,12 +63,11 @@ class Exercise extends Equatable {
|
||||
this.creationDate,
|
||||
required this.name,
|
||||
required this.description,
|
||||
base,
|
||||
int? baseId,
|
||||
language,
|
||||
}) {
|
||||
if (base != null) {
|
||||
baseObj = base;
|
||||
baseId = base.id;
|
||||
if (baseId != null) {
|
||||
baseId = baseId;
|
||||
}
|
||||
|
||||
if (language != null) {
|
||||
@@ -84,15 +76,7 @@ class Exercise extends Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
ExerciseImage? get getMainImage => baseObj.getMainImage;
|
||||
ExerciseCategory get category => baseObj.category;
|
||||
List<ExerciseImage> get images => baseObj.images;
|
||||
List<Equipment> get equipment => baseObj.equipment;
|
||||
List<Muscle> get muscles => baseObj.muscles;
|
||||
List<Muscle> get musclesSecondary => baseObj.musclesSecondary;
|
||||
|
||||
set base(ExerciseBase base) {
|
||||
baseObj = base;
|
||||
baseId = base.id;
|
||||
}
|
||||
|
||||
@@ -114,6 +98,5 @@ class Exercise extends Equatable {
|
||||
creationDate,
|
||||
name,
|
||||
description,
|
||||
baseObj,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -27,9 +27,8 @@ Exercise _$ExerciseFromJson(Map<String, dynamic> json) {
|
||||
: DateTime.parse(json['creation_date'] as String),
|
||||
name: json['name'] as String,
|
||||
description: json['description'] as String,
|
||||
)
|
||||
..languageId = json['language'] as int
|
||||
..baseId = json['exercise_base'] as int?;
|
||||
baseId: json['exercise_base'] as int?,
|
||||
)..languageId = json['language'] as int;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$ExerciseToJson(Exercise instance) => <String, dynamic>{
|
||||
|
||||
@@ -21,7 +21,7 @@ import 'dart:ui';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:wger/helpers/json.dart';
|
||||
import 'package:wger/helpers/misc.dart';
|
||||
import 'package:wger/models/exercises/exercise.dart';
|
||||
import 'package:wger/models/exercises/base.dart';
|
||||
import 'package:wger/models/workouts/repetition_unit.dart';
|
||||
import 'package:wger/models/workouts/weight_unit.dart';
|
||||
|
||||
@@ -32,11 +32,11 @@ class Log {
|
||||
@JsonKey(required: true)
|
||||
int? id;
|
||||
|
||||
@JsonKey(required: true, name: 'exercise')
|
||||
late int exerciseId;
|
||||
@JsonKey(required: true, name: 'exercise_base')
|
||||
late int exerciseBaseId;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
late Exercise exerciseObj;
|
||||
late ExerciseBase exerciseBaseObj;
|
||||
|
||||
@JsonKey(required: true, name: 'workout')
|
||||
late int workoutPlan;
|
||||
@@ -70,7 +70,7 @@ class Log {
|
||||
|
||||
Log({
|
||||
this.id,
|
||||
required this.exerciseId,
|
||||
required this.exerciseBaseId,
|
||||
required this.workoutPlan,
|
||||
required this.reps,
|
||||
required this.rir,
|
||||
@@ -86,9 +86,9 @@ class Log {
|
||||
factory Log.fromJson(Map<String, dynamic> json) => _$LogFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$LogToJson(this);
|
||||
|
||||
set exercise(Exercise exercise) {
|
||||
exerciseObj = exercise;
|
||||
exerciseId = exercise.id!;
|
||||
set exerciseBase(ExerciseBase base) {
|
||||
exerciseBaseObj = base;
|
||||
exerciseBaseId = base.id!;
|
||||
}
|
||||
|
||||
set weightUnit(WeightUnit weightUnit) {
|
||||
@@ -123,7 +123,7 @@ class Log {
|
||||
//ignore: avoid_equals_and_hash_code_on_mutable_classes
|
||||
bool operator ==(o) {
|
||||
return o is Log &&
|
||||
exerciseId == o.exerciseId &&
|
||||
exerciseBaseId == o.exerciseBaseId &&
|
||||
weight == o.weight &&
|
||||
weightUnitId == o.weightUnitId &&
|
||||
reps == o.reps &&
|
||||
@@ -133,13 +133,13 @@ class Log {
|
||||
|
||||
@override
|
||||
//ignore: avoid_equals_and_hash_code_on_mutable_classes
|
||||
int get hashCode => hashValues(exerciseId, weight, weightUnitId, reps, repetitionUnitId, rir);
|
||||
int get hashCode => hashValues(exerciseBaseId, weight, weightUnitId, reps, repetitionUnitId, rir);
|
||||
|
||||
//@override
|
||||
//int get hashCode => super.hashCode;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Log(id: $id, ex: $exerciseId, weightU: $weightUnitId, w: $weight, repU: $repetitionUnitId, rep: $reps, rir: $rir)';
|
||||
return 'Log(id: $id, ex: $exerciseBaseId, weightU: $weightUnitId, w: $weight, repU: $repetitionUnitId, rep: $reps, rir: $rir)';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ Log _$LogFromJson(Map<String, dynamic> json) {
|
||||
json,
|
||||
requiredKeys: const [
|
||||
'id',
|
||||
'exercise',
|
||||
'exercise_base',
|
||||
'workout',
|
||||
'reps',
|
||||
'repetition_unit',
|
||||
@@ -22,7 +22,7 @@ Log _$LogFromJson(Map<String, dynamic> json) {
|
||||
);
|
||||
return Log(
|
||||
id: json['id'] as int?,
|
||||
exerciseId: json['exercise'] as int,
|
||||
exerciseBaseId: json['exercise_base'] as int,
|
||||
workoutPlan: json['workout'] as int,
|
||||
reps: json['reps'] as int,
|
||||
rir: json['rir'] as String?,
|
||||
@@ -35,7 +35,7 @@ Log _$LogFromJson(Map<String, dynamic> json) {
|
||||
|
||||
Map<String, dynamic> _$LogToJson(Log instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'exercise': instance.exerciseId,
|
||||
'exercise_base': instance.exerciseBaseId,
|
||||
'workout': instance.workoutPlan,
|
||||
'reps': instance.reps,
|
||||
'rir': instance.rir,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:wger/models/exercises/exercise.dart';
|
||||
import 'package:wger/models/exercises/base.dart';
|
||||
import 'package:wger/models/workouts/setting.dart';
|
||||
|
||||
part 'set.g.dart';
|
||||
@@ -42,10 +42,10 @@ class Set {
|
||||
late String comment;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
List<Exercise> exercisesObj = [];
|
||||
List<ExerciseBase> exerciseBasesObj = [];
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
List<int> exercisesIds = [];
|
||||
List<int> exerciseBasesIds = [];
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
List<Setting> settings = [];
|
||||
@@ -76,8 +76,8 @@ class Set {
|
||||
this.sets = sets ?? DEFAULT_NR_SETS;
|
||||
this.order = order ?? 1;
|
||||
this.comment = comment ?? '';
|
||||
exercisesObj = exercises ?? [];
|
||||
exercisesIds = exercisesObj.map((e) => e.id!).toList();
|
||||
exerciseBasesObj = exercises ?? [];
|
||||
exerciseBasesIds = exerciseBasesObj.map((e) => e.id!).toList();
|
||||
this.settings = settings ?? [];
|
||||
this.settingsComputed = settingsComputed ?? [];
|
||||
if (day != null) {
|
||||
@@ -92,7 +92,7 @@ class Set {
|
||||
|
||||
for (final setting in settings) {
|
||||
final foundSettings = out.where(
|
||||
(element) => element.exerciseId == setting.exerciseId,
|
||||
(element) => element.exerciseBaseId == setting.exerciseBaseId,
|
||||
);
|
||||
|
||||
if (foundSettings.isEmpty) {
|
||||
@@ -102,26 +102,26 @@ class Set {
|
||||
return out;
|
||||
}
|
||||
|
||||
void addExercise(Exercise exercise) {
|
||||
exercisesObj.add(exercise);
|
||||
exercisesIds.add(exercise.id!);
|
||||
void addExerciseBase(ExerciseBase base) {
|
||||
exerciseBasesObj.add(base);
|
||||
exerciseBasesIds.add(base.id!);
|
||||
}
|
||||
|
||||
void removeExercise(Exercise exercise) {
|
||||
exercisesObj.removeWhere((e) => e.id == exercise.id);
|
||||
exercisesIds.removeWhere((e) => e == exercise.id);
|
||||
void removeExercise(ExerciseBase base) {
|
||||
exerciseBasesObj.removeWhere((e) => e.id == base.id);
|
||||
exerciseBasesIds.removeWhere((e) => e == base.id);
|
||||
}
|
||||
|
||||
/// Returns all settings for the given exercise
|
||||
List<Setting> filterSettingsByExercise(Exercise exercise) {
|
||||
return settings.where((element) => element.exerciseId == exercise.id).toList();
|
||||
List<Setting> filterSettingsByExercise(ExerciseBase exerciseBase) {
|
||||
return settings.where((element) => element.exerciseBaseId == exerciseBase.id).toList();
|
||||
}
|
||||
|
||||
/// Returns a list with all repetitions for the given exercise
|
||||
List<String> getSmartRepr(Exercise exercise) {
|
||||
List<String> getSmartRepr(ExerciseBase exerciseBase) {
|
||||
final List<String> out = [];
|
||||
|
||||
final settingList = filterSettingsByExercise(exercise);
|
||||
final settingList = filterSettingsByExercise(exerciseBase);
|
||||
|
||||
if (settingList.isEmpty) {
|
||||
out.add('');
|
||||
@@ -141,8 +141,8 @@ class Set {
|
||||
}
|
||||
|
||||
/// Returns a string with all repetitions for the given exercise
|
||||
String getSmartTextRepr(Exercise exercise) {
|
||||
return getSmartRepr(exercise).join(' – ');
|
||||
String getSmartTextRepr(ExerciseBase execiseBase) {
|
||||
return getSmartRepr(execiseBase).join(' – ');
|
||||
}
|
||||
|
||||
// Boilerplate
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:wger/helpers/json.dart';
|
||||
import 'package:wger/helpers/misc.dart';
|
||||
import 'package:wger/models/exercises/exercise.dart';
|
||||
import 'package:wger/models/exercises/base.dart';
|
||||
import 'package:wger/models/workouts/repetition_unit.dart';
|
||||
import 'package:wger/models/workouts/weight_unit.dart';
|
||||
|
||||
@@ -42,10 +42,10 @@ class Setting {
|
||||
late int order;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
late Exercise exerciseObj;
|
||||
late ExerciseBase exerciseBaseObj;
|
||||
|
||||
@JsonKey(required: true, name: 'exercise')
|
||||
late int exerciseId;
|
||||
@JsonKey(required: true, name: 'exercise_base')
|
||||
late int exerciseBaseId;
|
||||
|
||||
@JsonKey(required: true, name: 'repetition_unit')
|
||||
late int repetitionUnitId;
|
||||
@@ -77,7 +77,7 @@ class Setting {
|
||||
this.id,
|
||||
required this.setId,
|
||||
required this.order,
|
||||
required this.exerciseId,
|
||||
required this.exerciseBaseId,
|
||||
required this.repetitionUnitId,
|
||||
required this.reps,
|
||||
required this.weightUnitId,
|
||||
@@ -91,9 +91,9 @@ class Setting {
|
||||
factory Setting.fromJson(Map<String, dynamic> json) => _$SettingFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$SettingToJson(this);
|
||||
|
||||
set exercise(Exercise exercise) {
|
||||
exerciseObj = exercise;
|
||||
exerciseId = exercise.id!;
|
||||
set exerciseBase(ExerciseBase exerciseBase) {
|
||||
exerciseBaseObj = exerciseBase;
|
||||
exerciseBaseId = exerciseBase.id!;
|
||||
}
|
||||
|
||||
set weightUnit(WeightUnit weightUnit) {
|
||||
|
||||
@@ -13,7 +13,7 @@ Setting _$SettingFromJson(Map<String, dynamic> json) {
|
||||
'id',
|
||||
'set',
|
||||
'order',
|
||||
'exercise',
|
||||
'exercise_base',
|
||||
'repetition_unit',
|
||||
'reps',
|
||||
'weight',
|
||||
@@ -26,7 +26,7 @@ Setting _$SettingFromJson(Map<String, dynamic> json) {
|
||||
id: json['id'] as int?,
|
||||
setId: json['set'] as int,
|
||||
order: json['order'] as int,
|
||||
exerciseId: json['exercise'] as int,
|
||||
exerciseBaseId: json['exercise_base'] as int,
|
||||
repetitionUnitId: json['repetition_unit'] as int,
|
||||
reps: json['reps'] as int?,
|
||||
weightUnitId: json['weight_unit'] as int,
|
||||
@@ -39,7 +39,7 @@ Map<String, dynamic> _$SettingToJson(Setting instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'set': instance.setId,
|
||||
'order': instance.order,
|
||||
'exercise': instance.exerciseId,
|
||||
'exercise_base': instance.exerciseBaseId,
|
||||
'repetition_unit': instance.repetitionUnitId,
|
||||
'reps': instance.reps,
|
||||
'weight': numToString(instance.weight),
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:wger/models/exercises/base.dart';
|
||||
import 'package:wger/models/exercises/exercise.dart';
|
||||
import 'package:wger/models/workouts/day.dart';
|
||||
import 'package:wger/models/workouts/log.dart';
|
||||
@@ -72,8 +73,8 @@ class WorkoutPlan {
|
||||
/// means here that the values are the same, i.e. logs with the same weight,
|
||||
/// reps, etc. are considered equal. Workout ID, Log ID and date are not
|
||||
/// considered.
|
||||
List<Log> filterLogsByExercise(Exercise exercise, {bool unique = false}) {
|
||||
var out = logs.where((element) => element.exerciseId == exercise.id).toList();
|
||||
List<Log> filterLogsByExerciseBase(ExerciseBase exerciseBase, {bool unique = false}) {
|
||||
var out = logs.where((element) => element.exerciseBaseId == exerciseBase.id).toList();
|
||||
|
||||
if (unique) {
|
||||
out = out.toSet().toList();
|
||||
@@ -88,7 +89,7 @@ class WorkoutPlan {
|
||||
Map<DateTime, Map<String, dynamic>> get logData {
|
||||
final out = <DateTime, Map<String, dynamic>>{};
|
||||
for (final log in logs) {
|
||||
final exercise = log.exerciseObj;
|
||||
final exercise = log.exerciseBaseObj;
|
||||
final date = log.date;
|
||||
|
||||
if (!out.containsKey(date)) {
|
||||
|
||||
@@ -155,8 +155,7 @@ class ExercisesProvider with ChangeNotifier {
|
||||
|
||||
List<ExerciseBase> filteredItems = _exerciseBases;
|
||||
if (filters!.searchTerm.length > 1) {
|
||||
final exercises = await searchExercise(filters!.searchTerm);
|
||||
filteredItems = exercises.map((e) => e.baseObj).toList();
|
||||
filteredItems = await searchExercise(filters!.searchTerm);
|
||||
}
|
||||
|
||||
// Filter by exercise category and equipment (REPLACE WITH HTTP REQUEST)
|
||||
@@ -182,11 +181,11 @@ class ExercisesProvider with ChangeNotifier {
|
||||
_exerciseBases = [];
|
||||
}
|
||||
|
||||
List<Exercise> findByCategory(ExerciseCategory? category) {
|
||||
List<ExerciseBase> findByCategory(ExerciseCategory? category) {
|
||||
if (category == null) {
|
||||
return items;
|
||||
return bases;
|
||||
}
|
||||
return items.where((exercise) => exercise.category == category).toList();
|
||||
return bases.where((base) => base.category.id == category.id).toList();
|
||||
}
|
||||
|
||||
/// Find exercise by ID
|
||||
@@ -197,6 +196,14 @@ class ExercisesProvider with ChangeNotifier {
|
||||
);
|
||||
}
|
||||
|
||||
/// Find exercise base by ID
|
||||
ExerciseBase findExerciseBaseById(int id) {
|
||||
return _exerciseBases.firstWhere(
|
||||
(base) => base.id == id,
|
||||
orElse: () => throw NoSuchEntryException(),
|
||||
);
|
||||
}
|
||||
|
||||
/// Find exercise bases by variation IDs
|
||||
///
|
||||
/// exerciseIdToExclude: the ID of the exercise to exclude from the list of
|
||||
@@ -206,17 +213,21 @@ class ExercisesProvider with ChangeNotifier {
|
||||
///
|
||||
/// languageId: the ID of the language to filter the results by. If this
|
||||
/// parameter is not passed, all exercises are returned.
|
||||
List<Exercise> findExercisesByVariationId(int id, {int? exerciseIdToExclude, int? languageId}) {
|
||||
var out = _exercises
|
||||
List<ExerciseBase> findExerciseBasesByVariationId(int id,
|
||||
{int? exerciseIdToExclude, int? languageId}) {
|
||||
var out = _exerciseBases
|
||||
.where(
|
||||
(base) => base.baseObj.variationId == id,
|
||||
(base) => base.variationId == id,
|
||||
)
|
||||
.toList();
|
||||
|
||||
/*
|
||||
if (languageId != null) {
|
||||
out = out.where((e) => e.languageId == languageId).toList();
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
if (exerciseIdToExclude != null) {
|
||||
out = out.where((e) => e.id != exerciseIdToExclude).toList();
|
||||
}
|
||||
@@ -362,6 +373,15 @@ class ExercisesProvider with ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the exercise with the given ID
|
||||
///
|
||||
/// If the exercise is not known locally, it is fetched from the server.
|
||||
/// This method is called when a workout is first loaded, after that the
|
||||
/// regular not-async getById method can be used
|
||||
Future<ExerciseBase> fetchAndSetExerciseBase(int exerciseBaseId) async {
|
||||
return findExerciseBaseById(exerciseBaseId);
|
||||
}
|
||||
|
||||
/// Checks the required cache version
|
||||
///
|
||||
/// This is needed since the content of the exercise cache can change and we need
|
||||
@@ -415,7 +435,7 @@ class ExercisesProvider with ChangeNotifier {
|
||||
for (var base in bases) {
|
||||
final filteredExercises = exercises.where((e) => e.baseId == base.id);
|
||||
for (final exercise in filteredExercises) {
|
||||
exercise.baseObj = base;
|
||||
exercise.base = base;
|
||||
base.exercises.add(exercise);
|
||||
out.add(exercise);
|
||||
}
|
||||
@@ -547,7 +567,7 @@ class ExercisesProvider with ChangeNotifier {
|
||||
///
|
||||
/// We could do this locally, but the server has better text searching capabilities
|
||||
/// with postgresql.
|
||||
Future<List<Exercise>> searchExercise(String name, [String languageCode = 'en']) async {
|
||||
Future<List<ExerciseBase>> searchExercise(String name, [String languageCode = 'en']) async {
|
||||
if (name.length <= 1) {
|
||||
return [];
|
||||
}
|
||||
@@ -562,8 +582,8 @@ class ExercisesProvider with ChangeNotifier {
|
||||
|
||||
// Process the response
|
||||
return await Future.wait(
|
||||
(result['suggestions'] as List).map<Future<Exercise>>(
|
||||
(entry) => fetchAndSetExercise(entry['data']['id']),
|
||||
(result['suggestions'] as List).map<Future<ExerciseBase>>(
|
||||
(entry) => fetchAndSetExerciseBase(entry['data']['base_id']),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -202,15 +202,16 @@ class WorkoutPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
for (final settingEntry in settingData) {
|
||||
final workoutSetting = Setting.fromJson(settingEntry);
|
||||
|
||||
workoutSetting.exercise = await _exercises.fetchAndSetExercise(workoutSetting.exerciseId);
|
||||
workoutSetting.exerciseBase =
|
||||
await _exercises.fetchAndSetExerciseBase(workoutSetting.exerciseBaseId);
|
||||
workoutSetting.weightUnit = _weightUnits.firstWhere(
|
||||
(e) => e.id == workoutSetting.weightUnitId,
|
||||
);
|
||||
workoutSetting.repetitionUnit = _repetitionUnit.firstWhere(
|
||||
(e) => e.id == workoutSetting.repetitionUnitId,
|
||||
);
|
||||
if (!workoutSet.exercisesIds.contains(workoutSetting.exerciseId)) {
|
||||
workoutSet.addExercise(workoutSetting.exerciseObj);
|
||||
if (!workoutSet.exerciseBasesIds.contains(workoutSetting.exerciseBaseId)) {
|
||||
workoutSet.addExerciseBase(workoutSetting.exerciseBaseObj);
|
||||
}
|
||||
|
||||
settings.add(workoutSetting);
|
||||
@@ -243,7 +244,7 @@ class WorkoutPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
final log = Log.fromJson(entry);
|
||||
log.weightUnit = _weightUnits.firstWhere((e) => e.id == log.weightUnitId);
|
||||
log.repetitionUnit = _repetitionUnit.firstWhere((e) => e.id == log.weightUnitId);
|
||||
log.exercise = await _exercises.fetchAndSetExercise(log.exerciseId);
|
||||
log.exerciseBase = await _exercises.fetchAndSetExerciseBase(log.exerciseBaseId);
|
||||
plan.logs.add(log);
|
||||
} catch (e) {
|
||||
dev.log('fire! fire!');
|
||||
@@ -499,7 +500,7 @@ class WorkoutPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
log.id = newLog.id;
|
||||
log.weightUnit = _weightUnits.firstWhere((e) => e.id == log.weightUnitId);
|
||||
log.repetitionUnit = _repetitionUnit.firstWhere((e) => e.id == log.weightUnitId);
|
||||
log.exercise = await _exercises.fetchAndSetExercise(log.exerciseId);
|
||||
log.exerciseBase = await _exercises.fetchAndSetExerciseBase(log.exerciseBaseId);
|
||||
|
||||
final plan = findById(log.workoutPlan);
|
||||
plan.logs.add(log);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:wger/models/exercises/exercise.dart';
|
||||
import 'package:wger/models/exercises/base.dart';
|
||||
import 'package:wger/widgets/exercises/exercises.dart';
|
||||
|
||||
class ExerciseDetailScreen extends StatelessWidget {
|
||||
@@ -27,15 +27,15 @@ class ExerciseDetailScreen extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final exercise = ModalRoute.of(context)!.settings.arguments as Exercise;
|
||||
final exerciseBase = ModalRoute.of(context)!.settings.arguments as ExerciseBase;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(exercise.name),
|
||||
title: Text(exerciseBase.getExercise(Localizations.localeOf(context).languageCode).name),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
child: ExerciseDetail(exercise),
|
||||
child: ExerciseDetail(exerciseBase),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -70,9 +70,8 @@ class _ExercisesList extends StatelessWidget {
|
||||
},
|
||||
itemCount: exerciseBaseList.length,
|
||||
itemBuilder: (context, index) {
|
||||
final exercise = exerciseBaseList[index];
|
||||
return ExerciseListTile(
|
||||
exercise: exercise.getExercises(Localizations.localeOf(context).languageCode),
|
||||
exerciseBase: exerciseBaseList[index],
|
||||
);
|
||||
|
||||
/*
|
||||
|
||||
@@ -43,7 +43,7 @@ class DuplicatesAndVariationsStepContent extends StatelessWidget {
|
||||
.map(
|
||||
(base) => Text(
|
||||
base
|
||||
.getExercises(
|
||||
.getExercise(
|
||||
Localizations.localeOf(context).languageCode)
|
||||
.name,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -77,7 +77,7 @@ class DuplicatesAndVariationsStepContent extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
base
|
||||
.getExercises(Localizations.localeOf(context).languageCode)
|
||||
.getExercise(Localizations.localeOf(context).languageCode)
|
||||
.name,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
|
||||
@@ -382,9 +382,9 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(s.exerciseObj.name),
|
||||
Text(s.exerciseBaseObj.name),
|
||||
const SizedBox(width: 10),
|
||||
MutedText(set.getSmartRepr(s.exerciseObj).join('\n')),
|
||||
MutedText(set.getSmartRepr(s.exerciseBaseObj).join('\n')),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
|
||||
@@ -23,6 +23,7 @@ import 'package:flutter_svg/svg.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:wger/helpers/consts.dart';
|
||||
import 'package:wger/helpers/i18n.dart';
|
||||
import 'package:wger/models/exercises/base.dart';
|
||||
import 'package:wger/models/exercises/exercise.dart';
|
||||
import 'package:wger/models/exercises/muscle.dart';
|
||||
import 'package:wger/providers/exercises.dart';
|
||||
@@ -32,13 +33,16 @@ import 'package:wger/widgets/exercises/list_tile.dart';
|
||||
import 'package:wger/widgets/exercises/videos.dart';
|
||||
|
||||
class ExerciseDetail extends StatelessWidget {
|
||||
final Exercise _exercise;
|
||||
final ExerciseBase _exerciseBase;
|
||||
late Exercise _exercise;
|
||||
static const PADDING = 9.0;
|
||||
|
||||
const ExerciseDetail(this._exercise);
|
||||
ExerciseDetail(this._exerciseBase);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_exercise = _exerciseBase.getExercise(Localizations.localeOf(context).languageCode);
|
||||
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -71,7 +75,7 @@ class ExerciseDetail extends StatelessWidget {
|
||||
|
||||
List<Widget> getVariations(BuildContext context) {
|
||||
final List<Widget> out = [];
|
||||
if (_exercise.baseObj.variationId == null) {
|
||||
if (_exerciseBase.variationId == null) {
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -80,14 +84,14 @@ class ExerciseDetail extends StatelessWidget {
|
||||
style: Theme.of(context).textTheme.headline5,
|
||||
));
|
||||
Provider.of<ExercisesProvider>(context, listen: false)
|
||||
.findExercisesByVariationId(
|
||||
_exercise.baseObj.variationId!,
|
||||
.findExerciseBasesByVariationId(
|
||||
_exerciseBase.variationId!,
|
||||
languageId: _exercise.languageId,
|
||||
exerciseIdToExclude: _exercise.id,
|
||||
exerciseIdToExclude: _exerciseBase.id,
|
||||
)
|
||||
.forEach((element) {
|
||||
out.add(ExerciseListTile(
|
||||
exercise: element,
|
||||
exerciseBase: element,
|
||||
));
|
||||
});
|
||||
|
||||
@@ -125,8 +129,8 @@ class ExerciseDetail extends StatelessWidget {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: PADDING),
|
||||
child: MuscleWidget(
|
||||
muscles: _exercise.muscles,
|
||||
musclesSecondary: _exercise.musclesSecondary,
|
||||
muscles: _exerciseBase.muscles,
|
||||
musclesSecondary: _exerciseBase.musclesSecondary,
|
||||
isFront: true,
|
||||
),
|
||||
),
|
||||
@@ -135,8 +139,8 @@ class ExerciseDetail extends StatelessWidget {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: PADDING),
|
||||
child: MuscleWidget(
|
||||
muscles: _exercise.muscles,
|
||||
musclesSecondary: _exercise.musclesSecondary,
|
||||
muscles: _exerciseBase.muscles,
|
||||
musclesSecondary: _exerciseBase.musclesSecondary,
|
||||
isFront: false,
|
||||
),
|
||||
),
|
||||
@@ -149,7 +153,7 @@ class ExerciseDetail extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const MuscleColorHelper(main: true),
|
||||
..._exercise.muscles.map((e) => Text(e.name)).toList(),
|
||||
..._exerciseBase.muscles.map((e) => Text(e.name)).toList(),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -159,7 +163,7 @@ class ExerciseDetail extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const MuscleColorHelper(main: false),
|
||||
..._exercise.musclesSecondary.map((e) => Text(e.name)).toList(),
|
||||
..._exerciseBase.musclesSecondary.map((e) => Text(e.name)).toList(),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -183,8 +187,8 @@ class ExerciseDetail extends StatelessWidget {
|
||||
List<Widget> getImages() {
|
||||
// TODO: add carousel for the other images
|
||||
final List<Widget> out = [];
|
||||
if (_exercise.getMainImage != null) {
|
||||
out.add(ExerciseImageWidget(image: _exercise.getMainImage));
|
||||
if (_exerciseBase.getMainImage != null) {
|
||||
out.add(ExerciseImageWidget(image: _exerciseBase.getMainImage));
|
||||
out.add(const SizedBox(height: PADDING));
|
||||
}
|
||||
|
||||
@@ -195,10 +199,10 @@ class ExerciseDetail extends StatelessWidget {
|
||||
final List<Widget> out = [];
|
||||
|
||||
out.add(
|
||||
Chip(label: Text(getTranslation(_exercise.baseObj.category.name, context))),
|
||||
Chip(label: Text(getTranslation(_exerciseBase.category.name, context))),
|
||||
);
|
||||
if (_exercise.baseObj.equipment.isNotEmpty) {
|
||||
_exercise.baseObj.equipment
|
||||
if (_exerciseBase.equipment.isNotEmpty) {
|
||||
_exerciseBase.equipment
|
||||
.map((e) => Chip(label: Text(getTranslation(e.name, context))))
|
||||
.forEach((element) {
|
||||
out.add(element);
|
||||
@@ -211,8 +215,8 @@ class ExerciseDetail extends StatelessWidget {
|
||||
List<Widget> getVideos() {
|
||||
// TODO: add carousel for the other videos
|
||||
final List<Widget> out = [];
|
||||
if (_exercise.baseObj.videos.isNotEmpty) {
|
||||
_exercise.baseObj.videos.map((v) => ExerciseVideoWidget(video: v)).forEach((element) {
|
||||
if (_exerciseBase.videos.isNotEmpty) {
|
||||
_exerciseBase.videos.map((v) => ExerciseVideoWidget(video: v)).forEach((element) {
|
||||
out.add(element);
|
||||
});
|
||||
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:wger/helpers/i18n.dart';
|
||||
import 'package:wger/models/exercises/exercise.dart';
|
||||
import 'package:wger/models/exercises/base.dart';
|
||||
import 'package:wger/screens/exercise_screen.dart';
|
||||
import 'package:wger/widgets/exercises/images.dart';
|
||||
|
||||
class ExerciseListTile extends StatelessWidget {
|
||||
const ExerciseListTile({Key? key, required this.exercise}) : super(key: key);
|
||||
const ExerciseListTile({Key? key, required this.exerciseBase}) : super(key: key);
|
||||
|
||||
final Exercise exercise;
|
||||
final ExerciseBase exerciseBase;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -44,23 +44,23 @@ class ExerciseListTile extends StatelessWidget {
|
||||
height: IMG_SIZE,
|
||||
width: IMG_SIZE,
|
||||
child: ExerciseImageWidget(
|
||||
image: exercise.getMainImage,
|
||||
image: exerciseBase.getMainImage,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
exercise.name,
|
||||
exerciseBase.getExercise(Localizations.localeOf(context).languageCode).name,
|
||||
//style: theme.textTheme.headline6,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
),
|
||||
subtitle: Text(
|
||||
'${getTranslation(exercise.category.name, context)} / ${exercise.equipment.map((e) => getTranslation(e.name, context)).toList().join(', ')}',
|
||||
'${getTranslation(exerciseBase.category.name, context)} / ${exerciseBase.equipment.map((e) => getTranslation(e.name, context)).toList().join(', ')}',
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, ExerciseDetailScreen.routeName, arguments: exercise);
|
||||
Navigator.pushNamed(context, ExerciseDetailScreen.routeName, arguments: exerciseBase);
|
||||
},
|
||||
/*
|
||||
trailing: Container(
|
||||
|
||||
@@ -50,7 +50,7 @@ class SettingWidget extends StatelessWidget {
|
||||
return ListTile(
|
||||
leading: InkWell(
|
||||
child: SizedBox(
|
||||
child: ExerciseImageWidget(image: setting.exerciseObj.getMainImage),
|
||||
child: ExerciseImageWidget(image: setting.exerciseBaseObj.getMainImage),
|
||||
width: 45,
|
||||
),
|
||||
onTap: () {
|
||||
@@ -58,8 +58,10 @@ class SettingWidget extends StatelessWidget {
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(setting.exerciseObj.name),
|
||||
content: ExerciseDetail(setting.exerciseObj),
|
||||
title: Text(setting.exerciseBaseObj
|
||||
.getExercise(Localizations.localeOf(context).languageCode)
|
||||
.name),
|
||||
content: ExerciseDetail(setting.exerciseBaseObj),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(MaterialLocalizations.of(context).closeButtonLabel),
|
||||
@@ -73,11 +75,12 @@ class SettingWidget extends StatelessWidget {
|
||||
);
|
||||
},
|
||||
),
|
||||
title: Text(setting.exerciseObj.name),
|
||||
title: Text(
|
||||
setting.exerciseBaseObj.getExercise(Localizations.localeOf(context).languageCode).name),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
...set.getSmartRepr(setting.exerciseObj).map((e) => Text(e)).toList(),
|
||||
...set.getSmartRepr(setting.exerciseBaseObj).map((e) => Text(e)).toList(),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -21,7 +21,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:wger/helpers/consts.dart';
|
||||
import 'package:wger/models/exercises/exercise.dart';
|
||||
import 'package:wger/models/exercises/base.dart';
|
||||
import 'package:wger/models/workouts/day.dart';
|
||||
import 'package:wger/models/workouts/repetition_unit.dart';
|
||||
import 'package:wger/models/workouts/set.dart';
|
||||
@@ -276,16 +276,16 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
final _exercisesController = TextEditingController();
|
||||
|
||||
/// Removes an exercise from the current set
|
||||
void removeExercise(Exercise exercise) {
|
||||
void removeExerciseBase(ExerciseBase base) {
|
||||
setState(() {
|
||||
widget._set.removeExercise(exercise);
|
||||
widget._set.removeExercise(base);
|
||||
});
|
||||
}
|
||||
|
||||
/// Adds an exercise to the current set
|
||||
void addExercise(Exercise exercise) {
|
||||
void addExercise(ExerciseBase base) {
|
||||
setState(() {
|
||||
widget._set.addExercise(exercise);
|
||||
widget._set.addExerciseBase(base);
|
||||
addSettings();
|
||||
});
|
||||
}
|
||||
@@ -294,12 +294,12 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
void addSettings() {
|
||||
widget._set.settings = [];
|
||||
int order = 0;
|
||||
for (final exercise in widget._set.exercisesObj) {
|
||||
for (final exercise in widget._set.exerciseBasesObj) {
|
||||
order++;
|
||||
for (int loop = 0; loop < widget._set.sets; loop++) {
|
||||
final Setting setting = Setting.empty();
|
||||
setting.order = order;
|
||||
setting.exercise = exercise;
|
||||
setting.exerciseBase = exercise;
|
||||
setting.weightUnit =
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false).defaultWeightUnit;
|
||||
setting.repetitionUnit =
|
||||
@@ -355,7 +355,7 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
child: Column(
|
||||
children: [
|
||||
Card(
|
||||
child: TypeAheadFormField<Exercise>(
|
||||
child: TypeAheadFormField<ExerciseBase>(
|
||||
key: const Key('field-typeahead'),
|
||||
textFieldConfiguration: TextFieldConfiguration(
|
||||
controller: _exercisesController,
|
||||
@@ -397,13 +397,15 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
Localizations.localeOf(context).languageCode,
|
||||
);
|
||||
},
|
||||
itemBuilder: (BuildContext context, Exercise exerciseSuggestion) {
|
||||
itemBuilder: (BuildContext context, ExerciseBase exerciseSuggestion) {
|
||||
return ListTile(
|
||||
leading: SizedBox(
|
||||
width: 45,
|
||||
child: ExerciseImageWidget(image: exerciseSuggestion.getMainImage),
|
||||
),
|
||||
title: Text(exerciseSuggestion.name),
|
||||
title: Text(exerciseSuggestion
|
||||
.getExercise(Localizations.localeOf(context).languageCode)
|
||||
.name),
|
||||
subtitle: Text(
|
||||
'${exerciseSuggestion.category.name} / ${exerciseSuggestion.equipment.map((e) => e.name).join(', ')}',
|
||||
),
|
||||
@@ -412,13 +414,13 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
transitionBuilder: (context, suggestionsBox, controller) {
|
||||
return suggestionsBox;
|
||||
},
|
||||
onSuggestionSelected: (Exercise exerciseSuggestion) {
|
||||
onSuggestionSelected: (ExerciseBase exerciseSuggestion) {
|
||||
addExercise(exerciseSuggestion);
|
||||
this._exercisesController.text = '';
|
||||
},
|
||||
validator: (value) {
|
||||
// At least one exercise must be selected
|
||||
if (widget._set.exercisesIds.isEmpty) {
|
||||
if (widget._set.exerciseBasesIds.isEmpty) {
|
||||
return AppLocalizations.of(context).selectExercise;
|
||||
}
|
||||
|
||||
@@ -453,12 +455,13 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
...widget._set.exercisesObj.asMap().entries.map((entry) {
|
||||
...widget._set.exerciseBasesObj.asMap().entries.map((entry) {
|
||||
final index = entry.key;
|
||||
final exercise = entry.value;
|
||||
final showSupersetInfo = (index + 1) < widget._set.exercisesObj.length;
|
||||
final settings =
|
||||
widget._set.settings.where((e) => e.exerciseObj.id == exercise.id).toList();
|
||||
final showSupersetInfo = (index + 1) < widget._set.exerciseBasesObj.length;
|
||||
final settings = widget._set.settings
|
||||
.where((e) => e.exerciseBaseObj.id == exercise.id)
|
||||
.toList();
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
@@ -467,7 +470,7 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
settings,
|
||||
_detailed,
|
||||
_currentSetSliderValue,
|
||||
removeExercise,
|
||||
removeExerciseBase,
|
||||
),
|
||||
if (showSupersetInfo)
|
||||
const Padding(
|
||||
@@ -530,14 +533,14 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
}
|
||||
|
||||
class ExerciseSetting extends StatelessWidget {
|
||||
final Exercise _exercise;
|
||||
final ExerciseBase _exerciseBase;
|
||||
late final int _numberOfSets;
|
||||
final bool _detailed;
|
||||
final Function removeExercise;
|
||||
final List<Setting> _settings;
|
||||
|
||||
ExerciseSetting(
|
||||
this._exercise,
|
||||
this._exerciseBase,
|
||||
this._settings,
|
||||
this._detailed,
|
||||
double sliderValue,
|
||||
@@ -630,16 +633,16 @@ class ExerciseSetting extends StatelessWidget {
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text(
|
||||
_exercise.name,
|
||||
_exerciseBase.getExercise(Localizations.localeOf(context).languageCode).name,
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
subtitle: Text(_exercise.category.name),
|
||||
subtitle: Text(_exerciseBase.category.name),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: ExerciseImageWidget(image: _exercise.getMainImage),
|
||||
leading: ExerciseImageWidget(image: _exerciseBase.getMainImage),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.delete),
|
||||
onPressed: () {
|
||||
removeExercise(_exercise);
|
||||
removeExercise(_exerciseBase);
|
||||
}),
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
@@ -29,7 +29,7 @@ import 'package:wger/helpers/i18n.dart';
|
||||
import 'package:wger/helpers/json.dart';
|
||||
import 'package:wger/helpers/misc.dart';
|
||||
import 'package:wger/helpers/ui.dart';
|
||||
import 'package:wger/models/exercises/exercise.dart';
|
||||
import 'package:wger/models/exercises/base.dart';
|
||||
import 'package:wger/models/workouts/day.dart';
|
||||
import 'package:wger/models/workouts/log.dart';
|
||||
import 'package:wger/models/workouts/session.dart';
|
||||
@@ -85,11 +85,11 @@ class _GymModeState extends State<GymMode> {
|
||||
for (final set in widget._workoutDay.sets) {
|
||||
var firstPage = true;
|
||||
for (final setting in set.settingsComputed) {
|
||||
final exercise = Provider.of<ExercisesProvider>(context, listen: false)
|
||||
.findExerciseById(setting.exerciseId);
|
||||
final exerciseBase = Provider.of<ExercisesProvider>(context, listen: false)
|
||||
.findExerciseBaseById(setting.exerciseBaseId);
|
||||
|
||||
if (firstPage) {
|
||||
_exercisePages[exercise.name] = currentPage;
|
||||
_exercisePages[exerciseBase.uuid!] = currentPage;
|
||||
currentPage++;
|
||||
}
|
||||
|
||||
@@ -114,13 +114,13 @@ class _GymModeState extends State<GymMode> {
|
||||
var firstPage = true;
|
||||
for (final setting in set.settingsComputed) {
|
||||
final ratioCompleted = currentElement / _totalElements;
|
||||
final exercise = exerciseProvider.findExerciseById(setting.exerciseId);
|
||||
final exerciseBase = exerciseProvider.findExerciseBaseById(setting.exerciseBaseId);
|
||||
currentElement++;
|
||||
|
||||
if (firstPage) {
|
||||
out.add(ExerciseOverview(
|
||||
_controller,
|
||||
exercise,
|
||||
exerciseBase,
|
||||
ratioCompleted,
|
||||
_exercisePages,
|
||||
));
|
||||
@@ -130,7 +130,7 @@ class _GymModeState extends State<GymMode> {
|
||||
_controller,
|
||||
setting,
|
||||
set,
|
||||
exercise,
|
||||
exerciseBase,
|
||||
workoutProvider.findById(widget._workoutDay.workoutId),
|
||||
ratioCompleted,
|
||||
_exercisePages,
|
||||
@@ -194,10 +194,12 @@ class StartPage extends StatelessWidget {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
s.exerciseObj.name,
|
||||
s.exerciseBaseObj
|
||||
.getExercise(Localizations.localeOf(context).languageCode)
|
||||
.name,
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
...set.getSmartRepr(s.exerciseObj).map((e) => Text(e)).toList(),
|
||||
...set.getSmartRepr(s.exerciseBaseObj).map((e) => Text(e)).toList(),
|
||||
const SizedBox(height: 15),
|
||||
],
|
||||
);
|
||||
@@ -230,7 +232,7 @@ class LogPage extends StatefulWidget {
|
||||
final PageController _controller;
|
||||
final Setting _setting;
|
||||
final Set _set;
|
||||
final Exercise _exercise;
|
||||
final ExerciseBase _exerciseBase;
|
||||
final WorkoutPlan _workoutPlan;
|
||||
final double _ratioCompleted;
|
||||
final Map<String, int> _exercisePages;
|
||||
@@ -240,14 +242,14 @@ class LogPage extends StatefulWidget {
|
||||
this._controller,
|
||||
this._setting,
|
||||
this._set,
|
||||
this._exercise,
|
||||
this._exerciseBase,
|
||||
this._workoutPlan,
|
||||
this._ratioCompleted,
|
||||
this._exercisePages,
|
||||
) {
|
||||
_log.date = DateTime.now();
|
||||
_log.workoutPlan = _workoutPlan.id!;
|
||||
_log.exercise = _exercise;
|
||||
_log.exerciseBase = _exerciseBase;
|
||||
_log.weightUnit = _setting.weightUnitObj;
|
||||
_log.repetitionUnit = _setting.repetitionUnitObj;
|
||||
_log.rir = _setting.rir;
|
||||
@@ -524,7 +526,9 @@ class _LogPageState extends State<LogPage> {
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
...widget._workoutPlan.filterLogsByExercise(widget._exercise, unique: true).map((log) {
|
||||
...widget._workoutPlan
|
||||
.filterLogsByExerciseBase(widget._exerciseBase, unique: true)
|
||||
.map((log) {
|
||||
return ListTile(
|
||||
title: Text(log.singleLogRepTextNoNl),
|
||||
subtitle:
|
||||
@@ -618,7 +622,7 @@ class _LogPageState extends State<LogPage> {
|
||||
return Column(
|
||||
children: [
|
||||
NavigationHeader(
|
||||
widget._exercise.name,
|
||||
widget._exerciseBase.getExercise(Localizations.localeOf(context).languageCode).name,
|
||||
widget._controller,
|
||||
exercisePages: widget._exercisePages,
|
||||
),
|
||||
@@ -636,11 +640,11 @@ class _LogPageState extends State<LogPage> {
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Expanded(
|
||||
child: (widget._workoutPlan.filterLogsByExercise(widget._exercise).isNotEmpty)
|
||||
child: (widget._workoutPlan.filterLogsByExerciseBase(widget._exerciseBase).isNotEmpty)
|
||||
? getPastLogs()
|
||||
: Container()),
|
||||
// Only show calculator for barbell
|
||||
if (widget._log.exerciseObj.equipment.map((e) => e.id).contains(ID_EQUIPMENT_BARBELL))
|
||||
if (widget._log.exerciseBaseObj.equipment.map((e) => e.id).contains(ID_EQUIPMENT_BARBELL))
|
||||
getPlates(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
@@ -657,13 +661,13 @@ class _LogPageState extends State<LogPage> {
|
||||
|
||||
class ExerciseOverview extends StatelessWidget {
|
||||
final PageController _controller;
|
||||
final Exercise _exercise;
|
||||
final ExerciseBase _exerciseBase;
|
||||
final double _ratioCompleted;
|
||||
final Map<String, int> _exercisePages;
|
||||
|
||||
const ExerciseOverview(
|
||||
this._controller,
|
||||
this._exercise,
|
||||
this._exerciseBase,
|
||||
this._ratioCompleted,
|
||||
this._exercisePages,
|
||||
);
|
||||
@@ -673,7 +677,7 @@ class ExerciseOverview extends StatelessWidget {
|
||||
return Column(
|
||||
children: [
|
||||
NavigationHeader(
|
||||
_exercise.name,
|
||||
_exerciseBase.getExercise(Localizations.localeOf(context).languageCode).name,
|
||||
_controller,
|
||||
exercisePages: _exercisePages,
|
||||
),
|
||||
@@ -683,29 +687,32 @@ class ExerciseOverview extends StatelessWidget {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
children: [
|
||||
Text(
|
||||
getTranslation(_exercise.category.name, context),
|
||||
getTranslation(_exerciseBase.category.name, context),
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
..._exercise.equipment
|
||||
..._exerciseBase.equipment
|
||||
.map((e) => Text(
|
||||
getTranslation(e.name, context),
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
textAlign: TextAlign.center,
|
||||
))
|
||||
.toList(),
|
||||
if (_exercise.images.isNotEmpty)
|
||||
if (_exerciseBase.images.isNotEmpty)
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 200,
|
||||
child: ListView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: [
|
||||
..._exercise.images.map((e) => ExerciseImageWidget(image: e)).toList(),
|
||||
..._exerciseBase.images.map((e) => ExerciseImageWidget(image: e)).toList(),
|
||||
],
|
||||
),
|
||||
),
|
||||
Html(data: _exercise.description),
|
||||
Html(
|
||||
data: _exerciseBase
|
||||
.getExercise(Localizations.localeOf(context).languageCode)
|
||||
.description),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -212,7 +212,7 @@ main() {
|
||||
|
||||
// assert
|
||||
verifyNever(provider.baseProvider.fetch(tSearchByNameUri));
|
||||
expect(provider.filteredExerciseBases, [data.getTestExercises()[0].baseObj]);
|
||||
expect(provider.filteredExerciseBases, [data.getTestExerciseBases()[0]]);
|
||||
});
|
||||
|
||||
test('A muscle is selected with no search term. Should not find results', () async {
|
||||
|
||||
@@ -38,7 +38,7 @@ void main() {
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
navigatorKey: GlobalKey<NavigatorState>(),
|
||||
home: Scaffold(
|
||||
body: ExerciseDetail(getTestExercises()[0]),
|
||||
body: ExerciseDetail(getTestExerciseBases()[0]),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -64,10 +64,8 @@ void main() {
|
||||
reason: 'Two diagrams, one for front, one for the back',
|
||||
);
|
||||
expect(find.text('Booty'), findsOneWidget, reason: 'Secondary muscles');
|
||||
|
||||
expect(find.text('Description'), findsOneWidget, reason: 'Description header');
|
||||
expect(find.text('add clever text'), findsOneWidget, reason: 'Description');
|
||||
|
||||
expect(find.text('Lorem ipsum etc'), findsOneWidget, reason: 'Description');
|
||||
expect(find.text('Variations'), findsNothing);
|
||||
});
|
||||
}
|
||||
|
||||
2
test/fixtures/exercise_search_entries.json
vendored
2
test/fixtures/exercise_search_entries.json
vendored
@@ -4,6 +4,7 @@
|
||||
"value": "Bench Press Narrow Grip",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"base_id": 1,
|
||||
"name": "test exercise 1",
|
||||
"category": "Arms",
|
||||
"image": "/media/exercise-images/76/Narrow-grip-bench-press-2.png",
|
||||
@@ -14,6 +15,7 @@
|
||||
"value": "Close-grip Bench Press",
|
||||
"data": {
|
||||
"id": 2,
|
||||
"base_id": 2,
|
||||
"name": "test exercise 2",
|
||||
"category": "Arms",
|
||||
"image": null,
|
||||
|
||||
@@ -15,8 +15,8 @@ import 'package:wger/models/nutrition/nutritional_plan.dart';
|
||||
import 'package:wger/providers/nutrition.dart';
|
||||
import 'package:wger/screens/nutritional_plan_screen.dart';
|
||||
import 'package:wger/widgets/nutrition/forms.dart';
|
||||
import '../../test_data/nutritional_plans.dart';
|
||||
|
||||
import '../../test_data/nutritional_plans.dart';
|
||||
import '../fixtures/fixture_reader.dart';
|
||||
import '../other/base_provider_test.mocks.dart';
|
||||
import '../utils.dart';
|
||||
@@ -49,20 +49,14 @@ void main() {
|
||||
final Uri tUriEmptyCode = Uri.parse('https://localhost/api/v2/ingredient/?code=\"%20\"');
|
||||
final Uri tUriBadCode = Uri.parse('https://localhost/api/v2/ingredient/?code=222');
|
||||
|
||||
when(client
|
||||
.get(tUriRightCode, headers: {'authorization': 'Token FooBar', 'user-agent': 'wger App'}))
|
||||
.thenAnswer(
|
||||
(_) => Future.value(http.Response(fixture('search_ingredient_right_code.json'), 200)));
|
||||
when(client.get(tUriRightCode, headers: anyNamed('headers'))).thenAnswer(
|
||||
(_) => Future.value(http.Response(fixture('search_ingredient_right_code.json'), 200)));
|
||||
|
||||
when(client
|
||||
.get(tUriEmptyCode, headers: {'authorization': 'Token FooBar', 'user-agent': 'wger App'}))
|
||||
.thenAnswer(
|
||||
(_) => Future.value(http.Response(fixture('search_ingredient_wrong_code.json'), 200)));
|
||||
when(client.get(tUriEmptyCode, headers: anyNamed('headers'))).thenAnswer(
|
||||
(_) => Future.value(http.Response(fixture('search_ingredient_wrong_code.json'), 200)));
|
||||
|
||||
when(client
|
||||
.get(tUriBadCode, headers: {'authorization': 'Token FooBar', 'user-agent': 'wger App'}))
|
||||
.thenAnswer(
|
||||
(_) => Future.value(http.Response(fixture('search_ingredient_wrong_code.json'), 200)));
|
||||
when(client.get(tUriBadCode, headers: anyNamed('headers'))).thenAnswer(
|
||||
(_) => Future.value(http.Response(fixture('search_ingredient_wrong_code.json'), 200)));
|
||||
|
||||
setUp(() {
|
||||
plan1 = getNutritionalPlan();
|
||||
|
||||
@@ -45,9 +45,11 @@ void main() {
|
||||
final mockExerciseProvider = MockExercisesProvider();
|
||||
final WorkoutPlan workoutPlan = getWorkout();
|
||||
|
||||
when(mockExerciseProvider.findExerciseById(1)).thenReturn(getTestExercises()[0]);
|
||||
when(mockExerciseProvider.findExerciseById(2)).thenReturn(getTestExercises()[1]);
|
||||
when(mockExerciseProvider.findExerciseById(3)).thenReturn(getTestExercises()[2]);
|
||||
final bases = getTestExerciseBases();
|
||||
|
||||
when(mockExerciseProvider.findExerciseBaseById(1)).thenReturn(bases[0]);
|
||||
when(mockExerciseProvider.findExerciseBaseById(2)).thenReturn(bases[1]);
|
||||
when(mockExerciseProvider.findExerciseBaseById(3)).thenReturn(bases[2]);
|
||||
|
||||
return ChangeNotifierProvider<WorkoutPlansProvider>(
|
||||
create: (context) => WorkoutPlansProvider(
|
||||
@@ -90,7 +92,7 @@ void main() {
|
||||
//
|
||||
expect(find.byType(StartPage), findsOneWidget);
|
||||
expect(find.text('Your workout today'), findsOneWidget);
|
||||
expect(find.text('test exercise 1'), findsOneWidget);
|
||||
expect(find.text('test exercise 2'), findsOneWidget);
|
||||
expect(find.byIcon(Icons.close), findsOneWidget);
|
||||
expect(find.byIcon(Icons.menu), findsOneWidget);
|
||||
expect(find.byIcon(Icons.chevron_left), findsNothing);
|
||||
@@ -101,7 +103,7 @@ void main() {
|
||||
//
|
||||
// Exercise overview page
|
||||
//
|
||||
expect(find.text('test exercise 1'), findsOneWidget);
|
||||
expect(find.text('test exercise 2'), findsOneWidget);
|
||||
expect(find.byType(ExerciseOverview), findsOneWidget);
|
||||
expect(find.byIcon(Icons.close), findsOneWidget);
|
||||
expect(find.byIcon(Icons.menu), findsOneWidget);
|
||||
@@ -113,7 +115,7 @@ void main() {
|
||||
//
|
||||
// Log
|
||||
//
|
||||
expect(find.text('test exercise 1'), findsOneWidget);
|
||||
expect(find.text('test exercise 2'), findsOneWidget);
|
||||
expect(find.byType(LogPage), findsOneWidget);
|
||||
expect(find.byType(Form), findsOneWidget);
|
||||
expect(find.byType(ListTile), findsNWidgets(3), reason: 'Two logs and the switch tile');
|
||||
@@ -156,7 +158,7 @@ void main() {
|
||||
//
|
||||
// Log
|
||||
//
|
||||
expect(find.text('test exercise 1'), findsOneWidget);
|
||||
expect(find.text('test exercise 2'), findsOneWidget);
|
||||
expect(find.byType(LogPage), findsOneWidget);
|
||||
expect(find.byType(Form), findsOneWidget);
|
||||
await tester.drag(find.byType(LogPage), const Offset(-500.0, 0.0));
|
||||
|
||||
@@ -39,7 +39,7 @@ void main() {
|
||||
final setting1 = Setting(
|
||||
setId: 1,
|
||||
order: 1,
|
||||
exerciseId: 1,
|
||||
exerciseBaseId: 1,
|
||||
repetitionUnitId: 1,
|
||||
reps: 2,
|
||||
weightUnitId: 1,
|
||||
|
||||
@@ -25,7 +25,7 @@ void main() {
|
||||
test('Repetitions and weigh units', () async {
|
||||
final workout = getWorkout();
|
||||
final set = workout.days.first.sets.first;
|
||||
final exercise1 = set.exercisesObj[0];
|
||||
final exercise1 = set.exerciseBasesObj[0];
|
||||
|
||||
expect(set.getSmartTextRepr(exercise1), '2 × 10 kg (2 RiR)');
|
||||
});
|
||||
|
||||
@@ -39,7 +39,7 @@ void main() {
|
||||
final setting1 = Setting(
|
||||
setId: 1,
|
||||
order: 1,
|
||||
exerciseId: 1,
|
||||
exerciseBaseId: 1,
|
||||
repetitionUnitId: 1,
|
||||
reps: 2,
|
||||
weightUnitId: 1,
|
||||
|
||||
@@ -28,7 +28,7 @@ void main() {
|
||||
log1 = Log(
|
||||
id: 123,
|
||||
workoutPlan: 100,
|
||||
exerciseId: 1,
|
||||
exerciseBaseId: 1,
|
||||
reps: 10,
|
||||
rir: '1.5',
|
||||
repetitionUnitId: 1,
|
||||
@@ -39,7 +39,7 @@ void main() {
|
||||
log2 = Log(
|
||||
id: 9,
|
||||
workoutPlan: 42,
|
||||
exerciseId: 1,
|
||||
exerciseBaseId: 1,
|
||||
reps: 10,
|
||||
rir: '1.5',
|
||||
repetitionUnitId: 1,
|
||||
|
||||
@@ -27,16 +27,16 @@ void main() {
|
||||
final workout = getWorkout();
|
||||
|
||||
expect(workout.logs.length, 3);
|
||||
final logExercise1 = workout.filterLogsByExercise(getTestExercises()[0]);
|
||||
final logExercise1 = workout.filterLogsByExerciseBase(getTestExerciseBases()[0]);
|
||||
expect(logExercise1.length, 2);
|
||||
expect(logExercise1[0].id, 1);
|
||||
expect(logExercise1[1].id, 2);
|
||||
|
||||
final logExercise2 = workout.filterLogsByExercise(getTestExercises()[1]);
|
||||
final logExercise2 = workout.filterLogsByExerciseBase(getTestExerciseBases()[1]);
|
||||
expect(logExercise2.length, 1);
|
||||
expect(logExercise2[0].id, 3);
|
||||
|
||||
expect(workout.filterLogsByExercise(getTestExercises()[2]).length, 0);
|
||||
expect(workout.filterLogsByExerciseBase(getTestExerciseBases()[2]).length, 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,14 +6,14 @@ import 'dart:async' as _i10;
|
||||
import 'dart:ui' as _i11;
|
||||
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:wger/models/exercises/base.dart' as _i9;
|
||||
import 'package:wger/models/exercises/category.dart' as _i4;
|
||||
import 'package:wger/models/exercises/equipment.dart' as _i5;
|
||||
import 'package:wger/models/exercises/base.dart' as _i4;
|
||||
import 'package:wger/models/exercises/category.dart' as _i5;
|
||||
import 'package:wger/models/exercises/equipment.dart' as _i6;
|
||||
import 'package:wger/models/exercises/exercise.dart' as _i3;
|
||||
import 'package:wger/models/exercises/language.dart' as _i7;
|
||||
import 'package:wger/models/exercises/muscle.dart' as _i6;
|
||||
import 'package:wger/models/exercises/language.dart' as _i8;
|
||||
import 'package:wger/models/exercises/muscle.dart' as _i7;
|
||||
import 'package:wger/providers/base_provider.dart' as _i2;
|
||||
import 'package:wger/providers/exercises.dart' as _i8;
|
||||
import 'package:wger/providers/exercises.dart' as _i9;
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: avoid_redundant_argument_values
|
||||
@@ -30,19 +30,21 @@ class _FakeWgerBaseProvider_0 extends _i1.Fake implements _i2.WgerBaseProvider {
|
||||
|
||||
class _FakeExercise_1 extends _i1.Fake implements _i3.Exercise {}
|
||||
|
||||
class _FakeExerciseCategory_2 extends _i1.Fake implements _i4.ExerciseCategory {
|
||||
class _FakeExerciseBase_2 extends _i1.Fake implements _i4.ExerciseBase {}
|
||||
|
||||
class _FakeExerciseCategory_3 extends _i1.Fake implements _i5.ExerciseCategory {
|
||||
}
|
||||
|
||||
class _FakeEquipment_3 extends _i1.Fake implements _i5.Equipment {}
|
||||
class _FakeEquipment_4 extends _i1.Fake implements _i6.Equipment {}
|
||||
|
||||
class _FakeMuscle_4 extends _i1.Fake implements _i6.Muscle {}
|
||||
class _FakeMuscle_5 extends _i1.Fake implements _i7.Muscle {}
|
||||
|
||||
class _FakeLanguage_5 extends _i1.Fake implements _i7.Language {}
|
||||
class _FakeLanguage_6 extends _i1.Fake implements _i8.Language {}
|
||||
|
||||
/// A class which mocks [ExercisesProvider].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockExercisesProvider extends _i1.Mock implements _i8.ExercisesProvider {
|
||||
class MockExercisesProvider extends _i1.Mock implements _i9.ExercisesProvider {
|
||||
MockExercisesProvider() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
@@ -52,7 +54,7 @@ class MockExercisesProvider extends _i1.Mock implements _i8.ExercisesProvider {
|
||||
(super.noSuchMethod(Invocation.getter(#baseProvider),
|
||||
returnValue: _FakeWgerBaseProvider_0()) as _i2.WgerBaseProvider);
|
||||
@override
|
||||
set exerciseBases(List<_i9.ExerciseBase>? exercisesBases) =>
|
||||
set exerciseBases(List<_i4.ExerciseBase>? exercisesBases) =>
|
||||
super.noSuchMethod(Invocation.setter(#exerciseBases, exercisesBases),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
@@ -60,48 +62,48 @@ class MockExercisesProvider extends _i1.Mock implements _i8.ExercisesProvider {
|
||||
super.noSuchMethod(Invocation.setter(#exercises, exercises),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
List<_i9.ExerciseBase> get filteredExerciseBases =>
|
||||
List<_i4.ExerciseBase> get filteredExerciseBases =>
|
||||
(super.noSuchMethod(Invocation.getter(#filteredExerciseBases),
|
||||
returnValue: <_i9.ExerciseBase>[]) as List<_i9.ExerciseBase>);
|
||||
returnValue: <_i4.ExerciseBase>[]) as List<_i4.ExerciseBase>);
|
||||
@override
|
||||
set filteredExerciseBases(List<_i9.ExerciseBase>? newFilteredExercises) =>
|
||||
set filteredExerciseBases(List<_i4.ExerciseBase>? newFilteredExercises) =>
|
||||
super.noSuchMethod(
|
||||
Invocation.setter(#filteredExerciseBases, newFilteredExercises),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
Map<int, List<_i9.ExerciseBase>> get exerciseBasesByVariation =>
|
||||
Map<int, List<_i4.ExerciseBase>> get exerciseBasesByVariation =>
|
||||
(super.noSuchMethod(Invocation.getter(#exerciseBasesByVariation),
|
||||
returnValue: <int, List<_i9.ExerciseBase>>{})
|
||||
as Map<int, List<_i9.ExerciseBase>>);
|
||||
returnValue: <int, List<_i4.ExerciseBase>>{})
|
||||
as Map<int, List<_i4.ExerciseBase>>);
|
||||
@override
|
||||
List<_i3.Exercise> get items => (super.noSuchMethod(Invocation.getter(#items),
|
||||
returnValue: <_i3.Exercise>[]) as List<_i3.Exercise>);
|
||||
@override
|
||||
List<_i9.ExerciseBase> get bases =>
|
||||
List<_i4.ExerciseBase> get bases =>
|
||||
(super.noSuchMethod(Invocation.getter(#bases),
|
||||
returnValue: <_i9.ExerciseBase>[]) as List<_i9.ExerciseBase>);
|
||||
returnValue: <_i4.ExerciseBase>[]) as List<_i4.ExerciseBase>);
|
||||
@override
|
||||
List<_i4.ExerciseCategory> get categories =>
|
||||
List<_i5.ExerciseCategory> get categories =>
|
||||
(super.noSuchMethod(Invocation.getter(#categories),
|
||||
returnValue: <_i4.ExerciseCategory>[]) as List<_i4.ExerciseCategory>);
|
||||
returnValue: <_i5.ExerciseCategory>[]) as List<_i5.ExerciseCategory>);
|
||||
@override
|
||||
List<_i6.Muscle> get muscles =>
|
||||
List<_i7.Muscle> get muscles =>
|
||||
(super.noSuchMethod(Invocation.getter(#muscles),
|
||||
returnValue: <_i6.Muscle>[]) as List<_i6.Muscle>);
|
||||
returnValue: <_i7.Muscle>[]) as List<_i7.Muscle>);
|
||||
@override
|
||||
List<_i5.Equipment> get equipment =>
|
||||
List<_i6.Equipment> get equipment =>
|
||||
(super.noSuchMethod(Invocation.getter(#equipment),
|
||||
returnValue: <_i5.Equipment>[]) as List<_i5.Equipment>);
|
||||
returnValue: <_i6.Equipment>[]) as List<_i6.Equipment>);
|
||||
@override
|
||||
List<_i7.Language> get languages =>
|
||||
List<_i8.Language> get languages =>
|
||||
(super.noSuchMethod(Invocation.getter(#languages),
|
||||
returnValue: <_i7.Language>[]) as List<_i7.Language>);
|
||||
returnValue: <_i8.Language>[]) as List<_i8.Language>);
|
||||
@override
|
||||
bool get hasListeners =>
|
||||
(super.noSuchMethod(Invocation.getter(#hasListeners), returnValue: false)
|
||||
as bool);
|
||||
@override
|
||||
_i10.Future<void> setFilters(_i8.Filters? newFilters) => (super.noSuchMethod(
|
||||
_i10.Future<void> setFilters(_i9.Filters? newFilters) => (super.noSuchMethod(
|
||||
Invocation.method(#setFilters, [newFilters]),
|
||||
returnValue: Future<void>.value(),
|
||||
returnValueForMissingStub: Future<void>.value()) as _i10.Future<void>);
|
||||
@@ -114,40 +116,44 @@ class MockExercisesProvider extends _i1.Mock implements _i8.ExercisesProvider {
|
||||
void clear() => super.noSuchMethod(Invocation.method(#clear, []),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
List<_i3.Exercise> findByCategory(_i4.ExerciseCategory? category) =>
|
||||
List<_i4.ExerciseBase> findByCategory(_i5.ExerciseCategory? category) =>
|
||||
(super.noSuchMethod(Invocation.method(#findByCategory, [category]),
|
||||
returnValue: <_i3.Exercise>[]) as List<_i3.Exercise>);
|
||||
returnValue: <_i4.ExerciseBase>[]) as List<_i4.ExerciseBase>);
|
||||
@override
|
||||
_i3.Exercise findExerciseById(int? id) =>
|
||||
(super.noSuchMethod(Invocation.method(#findExerciseById, [id]),
|
||||
returnValue: _FakeExercise_1()) as _i3.Exercise);
|
||||
@override
|
||||
List<_i3.Exercise> findExercisesByVariationId(int? id,
|
||||
_i4.ExerciseBase findExerciseBaseById(int? id) =>
|
||||
(super.noSuchMethod(Invocation.method(#findExerciseBaseById, [id]),
|
||||
returnValue: _FakeExerciseBase_2()) as _i4.ExerciseBase);
|
||||
@override
|
||||
List<_i4.ExerciseBase> findExerciseBasesByVariationId(int? id,
|
||||
{int? exerciseIdToExclude, int? languageId}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#findExercisesByVariationId, [
|
||||
Invocation.method(#findExerciseBasesByVariationId, [
|
||||
id
|
||||
], {
|
||||
#exerciseIdToExclude: exerciseIdToExclude,
|
||||
#languageId: languageId
|
||||
}),
|
||||
returnValue: <_i3.Exercise>[]) as List<_i3.Exercise>);
|
||||
returnValue: <_i4.ExerciseBase>[]) as List<_i4.ExerciseBase>);
|
||||
@override
|
||||
_i4.ExerciseCategory findCategoryById(int? id) =>
|
||||
_i5.ExerciseCategory findCategoryById(int? id) =>
|
||||
(super.noSuchMethod(Invocation.method(#findCategoryById, [id]),
|
||||
returnValue: _FakeExerciseCategory_2()) as _i4.ExerciseCategory);
|
||||
returnValue: _FakeExerciseCategory_3()) as _i5.ExerciseCategory);
|
||||
@override
|
||||
_i5.Equipment findEquipmentById(int? id) =>
|
||||
_i6.Equipment findEquipmentById(int? id) =>
|
||||
(super.noSuchMethod(Invocation.method(#findEquipmentById, [id]),
|
||||
returnValue: _FakeEquipment_3()) as _i5.Equipment);
|
||||
returnValue: _FakeEquipment_4()) as _i6.Equipment);
|
||||
@override
|
||||
_i6.Muscle findMuscleById(int? id) =>
|
||||
_i7.Muscle findMuscleById(int? id) =>
|
||||
(super.noSuchMethod(Invocation.method(#findMuscleById, [id]),
|
||||
returnValue: _FakeMuscle_4()) as _i6.Muscle);
|
||||
returnValue: _FakeMuscle_5()) as _i7.Muscle);
|
||||
@override
|
||||
_i7.Language findLanguageById(int? id) =>
|
||||
_i8.Language findLanguageById(int? id) =>
|
||||
(super.noSuchMethod(Invocation.method(#findLanguageById, [id]),
|
||||
returnValue: _FakeLanguage_5()) as _i7.Language);
|
||||
returnValue: _FakeLanguage_6()) as _i8.Language);
|
||||
@override
|
||||
_i10.Future<void> fetchAndSetCategories() => (super.noSuchMethod(
|
||||
Invocation.method(#fetchAndSetCategories, []),
|
||||
@@ -179,23 +185,30 @@ class MockExercisesProvider extends _i1.Mock implements _i8.ExercisesProvider {
|
||||
returnValue: Future<_i3.Exercise>.value(_FakeExercise_1()))
|
||||
as _i10.Future<_i3.Exercise>);
|
||||
@override
|
||||
_i10.Future<_i4.ExerciseBase> fetchAndSetExerciseBase(int? exerciseBaseId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#fetchAndSetExerciseBase, [exerciseBaseId]),
|
||||
returnValue:
|
||||
Future<_i4.ExerciseBase>.value(_FakeExerciseBase_2()))
|
||||
as _i10.Future<_i4.ExerciseBase>);
|
||||
@override
|
||||
_i10.Future<void> checkExerciseCacheVersion() => (super.noSuchMethod(
|
||||
Invocation.method(#checkExerciseCacheVersion, []),
|
||||
returnValue: Future<void>.value(),
|
||||
returnValueForMissingStub: Future<void>.value()) as _i10.Future<void>);
|
||||
@override
|
||||
List<_i9.ExerciseBase> mapImages(
|
||||
dynamic data, List<_i9.ExerciseBase>? bases) =>
|
||||
List<_i4.ExerciseBase> mapImages(
|
||||
dynamic data, List<_i4.ExerciseBase>? bases) =>
|
||||
(super.noSuchMethod(Invocation.method(#mapImages, [data, bases]),
|
||||
returnValue: <_i9.ExerciseBase>[]) as List<_i9.ExerciseBase>);
|
||||
returnValue: <_i4.ExerciseBase>[]) as List<_i4.ExerciseBase>);
|
||||
@override
|
||||
List<_i9.ExerciseBase> setBaseData(
|
||||
List<_i4.ExerciseBase> setBaseData(
|
||||
dynamic data, List<_i3.Exercise>? exercises) =>
|
||||
(super.noSuchMethod(Invocation.method(#setBaseData, [data, exercises]),
|
||||
returnValue: <_i9.ExerciseBase>[]) as List<_i9.ExerciseBase>);
|
||||
returnValue: <_i4.ExerciseBase>[]) as List<_i4.ExerciseBase>);
|
||||
@override
|
||||
List<dynamic> mapBases(
|
||||
List<_i9.ExerciseBase>? bases, List<_i3.Exercise>? exercises) =>
|
||||
List<_i4.ExerciseBase>? bases, List<_i3.Exercise>? exercises) =>
|
||||
(super.noSuchMethod(Invocation.method(#mapBases, [bases, exercises]),
|
||||
returnValue: <dynamic>[]) as List<dynamic>);
|
||||
@override
|
||||
@@ -216,12 +229,13 @@ class MockExercisesProvider extends _i1.Mock implements _i8.ExercisesProvider {
|
||||
returnValue: Future<void>.value(),
|
||||
returnValueForMissingStub: Future<void>.value()) as _i10.Future<void>);
|
||||
@override
|
||||
_i10.Future<List<_i3.Exercise>> searchExercise(String? name,
|
||||
_i10.Future<List<_i4.ExerciseBase>> searchExercise(String? name,
|
||||
[String? languageCode = r'en']) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#searchExercise, [name, languageCode]),
|
||||
returnValue: Future<List<_i3.Exercise>>.value(<_i3.Exercise>[]))
|
||||
as _i10.Future<List<_i3.Exercise>>);
|
||||
returnValue:
|
||||
Future<List<_i4.ExerciseBase>>.value(<_i4.ExerciseBase>[]))
|
||||
as _i10.Future<List<_i4.ExerciseBase>>);
|
||||
@override
|
||||
void addListener(_i11.VoidCallback? listener) =>
|
||||
super.noSuchMethod(Invocation.method(#addListener, [listener]),
|
||||
|
||||
@@ -25,6 +25,7 @@ import 'package:wger/models/exercises/muscle.dart';
|
||||
|
||||
const tLanguage1 = Language(id: 1, shortName: 'de', fullName: 'Deutsch');
|
||||
const tLanguage2 = Language(id: 2, shortName: 'en', fullName: 'English');
|
||||
const tLanguage3 = Language(id: 3, shortName: 'fr', fullName: 'Français');
|
||||
|
||||
const tMuscle1 = Muscle(id: 1, name: 'Flutterus maximus', isFront: true);
|
||||
const tMuscle2 = Muscle(id: 2, name: 'Biceps', isFront: true);
|
||||
@@ -41,7 +42,7 @@ const tEquipment3 = Equipment(id: 2, name: 'Matress');
|
||||
|
||||
final tBase1 = ExerciseBase(
|
||||
id: 1,
|
||||
uuid: 'uuid1',
|
||||
uuid: '364f196c-881b-4839-8bfc-9e8f651521b6',
|
||||
creationDate: DateTime(2021, 09, 01),
|
||||
updateDate: DateTime(2021, 09, 10),
|
||||
category: tCategory1,
|
||||
@@ -52,7 +53,7 @@ final tBase1 = ExerciseBase(
|
||||
|
||||
final tBase2 = ExerciseBase(
|
||||
id: 2,
|
||||
uuid: 'uuid2',
|
||||
uuid: '82415754-fc4c-49ea-8ca7-1516dd36d5a0',
|
||||
creationDate: DateTime(2021, 08, 01),
|
||||
updateDate: DateTime(2021, 08, 10),
|
||||
category: tCategory2,
|
||||
@@ -63,7 +64,7 @@ final tBase2 = ExerciseBase(
|
||||
|
||||
final tBase3 = ExerciseBase(
|
||||
id: 3,
|
||||
uuid: 'uuid3',
|
||||
uuid: 'ca84e2c5-5608-4d6d-ba57-6d4b6b5e7acd',
|
||||
creationDate: DateTime(2021, 08, 01),
|
||||
updateDate: DateTime(2021, 08, 01),
|
||||
category: tCategory3,
|
||||
@@ -74,31 +75,61 @@ final tBase3 = ExerciseBase(
|
||||
|
||||
final tExercise1 = Exercise(
|
||||
id: 1,
|
||||
uuid: 'uuid',
|
||||
uuid: 'f4cc326b-e497-4bd7-a71d-0eb1db522743',
|
||||
creationDate: DateTime(2021, 1, 15),
|
||||
name: 'test exercise 1',
|
||||
description: 'add clever text',
|
||||
base: tBase1,
|
||||
baseId: tBase1.id,
|
||||
language: tLanguage1,
|
||||
);
|
||||
|
||||
final tExercise2 = Exercise(
|
||||
id: 2,
|
||||
uuid: '111-2222-44444',
|
||||
uuid: 'b7f51a1a-0368-4dfc-a03c-d629a4089b4a',
|
||||
creationDate: DateTime(2021, 1, 15),
|
||||
name: 'test exercise 2',
|
||||
description: 'Lorem ipsum etc',
|
||||
base: tBase2,
|
||||
baseId: tBase2.id,
|
||||
language: tLanguage2,
|
||||
);
|
||||
|
||||
final tExercise3 = Exercise(
|
||||
id: 3,
|
||||
uuid: 'a3b6c7bb-9d22-4119-a5fc-818584d5e9bc',
|
||||
uuid: 'd83f572d-add5-48dc-89cf-75f6770284f1',
|
||||
creationDate: DateTime(2021, 4, 1),
|
||||
name: 'test exercise 3',
|
||||
description: 'The man in black fled across the desert, and the gunslinger followed',
|
||||
base: tBase3,
|
||||
baseId: tBase3.id,
|
||||
language: tLanguage3,
|
||||
);
|
||||
|
||||
final tExercise4 = Exercise(
|
||||
id: 4,
|
||||
uuid: 'a3e96c1d-b35f-4b0e-9cf4-ca37666cf521',
|
||||
creationDate: DateTime(2021, 4, 1),
|
||||
name: 'test exercise 4',
|
||||
description: 'The man in black fled across the desert, and the gunslinger followed',
|
||||
baseId: tBase3.id,
|
||||
language: tLanguage1,
|
||||
);
|
||||
|
||||
final tExercise5 = Exercise(
|
||||
id: 5,
|
||||
uuid: '8c49a816-2247-4116-94bb-b5c0ce09c609',
|
||||
creationDate: DateTime(2021, 4, 1),
|
||||
name: 'test exercise 5',
|
||||
description: 'The man in black fled across the desert, and the gunslinger followed',
|
||||
baseId: tBase3.id,
|
||||
language: tLanguage2,
|
||||
);
|
||||
|
||||
final tExercise6 = Exercise(
|
||||
id: 6,
|
||||
uuid: '259a637e-957f-4fe1-b61b-f56e3793ebcd',
|
||||
creationDate: DateTime(2021, 4, 1),
|
||||
name: 'test exercise 5',
|
||||
description: 'The man in black fled across the desert, and the gunslinger followed',
|
||||
baseId: tBase3.id,
|
||||
language: tLanguage2,
|
||||
);
|
||||
|
||||
@@ -107,5 +138,9 @@ List<Exercise> getTestExercises() {
|
||||
}
|
||||
|
||||
List<ExerciseBase> getTestExerciseBases() {
|
||||
return getTestExercises().map((e) => e.baseObj).toList();
|
||||
tBase1.exercises = [tExercise1, tExercise2, tExercise3];
|
||||
tBase2.exercises = [tExercise4, tExercise5];
|
||||
tBase3.exercises = [tExercise6];
|
||||
|
||||
return [tBase1, tBase2, tBase3];
|
||||
}
|
||||
|
||||
@@ -33,10 +33,12 @@ const RepetitionUnit repetitionUnit1 = RepetitionUnit(id: 1, name: 'Repetitions'
|
||||
const RepetitionUnit repetitionUnit2 = RepetitionUnit(id: 2, name: 'Hours');
|
||||
|
||||
WorkoutPlan getWorkout() {
|
||||
final testBases = getTestExerciseBases();
|
||||
|
||||
final setting1 = Setting(
|
||||
setId: 1,
|
||||
order: 1,
|
||||
exerciseId: 1,
|
||||
exerciseBaseId: 1,
|
||||
repetitionUnitId: 1,
|
||||
reps: 2,
|
||||
weightUnitId: 1,
|
||||
@@ -45,7 +47,7 @@ WorkoutPlan getWorkout() {
|
||||
);
|
||||
setting1.repetitionUnit = repetitionUnit1;
|
||||
setting1.weightUnit = weightUnit1;
|
||||
setting1.exercise = getTestExercises()[0];
|
||||
setting1.exerciseBase = testBases[0];
|
||||
setting1.weight = 10;
|
||||
|
||||
final log1 = Log.empty()
|
||||
@@ -55,7 +57,7 @@ WorkoutPlan getWorkout() {
|
||||
..date = DateTime(2021, 5, 1)
|
||||
..reps = 10
|
||||
..workoutPlan = 1;
|
||||
log1.exercise = getTestExercises()[0];
|
||||
log1.exerciseBase = testBases[0];
|
||||
log1.weightUnit = weightUnit1;
|
||||
log1.repetitionUnit = repetitionUnit1;
|
||||
|
||||
@@ -66,7 +68,7 @@ WorkoutPlan getWorkout() {
|
||||
..date = DateTime(2021, 5, 1)
|
||||
..reps = 12
|
||||
..workoutPlan = 1;
|
||||
log2.exercise = getTestExercises()[0];
|
||||
log2.exerciseBase = testBases[0];
|
||||
log2.weightUnit = weightUnit1;
|
||||
log2.repetitionUnit = repetitionUnit1;
|
||||
|
||||
@@ -77,7 +79,7 @@ WorkoutPlan getWorkout() {
|
||||
..date = DateTime(2021, 5, 2)
|
||||
..reps = 8
|
||||
..workoutPlan = 1;
|
||||
log3.exercise = getTestExercises()[1];
|
||||
log3.exerciseBase = testBases[1];
|
||||
log3.weightUnit = weightUnit1;
|
||||
log3.repetitionUnit = repetitionUnit1;
|
||||
|
||||
@@ -88,7 +90,7 @@ WorkoutPlan getWorkout() {
|
||||
order: 1,
|
||||
comment: 'Important to do exercises correctly',
|
||||
);
|
||||
set1.addExercise(getTestExercises()[0]);
|
||||
set1.addExerciseBase(testBases[0]);
|
||||
set1.settings.add(setting1);
|
||||
set1.settingsComputed = [setting1, setting1];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user