mirror of
https://github.com/wger-project/flutter.git
synced 2026-02-18 00:17:48 +01:00
Automatic linting
This commit is contained in:
@@ -60,5 +60,6 @@ String? timeToString(TimeOfDay? time) {
|
||||
if (time == null) {
|
||||
return null;
|
||||
}
|
||||
return DefaultMaterialLocalizations().formatTimeOfDay(time, alwaysUse24HourFormat: true);
|
||||
return DefaultMaterialLocalizations()
|
||||
.formatTimeOfDay(time, alwaysUse24HourFormat: true);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,9 @@ String repText(
|
||||
// rather "8 repetitions". If there is weight we want to output "8 x 50kg",
|
||||
// since the repetitions are implied. If other units are used, we always
|
||||
// print them
|
||||
if (repetitionUnitObj.id != DEFAULT_REPETITION_UNIT || weight == 0 || weight == null) {
|
||||
if (repetitionUnitObj.id != DEFAULT_REPETITION_UNIT ||
|
||||
weight == 0 ||
|
||||
weight == null) {
|
||||
out.add(repetitionUnitObj.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,8 @@ void showErrorDialog(dynamic exception, BuildContext context) {
|
||||
);
|
||||
}
|
||||
|
||||
void showHttpExceptionErrorDialog(WgerHttpException exception, BuildContext context) {
|
||||
void showHttpExceptionErrorDialog(
|
||||
WgerHttpException exception, BuildContext context) {
|
||||
log('showHttpExceptionErrorDialog: ');
|
||||
log(exception.toString());
|
||||
log('-------------------');
|
||||
|
||||
@@ -58,35 +58,37 @@ class MyApp extends StatelessWidget {
|
||||
create: (ctx) => AuthProvider(),
|
||||
),
|
||||
ChangeNotifierProxyProvider<AuthProvider, ExercisesProvider>(
|
||||
create: (context) =>
|
||||
ExercisesProvider(Provider.of<AuthProvider>(context, listen: false), []),
|
||||
create: (context) => ExercisesProvider(
|
||||
Provider.of<AuthProvider>(context, listen: false), []),
|
||||
update: (context, auth, previous) =>
|
||||
previous != null ? previous : ExercisesProvider(auth, []),
|
||||
),
|
||||
ChangeNotifierProxyProvider2<AuthProvider, ExercisesProvider, WorkoutPlansProvider>(
|
||||
ChangeNotifierProxyProvider2<AuthProvider, ExercisesProvider,
|
||||
WorkoutPlansProvider>(
|
||||
create: (context) => WorkoutPlansProvider(
|
||||
Provider.of<AuthProvider>(context, listen: false),
|
||||
Provider.of<ExercisesProvider>(context, listen: false),
|
||||
[],
|
||||
),
|
||||
update: (context, auth, exercises, previous) =>
|
||||
previous != null ? previous : WorkoutPlansProvider(auth, exercises, []),
|
||||
update: (context, auth, exercises, previous) => previous != null
|
||||
? previous
|
||||
: WorkoutPlansProvider(auth, exercises, []),
|
||||
),
|
||||
ChangeNotifierProxyProvider<AuthProvider, NutritionPlansProvider>(
|
||||
create: (context) =>
|
||||
NutritionPlansProvider(Provider.of<AuthProvider>(context, listen: false), []),
|
||||
create: (context) => NutritionPlansProvider(
|
||||
Provider.of<AuthProvider>(context, listen: false), []),
|
||||
update: (context, auth, previous) =>
|
||||
previous != null ? previous : NutritionPlansProvider(auth, []),
|
||||
),
|
||||
ChangeNotifierProxyProvider<AuthProvider, BodyWeightProvider>(
|
||||
create: (context) =>
|
||||
BodyWeightProvider(Provider.of<AuthProvider>(context, listen: false), []),
|
||||
create: (context) => BodyWeightProvider(
|
||||
Provider.of<AuthProvider>(context, listen: false), []),
|
||||
update: (context, auth, previous) =>
|
||||
previous != null ? previous : BodyWeightProvider(auth, []),
|
||||
),
|
||||
ChangeNotifierProxyProvider<AuthProvider, GalleryProvider>(
|
||||
create: (context) =>
|
||||
GalleryProvider(Provider.of<AuthProvider>(context, listen: false), []),
|
||||
create: (context) => GalleryProvider(
|
||||
Provider.of<AuthProvider>(context, listen: false), []),
|
||||
update: (context, auth, previous) =>
|
||||
previous != null ? previous : GalleryProvider(auth, []),
|
||||
),
|
||||
@@ -100,7 +102,8 @@ class MyApp extends StatelessWidget {
|
||||
: FutureBuilder(
|
||||
future: auth.tryAutoLogin(),
|
||||
builder: (ctx, authResultSnapshot) =>
|
||||
authResultSnapshot.connectionState == ConnectionState.waiting
|
||||
authResultSnapshot.connectionState ==
|
||||
ConnectionState.waiting
|
||||
? SplashScreen()
|
||||
: AuthScreen(),
|
||||
),
|
||||
|
||||
@@ -45,6 +45,7 @@ class WeightEntry {
|
||||
}
|
||||
|
||||
// Boilerplate
|
||||
factory WeightEntry.fromJson(Map<String, dynamic> json) => _$WeightEntryFromJson(json);
|
||||
factory WeightEntry.fromJson(Map<String, dynamic> json) =>
|
||||
_$WeightEntryFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$WeightEntryToJson(this);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ class ExerciseCategory {
|
||||
}
|
||||
|
||||
// Boilerplate
|
||||
factory ExerciseCategory.fromJson(Map<String, dynamic> json) => _$ExerciseCategoryFromJson(json);
|
||||
factory ExerciseCategory.fromJson(Map<String, dynamic> json) =>
|
||||
_$ExerciseCategoryFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$ExerciseCategoryToJson(this);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ class Comment {
|
||||
});
|
||||
|
||||
// Boilerplate
|
||||
factory Comment.fromJson(Map<String, dynamic> json) => _$CommentFromJson(json);
|
||||
factory Comment.fromJson(Map<String, dynamic> json) =>
|
||||
_$CommentFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$CommentToJson(this);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ class Equipment {
|
||||
});
|
||||
|
||||
// Boilerplate
|
||||
factory Equipment.fromJson(Map<String, dynamic> json) => _$EquipmentFromJson(json);
|
||||
factory Equipment.fromJson(Map<String, dynamic> json) =>
|
||||
_$EquipmentFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$EquipmentToJson(this);
|
||||
}
|
||||
|
||||
@@ -100,6 +100,7 @@ class Exercise {
|
||||
}
|
||||
|
||||
// Boilerplate
|
||||
factory Exercise.fromJson(Map<String, dynamic> json) => _$ExerciseFromJson(json);
|
||||
factory Exercise.fromJson(Map<String, dynamic> json) =>
|
||||
_$ExerciseFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$ExerciseToJson(this);
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ class ExerciseImage {
|
||||
});
|
||||
|
||||
// Boilerplate
|
||||
factory ExerciseImage.fromJson(Map<String, dynamic> json) => _$ExerciseImageFromJson(json);
|
||||
factory ExerciseImage.fromJson(Map<String, dynamic> json) =>
|
||||
_$ExerciseImageFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$ExerciseImageToJson(this);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,10 @@ class WgerHttpException implements Exception {
|
||||
/// JSON. Will use the response as-is if it fails.
|
||||
WgerHttpException(dynamic responseBody) {
|
||||
if (responseBody == null) {
|
||||
errors = {'unknown_error': 'An unknown error occurred, no further information available'};
|
||||
errors = {
|
||||
'unknown_error':
|
||||
'An unknown error occurred, no further information available'
|
||||
};
|
||||
} else {
|
||||
try {
|
||||
errors = json.decode(responseBody);
|
||||
|
||||
@@ -41,7 +41,11 @@ class Ingredient {
|
||||
final num carbohydrates;
|
||||
|
||||
/// g per 100g of product
|
||||
@JsonKey(required: true, fromJson: stringToNum, toJson: numToString, name: 'carbohydrates_sugar')
|
||||
@JsonKey(
|
||||
required: true,
|
||||
fromJson: stringToNum,
|
||||
toJson: numToString,
|
||||
name: 'carbohydrates_sugar')
|
||||
final num carbohydratesSugar;
|
||||
|
||||
/// g per 100g of product
|
||||
@@ -53,7 +57,11 @@ class Ingredient {
|
||||
final num fat;
|
||||
|
||||
/// g per 100g of product
|
||||
@JsonKey(required: true, fromJson: stringToNum, toJson: numToString, name: 'fat_saturated')
|
||||
@JsonKey(
|
||||
required: true,
|
||||
fromJson: stringToNum,
|
||||
toJson: numToString,
|
||||
name: 'fat_saturated')
|
||||
final num fatSaturated;
|
||||
|
||||
/// g per 100g of product
|
||||
@@ -79,6 +87,7 @@ class Ingredient {
|
||||
});
|
||||
|
||||
// Boilerplate
|
||||
factory Ingredient.fromJson(Map<String, dynamic> json) => _$IngredientFromJson(json);
|
||||
factory Ingredient.fromJson(Map<String, dynamic> json) =>
|
||||
_$IngredientFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$IngredientToJson(this);
|
||||
}
|
||||
|
||||
@@ -82,8 +82,9 @@ class Log {
|
||||
var out = NutritionalValues();
|
||||
|
||||
//final weight = amount;
|
||||
final weight =
|
||||
this.weightUnitObj == null ? amount : amount * weightUnitObj!.amount * weightUnitObj!.grams;
|
||||
final weight = this.weightUnitObj == null
|
||||
? amount
|
||||
: amount * weightUnitObj!.amount * weightUnitObj!.grams;
|
||||
|
||||
out.energy = ingredientObj.energy * weight / 100;
|
||||
out.protein = ingredientObj.protein * weight / 100;
|
||||
|
||||
@@ -63,7 +63,8 @@ class MealItem {
|
||||
MealItem.empty();
|
||||
|
||||
// Boilerplate
|
||||
factory MealItem.fromJson(Map<String, dynamic> json) => _$MealItemFromJson(json);
|
||||
factory MealItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$MealItemFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$MealItemToJson(this);
|
||||
|
||||
|
||||
@@ -59,7 +59,8 @@ class NutritionalPlan {
|
||||
}
|
||||
|
||||
// Boilerplate
|
||||
factory NutritionalPlan.fromJson(Map<String, dynamic> json) => _$NutritionalPlanFromJson(json);
|
||||
factory NutritionalPlan.fromJson(Map<String, dynamic> json) =>
|
||||
_$NutritionalPlanFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$NutritionalPlanToJson(this);
|
||||
|
||||
/// Calculations
|
||||
@@ -77,7 +78,8 @@ class NutritionalPlan {
|
||||
Map<DateTime, NutritionalValues> get logEntriesValues {
|
||||
var out = <DateTime, NutritionalValues>{};
|
||||
for (var log in logs) {
|
||||
final date = DateTime(log.datetime.year, log.datetime.month, log.datetime.day);
|
||||
final date =
|
||||
DateTime(log.datetime.year, log.datetime.month, log.datetime.day);
|
||||
|
||||
if (!out.containsKey(date)) {
|
||||
out[date] = NutritionalValues();
|
||||
|
||||
@@ -34,6 +34,7 @@ class WeightUnit {
|
||||
});
|
||||
|
||||
// Boilerplate
|
||||
factory WeightUnit.fromJson(Map<String, dynamic> json) => _$WeightUnitFromJson(json);
|
||||
factory WeightUnit.fromJson(Map<String, dynamic> json) =>
|
||||
_$WeightUnitFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$WeightUnitToJson(this);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,8 @@ class Day {
|
||||
final now = DateTime.now();
|
||||
final firstDayOfWeek = now.subtract(Duration(days: now.weekday));
|
||||
|
||||
return DateFormat(DateFormat.WEEKDAY, locale).format(firstDayOfWeek.add(Duration(days: day)));
|
||||
return DateFormat(DateFormat.WEEKDAY, locale)
|
||||
.format(firstDayOfWeek.add(Duration(days: day)));
|
||||
}
|
||||
|
||||
// Boilerplate
|
||||
|
||||
@@ -112,7 +112,8 @@ class Log {
|
||||
|
||||
/// Returns the text representation for a single setting, used in the gym mode
|
||||
String get singleLogRepTextNoNl {
|
||||
return repText(reps, repetitionUnitObj, weight, weightUnitObj, rir).replaceAll('\n', '');
|
||||
return repText(reps, repetitionUnitObj, weight, weightUnitObj, rir)
|
||||
.replaceAll('\n', '');
|
||||
}
|
||||
|
||||
/// Override the equals operator
|
||||
@@ -130,7 +131,8 @@ class Log {
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => hashValues(exerciseId, weight, weightUnitId, reps, repetitionUnitId, rir);
|
||||
int get hashCode =>
|
||||
hashValues(exerciseId, weight, weightUnitId, reps, repetitionUnitId, rir);
|
||||
|
||||
//@override
|
||||
//int get hashCode => super.hashCode;
|
||||
|
||||
@@ -34,6 +34,7 @@ class RepetitionUnit {
|
||||
});
|
||||
|
||||
// Boilerplate
|
||||
factory RepetitionUnit.fromJson(Map<String, dynamic> json) => _$RepetitionUnitFromJson(json);
|
||||
factory RepetitionUnit.fromJson(Map<String, dynamic> json) =>
|
||||
_$RepetitionUnitFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$RepetitionUnitToJson(this);
|
||||
}
|
||||
|
||||
@@ -41,10 +41,18 @@ class WorkoutSession {
|
||||
@JsonKey(required: false, defaultValue: '')
|
||||
late String notes;
|
||||
|
||||
@JsonKey(required: true, name: 'time_start', toJson: timeToString, fromJson: stringToTime)
|
||||
@JsonKey(
|
||||
required: true,
|
||||
name: 'time_start',
|
||||
toJson: timeToString,
|
||||
fromJson: stringToTime)
|
||||
late TimeOfDay timeStart;
|
||||
|
||||
@JsonKey(required: true, name: 'time_end', toJson: timeToString, fromJson: stringToTime)
|
||||
@JsonKey(
|
||||
required: true,
|
||||
name: 'time_end',
|
||||
toJson: timeToString,
|
||||
fromJson: stringToTime)
|
||||
late TimeOfDay timeEnd;
|
||||
|
||||
WorkoutSession();
|
||||
@@ -60,7 +68,8 @@ class WorkoutSession {
|
||||
});
|
||||
|
||||
// Boilerplate
|
||||
factory WorkoutSession.fromJson(Map<String, dynamic> json) => _$WorkoutSessionFromJson(json);
|
||||
factory WorkoutSession.fromJson(Map<String, dynamic> json) =>
|
||||
_$WorkoutSessionFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$WorkoutSessionToJson(this);
|
||||
|
||||
get impressionAsString {
|
||||
|
||||
@@ -109,7 +109,9 @@ class Set {
|
||||
|
||||
/// Returns all settings for the given exercise
|
||||
List<Setting> filterSettingsByExercise(Exercise exercise) {
|
||||
return settings.where((element) => element.exerciseId == exercise.id).toList();
|
||||
return settings
|
||||
.where((element) => element.exerciseId == exercise.id)
|
||||
.toList();
|
||||
}
|
||||
|
||||
/// Returns a list with all repetitions for the given exercise
|
||||
|
||||
@@ -29,7 +29,18 @@ part 'setting.g.dart';
|
||||
class Setting {
|
||||
/// Allowed RiR values. This list must be kept in sync with RIR_OPTIONS in the
|
||||
/// wger server
|
||||
static const POSSIBLE_RIR_VALUES = ['', '0', '0.5', '1', '1.5', '2', '2.5', '3', '3.5', '4'];
|
||||
static const POSSIBLE_RIR_VALUES = [
|
||||
'',
|
||||
'0',
|
||||
'0.5',
|
||||
'1',
|
||||
'1.5',
|
||||
'2',
|
||||
'2.5',
|
||||
'3',
|
||||
'3.5',
|
||||
'4'
|
||||
];
|
||||
static const DEFAULT_RIR = '';
|
||||
|
||||
@JsonKey(required: true)
|
||||
@@ -88,7 +99,8 @@ class Setting {
|
||||
Setting.empty();
|
||||
|
||||
// Boilerplate
|
||||
factory Setting.fromJson(Map<String, dynamic> json) => _$SettingFromJson(json);
|
||||
factory Setting.fromJson(Map<String, dynamic> json) =>
|
||||
_$SettingFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$SettingToJson(this);
|
||||
|
||||
set exercise(Exercise exercise) {
|
||||
|
||||
@@ -34,6 +34,7 @@ class WeightUnit {
|
||||
});
|
||||
|
||||
// Boilerplate
|
||||
factory WeightUnit.fromJson(Map<String, dynamic> json) => _$WeightUnitFromJson(json);
|
||||
factory WeightUnit.fromJson(Map<String, dynamic> json) =>
|
||||
_$WeightUnitFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$WeightUnitToJson(this);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,8 @@ class WorkoutPlan {
|
||||
}
|
||||
|
||||
// Boilerplate
|
||||
factory WorkoutPlan.fromJson(Map<String, dynamic> json) => _$WorkoutPlanFromJson(json);
|
||||
factory WorkoutPlan.fromJson(Map<String, dynamic> json) =>
|
||||
_$WorkoutPlanFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$WorkoutPlanToJson(this);
|
||||
|
||||
/// Filters the workout logs by exercise and sorts them by date
|
||||
@@ -75,7 +76,8 @@ class WorkoutPlan {
|
||||
/// 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();
|
||||
var out =
|
||||
logs.where((element) => element.exerciseId == exercise.id).toList();
|
||||
|
||||
if (unique) {
|
||||
out = out.toSet().toList();
|
||||
|
||||
@@ -38,7 +38,8 @@ class WgerBaseProvider {
|
||||
}
|
||||
|
||||
/// Helper function to make a URL.
|
||||
Uri makeUrl(String path, {int? id, String? objectMethod, Map<String, dynamic>? query}) {
|
||||
Uri makeUrl(String path,
|
||||
{int? id, String? objectMethod, Map<String, dynamic>? query}) {
|
||||
return makeUri(auth.serverUrl!, path, id, objectMethod, query);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@ class BodyWeightProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
static const bodyWeightUrl = 'weightentry';
|
||||
|
||||
List<WeightEntry> _entries = [];
|
||||
BodyWeightProvider(AuthProvider auth, List<WeightEntry> entries, [http.Client? client])
|
||||
BodyWeightProvider(AuthProvider auth, List<WeightEntry> entries,
|
||||
[http.Client? client])
|
||||
: this._entries = entries,
|
||||
super(auth, client);
|
||||
|
||||
@@ -54,7 +55,8 @@ class BodyWeightProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
|
||||
Future<List<WeightEntry>> fetchAndSetEntries() async {
|
||||
// Process the response
|
||||
final data = await fetch(makeUrl(bodyWeightUrl, query: {'ordering': '-date'}));
|
||||
final data =
|
||||
await fetch(makeUrl(bodyWeightUrl, query: {'ordering': '-date'}));
|
||||
final List<WeightEntry> loadedEntries = [];
|
||||
for (final entry in data['results']) {
|
||||
loadedEntries.add(WeightEntry.fromJson(entry));
|
||||
@@ -83,7 +85,8 @@ class BodyWeightProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
|
||||
Future<void> deleteEntry(int id) async {
|
||||
// Send the request and remove the entry from the list...
|
||||
final existingEntryIndex = _entries.indexWhere((element) => element.id == id);
|
||||
final existingEntryIndex =
|
||||
_entries.indexWhere((element) => element.id == id);
|
||||
var existingWeightEntry = _entries[existingEntryIndex];
|
||||
_entries.removeAt(existingEntryIndex);
|
||||
notifyListeners();
|
||||
|
||||
@@ -51,7 +51,8 @@ class ExercisesProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
List<Muscle> _muscles = [];
|
||||
List<Equipment> _equipment = [];
|
||||
|
||||
ExercisesProvider(AuthProvider auth, List<Exercise> entries, [http.Client? client])
|
||||
ExercisesProvider(AuthProvider auth, List<Exercise> entries,
|
||||
[http.Client? client])
|
||||
: this._exercises = entries,
|
||||
super(auth, client);
|
||||
|
||||
@@ -129,10 +130,14 @@ class ExercisesProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
if (prefs.containsKey(PREFS_EXERCISES)) {
|
||||
final exerciseData = json.decode(prefs.getString(PREFS_EXERCISES)!);
|
||||
if (DateTime.parse(exerciseData['expiresIn']).isAfter(DateTime.now())) {
|
||||
exerciseData['exercises'].forEach((e) => _exercises.add(Exercise.fromJson(e)));
|
||||
exerciseData['equipment'].forEach((e) => _equipment.add(Equipment.fromJson(e)));
|
||||
exerciseData['muscles'].forEach((e) => _muscles.add(Muscle.fromJson(e)));
|
||||
exerciseData['categories'].forEach((e) => _categories.add(ExerciseCategory.fromJson(e)));
|
||||
exerciseData['exercises']
|
||||
.forEach((e) => _exercises.add(Exercise.fromJson(e)));
|
||||
exerciseData['equipment']
|
||||
.forEach((e) => _equipment.add(Equipment.fromJson(e)));
|
||||
exerciseData['muscles']
|
||||
.forEach((e) => _muscles.add(Muscle.fromJson(e)));
|
||||
exerciseData['categories']
|
||||
.forEach((e) => _categories.add(ExerciseCategory.fromJson(e)));
|
||||
log("Read ${exerciseData['exercises'].length} exercises from cache. Valid till ${exerciseData['expiresIn']}");
|
||||
return;
|
||||
}
|
||||
@@ -151,16 +156,19 @@ class ExercisesProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
headers: {
|
||||
HttpHeaders.contentTypeHeader: 'application/json; charset=UTF-8',
|
||||
});
|
||||
final exercisesData = json.decode(utf8.decode(response.bodyBytes)) as Map<String, dynamic>;
|
||||
final exercisesData =
|
||||
json.decode(utf8.decode(response.bodyBytes)) as Map<String, dynamic>;
|
||||
|
||||
try {
|
||||
// Load exercises
|
||||
exercisesData['results'].forEach((e) => _exercises.add(Exercise.fromJson(e)));
|
||||
exercisesData['results']
|
||||
.forEach((e) => _exercises.add(Exercise.fromJson(e)));
|
||||
|
||||
// Save the result to the cache
|
||||
final exerciseData = {
|
||||
'date': DateTime.now().toIso8601String(),
|
||||
'expiresIn': DateTime.now().add(Duration(days: daysToCache)).toIso8601String(),
|
||||
'expiresIn':
|
||||
DateTime.now().add(Duration(days: daysToCache)).toIso8601String(),
|
||||
'exercises': _exercises.map((e) => e.toJson()).toList(),
|
||||
'equipment': _equipment.map((e) => e.toJson()).toList(),
|
||||
'categories': _categories.map((e) => e.toJson()).toList(),
|
||||
@@ -202,7 +210,8 @@ class ExercisesProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
}
|
||||
|
||||
// Process the response
|
||||
final result = json.decode(utf8.decode(response.bodyBytes))['suggestions'] as List<dynamic>;
|
||||
final result = json.decode(utf8.decode(response.bodyBytes))['suggestions']
|
||||
as List<dynamic>;
|
||||
for (var entry in result) {
|
||||
entry['exercise_obj'] = await fetchAndSetExercise(entry['data']['id']);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ class GalleryProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
|
||||
List<gallery.Image> images = [];
|
||||
|
||||
GalleryProvider(AuthProvider auth, List<gallery.Image> entries, [http.Client? client])
|
||||
GalleryProvider(AuthProvider auth, List<gallery.Image> entries,
|
||||
[http.Client? client])
|
||||
: this.images = entries,
|
||||
super(auth, client);
|
||||
|
||||
@@ -62,7 +63,8 @@ class GalleryProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
HttpHeaders.authorizationHeader: 'Token ${auth.token}',
|
||||
HttpHeaders.userAgentHeader: auth.getAppNameHeader(),
|
||||
});
|
||||
request.files.add(await http.MultipartFile.fromPath('image', imageFile.path));
|
||||
request.files
|
||||
.add(await http.MultipartFile.fromPath('image', imageFile.path));
|
||||
request.fields['date'] = toDate(image.date)!;
|
||||
request.fields['description'] = image.description;
|
||||
|
||||
@@ -76,7 +78,8 @@ class GalleryProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
}
|
||||
|
||||
Future<void> editImage(gallery.Image image, PickedFile? imageFile) async {
|
||||
var request = http.MultipartRequest('PATCH', makeUrl(_galleryUrlPath, id: image.id));
|
||||
var request =
|
||||
http.MultipartRequest('PATCH', makeUrl(_galleryUrlPath, id: image.id));
|
||||
request.headers.addAll({
|
||||
HttpHeaders.authorizationHeader: 'Token ${auth.token}',
|
||||
HttpHeaders.userAgentHeader: auth.getAppNameHeader(),
|
||||
@@ -84,7 +87,8 @@ class GalleryProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
|
||||
// Only send the image if a new one was selected
|
||||
if (imageFile != null) {
|
||||
request.files.add(await http.MultipartFile.fromPath('image', imageFile.path));
|
||||
request.files
|
||||
.add(await http.MultipartFile.fromPath('image', imageFile.path));
|
||||
}
|
||||
|
||||
// Update image info
|
||||
|
||||
@@ -45,7 +45,8 @@ class NutritionPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
List<NutritionalPlan> _plans = [];
|
||||
List<Ingredient> _ingredients = [];
|
||||
|
||||
NutritionPlansProvider(AuthProvider auth, List<NutritionalPlan> entries, [http.Client? client])
|
||||
NutritionPlansProvider(AuthProvider auth, List<NutritionalPlan> entries,
|
||||
[http.Client? client])
|
||||
: this._plans = entries,
|
||||
super(auth, client);
|
||||
|
||||
@@ -84,7 +85,8 @@ class NutritionPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
/// Fetches and sets all plans sparsely, i.e. only with the data on the plan
|
||||
/// object itself and no child attributes
|
||||
Future<void> fetchAndSetAllPlansSparse() async {
|
||||
final data = await fetch(makeUrl(_nutritionalPlansPath, query: {'limit': '1000'}));
|
||||
final data =
|
||||
await fetch(makeUrl(_nutritionalPlansPath, query: {'limit': '1000'}));
|
||||
for (final planData in data['results']) {
|
||||
final plan = NutritionalPlan.fromJson(planData);
|
||||
_plans.add(plan);
|
||||
@@ -125,7 +127,8 @@ class NutritionPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
}
|
||||
|
||||
// Plan
|
||||
final fullPlanData = await fetch(makeUrl(_nutritionalPlansInfoPath, id: planId));
|
||||
final fullPlanData =
|
||||
await fetch(makeUrl(_nutritionalPlansInfoPath, id: planId));
|
||||
|
||||
// Meals
|
||||
List<Meal> meals = [];
|
||||
@@ -283,7 +286,8 @@ class NutritionPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
if (prefs.containsKey('ingredientData')) {
|
||||
final ingredientData = json.decode(prefs.getString('ingredientData')!);
|
||||
if (DateTime.parse(ingredientData['expiresIn']).isAfter(DateTime.now())) {
|
||||
ingredientData['ingredients'].forEach((e) => _ingredients.add(Ingredient.fromJson(e)));
|
||||
ingredientData['ingredients']
|
||||
.forEach((e) => _ingredients.add(Ingredient.fromJson(e)));
|
||||
log("Read ${ingredientData['ingredients'].length} ingredients from cache. Valid till ${ingredientData['expiresIn']}");
|
||||
return;
|
||||
}
|
||||
@@ -292,7 +296,8 @@ class NutritionPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
// Initialise an empty cache
|
||||
final ingredientData = {
|
||||
'date': DateTime.now().toIso8601String(),
|
||||
'expiresIn': DateTime.now().add(Duration(days: DAYS_TO_CACHE)).toIso8601String(),
|
||||
'expiresIn':
|
||||
DateTime.now().add(Duration(days: DAYS_TO_CACHE)).toIso8601String(),
|
||||
'ingredients': []
|
||||
};
|
||||
prefs.setString('ingredientData', json.encode(ingredientData));
|
||||
@@ -300,7 +305,8 @@ class NutritionPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
}
|
||||
|
||||
/// Searches for an ingredient
|
||||
Future<List> searchIngredient(String name, [String languageCode = 'en']) async {
|
||||
Future<List> searchIngredient(String name,
|
||||
[String languageCode = 'en']) async {
|
||||
if (name.length <= 1) {
|
||||
return [];
|
||||
}
|
||||
@@ -323,7 +329,8 @@ class NutritionPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
}
|
||||
|
||||
// Process the response
|
||||
return json.decode(utf8.decode(response.bodyBytes))['suggestions'] as List<dynamic>;
|
||||
return json.decode(utf8.decode(response.bodyBytes))['suggestions']
|
||||
as List<dynamic>;
|
||||
}
|
||||
|
||||
/// Log meal to nutrition diary
|
||||
@@ -343,7 +350,8 @@ class NutritionPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
Future<void> fetchAndSetLogs(NutritionalPlan plan) async {
|
||||
// TODO: update fetch to that it can use the pagination
|
||||
final data = await fetch(
|
||||
makeUrl(_nutritionDiaryPath, query: {'plan': plan.id.toString(), 'limit': '1000'}),
|
||||
makeUrl(_nutritionDiaryPath,
|
||||
query: {'plan': plan.id.toString(), 'limit': '1000'}),
|
||||
);
|
||||
|
||||
for (var logData in data['results']) {
|
||||
|
||||
@@ -53,7 +53,8 @@ class WorkoutPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
List<WeightUnit> _weightUnits = [];
|
||||
List<RepetitionUnit> _repetitionUnit = [];
|
||||
|
||||
WorkoutPlansProvider(AuthProvider auth, ExercisesProvider exercises, List<WorkoutPlan> entries,
|
||||
WorkoutPlansProvider(
|
||||
AuthProvider auth, ExercisesProvider exercises, List<WorkoutPlan> entries,
|
||||
[http.Client? client])
|
||||
: this._exercises = exercises,
|
||||
this._workoutPlans = entries,
|
||||
@@ -77,7 +78,8 @@ class WorkoutPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
|
||||
/// Return the default weight unit (kg)
|
||||
WeightUnit get defaultWeightUnit {
|
||||
return _weightUnits.firstWhere((element) => element.id == DEFAULT_WEIGHT_UNIT);
|
||||
return _weightUnits
|
||||
.firstWhere((element) => element.id == DEFAULT_WEIGHT_UNIT);
|
||||
}
|
||||
|
||||
List<RepetitionUnit> get repetitionUnits {
|
||||
@@ -86,7 +88,8 @@ class WorkoutPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
|
||||
/// Return the default weight unit (reps)
|
||||
RepetitionUnit get defaultRepetitionUnit {
|
||||
return _repetitionUnit.firstWhere((element) => element.id == DEFAULT_REPETITION_UNIT);
|
||||
return _repetitionUnit
|
||||
.firstWhere((element) => element.id == DEFAULT_REPETITION_UNIT);
|
||||
}
|
||||
|
||||
WorkoutPlan findById(int id) {
|
||||
@@ -141,7 +144,8 @@ class WorkoutPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
/// Fetches all workout plan sparsely, i.e. only with the data on the plan
|
||||
/// object itself and no child attributes
|
||||
Future<void> fetchAndSetAllPlansSparse() async {
|
||||
final data = await fetch(makeUrl(_workoutPlansUrlPath, query: {'limit': '1000'}));
|
||||
final data =
|
||||
await fetch(makeUrl(_workoutPlansUrlPath, query: {'limit': '1000'}));
|
||||
for (final workoutPlanData in data['results']) {
|
||||
final plan = WorkoutPlan.fromJson(workoutPlanData);
|
||||
_workoutPlans.add(plan);
|
||||
@@ -183,7 +187,8 @@ class WorkoutPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
|
||||
// Plan
|
||||
final fullPlanData = await fetch(
|
||||
makeUrl(_workoutPlansUrlPath, id: workoutId, objectMethod: 'canonical_representation'),
|
||||
makeUrl(_workoutPlansUrlPath,
|
||||
id: workoutId, objectMethod: 'canonical_representation'),
|
||||
);
|
||||
|
||||
// Days
|
||||
@@ -200,12 +205,14 @@ class WorkoutPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
|
||||
// Settings
|
||||
List<Setting> settings = [];
|
||||
final settingData = allSettingsData['results'].where((s) => s['set'] == workoutSet.id);
|
||||
final settingData =
|
||||
allSettingsData['results'].where((s) => s['set'] == workoutSet.id);
|
||||
|
||||
for (final settingEntry in settingData) {
|
||||
final workoutSetting = Setting.fromJson(settingEntry);
|
||||
|
||||
workoutSetting.exercise = await _exercises.fetchAndSetExercise(workoutSetting.exerciseId);
|
||||
workoutSetting.exercise =
|
||||
await _exercises.fetchAndSetExercise(workoutSetting.exerciseId);
|
||||
workoutSetting.weightUnit = _weightUnits.firstWhere(
|
||||
(e) => e.id == workoutSetting.weightUnitId,
|
||||
);
|
||||
@@ -244,8 +251,10 @@ class WorkoutPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
for (final entry in logData['results']) {
|
||||
try {
|
||||
var log = Log.fromJson(entry);
|
||||
log.weightUnit = _weightUnits.firstWhere((e) => e.id == log.weightUnitId);
|
||||
log.repetitionUnit = _repetitionUnit.firstWhere((e) => e.id == log.weightUnitId);
|
||||
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);
|
||||
plan.logs.add(log);
|
||||
} catch (e) {
|
||||
@@ -275,12 +284,14 @@ class WorkoutPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
}
|
||||
|
||||
Future<void> editWorkout(WorkoutPlan workout) async {
|
||||
await patch(workout.toJson(), makeUrl(_workoutPlansUrlPath, id: workout.id));
|
||||
await patch(
|
||||
workout.toJson(), makeUrl(_workoutPlansUrlPath, id: workout.id));
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> deleteWorkout(int id) async {
|
||||
final existingWorkoutIndex = _workoutPlans.indexWhere((element) => element.id == id);
|
||||
final existingWorkoutIndex =
|
||||
_workoutPlans.indexWhere((element) => element.id == id);
|
||||
var existingWorkout = _workoutPlans[existingWorkoutIndex];
|
||||
_workoutPlans.removeAt(existingWorkoutIndex);
|
||||
notifyListeners();
|
||||
@@ -294,7 +305,8 @@ class WorkoutPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> fetchLogData(WorkoutPlan workout, Exercise exercise) async {
|
||||
Future<Map<String, dynamic>> fetchLogData(
|
||||
WorkoutPlan workout, Exercise exercise) async {
|
||||
final data = await fetch(
|
||||
makeUrl(
|
||||
_workoutPlansUrlPath,
|
||||
@@ -344,7 +356,8 @@ class WorkoutPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
unitData['weightUnit'].forEach(
|
||||
(e) => _weightUnits.add(WeightUnit.fromJson(e)),
|
||||
);
|
||||
dev.log("Read workout units data from cache. Valid till ${unitData['expiresIn']}");
|
||||
dev.log(
|
||||
"Read workout units data from cache. Valid till ${unitData['expiresIn']}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -356,7 +369,8 @@ class WorkoutPlansProvider extends WgerBaseProvider with ChangeNotifier {
|
||||
// Save the result to the cache
|
||||
final exerciseData = {
|
||||
'date': DateTime.now().toIso8601String(),
|
||||
'expiresIn': DateTime.now().add(Duration(days: DAYS_TO_CACHE)).toIso8601String(),
|
||||
'expiresIn':
|
||||
DateTime.now().add(Duration(days: DAYS_TO_CACHE)).toIso8601String(),
|
||||
'repetitionUnits': _repetitionUnit.map((e) => e.toJson()).toList(),
|
||||
'weightUnit': _weightUnits.map((e) => e.toJson()).toList(),
|
||||
};
|
||||
@@ -487,7 +501,8 @@ 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.repetitionUnit =
|
||||
_repetitionUnit.firstWhere((e) => e.id == log.weightUnitId);
|
||||
log.exercise = await _exercises.fetchAndSetExercise(log.exerciseId);
|
||||
|
||||
final plan = findById(log.workoutPlan);
|
||||
|
||||
@@ -56,7 +56,8 @@ class AuthScreen extends StatelessWidget {
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(bottom: 20.0),
|
||||
padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 94.0),
|
||||
padding:
|
||||
EdgeInsets.symmetric(vertical: 8.0, horizontal: 94.0),
|
||||
child: Text(
|
||||
'WGER',
|
||||
style: TextStyle(
|
||||
@@ -207,7 +208,8 @@ class _AuthCardState extends State<AuthCard> {
|
||||
if (_authMode == AuthMode.Signup)
|
||||
TextFormField(
|
||||
key: Key('inputEmail'),
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).email),
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).email),
|
||||
autofillHints: [AutofillHints.email],
|
||||
controller: _emailController,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
@@ -226,7 +228,8 @@ class _AuthCardState extends State<AuthCard> {
|
||||
),
|
||||
TextFormField(
|
||||
key: Key('inputPassword'),
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).password),
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).password),
|
||||
autofillHints: [AutofillHints.password],
|
||||
obscureText: true,
|
||||
controller: _passwordController,
|
||||
@@ -244,15 +247,17 @@ class _AuthCardState extends State<AuthCard> {
|
||||
if (_authMode == AuthMode.Signup)
|
||||
TextFormField(
|
||||
key: Key('inputPassword2'),
|
||||
decoration:
|
||||
InputDecoration(labelText: AppLocalizations.of(context).confirmPassword),
|
||||
decoration: InputDecoration(
|
||||
labelText:
|
||||
AppLocalizations.of(context).confirmPassword),
|
||||
controller: _password2Controller,
|
||||
enabled: _authMode == AuthMode.Signup,
|
||||
obscureText: true,
|
||||
validator: _authMode == AuthMode.Signup
|
||||
? (value) {
|
||||
if (value != _passwordController.text) {
|
||||
return AppLocalizations.of(context).passwordsDontMatch;
|
||||
return AppLocalizations.of(context)
|
||||
.passwordsDontMatch;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -269,8 +274,10 @@ class _AuthCardState extends State<AuthCard> {
|
||||
child: TextFormField(
|
||||
key: Key('inputServer'),
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).customServerUrl,
|
||||
helperText: AppLocalizations.of(context).customServerHint,
|
||||
labelText: AppLocalizations.of(context)
|
||||
.customServerUrl,
|
||||
helperText: AppLocalizations.of(context)
|
||||
.customServerHint,
|
||||
helperMaxLines: 4),
|
||||
controller: _serverUrlController,
|
||||
validator: (value) {
|
||||
@@ -325,8 +332,12 @@ class _AuthCardState extends State<AuthCard> {
|
||||
key: Key('toggleActionButton'),
|
||||
child: Text(
|
||||
_authMode == AuthMode.Login
|
||||
? AppLocalizations.of(context).registerInstead.toUpperCase()
|
||||
: AppLocalizations.of(context).loginInstead.toUpperCase(),
|
||||
? AppLocalizations.of(context)
|
||||
.registerInstead
|
||||
.toUpperCase()
|
||||
: AppLocalizations.of(context)
|
||||
.loginInstead
|
||||
.toUpperCase(),
|
||||
),
|
||||
onPressed: _switchAuthMode,
|
||||
),
|
||||
|
||||
@@ -53,11 +53,16 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
||||
if (!Provider.of<AuthProvider>(context, listen: false).dataInit) {
|
||||
Provider.of<AuthProvider>(context, listen: false).setServerVersion();
|
||||
|
||||
final workoutPlansProvider = Provider.of<WorkoutPlansProvider>(context, listen: false);
|
||||
final nutritionPlansProvider = Provider.of<NutritionPlansProvider>(context, listen: false);
|
||||
final exercisesProvider = Provider.of<ExercisesProvider>(context, listen: false);
|
||||
final galleryProvider = Provider.of<GalleryProvider>(context, listen: false);
|
||||
final weightProvider = Provider.of<BodyWeightProvider>(context, listen: false);
|
||||
final workoutPlansProvider =
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false);
|
||||
final nutritionPlansProvider =
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false);
|
||||
final exercisesProvider =
|
||||
Provider.of<ExercisesProvider>(context, listen: false);
|
||||
final galleryProvider =
|
||||
Provider.of<GalleryProvider>(context, listen: false);
|
||||
final weightProvider =
|
||||
Provider.of<BodyWeightProvider>(context, listen: false);
|
||||
|
||||
// Base data
|
||||
await Future.wait([
|
||||
|
||||
@@ -33,7 +33,8 @@ class HomeTabsScreen extends StatefulWidget {
|
||||
_HomeTabsScreenState createState() => _HomeTabsScreenState();
|
||||
}
|
||||
|
||||
class _HomeTabsScreenState extends State<HomeTabsScreen> with SingleTickerProviderStateMixin {
|
||||
class _HomeTabsScreenState extends State<HomeTabsScreen>
|
||||
with SingleTickerProviderStateMixin {
|
||||
int _selectedIndex = 0;
|
||||
|
||||
void _onItemTapped(int index) {
|
||||
|
||||
@@ -34,14 +34,16 @@ enum NutritionalPlanOptions {
|
||||
class NutritionalPlanScreen extends StatelessWidget {
|
||||
static const routeName = '/nutritional-plan-detail';
|
||||
|
||||
Future<NutritionalPlan> _loadFullPlan(BuildContext context, int planId) async {
|
||||
Future<NutritionalPlan> _loadFullPlan(
|
||||
BuildContext context, int planId) async {
|
||||
return await Provider.of<NutritionPlansProvider>(context, listen: false)
|
||||
.fetchAndSetPlanFull(planId);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final _nutritionalPlan = ModalRoute.of(context)!.settings.arguments as NutritionalPlan;
|
||||
final _nutritionalPlan =
|
||||
ModalRoute.of(context)!.settings.arguments as NutritionalPlan;
|
||||
|
||||
return Scaffold(
|
||||
//appBar: getAppBar(nutritionalPlan),
|
||||
@@ -91,7 +93,8 @@ class NutritionalPlanScreen extends StatelessWidget {
|
||||
flexibleSpace: FlexibleSpaceBar(
|
||||
title: Text(_nutritionalPlan.description),
|
||||
background: Image(
|
||||
image: AssetImage('assets/images/backgrounds/nutritional_plans.jpg'),
|
||||
image: AssetImage(
|
||||
'assets/images/backgrounds/nutritional_plans.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -46,7 +46,8 @@ class NutritionScreen extends StatelessWidget {
|
||||
},
|
||||
),
|
||||
body: Consumer<NutritionPlansProvider>(
|
||||
builder: (context, nutritionProvider, child) => NutritionalPlansList(nutritionProvider),
|
||||
builder: (context, nutritionProvider, child) =>
|
||||
NutritionalPlansList(nutritionProvider),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -70,7 +70,8 @@ class _WorkoutPlanScreenState extends State<WorkoutPlanScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final workoutPlan = ModalRoute.of(context)!.settings.arguments as WorkoutPlan;
|
||||
final workoutPlan =
|
||||
ModalRoute.of(context)!.settings.arguments as WorkoutPlan;
|
||||
|
||||
return Scaffold(
|
||||
body: CustomScrollView(
|
||||
@@ -81,7 +82,8 @@ class _WorkoutPlanScreenState extends State<WorkoutPlanScreen> {
|
||||
flexibleSpace: FlexibleSpaceBar(
|
||||
title: Text(workoutPlan.name),
|
||||
background: Image(
|
||||
image: AssetImage('assets/images/backgrounds/workout_plans.jpg'),
|
||||
image:
|
||||
AssetImage('assets/images/backgrounds/workout_plans.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
@@ -127,7 +129,8 @@ class _WorkoutPlanScreenState extends State<WorkoutPlanScreen> {
|
||||
),
|
||||
FutureBuilder(
|
||||
future: _loadFullWorkout(context, workoutPlan.id!),
|
||||
builder: (context, AsyncSnapshot<WorkoutPlan> snapshot) => SliverList(
|
||||
builder: (context, AsyncSnapshot<WorkoutPlan> snapshot) =>
|
||||
SliverList(
|
||||
delegate: SliverChildListDelegate(
|
||||
[
|
||||
snapshot.connectionState == ConnectionState.waiting
|
||||
@@ -138,7 +141,8 @@ class _WorkoutPlanScreenState extends State<WorkoutPlanScreen> {
|
||||
),
|
||||
)
|
||||
: Consumer<WorkoutPlansProvider>(
|
||||
builder: (context, value, child) => getBody(workoutPlan),
|
||||
builder: (context, value, child) =>
|
||||
getBody(workoutPlan),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -50,7 +50,8 @@ class WorkoutPlansScreen extends StatelessWidget {
|
||||
},
|
||||
),
|
||||
body: Consumer<WorkoutPlansProvider>(
|
||||
builder: (context, workoutProvider, child) => WorkoutPlansList(workoutProvider),
|
||||
builder: (context, workoutProvider, child) =>
|
||||
WorkoutPlansList(workoutProvider),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -30,8 +30,10 @@ const Color wgerTextMuted = Colors.black38;
|
||||
const Color wgerBackground = Color(0xfff4f4f6);
|
||||
|
||||
// Chart colors
|
||||
const charts.Color wgerChartPrimaryColor = charts.Color(r: 0x2a, g: 0x4c, b: 0x7d);
|
||||
const charts.Color wgerChartSecondaryColor = charts.Color(r: 0xe6, g: 0x39, b: 0x46);
|
||||
const charts.Color wgerChartPrimaryColor =
|
||||
charts.Color(r: 0x2a, g: 0x4c, b: 0x7d);
|
||||
const charts.Color wgerChartSecondaryColor =
|
||||
charts.Color(r: 0xe6, g: 0x39, b: 0x46);
|
||||
|
||||
/// Original sizes for the material text theme
|
||||
/// https://api.flutter.dev/flutter/material/TextTheme-class.html
|
||||
|
||||
@@ -43,7 +43,8 @@ class AppDrawer extends StatelessWidget {
|
||||
onTap: () {
|
||||
Provider.of<AuthProvider>(context, listen: false).logout();
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false).clear();
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false).clear();
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false)
|
||||
.clear();
|
||||
Provider.of<BodyWeightProvider>(context, listen: false).clear();
|
||||
Provider.of<GalleryProvider>(context, listen: false).clear();
|
||||
Navigator.of(context).pop();
|
||||
|
||||
@@ -68,7 +68,8 @@ class WgerAboutListTile extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
onTap: () async => _launchURL("https://github.com/wger-project", context),
|
||||
onTap: () async =>
|
||||
_launchURL("https://github.com/wger-project", context),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
ListTile(
|
||||
@@ -85,8 +86,9 @@ class WgerAboutListTile extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
onTap: () async =>
|
||||
_launchURL('https://github.com/wger-project/flutter/issues/new/choose', context),
|
||||
onTap: () async => _launchURL(
|
||||
'https://github.com/wger-project/flutter/issues/new/choose',
|
||||
context),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
ListTile(
|
||||
@@ -120,7 +122,8 @@ class WgerAboutListTile extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
onTap: () async => _launchURL('https://hosted.weblate.org/engage/wger/', context),
|
||||
onTap: () async =>
|
||||
_launchURL('https://hosted.weblate.org/engage/wger/', context),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -47,7 +47,8 @@ class WgerAppBar extends StatelessWidget with PreferredSizeWidget {
|
||||
title: Text(AppLocalizations.of(context).optionsLabel),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(MaterialLocalizations.of(context).closeButtonLabel),
|
||||
child: Text(
|
||||
MaterialLocalizations.of(context).closeButtonLabel),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
@@ -63,11 +64,19 @@ class WgerAppBar extends StatelessWidget with PreferredSizeWidget {
|
||||
leading: Icon(Icons.exit_to_app),
|
||||
title: Text(AppLocalizations.of(context).logout),
|
||||
onTap: () {
|
||||
Provider.of<AuthProvider>(context, listen: false).logout();
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false).clear();
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false).clear();
|
||||
Provider.of<BodyWeightProvider>(context, listen: false).clear();
|
||||
Provider.of<GalleryProvider>(context, listen: false).clear();
|
||||
Provider.of<AuthProvider>(context, listen: false)
|
||||
.logout();
|
||||
Provider.of<WorkoutPlansProvider>(context,
|
||||
listen: false)
|
||||
.clear();
|
||||
Provider.of<NutritionPlansProvider>(context,
|
||||
listen: false)
|
||||
.clear();
|
||||
Provider.of<BodyWeightProvider>(context,
|
||||
listen: false)
|
||||
.clear();
|
||||
Provider.of<GalleryProvider>(context, listen: false)
|
||||
.clear();
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushReplacementNamed('/');
|
||||
},
|
||||
|
||||
@@ -57,15 +57,16 @@ class DashboardCalendarWidget extends StatefulWidget {
|
||||
DashboardCalendarWidget();
|
||||
|
||||
@override
|
||||
_DashboardCalendarWidgetState createState() => _DashboardCalendarWidgetState();
|
||||
_DashboardCalendarWidgetState createState() =>
|
||||
_DashboardCalendarWidgetState();
|
||||
}
|
||||
|
||||
class _DashboardCalendarWidgetState extends State<DashboardCalendarWidget>
|
||||
with TickerProviderStateMixin {
|
||||
late Map<String, List<Event>> _events;
|
||||
late final ValueNotifier<List<Event>> _selectedEvents;
|
||||
RangeSelectionMode _rangeSelectionMode =
|
||||
RangeSelectionMode.toggledOff; // Can be toggled on/off by longpressing a date
|
||||
RangeSelectionMode _rangeSelectionMode = RangeSelectionMode
|
||||
.toggledOff; // Can be toggled on/off by longpressing a date
|
||||
DateTime _focusedDay = DateTime.now();
|
||||
DateTime? _selectedDay;
|
||||
DateTime? _rangeStart;
|
||||
@@ -83,7 +84,8 @@ class _DashboardCalendarWidgetState extends State<DashboardCalendarWidget>
|
||||
|
||||
void loadEvents() async {
|
||||
// Process weight entries
|
||||
BodyWeightProvider weightProvider = Provider.of<BodyWeightProvider>(context, listen: false);
|
||||
BodyWeightProvider weightProvider =
|
||||
Provider.of<BodyWeightProvider>(context, listen: false);
|
||||
for (var entry in weightProvider.items) {
|
||||
final date = DateFormatLists.format(entry.date);
|
||||
|
||||
@@ -96,7 +98,8 @@ class _DashboardCalendarWidgetState extends State<DashboardCalendarWidget>
|
||||
}
|
||||
|
||||
// Process workout sessions
|
||||
WorkoutPlansProvider plans = Provider.of<WorkoutPlansProvider>(context, listen: false);
|
||||
WorkoutPlansProvider plans =
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false);
|
||||
plans.fetchSessionData().then((entries) {
|
||||
for (var entry in entries['results']) {
|
||||
final session = WorkoutSession.fromJson(entry);
|
||||
@@ -106,7 +109,8 @@ class _DashboardCalendarWidgetState extends State<DashboardCalendarWidget>
|
||||
}
|
||||
var time = '';
|
||||
if (session.timeStart != null && session.timeEnd != null) {
|
||||
time = '(${timeToString(session.timeStart)} - ${timeToString(session.timeEnd)})';
|
||||
time =
|
||||
'(${timeToString(session.timeStart)} - ${timeToString(session.timeEnd)})';
|
||||
}
|
||||
|
||||
// Add events to lists
|
||||
@@ -236,10 +240,12 @@ class _DashboardCalendarWidgetState extends State<DashboardCalendarWidget>
|
||||
title: Text((() {
|
||||
switch (event.type) {
|
||||
case EventType.caloriesDiary:
|
||||
return AppLocalizations.of(context).nutritionalDiary;
|
||||
return AppLocalizations.of(context)
|
||||
.nutritionalDiary;
|
||||
|
||||
case EventType.session:
|
||||
return AppLocalizations.of(context).workoutSession;
|
||||
return AppLocalizations.of(context)
|
||||
.workoutSession;
|
||||
|
||||
case EventType.weight:
|
||||
return AppLocalizations.of(context).weight;
|
||||
|
||||
@@ -41,7 +41,8 @@ import 'package:wger/widgets/workouts/forms.dart';
|
||||
|
||||
class DashboardNutritionWidget extends StatefulWidget {
|
||||
@override
|
||||
_DashboardNutritionWidgetState createState() => _DashboardNutritionWidgetState();
|
||||
_DashboardNutritionWidgetState createState() =>
|
||||
_DashboardNutritionWidgetState();
|
||||
}
|
||||
|
||||
class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
|
||||
@@ -52,7 +53,8 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_plan = Provider.of<NutritionPlansProvider>(context, listen: false).currentPlan;
|
||||
_plan =
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false).currentPlan;
|
||||
_hasContent = _plan != null;
|
||||
}
|
||||
|
||||
@@ -95,7 +97,8 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
|
||||
icon: Icon(Icons.history_edu),
|
||||
color: wgerPrimaryButtonColor,
|
||||
onPressed: () {
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false).logMealToDiary(meal);
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false)
|
||||
.logMealToDiary(meal);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
@@ -126,7 +129,8 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
|
||||
),
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Text('${item.amount.toStringAsFixed(0)} ${AppLocalizations.of(context).g}'),
|
||||
Text(
|
||||
'${item.amount.toStringAsFixed(0)} ${AppLocalizations.of(context).g}'),
|
||||
],
|
||||
),
|
||||
],
|
||||
@@ -156,7 +160,9 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text(
|
||||
_hasContent ? _plan!.description : AppLocalizations.of(context).labelWorkoutPlan,
|
||||
_hasContent
|
||||
? _plan!.description
|
||||
: AppLocalizations.of(context).labelWorkoutPlan,
|
||||
style: Theme.of(context).textTheme.headline4,
|
||||
),
|
||||
subtitle: Text(
|
||||
@@ -185,7 +191,8 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
|
||||
Container(
|
||||
padding: EdgeInsets.all(15),
|
||||
height: 180,
|
||||
child: NutritionalPlanPieChartWidget(_plan!.nutritionalValues),
|
||||
child: NutritionalPlanPieChartWidget(
|
||||
_plan!.nutritionalValues),
|
||||
)
|
||||
],
|
||||
),
|
||||
@@ -202,8 +209,9 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
|
||||
TextButton(
|
||||
child: Text(AppLocalizations.of(context).goToDetailPage),
|
||||
onPressed: () {
|
||||
Navigator.of(context)
|
||||
.pushNamed(NutritionalPlanScreen.routeName, arguments: _plan);
|
||||
Navigator.of(context).pushNamed(
|
||||
NutritionalPlanScreen.routeName,
|
||||
arguments: _plan);
|
||||
}),
|
||||
],
|
||||
),
|
||||
@@ -326,7 +334,8 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
|
||||
icon: Icon(Icons.play_arrow),
|
||||
color: wgerPrimaryButtonColor,
|
||||
onPressed: () {
|
||||
Navigator.of(context).pushNamed(GymModeScreen.routeName, arguments: day);
|
||||
Navigator.of(context)
|
||||
.pushNamed(GymModeScreen.routeName, arguments: day);
|
||||
},
|
||||
),
|
||||
],
|
||||
@@ -348,7 +357,8 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
|
||||
children: [
|
||||
Text(s.exerciseObj.name),
|
||||
SizedBox(width: 10),
|
||||
MutedText(set.getSmartRepr(s.exerciseObj).join('\n')),
|
||||
MutedText(
|
||||
set.getSmartRepr(s.exerciseObj).join('\n')),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
@@ -373,7 +383,9 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text(
|
||||
_hasContent ? _workoutPlan!.name : AppLocalizations.of(context).labelWorkoutPlan,
|
||||
_hasContent
|
||||
? _workoutPlan!.name
|
||||
: AppLocalizations.of(context).labelWorkoutPlan,
|
||||
style: Theme.of(context).textTheme.headline4,
|
||||
),
|
||||
subtitle: Text(
|
||||
@@ -414,8 +426,8 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
|
||||
TextButton(
|
||||
child: Text(AppLocalizations.of(context).goToDetailPage),
|
||||
onPressed: () {
|
||||
Navigator.of(context)
|
||||
.pushNamed(WorkoutPlanScreen.routeName, arguments: _workoutPlan);
|
||||
Navigator.of(context).pushNamed(WorkoutPlanScreen.routeName,
|
||||
arguments: _workoutPlan);
|
||||
},
|
||||
),
|
||||
],
|
||||
|
||||
@@ -68,7 +68,10 @@ class ExerciseDetail extends StatelessWidget {
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
if (_exercise.musclesSecondary.length > 0)
|
||||
Text(_exercise.musclesSecondary.map((e) => e.name).toList().join('\n')),
|
||||
Text(_exercise.musclesSecondary
|
||||
.map((e) => e.name)
|
||||
.toList()
|
||||
.join('\n')),
|
||||
if (_exercise.musclesSecondary.length == 0) Text('-/-'),
|
||||
SizedBox(height: 8),
|
||||
|
||||
|
||||
@@ -113,7 +113,8 @@ class _ImageFormState extends State<ImageForm> {
|
||||
_showPicker(ImageSource.camera);
|
||||
},
|
||||
leading: Icon(Icons.photo_camera),
|
||||
title: Text(AppLocalizations.of(context).takePicture),
|
||||
title:
|
||||
Text(AppLocalizations.of(context).takePicture),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
@@ -121,7 +122,8 @@ class _ImageFormState extends State<ImageForm> {
|
||||
_showPicker(ImageSource.gallery);
|
||||
},
|
||||
leading: Icon(Icons.photo_library),
|
||||
title: Text(AppLocalizations.of(context).chooseFromLibrary))
|
||||
title: Text(AppLocalizations.of(context)
|
||||
.chooseFromLibrary))
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -133,7 +135,8 @@ class _ImageFormState extends State<ImageForm> {
|
||||
),
|
||||
TextFormField(
|
||||
key: Key('field-date'),
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).date),
|
||||
decoration:
|
||||
InputDecoration(labelText: AppLocalizations.of(context).date),
|
||||
controller: dateController,
|
||||
onTap: () async {
|
||||
// Stop keyboard from appearing
|
||||
@@ -162,7 +165,8 @@ class _ImageFormState extends State<ImageForm> {
|
||||
),
|
||||
TextFormField(
|
||||
key: Key('field-description'),
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).description),
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).description),
|
||||
minLines: 3,
|
||||
maxLines: 10,
|
||||
controller: descriptionController,
|
||||
|
||||
@@ -53,7 +53,8 @@ class Gallery extends StatelessWidget {
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
DateFormat.yMd(Localizations.localeOf(context).languageCode)
|
||||
DateFormat.yMd(
|
||||
Localizations.localeOf(context).languageCode)
|
||||
.format(currentImage.date),
|
||||
style: Theme.of(context).textTheme.headline5,
|
||||
),
|
||||
@@ -70,7 +71,8 @@ class Gallery extends StatelessWidget {
|
||||
IconButton(
|
||||
icon: Icon(Icons.delete),
|
||||
onPressed: () {
|
||||
Provider.of<GalleryProvider>(context, listen: false)
|
||||
Provider.of<GalleryProvider>(context,
|
||||
listen: false)
|
||||
.deleteImage(currentImage);
|
||||
Navigator.of(context).pop();
|
||||
}),
|
||||
|
||||
@@ -47,7 +47,10 @@ class NutritionalPlanPieChartWidget extends StatelessWidget {
|
||||
data: [
|
||||
[AppLocalizations.of(context).protein, _nutritionalValues.protein],
|
||||
[AppLocalizations.of(context).fat, _nutritionalValues.fat],
|
||||
[AppLocalizations.of(context).carbohydrates, _nutritionalValues.carbohydrates],
|
||||
[
|
||||
AppLocalizations.of(context).carbohydrates,
|
||||
_nutritionalValues.carbohydrates
|
||||
],
|
||||
],
|
||||
labelAccessorFn: (List<dynamic> row, _) =>
|
||||
'${row[0]}\n${row[1].toStringAsFixed(0)}${AppLocalizations.of(context).g}',
|
||||
|
||||
@@ -52,7 +52,8 @@ class MealForm extends StatelessWidget {
|
||||
children: [
|
||||
TextFormField(
|
||||
key: Key('field-time'),
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).time),
|
||||
decoration:
|
||||
InputDecoration(labelText: AppLocalizations.of(context).time),
|
||||
controller: _timeController,
|
||||
onTap: () async {
|
||||
// Stop keyboard from appearing
|
||||
@@ -82,9 +83,12 @@ class MealForm extends StatelessWidget {
|
||||
|
||||
try {
|
||||
_meal.id == null
|
||||
? Provider.of<NutritionPlansProvider>(context, listen: false)
|
||||
? Provider.of<NutritionPlansProvider>(context,
|
||||
listen: false)
|
||||
.addMeal(_meal, _planId)
|
||||
: Provider.of<NutritionPlansProvider>(context, listen: false).editMeal(_meal);
|
||||
: Provider.of<NutritionPlansProvider>(context,
|
||||
listen: false)
|
||||
.editMeal(_meal);
|
||||
} on WgerHttpException catch (error) {
|
||||
showHttpExceptionErrorDialog(error, context);
|
||||
} catch (error) {
|
||||
@@ -124,10 +128,12 @@ class MealItemForm extends StatelessWidget {
|
||||
TypeAheadFormField(
|
||||
textFieldConfiguration: TextFieldConfiguration(
|
||||
controller: this._ingredientController,
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).ingredient),
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).ingredient),
|
||||
),
|
||||
suggestionsCallback: (pattern) async {
|
||||
return await Provider.of<NutritionPlansProvider>(context, listen: false)
|
||||
return await Provider.of<NutritionPlansProvider>(context,
|
||||
listen: false)
|
||||
.searchIngredient(
|
||||
pattern,
|
||||
Localizations.localeOf(context).languageCode,
|
||||
@@ -154,7 +160,8 @@ class MealItemForm extends StatelessWidget {
|
||||
},
|
||||
),
|
||||
TextFormField(
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).weight),
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).weight),
|
||||
controller: _amountController,
|
||||
keyboardType: TextInputType.number,
|
||||
onFieldSubmitted: (_) {},
|
||||
@@ -215,7 +222,8 @@ class PlanForm extends StatelessWidget {
|
||||
// Description
|
||||
TextFormField(
|
||||
key: Key('field-description'),
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).description),
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).description),
|
||||
controller: _descriptionController,
|
||||
onFieldSubmitted: (_) {},
|
||||
onSaved: (newValue) {
|
||||
@@ -236,10 +244,13 @@ class PlanForm extends StatelessWidget {
|
||||
// Save to DB
|
||||
try {
|
||||
if (_plan.id != null) {
|
||||
await Provider.of<NutritionPlansProvider>(context, listen: false).editPlan(_plan);
|
||||
await Provider.of<NutritionPlansProvider>(context,
|
||||
listen: false)
|
||||
.editPlan(_plan);
|
||||
Navigator.of(context).pop();
|
||||
} else {
|
||||
_plan = await Provider.of<NutritionPlansProvider>(context, listen: false)
|
||||
_plan = await Provider.of<NutritionPlansProvider>(context,
|
||||
listen: false)
|
||||
.addPlan(_plan);
|
||||
Navigator.of(context).pushReplacementNamed(
|
||||
NutritionalPlanScreen.routeName,
|
||||
|
||||
@@ -54,7 +54,8 @@ class _MealWidgetState extends State<MealWidget> {
|
||||
child: Card(
|
||||
child: Column(
|
||||
children: [
|
||||
DismissibleMealHeader(_expanded, _toggleExpanded, meal: widget._meal),
|
||||
DismissibleMealHeader(_expanded, _toggleExpanded,
|
||||
meal: widget._meal),
|
||||
if (_expanded)
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
@@ -63,7 +64,8 @@ class _MealWidgetState extends State<MealWidget> {
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
// Delete the meal
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false)
|
||||
Provider.of<NutritionPlansProvider>(context,
|
||||
listen: false)
|
||||
.deleteMeal(widget._meal);
|
||||
|
||||
// and inform the user
|
||||
@@ -88,7 +90,8 @@ class _MealWidgetState extends State<MealWidget> {
|
||||
icon: const Icon(Icons.history_edu),
|
||||
color: Colors.white,
|
||||
onPressed: () {
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false)
|
||||
Provider.of<NutritionPlansProvider>(context,
|
||||
listen: false)
|
||||
.logMealToDiary(widget._meal);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
@@ -149,7 +152,9 @@ class _MealWidgetState extends State<MealWidget> {
|
||||
],
|
||||
),
|
||||
),
|
||||
...widget._meal.mealItems.map((item) => MealItemWidget(item, _expanded)).toList(),
|
||||
...widget._meal.mealItems
|
||||
.map((item) => MealItemWidget(item, _expanded))
|
||||
.toList(),
|
||||
OutlinedButton(
|
||||
child: Text(AppLocalizations.of(context).addIngredient),
|
||||
onPressed: () {
|
||||
@@ -210,7 +215,8 @@ class MealItemWidget extends StatelessWidget {
|
||||
iconSize: ICON_SIZE_SMALL,
|
||||
onPressed: () {
|
||||
// Delete the meal item
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false)
|
||||
Provider.of<NutritionPlansProvider>(context,
|
||||
listen: false)
|
||||
.deleteMealItem(_item);
|
||||
|
||||
// and inform the user
|
||||
@@ -291,7 +297,8 @@ class DismissibleMealHeader extends StatelessWidget {
|
||||
),
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
icon: _expanded ? Icon(Icons.unfold_less) : Icon(Icons.unfold_more),
|
||||
icon:
|
||||
_expanded ? Icon(Icons.unfold_less) : Icon(Icons.unfold_more),
|
||||
onPressed: () {
|
||||
_toggle();
|
||||
},
|
||||
@@ -320,7 +327,8 @@ class DismissibleMealHeader extends StatelessWidget {
|
||||
confirmDismiss: (direction) async {
|
||||
// Delete
|
||||
if (direction == DismissDirection.startToEnd) {
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false).logMealToDiary(_meal);
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false)
|
||||
.logMealToDiary(_meal);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
|
||||
@@ -89,7 +89,8 @@ class NutritionalPlanDetailWidget extends StatelessWidget {
|
||||
Text(nutritionalValues.energy.toStringAsFixed(0)),
|
||||
Text(nutritionalValues.protein.toStringAsFixed(0)),
|
||||
Text(nutritionalValues.carbohydrates.toStringAsFixed(0)),
|
||||
Text(nutritionalValues.carbohydratesSugar.toStringAsFixed(0)),
|
||||
Text(nutritionalValues.carbohydratesSugar
|
||||
.toStringAsFixed(0)),
|
||||
Text(nutritionalValues.fat.toStringAsFixed(0)),
|
||||
Text(nutritionalValues.fatSaturated.toStringAsFixed(0)),
|
||||
Text(nutritionalValues.fibres.toStringAsFixed(0)),
|
||||
@@ -121,7 +122,8 @@ class NutritionalPlanDetailWidget extends StatelessWidget {
|
||||
Container(
|
||||
padding: EdgeInsets.all(15),
|
||||
height: 220,
|
||||
child: NutritionalDiaryChartWidget(nutritionalPlan: _nutritionalPlan),
|
||||
child:
|
||||
NutritionalDiaryChartWidget(nutritionalPlan: _nutritionalPlan),
|
||||
),
|
||||
Container(
|
||||
height: 200,
|
||||
@@ -179,7 +181,8 @@ class NutritionDiaryEntry extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
DateFormat.yMd(Localizations.localeOf(context).languageCode).format(date),
|
||||
DateFormat.yMd(Localizations.localeOf(context).languageCode)
|
||||
.format(date),
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(values.energy.toStringAsFixed(0)),
|
||||
|
||||
@@ -42,11 +42,13 @@ class NutritionalPlansList extends StatelessWidget {
|
||||
builder: (BuildContext contextDialog) {
|
||||
return AlertDialog(
|
||||
content: Text(
|
||||
AppLocalizations.of(context).confirmDelete(currentPlan.description),
|
||||
AppLocalizations.of(context)
|
||||
.confirmDelete(currentPlan.description),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
||||
child: Text(MaterialLocalizations.of(context)
|
||||
.cancelButtonLabel),
|
||||
onPressed: () => Navigator.of(contextDialog).pop(),
|
||||
),
|
||||
TextButton(
|
||||
@@ -65,7 +67,8 @@ class NutritionalPlansList extends StatelessWidget {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
AppLocalizations.of(context).successfullyDeleted,
|
||||
AppLocalizations.of(context)
|
||||
.successfullyDeleted,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -43,7 +43,8 @@ class WeightChartWidget extends StatelessWidget {
|
||||
],
|
||||
defaultRenderer: new charts.LineRendererConfig(includePoints: true),
|
||||
primaryMeasureAxis: new charts.NumericAxisSpec(
|
||||
tickProviderSpec: new charts.BasicNumericTickProviderSpec(zeroBound: false),
|
||||
tickProviderSpec:
|
||||
new charts.BasicNumericTickProviderSpec(zeroBound: false),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@ import 'package:wger/widgets/weight/forms.dart';
|
||||
class WeightEntriesList extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final _weightProvider = Provider.of<BodyWeightProvider>(context, listen: false);
|
||||
final _weightProvider =
|
||||
Provider.of<BodyWeightProvider>(context, listen: false);
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
@@ -106,7 +107,8 @@ class WeightEntriesList extends StatelessWidget {
|
||||
child: ListTile(
|
||||
title: Text('${currentEntry.weight} kg'),
|
||||
subtitle: Text(
|
||||
DateFormat.yMd(Localizations.localeOf(context).languageCode)
|
||||
DateFormat.yMd(
|
||||
Localizations.localeOf(context).languageCode)
|
||||
.format(currentEntry.date),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -35,7 +35,8 @@ class WeightForm extends StatelessWidget {
|
||||
|
||||
WeightForm([WeightEntry? weightEntry]) {
|
||||
this._weightEntry = weightEntry ?? WeightEntry(date: DateTime.now());
|
||||
weightController.text = _weightEntry.id == null ? '' : _weightEntry.weight.toString();
|
||||
weightController.text =
|
||||
_weightEntry.id == null ? '' : _weightEntry.weight.toString();
|
||||
dateController.text = toDate(_weightEntry.date)!;
|
||||
}
|
||||
|
||||
@@ -47,7 +48,8 @@ class WeightForm extends StatelessWidget {
|
||||
children: [
|
||||
// Weight date
|
||||
TextFormField(
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).date),
|
||||
decoration:
|
||||
InputDecoration(labelText: AppLocalizations.of(context).date),
|
||||
controller: dateController,
|
||||
onTap: () async {
|
||||
// Stop keyboard from appearing
|
||||
@@ -66,7 +68,8 @@ class WeightForm extends StatelessWidget {
|
||||
}
|
||||
|
||||
// if the date is known, don't allow it
|
||||
return Provider.of<BodyWeightProvider>(context, listen: false).findByDate(day) ==
|
||||
return Provider.of<BodyWeightProvider>(context, listen: false)
|
||||
.findByDate(day) ==
|
||||
null
|
||||
? true
|
||||
: false;
|
||||
@@ -82,7 +85,8 @@ class WeightForm extends StatelessWidget {
|
||||
|
||||
// Weight
|
||||
TextFormField(
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).weight),
|
||||
decoration:
|
||||
InputDecoration(labelText: AppLocalizations.of(context).weight),
|
||||
controller: weightController,
|
||||
keyboardType: TextInputType.number,
|
||||
onSaved: (newValue) {
|
||||
@@ -113,9 +117,11 @@ class WeightForm extends StatelessWidget {
|
||||
// Save the entry on the server
|
||||
try {
|
||||
_weightEntry.id == null
|
||||
? await Provider.of<BodyWeightProvider>(context, listen: false)
|
||||
? await Provider.of<BodyWeightProvider>(context,
|
||||
listen: false)
|
||||
.addEntry(_weightEntry)
|
||||
: await Provider.of<BodyWeightProvider>(context, listen: false)
|
||||
: await Provider.of<BodyWeightProvider>(context,
|
||||
listen: false)
|
||||
.editEntry(_weightEntry);
|
||||
} on WgerHttpException catch (error) {
|
||||
showHttpExceptionErrorDialog(error, context);
|
||||
|
||||
@@ -56,7 +56,8 @@ class LogChartWidget extends StatelessWidget {
|
||||
}),
|
||||
],
|
||||
primaryMeasureAxis: new charts.NumericAxisSpec(
|
||||
tickProviderSpec: new charts.BasicNumericTickProviderSpec(zeroBound: false),
|
||||
tickProviderSpec:
|
||||
new charts.BasicNumericTickProviderSpec(zeroBound: false),
|
||||
),
|
||||
behaviors: [
|
||||
new charts.SeriesLegend(
|
||||
|
||||
@@ -61,7 +61,8 @@ class SettingWidget extends StatelessWidget {
|
||||
content: ExerciseDetail(setting.exerciseObj),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(MaterialLocalizations.of(context).closeButtonLabel),
|
||||
child: Text(
|
||||
MaterialLocalizations.of(context).closeButtonLabel),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
@@ -128,7 +129,8 @@ class _WorkoutDayWidgetState extends State<WorkoutDayWidget> {
|
||||
icon: Icon(Icons.delete),
|
||||
iconSize: ICON_SIZE_SMALL,
|
||||
onPressed: () {
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false).deleteSet(set);
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false)
|
||||
.deleteSet(set);
|
||||
},
|
||||
),
|
||||
],
|
||||
@@ -155,7 +157,8 @@ class _WorkoutDayWidgetState extends State<WorkoutDayWidget> {
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false).deleteDay(
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false)
|
||||
.deleteDay(
|
||||
widget._day,
|
||||
);
|
||||
},
|
||||
@@ -186,7 +189,8 @@ class _WorkoutDayWidgetState extends State<WorkoutDayWidget> {
|
||||
arguments: FormScreenArguments(
|
||||
AppLocalizations.of(context).edit,
|
||||
DayFormWidget(
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false)
|
||||
Provider.of<WorkoutPlansProvider>(context,
|
||||
listen: false)
|
||||
.findById(widget._day.workoutId),
|
||||
widget._day),
|
||||
hasListView: true,
|
||||
@@ -259,12 +263,14 @@ class DayHeaderDismissible extends StatelessWidget {
|
||||
style: Theme.of(context).textTheme.headline5,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Text(_day.getDaysTextTranslated(Localizations.localeOf(context).languageCode)),
|
||||
Text(_day.getDaysTextTranslated(
|
||||
Localizations.localeOf(context).languageCode)),
|
||||
],
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: _expanded ? Icon(Icons.unfold_less) : Icon(Icons.unfold_more),
|
||||
icon:
|
||||
_expanded ? Icon(Icons.unfold_less) : Icon(Icons.unfold_more),
|
||||
onPressed: () {
|
||||
_toggle();
|
||||
},
|
||||
@@ -293,7 +299,8 @@ class DayHeaderDismissible extends StatelessWidget {
|
||||
confirmDismiss: (direction) async {
|
||||
// Delete day
|
||||
if (direction == DismissDirection.startToEnd) {
|
||||
Navigator.of(context).pushNamed(GymModeScreen.routeName, arguments: _day);
|
||||
Navigator.of(context)
|
||||
.pushNamed(GymModeScreen.routeName, arguments: _day);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
@@ -41,7 +41,8 @@ class WorkoutForm extends StatelessWidget {
|
||||
WorkoutForm(this._plan);
|
||||
|
||||
final TextEditingController workoutNameController = TextEditingController();
|
||||
final TextEditingController workoutDescriptionController = TextEditingController();
|
||||
final TextEditingController workoutDescriptionController =
|
||||
TextEditingController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -56,13 +57,17 @@ class WorkoutForm extends StatelessWidget {
|
||||
children: [
|
||||
TextFormField(
|
||||
key: Key('field-name'),
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).name),
|
||||
decoration:
|
||||
InputDecoration(labelText: AppLocalizations.of(context).name),
|
||||
controller: workoutNameController,
|
||||
validator: (value) {
|
||||
const minLength = 5;
|
||||
const maxLength = 100;
|
||||
if (value!.isEmpty || value.length < minLength || value.length > maxLength) {
|
||||
return AppLocalizations.of(context).enterCharacters(minLength, maxLength);
|
||||
if (value!.isEmpty ||
|
||||
value.length < minLength ||
|
||||
value.length > maxLength) {
|
||||
return AppLocalizations.of(context)
|
||||
.enterCharacters(minLength, maxLength);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
@@ -73,7 +78,8 @@ class WorkoutForm extends StatelessWidget {
|
||||
),
|
||||
TextFormField(
|
||||
key: Key('field-description'),
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).description),
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).description),
|
||||
minLines: 3,
|
||||
maxLines: 10,
|
||||
controller: workoutDescriptionController,
|
||||
@@ -81,7 +87,8 @@ class WorkoutForm extends StatelessWidget {
|
||||
const minLength = 0;
|
||||
const maxLength = 1000;
|
||||
if (value!.length > maxLength) {
|
||||
return AppLocalizations.of(context).enterCharacters(minLength, maxLength);
|
||||
return AppLocalizations.of(context)
|
||||
.enterCharacters(minLength, maxLength);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
@@ -103,10 +110,12 @@ class WorkoutForm extends StatelessWidget {
|
||||
|
||||
// Save to DB
|
||||
if (_plan.id != null) {
|
||||
await Provider.of<WorkoutPlansProvider>(context, listen: false).editWorkout(_plan);
|
||||
await Provider.of<WorkoutPlansProvider>(context, listen: false)
|
||||
.editWorkout(_plan);
|
||||
Navigator.of(context).pop();
|
||||
} else {
|
||||
_plan = await Provider.of<WorkoutPlansProvider>(context, listen: false)
|
||||
_plan = await Provider.of<WorkoutPlansProvider>(context,
|
||||
listen: false)
|
||||
.addWorkout(_plan);
|
||||
Navigator.of(context).pushReplacementNamed(
|
||||
WorkoutPlanScreen.routeName,
|
||||
@@ -194,8 +203,11 @@ class _DayFormWidgetState extends State<DayFormWidget> {
|
||||
validator: (value) {
|
||||
const minLength = 5;
|
||||
const maxLength = 100;
|
||||
if (value!.isEmpty || value.length < minLength || value.length > maxLength) {
|
||||
return AppLocalizations.of(context).enterCharacters(minLength, maxLength);
|
||||
if (value!.isEmpty ||
|
||||
value.length < minLength ||
|
||||
value.length > maxLength) {
|
||||
return AppLocalizations.of(context)
|
||||
.enterCharacters(minLength, maxLength);
|
||||
}
|
||||
|
||||
if (widget._day.daysOfWeek.length == 0) {
|
||||
@@ -205,7 +217,9 @@ class _DayFormWidgetState extends State<DayFormWidget> {
|
||||
},
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
...Day.weekdays.keys.map((dayNr) => DayCheckbox(dayNr, widget._day)).toList(),
|
||||
...Day.weekdays.keys
|
||||
.map((dayNr) => DayCheckbox(dayNr, widget._day))
|
||||
.toList(),
|
||||
ElevatedButton(
|
||||
key: Key(SUBMIT_BUTTON_KEY_NAME),
|
||||
child: Text(AppLocalizations.of(context).save),
|
||||
@@ -217,12 +231,14 @@ class _DayFormWidgetState extends State<DayFormWidget> {
|
||||
|
||||
try {
|
||||
if (widget._day.id == null) {
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false).addDay(
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false)
|
||||
.addDay(
|
||||
widget._day,
|
||||
widget.workout,
|
||||
);
|
||||
} else {
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false).editDay(
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false)
|
||||
.editDay(
|
||||
widget._day,
|
||||
);
|
||||
}
|
||||
@@ -300,9 +316,11 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
setting.order = order;
|
||||
setting.exercise = exercise;
|
||||
setting.weightUnit =
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false).defaultWeightUnit;
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false)
|
||||
.defaultWeightUnit;
|
||||
setting.repetitionUnit =
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false).defaultRepetitionUnit;
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false)
|
||||
.defaultRepetitionUnit;
|
||||
|
||||
widget._set.settings.add(setting);
|
||||
}
|
||||
@@ -321,7 +339,8 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
child: Column(
|
||||
//crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(AppLocalizations.of(context).nrOfSets(_currentSetSliderValue.round())),
|
||||
Text(AppLocalizations.of(context)
|
||||
.nrOfSets(_currentSetSliderValue.round())),
|
||||
Slider(
|
||||
value: _currentSetSliderValue,
|
||||
min: 1,
|
||||
@@ -370,14 +389,18 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(AppLocalizations.of(context).selectExercises),
|
||||
Text(AppLocalizations.of(context)
|
||||
.selectExercises),
|
||||
SizedBox(height: 10),
|
||||
Text(AppLocalizations.of(context).sameRepetitions)
|
||||
Text(AppLocalizations.of(context)
|
||||
.sameRepetitions)
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(MaterialLocalizations.of(context).closeButtonLabel),
|
||||
child: Text(
|
||||
MaterialLocalizations.of(context)
|
||||
.closeButtonLabel),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
@@ -391,7 +414,8 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
),
|
||||
),
|
||||
suggestionsCallback: (pattern) async {
|
||||
return await Provider.of<ExercisesProvider>(context, listen: false)
|
||||
return await Provider.of<ExercisesProvider>(context,
|
||||
listen: false)
|
||||
.searchExercise(
|
||||
pattern,
|
||||
Localizations.localeOf(context).languageCode,
|
||||
@@ -400,12 +424,14 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
itemBuilder: (context, suggestion) {
|
||||
final result = suggestion! as Map;
|
||||
|
||||
final exercise = Provider.of<ExercisesProvider>(context, listen: false)
|
||||
.findById(result['data']['id']);
|
||||
final exercise =
|
||||
Provider.of<ExercisesProvider>(context, listen: false)
|
||||
.findById(result['data']['id']);
|
||||
return ListTile(
|
||||
leading: Container(
|
||||
width: 45,
|
||||
child: ExerciseImageWidget(image: exercise.getMainImage),
|
||||
child:
|
||||
ExerciseImageWidget(image: exercise.getMainImage),
|
||||
),
|
||||
title: Text(exercise.name),
|
||||
subtitle: Text(
|
||||
@@ -417,8 +443,9 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
},
|
||||
onSuggestionSelected: (suggestion) {
|
||||
final result = suggestion! as Map;
|
||||
final exercise = Provider.of<ExercisesProvider>(context, listen: false)
|
||||
.findById(result['data']['id']);
|
||||
final exercise =
|
||||
Provider.of<ExercisesProvider>(context, listen: false)
|
||||
.findById(result['data']['id']);
|
||||
addExercise(exercise);
|
||||
this._exercisesController.text = '';
|
||||
},
|
||||
@@ -433,7 +460,8 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
.where((s) => s.weight == null && s.reps == null)
|
||||
.length ==
|
||||
widget._set.settings.length) {
|
||||
return AppLocalizations.of(context).enterRepetitionsOrWeight;
|
||||
return AppLocalizations.of(context)
|
||||
.enterRepetitionsOrWeight;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
@@ -441,8 +469,9 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
...widget._set.exercisesObj.map((exercise) {
|
||||
final settings =
|
||||
widget._set.settings.where((e) => e.exerciseObj.id == exercise.id).toList();
|
||||
final settings = widget._set.settings
|
||||
.where((e) => e.exerciseObj.id == exercise.id)
|
||||
.toList();
|
||||
|
||||
return ExerciseSetting(
|
||||
exercise,
|
||||
@@ -462,22 +491,25 @@ class _SetFormWidgetState extends State<SetFormWidget> {
|
||||
}
|
||||
_formKey.currentState!.save();
|
||||
|
||||
final workoutProvider =
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false);
|
||||
final workoutProvider = Provider.of<WorkoutPlansProvider>(
|
||||
context,
|
||||
listen: false);
|
||||
|
||||
// Save set
|
||||
Set setDb = await workoutProvider.addSet(widget._set);
|
||||
widget._set.id = setDb.id;
|
||||
|
||||
// Remove unused settings
|
||||
widget._set.settings.removeWhere((s) => s.weight == null && s.reps == null);
|
||||
widget._set.settings
|
||||
.removeWhere((s) => s.weight == null && s.reps == null);
|
||||
|
||||
// Save remaining settings
|
||||
for (var setting in widget._set.settings) {
|
||||
setting.setId = setDb.id!;
|
||||
setting.comment = '';
|
||||
|
||||
Setting settingDb = await workoutProvider.addSetting(setting);
|
||||
Setting settingDb =
|
||||
await workoutProvider.addSetting(setting);
|
||||
setting.id = settingDb.id;
|
||||
}
|
||||
|
||||
@@ -553,7 +585,8 @@ class ExerciseSetting extends StatelessWidget {
|
||||
SizedBox(width: 4),
|
||||
Flexible(
|
||||
flex: 3,
|
||||
child: WeightUnitInputWidget(setting, key: Key(i.toString())),
|
||||
child:
|
||||
WeightUnitInputWidget(setting, key: Key(i.toString())),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -800,7 +833,8 @@ class _WeightUnitInputWidgetState extends State<WeightUnitInputWidget> {
|
||||
|
||||
return DropdownButtonFormField(
|
||||
value: selectedWeightUnit,
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).weightUnit),
|
||||
decoration:
|
||||
InputDecoration(labelText: AppLocalizations.of(context).weightUnit),
|
||||
onChanged: (WeightUnit? newValue) {
|
||||
setState(() {
|
||||
selectedWeightUnit = newValue!;
|
||||
@@ -827,7 +861,8 @@ class RepetitionUnitInputWidget extends StatefulWidget {
|
||||
RepetitionUnitInputWidget(this._setting);
|
||||
|
||||
@override
|
||||
_RepetitionUnitInputWidgetState createState() => _RepetitionUnitInputWidgetState();
|
||||
_RepetitionUnitInputWidgetState createState() =>
|
||||
_RepetitionUnitInputWidgetState();
|
||||
}
|
||||
|
||||
class _RepetitionUnitInputWidgetState extends State<RepetitionUnitInputWidget> {
|
||||
@@ -837,7 +872,8 @@ class _RepetitionUnitInputWidgetState extends State<RepetitionUnitInputWidget> {
|
||||
|
||||
return DropdownButtonFormField(
|
||||
value: selectedWeightUnit,
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).repetitionUnit),
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).repetitionUnit),
|
||||
isDense: true,
|
||||
onChanged: (RepetitionUnit? newValue) {
|
||||
setState(() {
|
||||
|
||||
@@ -86,8 +86,8 @@ class _GymModeState extends State<GymMode> {
|
||||
for (var set in widget._workoutDay.sets) {
|
||||
var firstPage = true;
|
||||
for (var setting in set.settingsComputed) {
|
||||
final exercise =
|
||||
Provider.of<ExercisesProvider>(context, listen: false).findById(setting.exerciseId);
|
||||
final exercise = Provider.of<ExercisesProvider>(context, listen: false)
|
||||
.findById(setting.exerciseId);
|
||||
|
||||
if (firstPage) {
|
||||
_exercisePages[exercise.name] = currentPage;
|
||||
@@ -106,8 +106,10 @@ class _GymModeState extends State<GymMode> {
|
||||
|
||||
// Returns the list of exercise overview, sets and pause pages
|
||||
List<Widget> getContent() {
|
||||
final exerciseProvider = Provider.of<ExercisesProvider>(context, listen: false);
|
||||
final workoutProvider = Provider.of<WorkoutPlansProvider>(context, listen: false);
|
||||
final exerciseProvider =
|
||||
Provider.of<ExercisesProvider>(context, listen: false);
|
||||
final workoutProvider =
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false);
|
||||
var currentElement = 1;
|
||||
List<Widget> out = [];
|
||||
|
||||
@@ -197,7 +199,10 @@ class StartPage extends StatelessWidget {
|
||||
s.exerciseObj.name,
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
...set.getSmartRepr(s.exerciseObj).map((e) => Text(e)).toList(),
|
||||
...set
|
||||
.getSmartRepr(s.exerciseObj)
|
||||
.map((e) => Text(e))
|
||||
.toList(),
|
||||
SizedBox(height: 15),
|
||||
],
|
||||
);
|
||||
@@ -212,7 +217,8 @@ class StartPage extends StatelessWidget {
|
||||
ElevatedButton(
|
||||
child: Text(AppLocalizations.of(context).start),
|
||||
onPressed: () {
|
||||
_controller.nextPage(duration: Duration(milliseconds: 200), curve: Curves.bounceIn);
|
||||
_controller.nextPage(
|
||||
duration: Duration(milliseconds: 200), curve: Curves.bounceIn);
|
||||
},
|
||||
),
|
||||
NavigationFooter(
|
||||
@@ -458,7 +464,8 @@ class _LogPageState extends State<LogPage> {
|
||||
|
||||
// Save the entry on the server
|
||||
try {
|
||||
await Provider.of<WorkoutPlansProvider>(context, listen: false).addLog(widget._log);
|
||||
await Provider.of<WorkoutPlansProvider>(context, listen: false)
|
||||
.addLog(widget._log);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
duration: Duration(seconds: 2), // default is 4
|
||||
@@ -492,11 +499,14 @@ 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
|
||||
.filterLogsByExercise(widget._exercise, unique: true)
|
||||
.map((log) {
|
||||
return ListTile(
|
||||
title: Text(log.singleLogRepTextNoNl),
|
||||
subtitle:
|
||||
Text(DateFormat.yMd(Localizations.localeOf(context).languageCode).format(log.date)),
|
||||
subtitle: Text(
|
||||
DateFormat.yMd(Localizations.localeOf(context).languageCode)
|
||||
.format(log.date)),
|
||||
trailing: Icon(Icons.copy),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
@@ -549,7 +559,8 @@ class _LogPageState extends State<LogPage> {
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 3),
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 3),
|
||||
child: SizedBox(
|
||||
height: 35,
|
||||
width: 35,
|
||||
@@ -557,7 +568,8 @@ class _LogPageState extends State<LogPage> {
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
key.toString(),
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -570,7 +582,8 @@ class _LogPageState extends State<LogPage> {
|
||||
.toList()
|
||||
],
|
||||
)
|
||||
: MutedText(AppLocalizations.of(context).plateCalculatorNotDivisible),
|
||||
: MutedText(
|
||||
AppLocalizations.of(context).plateCalculatorNotDivisible),
|
||||
),
|
||||
SizedBox(height: 3),
|
||||
],
|
||||
@@ -595,11 +608,16 @@ class _LogPageState extends State<LogPage> {
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Expanded(
|
||||
child: (widget._workoutPlan.filterLogsByExercise(widget._exercise).length > 0)
|
||||
child: (widget._workoutPlan
|
||||
.filterLogsByExercise(widget._exercise)
|
||||
.length >
|
||||
0)
|
||||
? getPastLogs()
|
||||
: Container()),
|
||||
// Only show calculator for barbell
|
||||
if (widget._log.exerciseObj.equipment.map((e) => e.id).contains(ID_EQUIPMENT_BARBELL))
|
||||
if (widget._log.exerciseObj.equipment
|
||||
.map((e) => e.id)
|
||||
.contains(ID_EQUIPMENT_BARBELL))
|
||||
getPlates(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
@@ -660,7 +678,9 @@ class ExerciseOverview extends StatelessWidget {
|
||||
child: ListView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: [
|
||||
..._exercise.images.map((e) => ExerciseImageWidget(image: e)).toList(),
|
||||
..._exercise.images
|
||||
.map((e) => ExerciseImageWidget(image: e))
|
||||
.toList(),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -778,8 +798,8 @@ class _SessionPageState extends State<SessionPage> {
|
||||
children: [
|
||||
Flexible(
|
||||
child: TextFormField(
|
||||
decoration:
|
||||
InputDecoration(labelText: AppLocalizations.of(context).timeStart),
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).timeStart),
|
||||
controller: timeStartController,
|
||||
onFieldSubmitted: (_) {},
|
||||
onTap: () async {
|
||||
@@ -793,7 +813,8 @@ class _SessionPageState extends State<SessionPage> {
|
||||
);
|
||||
|
||||
if (pickedTime != null) {
|
||||
timeStartController.text = timeToString(pickedTime)!;
|
||||
timeStartController.text =
|
||||
timeToString(pickedTime)!;
|
||||
}
|
||||
},
|
||||
onSaved: (newValue) {
|
||||
@@ -804,8 +825,8 @@ class _SessionPageState extends State<SessionPage> {
|
||||
SizedBox(width: 10),
|
||||
Flexible(
|
||||
child: TextFormField(
|
||||
decoration:
|
||||
InputDecoration(labelText: AppLocalizations.of(context).timeEnd),
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).timeEnd),
|
||||
controller: timeEndController,
|
||||
onFieldSubmitted: (_) {},
|
||||
onTap: () async {
|
||||
@@ -839,7 +860,8 @@ class _SessionPageState extends State<SessionPage> {
|
||||
|
||||
// Save the entry on the server
|
||||
try {
|
||||
await Provider.of<WorkoutPlansProvider>(context, listen: false)
|
||||
await Provider.of<WorkoutPlansProvider>(context,
|
||||
listen: false)
|
||||
.addSession(_session);
|
||||
Navigator.of(context).pop();
|
||||
} on WgerHttpException catch (error) {
|
||||
@@ -932,7 +954,10 @@ class _TimerWidgetState extends State<TimerWidget> {
|
||||
child: Center(
|
||||
child: Text(
|
||||
DateFormat('m:ss').format(today.add(Duration(seconds: _seconds))),
|
||||
style: Theme.of(context).textTheme.headline1!.copyWith(color: wgerPrimaryColor),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.headline1!
|
||||
.copyWith(color: wgerPrimaryColor),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -34,7 +34,8 @@ class ExerciseLogChart extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final _workoutPlansData = Provider.of<WorkoutPlansProvider>(context, listen: false);
|
||||
final _workoutPlansData =
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false);
|
||||
final _workout = _workoutPlansData.currentPlan;
|
||||
|
||||
Future<Map<String, dynamic>> _getChartEntries(BuildContext context) async {
|
||||
@@ -43,7 +44,8 @@ class ExerciseLogChart extends StatelessWidget {
|
||||
|
||||
return FutureBuilder(
|
||||
future: _getChartEntries(context),
|
||||
builder: (context, AsyncSnapshot<Map<String, dynamic>> snapshot) => Container(
|
||||
builder: (context, AsyncSnapshot<Map<String, dynamic>> snapshot) =>
|
||||
Container(
|
||||
height: 150,
|
||||
child: snapshot.connectionState == ConnectionState.waiting
|
||||
? Center(child: CircularProgressIndicator())
|
||||
@@ -66,7 +68,8 @@ class DayLogWidget extends StatelessWidget {
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
DateFormat.yMd(Localizations.localeOf(context).languageCode).format(_date),
|
||||
DateFormat.yMd(Localizations.localeOf(context).languageCode)
|
||||
.format(_date),
|
||||
style: Theme.of(context).textTheme.headline5,
|
||||
),
|
||||
if (_session != null) Text('Session data here'),
|
||||
@@ -77,7 +80,9 @@ class DayLogWidget extends StatelessWidget {
|
||||
exercise.name,
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
..._exerciseData[exercise]!.map((log) => Text(log.singleLogRepTextNoNl)).toList(),
|
||||
..._exerciseData[exercise]!
|
||||
.map((log) => Text(log.singleLogRepTextNoNl))
|
||||
.toList(),
|
||||
ExerciseLogChart(exercise, _date),
|
||||
SizedBox(height: 30),
|
||||
],
|
||||
|
||||
@@ -57,7 +57,9 @@ class _WorkoutPlanDetailState extends State<WorkoutPlanDetail> {
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: Text(widget._workoutPlan.description),
|
||||
),
|
||||
...widget._workoutPlan.days.map((workoutDay) => WorkoutDayWidget(workoutDay)).toList(),
|
||||
...widget._workoutPlan.days
|
||||
.map((workoutDay) => WorkoutDayWidget(workoutDay))
|
||||
.toList(),
|
||||
Column(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
|
||||
@@ -44,11 +44,13 @@ class WorkoutPlansList extends StatelessWidget {
|
||||
builder: (BuildContext contextDialog) {
|
||||
return AlertDialog(
|
||||
content: Text(
|
||||
AppLocalizations.of(context).confirmDelete(currentWorkout.name),
|
||||
AppLocalizations.of(context)
|
||||
.confirmDelete(currentWorkout.name),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
||||
child: Text(MaterialLocalizations.of(context)
|
||||
.cancelButtonLabel),
|
||||
onPressed: () => Navigator.of(contextDialog).pop(),
|
||||
),
|
||||
TextButton(
|
||||
@@ -58,7 +60,8 @@ class WorkoutPlansList extends StatelessWidget {
|
||||
),
|
||||
onPressed: () {
|
||||
// Confirmed, delete the workout
|
||||
Provider.of<WorkoutPlansProvider>(context, listen: false)
|
||||
Provider.of<WorkoutPlansProvider>(context,
|
||||
listen: false)
|
||||
.deleteWorkout(currentWorkout.id!);
|
||||
|
||||
// Close the popup
|
||||
@@ -68,7 +71,8 @@ class WorkoutPlansList extends StatelessWidget {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
AppLocalizations.of(context).successfullyDeleted,
|
||||
AppLocalizations.of(context)
|
||||
.successfullyDeleted,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
@@ -99,8 +103,8 @@ class WorkoutPlansList extends StatelessWidget {
|
||||
onTap: () {
|
||||
_workoutProvider.setCurrentPlan(currentWorkout.id!);
|
||||
|
||||
Navigator.of(context)
|
||||
.pushNamed(WorkoutPlanScreen.routeName, arguments: currentWorkout);
|
||||
Navigator.of(context).pushNamed(WorkoutPlanScreen.routeName,
|
||||
arguments: currentWorkout);
|
||||
},
|
||||
title: Text(currentWorkout.name),
|
||||
subtitle: Text(
|
||||
|
||||
@@ -24,7 +24,8 @@ import 'package:wger/providers/auth.dart';
|
||||
import 'package:wger/screens/auth_screen.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Test the widgets on the auth screen, login mode', (WidgetTester tester) async {
|
||||
testWidgets('Test the widgets on the auth screen, login mode',
|
||||
(WidgetTester tester) async {
|
||||
// Wrap screen in material app so that the media query gets a context
|
||||
await tester.pumpWidget(
|
||||
MultiProvider(
|
||||
@@ -80,7 +81,8 @@ void main() {
|
||||
// either the provider wasn't found or, if the call was removed, the
|
||||
// localization data could not be loaded...
|
||||
|
||||
testWidgets('Test the widgets on the auth screen, registration', (WidgetTester tester) async {
|
||||
testWidgets('Test the widgets on the auth screen, registration',
|
||||
(WidgetTester tester) async {
|
||||
// Wrap screen in material app so that the media query gets a context
|
||||
await tester.pumpWidget(MaterialApp(home: AuthScreen()));
|
||||
await tester.tap(find.byKey(Key('toggleActionButton')));
|
||||
|
||||
@@ -46,16 +46,20 @@ void main() {
|
||||
provider.makeUrl('endpoint', query: {'a': '2', 'b': 'c'}),
|
||||
);
|
||||
expect(
|
||||
Uri.https('localhost', '/api/v2/endpoint/log_data/', {'a': '2', 'b': 'c'}),
|
||||
provider.makeUrl('endpoint', objectMethod: 'log_data', query: {'a': '2', 'b': 'c'}),
|
||||
Uri.https(
|
||||
'localhost', '/api/v2/endpoint/log_data/', {'a': '2', 'b': 'c'}),
|
||||
provider.makeUrl('endpoint',
|
||||
objectMethod: 'log_data', query: {'a': '2', 'b': 'c'}),
|
||||
);
|
||||
expect(
|
||||
Uri.https('localhost', '/api/v2/endpoint/42/', {'a': '2', 'b': 'c'}),
|
||||
provider.makeUrl('endpoint', id: 42, query: {'a': '2', 'b': 'c'}),
|
||||
);
|
||||
expect(
|
||||
Uri.https('localhost', '/api/v2/endpoint/42/log_data/', {'a': '2', 'b': 'c'}),
|
||||
provider.makeUrl('endpoint', id: 42, objectMethod: 'log_data', query: {'a': '2', 'b': 'c'}),
|
||||
Uri.https(
|
||||
'localhost', '/api/v2/endpoint/42/log_data/', {'a': '2', 'b': 'c'}),
|
||||
provider.makeUrl('endpoint',
|
||||
id: 42, objectMethod: 'log_data', query: {'a': '2', 'b': 'c'}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -54,7 +54,8 @@ main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Test the widgets on the SetFormWidget', (WidgetTester tester) async {
|
||||
testWidgets('Test the widgets on the SetFormWidget',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
@@ -65,7 +66,8 @@ main() {
|
||||
expect(find.text('Bench\nDumbbell'), findsOneWidget, reason: 'Equipment');
|
||||
|
||||
expect(find.text('Muscles'), findsOneWidget);
|
||||
expect(find.text('Flutterus maximus\nBiceps'), findsOneWidget, reason: 'Muscles');
|
||||
expect(find.text('Flutterus maximus\nBiceps'), findsOneWidget,
|
||||
reason: 'Muscles');
|
||||
|
||||
expect(find.text('Secondary muscles'), findsOneWidget);
|
||||
expect(find.text('Booty'), findsOneWidget, reason: 'Secondary muscles');
|
||||
|
||||
@@ -52,11 +52,14 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Test opening the form for an existing image', (WidgetTester tester) async {
|
||||
await mockNetworkImagesFor(() => tester.pumpWidget(createScreen(useImage: true)));
|
||||
testWidgets('Test opening the form for an existing image',
|
||||
(WidgetTester tester) async {
|
||||
await mockNetworkImagesFor(
|
||||
() => tester.pumpWidget(createScreen(useImage: true)));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(TextFormField), findsNWidgets(2)); // four in the overview, one in the popup
|
||||
expect(find.byType(TextFormField),
|
||||
findsNWidgets(2)); // four in the overview, one in the popup
|
||||
expect(find.text('A very cool image from the gym'), findsOneWidget);
|
||||
expect(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)), findsOneWidget);
|
||||
|
||||
@@ -67,8 +70,10 @@ void main() {
|
||||
verify(mockGalleryProvider.editImage(any, any));
|
||||
});
|
||||
|
||||
testWidgets('Test opening the form for a new image', (WidgetTester tester) async {
|
||||
await mockNetworkImagesFor(() => tester.pumpWidget(createScreen(useImage: false)));
|
||||
testWidgets('Test opening the form for a new image',
|
||||
(WidgetTester tester) async {
|
||||
await mockNetworkImagesFor(
|
||||
() => tester.pumpWidget(createScreen(useImage: false)));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Please select an image'), findsOneWidget);
|
||||
|
||||
@@ -54,13 +54,15 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Test the widgets on the gallery screen', (WidgetTester tester) async {
|
||||
testWidgets('Test the widgets on the gallery screen',
|
||||
(WidgetTester tester) async {
|
||||
await mockNetworkImagesFor(() => tester.pumpWidget(createScreen()));
|
||||
|
||||
expect(find.byType(GestureDetector), findsNWidgets(4));
|
||||
});
|
||||
|
||||
testWidgets('Test opening the form for an existing image', (WidgetTester tester) async {
|
||||
testWidgets('Test opening the form for an existing image',
|
||||
(WidgetTester tester) async {
|
||||
await mockNetworkImagesFor(() => tester.pumpWidget(createScreen()));
|
||||
|
||||
await tester.tap(find.byKey(Key('image-1')));
|
||||
@@ -68,7 +70,8 @@ void main() {
|
||||
|
||||
// Detail dialog opens
|
||||
expect(find.byKey(Key('image-1-detail')), findsOneWidget);
|
||||
expect(find.byType(Image), findsNWidgets(5)); // four in the overview, one in the popup
|
||||
expect(find.byType(Image),
|
||||
findsNWidgets(5)); // four in the overview, one in the popup
|
||||
expect(find.text('A very cool image from the gym'), findsOneWidget);
|
||||
expect(find.byIcon(Icons.edit), findsOneWidget);
|
||||
expect(find.byIcon(Icons.delete), findsOneWidget);
|
||||
@@ -82,7 +85,8 @@ void main() {
|
||||
expect(find.byType(ElevatedButton), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Tests the localization of dates - EN', (WidgetTester tester) async {
|
||||
testWidgets('Tests the localization of dates - EN',
|
||||
(WidgetTester tester) async {
|
||||
await mockNetworkImagesFor(() => tester.pumpWidget(createScreen()));
|
||||
await tester.tap(find.byKey(Key('image-1')));
|
||||
await tester.pumpAndSettle();
|
||||
@@ -90,8 +94,10 @@ void main() {
|
||||
expect(find.text('5/30/2021'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Tests the localization of dates - DE', (WidgetTester tester) async {
|
||||
await mockNetworkImagesFor(() => tester.pumpWidget(createScreen(locale: 'de')));
|
||||
testWidgets('Tests the localization of dates - DE',
|
||||
(WidgetTester tester) async {
|
||||
await mockNetworkImagesFor(
|
||||
() => tester.pumpWidget(createScreen(locale: 'de')));
|
||||
await tester.tap(find.byKey(Key('image-1')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ import 'dart:ui' as _i9;
|
||||
|
||||
import 'package:http/src/client.dart' as _i3;
|
||||
import 'package:http/src/response.dart' as _i4;
|
||||
import 'package:image_picker_platform_interface/src/types/picked_file/io.dart' as _i8;
|
||||
import 'package:image_picker_platform_interface/src/types/picked_file/io.dart'
|
||||
as _i8;
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:wger/models/gallery/image.dart' as _i6;
|
||||
import 'package:wger/providers/auth.dart' as _i2;
|
||||
@@ -37,28 +38,30 @@ class MockGalleryProvider extends _i1.Mock implements _i5.GalleryProvider {
|
||||
}
|
||||
|
||||
@override
|
||||
List<_i6.Image> get images =>
|
||||
(super.noSuchMethod(Invocation.getter(#images), returnValue: <_i6.Image>[])
|
||||
as List<_i6.Image>);
|
||||
List<_i6.Image> get images => (super.noSuchMethod(Invocation.getter(#images),
|
||||
returnValue: <_i6.Image>[]) as List<_i6.Image>);
|
||||
@override
|
||||
set images(List<_i6.Image>? _images) =>
|
||||
super.noSuchMethod(Invocation.setter(#images, _images), returnValueForMissingStub: null);
|
||||
super.noSuchMethod(Invocation.setter(#images, _images),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
bool get hasListeners =>
|
||||
(super.noSuchMethod(Invocation.getter(#hasListeners), returnValue: false) as bool);
|
||||
(super.noSuchMethod(Invocation.getter(#hasListeners), returnValue: false)
|
||||
as bool);
|
||||
@override
|
||||
_i2.AuthProvider get auth =>
|
||||
(super.noSuchMethod(Invocation.getter(#auth), returnValue: _FakeAuthProvider())
|
||||
as _i2.AuthProvider);
|
||||
_i2.AuthProvider get auth => (super.noSuchMethod(Invocation.getter(#auth),
|
||||
returnValue: _FakeAuthProvider()) as _i2.AuthProvider);
|
||||
@override
|
||||
set auth(_i2.AuthProvider? _auth) =>
|
||||
super.noSuchMethod(Invocation.setter(#auth, _auth), returnValueForMissingStub: null);
|
||||
super.noSuchMethod(Invocation.setter(#auth, _auth),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
_i3.Client get client =>
|
||||
(super.noSuchMethod(Invocation.getter(#client), returnValue: _FakeClient()) as _i3.Client);
|
||||
_i3.Client get client => (super.noSuchMethod(Invocation.getter(#client),
|
||||
returnValue: _FakeClient()) as _i3.Client);
|
||||
@override
|
||||
set client(_i3.Client? _client) =>
|
||||
super.noSuchMethod(Invocation.setter(#client, _client), returnValueForMissingStub: null);
|
||||
super.noSuchMethod(Invocation.setter(#client, _client),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
_i7.Future<void> fetchAndSetGallery() =>
|
||||
(super.noSuchMethod(Invocation.method(#fetchAndSetGallery, []),
|
||||
@@ -80,41 +83,48 @@ class MockGalleryProvider extends _i1.Mock implements _i5.GalleryProvider {
|
||||
returnValue: Future<void>.value(null),
|
||||
returnValueForMissingStub: Future.value()) as _i7.Future<void>);
|
||||
@override
|
||||
void addListener(_i9.VoidCallback? listener) => super
|
||||
.noSuchMethod(Invocation.method(#addListener, [listener]), returnValueForMissingStub: null);
|
||||
void addListener(_i9.VoidCallback? listener) =>
|
||||
super.noSuchMethod(Invocation.method(#addListener, [listener]),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
void removeListener(_i9.VoidCallback? listener) =>
|
||||
super.noSuchMethod(Invocation.method(#removeListener, [listener]),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
void dispose() =>
|
||||
super.noSuchMethod(Invocation.method(#dispose, []), returnValueForMissingStub: null);
|
||||
void dispose() => super.noSuchMethod(Invocation.method(#dispose, []),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
void notifyListeners() =>
|
||||
super.noSuchMethod(Invocation.method(#notifyListeners, []), returnValueForMissingStub: null);
|
||||
super.noSuchMethod(Invocation.method(#notifyListeners, []),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
Uri makeUrl(String? path, {int? id, String? objectMethod, Map<String, dynamic>? query}) =>
|
||||
Uri makeUrl(String? path,
|
||||
{int? id, String? objectMethod, Map<String, dynamic>? query}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#makeUrl, [path], {#id: id, #objectMethod: objectMethod, #query: query}),
|
||||
Invocation.method(#makeUrl, [path],
|
||||
{#id: id, #objectMethod: objectMethod, #query: query}),
|
||||
returnValue: _FakeUri()) as Uri);
|
||||
@override
|
||||
_i7.Future<Map<String, dynamic>> fetch(Uri? uri) =>
|
||||
(super.noSuchMethod(Invocation.method(#fetch, [uri]),
|
||||
returnValue: Future<Map<String, dynamic>>.value(<String, dynamic>{}))
|
||||
as _i7.Future<Map<String, dynamic>>);
|
||||
_i7.Future<Map<String, dynamic>> fetch(Uri? uri) => (super.noSuchMethod(
|
||||
Invocation.method(#fetch, [uri]),
|
||||
returnValue: Future<Map<String, dynamic>>.value(<String, dynamic>{}))
|
||||
as _i7.Future<Map<String, dynamic>>);
|
||||
@override
|
||||
_i7.Future<Map<String, dynamic>> post(Map<String, dynamic>? data, Uri? uri) =>
|
||||
(super.noSuchMethod(Invocation.method(#post, [data, uri]),
|
||||
returnValue: Future<Map<String, dynamic>>.value(<String, dynamic>{}))
|
||||
returnValue:
|
||||
Future<Map<String, dynamic>>.value(<String, dynamic>{}))
|
||||
as _i7.Future<Map<String, dynamic>>);
|
||||
@override
|
||||
_i7.Future<Map<String, dynamic>> patch(Map<String, dynamic>? data, Uri? uri) =>
|
||||
_i7.Future<Map<String, dynamic>> patch(
|
||||
Map<String, dynamic>? data, Uri? uri) =>
|
||||
(super.noSuchMethod(Invocation.method(#patch, [data, uri]),
|
||||
returnValue: Future<Map<String, dynamic>>.value(<String, dynamic>{}))
|
||||
returnValue:
|
||||
Future<Map<String, dynamic>>.value(<String, dynamic>{}))
|
||||
as _i7.Future<Map<String, dynamic>>);
|
||||
@override
|
||||
_i7.Future<_i4.Response> deleteRequest(String? url, int? id) =>
|
||||
(super.noSuchMethod(Invocation.method(#deleteRequest, [url, id]),
|
||||
returnValue: Future<_i4.Response>.value(_FakeResponse())) as _i7.Future<_i4.Response>);
|
||||
returnValue: Future<_i4.Response>.value(_FakeResponse()))
|
||||
as _i7.Future<_i4.Response>);
|
||||
}
|
||||
|
||||
@@ -69,7 +69,8 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Test the widgets on the gym mode screen', (WidgetTester tester) async {
|
||||
testWidgets('Test the widgets on the gym mode screen',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
await tester.tap(find.byType(TextButton));
|
||||
await tester.pumpAndSettle();
|
||||
@@ -105,7 +106,8 @@ void main() {
|
||||
expect(find.text('test exercise 1'), findsOneWidget);
|
||||
expect(find.byType(LogPage), findsOneWidget);
|
||||
expect(find.byType(Form), findsOneWidget);
|
||||
expect(find.byType(ListTile), findsNWidgets(3), reason: 'Two logs and the switch tile');
|
||||
expect(find.byType(ListTile), findsNWidgets(3),
|
||||
reason: 'Two logs and the switch tile');
|
||||
expect(find.text('10 × 10 kg (1.5 RiR)'), findsOneWidget);
|
||||
expect(find.text('12 × 10 kg (2 RiR)'), findsOneWidget);
|
||||
expect(find.byIcon(Icons.close), findsOneWidget);
|
||||
|
||||
@@ -94,7 +94,8 @@ void main() {
|
||||
verifyNever(mockNutrition.addMeal(any, any));
|
||||
});
|
||||
|
||||
testWidgets('Test creating a new nutritional plan', (WidgetTester tester) async {
|
||||
testWidgets('Test creating a new nutritional plan',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen(meal2));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
|
||||
@@ -68,7 +68,8 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Test the widgets on the nutritional plan form', (WidgetTester tester) async {
|
||||
testWidgets('Test the widgets on the nutritional plan form',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen(plan1));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
@@ -77,7 +78,8 @@ void main() {
|
||||
expect(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Test editing an existing nutritional plan', (WidgetTester tester) async {
|
||||
testWidgets('Test editing an existing nutritional plan',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen(plan1));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
@@ -86,7 +88,8 @@ void main() {
|
||||
findsOneWidget,
|
||||
reason: 'Description of existing nutritional plan is filled in',
|
||||
);
|
||||
await tester.enterText(find.byKey(Key('field-description')), 'New description');
|
||||
await tester.enterText(
|
||||
find.byKey(Key('field-description')), 'New description');
|
||||
await tester.tap(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)));
|
||||
|
||||
// Correct method was called
|
||||
@@ -107,12 +110,15 @@ void main() {
|
||||
//);
|
||||
});
|
||||
|
||||
testWidgets('Test creating a new nutritional plan', (WidgetTester tester) async {
|
||||
testWidgets('Test creating a new nutritional plan',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen(plan2));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text(('')), findsOneWidget, reason: 'New nutritional plan has no description');
|
||||
await tester.enterText(find.byKey(Key('field-description')), 'New cool plan');
|
||||
expect(find.text(('')), findsOneWidget,
|
||||
reason: 'New nutritional plan has no description');
|
||||
await tester.enterText(
|
||||
find.byKey(Key('field-description')), 'New cool plan');
|
||||
await tester.tap(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)));
|
||||
|
||||
// Correct method was called
|
||||
@@ -121,6 +127,7 @@ void main() {
|
||||
|
||||
// Detail page
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text(('New cool plan')), findsOneWidget, reason: 'Nutritional plan detail page');
|
||||
expect(find.text(('New cool plan')), findsOneWidget,
|
||||
reason: 'Nutritional plan detail page');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -25,14 +25,16 @@ void main() {
|
||||
group('model tests', () {
|
||||
test('Test the nutritionalValues method for nutritional plans', () {
|
||||
final plan = getNutritionalPlan();
|
||||
final values = NutritionalValues.values(4118.75, 28.75, 347.5, 9.5, 41.0, 31.75, 41.5, 30.0);
|
||||
final values = NutritionalValues.values(
|
||||
4118.75, 28.75, 347.5, 9.5, 41.0, 31.75, 41.5, 30.0);
|
||||
expect(plan.nutritionalValues, values);
|
||||
});
|
||||
|
||||
test('Test the nutritionalValues method for meals', () {
|
||||
final plan = getNutritionalPlan();
|
||||
final meal = plan.meals.first;
|
||||
final values = NutritionalValues.values(518.75, 1.75, 17.5, 3.5, 11.0, 7.75, 38.5, 0.0);
|
||||
final values = NutritionalValues.values(
|
||||
518.75, 1.75, 17.5, 3.5, 11.0, 7.75, 38.5, 0.0);
|
||||
expect(meal.nutritionalValues, values);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -55,7 +55,8 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Test the widgets on the nutritional plan screen', (WidgetTester tester) async {
|
||||
testWidgets('Test the widgets on the nutritional plan screen',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createNutritionalPlan());
|
||||
await tester.tap(find.byType(TextButton));
|
||||
await tester.pumpAndSettle();
|
||||
@@ -72,7 +73,8 @@ void main() {
|
||||
expect(find.byType(NutritionalDiaryChartWidget), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('Tests the localization of times - EN', (WidgetTester tester) async {
|
||||
testWidgets('Tests the localization of times - EN',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createNutritionalPlan());
|
||||
await tester.tap(find.byType(TextButton));
|
||||
await tester.pumpAndSettle();
|
||||
@@ -80,7 +82,8 @@ void main() {
|
||||
expect(find.text('5:00 PM'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Tests the localization of times - DE', (WidgetTester tester) async {
|
||||
testWidgets('Tests the localization of times - DE',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createNutritionalPlan(locale: 'de'));
|
||||
await tester.tap(find.byType(TextButton));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
@@ -43,8 +43,14 @@ void main() {
|
||||
create: (context) => NutritionPlansProvider(
|
||||
testAuthProvider,
|
||||
[
|
||||
NutritionalPlan(id: 1, description: 'test plan 1', creationDate: DateTime(2021, 01, 01)),
|
||||
NutritionalPlan(id: 2, description: 'test plan 2', creationDate: DateTime(2021, 01, 10)),
|
||||
NutritionalPlan(
|
||||
id: 1,
|
||||
description: 'test plan 1',
|
||||
creationDate: DateTime(2021, 01, 01)),
|
||||
NutritionalPlan(
|
||||
id: 2,
|
||||
description: 'test plan 2',
|
||||
creationDate: DateTime(2021, 01, 10)),
|
||||
],
|
||||
client,
|
||||
),
|
||||
@@ -60,7 +66,8 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Test the widgets on the nutritional plans screen', (WidgetTester tester) async {
|
||||
testWidgets('Test the widgets on the nutritional plans screen',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
|
||||
//debugDumpApp();
|
||||
@@ -69,7 +76,8 @@ void main() {
|
||||
expect(find.byType(ListTile), findsNWidgets(2));
|
||||
});
|
||||
|
||||
testWidgets('Test deleting an item by dragging the dismissible', (WidgetTester tester) async {
|
||||
testWidgets('Test deleting an item by dragging the dismissible',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
|
||||
await tester.drag(find.byKey(Key('1')), Offset(-500.0, 0.0));
|
||||
@@ -84,7 +92,8 @@ void main() {
|
||||
expect(find.byType(ListTile), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Test the form on the nutritional plan screen', (WidgetTester tester) async {
|
||||
testWidgets('Test the form on the nutritional plan screen',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
|
||||
expect(find.byType(PlanForm), findsNothing);
|
||||
@@ -93,14 +102,16 @@ void main() {
|
||||
expect(find.byType(PlanForm), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Tests the localization of dates - EN', (WidgetTester tester) async {
|
||||
testWidgets('Tests the localization of dates - EN',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
|
||||
expect(find.text('1/1/2021'), findsOneWidget);
|
||||
expect(find.text('1/10/2021'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Tests the localization of dates - DE', (WidgetTester tester) async {
|
||||
testWidgets('Tests the localization of dates - DE',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen(locale: 'de'));
|
||||
|
||||
expect(find.text('1.1.2021'), findsOneWidget);
|
||||
|
||||
@@ -27,9 +27,12 @@ void main() {
|
||||
|
||||
group('Test the NutritionalValues class', () {
|
||||
setUp(() {
|
||||
values1 = NutritionalValues.values(4000, 30.5, 340.5, 11.7, 41.0, 31.75, 21.3, 33.3);
|
||||
values2 = NutritionalValues.values(4000, 30.5, 340.5, 11.7, 41.0, 31.75, 21.3, 33.3);
|
||||
values3 = NutritionalValues.values(5000, 30.5, 340.5, 11.7, 41.0, 31.75, 21.3, 33.3);
|
||||
values1 = NutritionalValues.values(
|
||||
4000, 30.5, 340.5, 11.7, 41.0, 31.75, 21.3, 33.3);
|
||||
values2 = NutritionalValues.values(
|
||||
4000, 30.5, 340.5, 11.7, 41.0, 31.75, 21.3, 33.3);
|
||||
values3 = NutritionalValues.values(
|
||||
5000, 30.5, 340.5, 11.7, 41.0, 31.75, 21.3, 33.3);
|
||||
values4 = NutritionalValues.values(1000, 10, 100, 1, 10.0, 10, 10, 10);
|
||||
});
|
||||
|
||||
@@ -40,13 +43,15 @@ void main() {
|
||||
|
||||
test('Test the plus operator', () {
|
||||
final values5 = values1 + values4;
|
||||
final result = NutritionalValues.values(5000, 40.5, 440.5, 12.7, 51.0, 41.75, 31.3, 43.3);
|
||||
final result = NutritionalValues.values(
|
||||
5000, 40.5, 440.5, 12.7, 51.0, 41.75, 31.3, 43.3);
|
||||
expect(values5, result);
|
||||
});
|
||||
|
||||
test('Test the add method', () {
|
||||
values1.add(values4);
|
||||
final result = NutritionalValues.values(5000, 40.5, 440.5, 12.7, 51.0, 41.75, 31.3, 43.3);
|
||||
final result = NutritionalValues.values(
|
||||
5000, 40.5, 440.5, 12.7, 51.0, 41.75, 31.3, 43.3);
|
||||
expect(values1, result);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,8 +25,10 @@ void main() {
|
||||
test('Regular weights', () async {
|
||||
expect(plateCalculator(40, BAR_WEIGHT, AVAILABLE_PLATES), [10]);
|
||||
expect(plateCalculator(100, BAR_WEIGHT, AVAILABLE_PLATES), [15, 15, 10]);
|
||||
expect(plateCalculator(102.5, BAR_WEIGHT, AVAILABLE_PLATES), [15, 15, 10, 1.25]);
|
||||
expect(plateCalculator(140, BAR_WEIGHT, AVAILABLE_PLATES), [15, 15, 15, 15]);
|
||||
expect(plateCalculator(102.5, BAR_WEIGHT, AVAILABLE_PLATES),
|
||||
[15, 15, 10, 1.25]);
|
||||
expect(
|
||||
plateCalculator(140, BAR_WEIGHT, AVAILABLE_PLATES), [15, 15, 15, 15]);
|
||||
expect(plateCalculator(45, BAR_WEIGHT, AVAILABLE_PLATES), [10, 2.5]);
|
||||
expect(plateCalculator(85, BAR_WEIGHT, AVAILABLE_PLATES), [15, 15, 2.5]);
|
||||
});
|
||||
|
||||
@@ -21,16 +21,23 @@ import 'package:wger/models/body_weight/weight_entry.dart';
|
||||
|
||||
void main() {
|
||||
group('fetchPost', () {
|
||||
test('Test that the weight entries are correctly converted to json', () async {
|
||||
WeightEntry weightEntry = WeightEntry(id: 1, weight: 80, date: DateTime(2020, 12, 31));
|
||||
expect(weightEntry.toJson(), {'id': 1, 'weight': '80', 'date': '2020-12-31'});
|
||||
test('Test that the weight entries are correctly converted to json',
|
||||
() async {
|
||||
WeightEntry weightEntry =
|
||||
WeightEntry(id: 1, weight: 80, date: DateTime(2020, 12, 31));
|
||||
expect(weightEntry.toJson(),
|
||||
{'id': 1, 'weight': '80', 'date': '2020-12-31'});
|
||||
|
||||
weightEntry = WeightEntry(id: 2, weight: 70.2, date: DateTime(2020, 12, 01));
|
||||
expect(weightEntry.toJson(), {'id': 2, 'weight': '70.2', 'date': '2020-12-01'});
|
||||
weightEntry =
|
||||
WeightEntry(id: 2, weight: 70.2, date: DateTime(2020, 12, 01));
|
||||
expect(weightEntry.toJson(),
|
||||
{'id': 2, 'weight': '70.2', 'date': '2020-12-01'});
|
||||
});
|
||||
|
||||
test('Test that the weight entries are correctly converted from json', () async {
|
||||
WeightEntry weightEntryObj = WeightEntry(id: 1, weight: 80, date: DateTime(2020, 12, 31));
|
||||
test('Test that the weight entries are correctly converted from json',
|
||||
() async {
|
||||
WeightEntry weightEntryObj =
|
||||
WeightEntry(id: 1, weight: 80, date: DateTime(2020, 12, 31));
|
||||
WeightEntry weightEntry = WeightEntry.fromJson({
|
||||
'id': 1,
|
||||
'weight': '80',
|
||||
@@ -46,7 +53,8 @@ void main() {
|
||||
test('Test the individual values from the model', () {
|
||||
WeightEntry _weightModel;
|
||||
//_weightModel = WeightEntry();
|
||||
_weightModel = WeightEntry(id: 1, weight: 80, date: DateTime(2020, 10, 01));
|
||||
_weightModel =
|
||||
WeightEntry(id: 1, weight: 80, date: DateTime(2020, 10, 01));
|
||||
|
||||
expect(_weightModel.id, 1);
|
||||
expect(_weightModel.weight, 80);
|
||||
|
||||
@@ -41,7 +41,8 @@ void main() {
|
||||
200));
|
||||
|
||||
// Load the entries
|
||||
BodyWeightProvider provider = BodyWeightProvider(testAuthProvider, [], client);
|
||||
BodyWeightProvider provider =
|
||||
BodyWeightProvider(testAuthProvider, [], client);
|
||||
await provider.fetchAndSetEntries();
|
||||
|
||||
// Check that everything is ok
|
||||
@@ -59,12 +60,14 @@ void main() {
|
||||
headers: anyNamed('headers'),
|
||||
body: '{"id":null,"weight":"80","date":"2021-01-01"}',
|
||||
),
|
||||
).thenAnswer(
|
||||
(_) async => http.Response('{"id": 25, "date": "2021-01-01", "weight": "80"}', 200));
|
||||
).thenAnswer((_) async => http.Response(
|
||||
'{"id": 25, "date": "2021-01-01", "weight": "80"}', 200));
|
||||
|
||||
// POST the data to the server
|
||||
final WeightEntry weightEntry = WeightEntry(date: DateTime(2021, 1, 1), weight: 80);
|
||||
final BodyWeightProvider provider = BodyWeightProvider(testAuthProvider, [], client);
|
||||
final WeightEntry weightEntry =
|
||||
WeightEntry(date: DateTime(2021, 1, 1), weight: 80);
|
||||
final BodyWeightProvider provider =
|
||||
BodyWeightProvider(testAuthProvider, [], client);
|
||||
final WeightEntry weightEntryNew = await provider.addEntry(weightEntry);
|
||||
|
||||
// Check that the server response is what we expect
|
||||
|
||||
@@ -43,8 +43,8 @@ void main() {
|
||||
any,
|
||||
headers: anyNamed('headers'),
|
||||
body: anyNamed('body'),
|
||||
)).thenAnswer(
|
||||
(_) async => http.Response('{"id": 3, "date": "2021-01-01", "weight": "80"}', 200));
|
||||
)).thenAnswer((_) async =>
|
||||
http.Response('{"id": 3, "date": "2021-01-01", "weight": "80"}', 200));
|
||||
|
||||
return ChangeNotifierProvider<BodyWeightProvider>(
|
||||
create: (context) => BodyWeightProvider(
|
||||
@@ -67,7 +67,8 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Test the widgets on the body weight screen', (WidgetTester tester) async {
|
||||
testWidgets('Test the widgets on the body weight screen',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
|
||||
//debugDumpApp();
|
||||
@@ -77,7 +78,8 @@ void main() {
|
||||
expect(find.byType(ListTile), findsNWidgets(2));
|
||||
});
|
||||
|
||||
testWidgets('Test deleting an item by dragging the dismissible', (WidgetTester tester) async {
|
||||
testWidgets('Test deleting an item by dragging the dismissible',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
|
||||
await tester.drag(find.byKey(Key('1')), Offset(-500.0, 0.0));
|
||||
@@ -85,7 +87,8 @@ void main() {
|
||||
expect(find.byType(ListTile), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Test the form on the body weight screen', (WidgetTester tester) async {
|
||||
testWidgets('Test the form on the body weight screen',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
|
||||
expect(find.byType(WeightForm), findsNothing);
|
||||
@@ -94,14 +97,16 @@ void main() {
|
||||
expect(find.byType(WeightForm), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Tests the localization of dates - EN', (WidgetTester tester) async {
|
||||
testWidgets('Tests the localization of dates - EN',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
|
||||
expect(find.text('1/1/2021'), findsOneWidget);
|
||||
expect(find.text('1/10/2021'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Tests the localization of dates - DE', (WidgetTester tester) async {
|
||||
testWidgets('Tests the localization of dates - DE',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen(locale: 'de'));
|
||||
|
||||
expect(find.text('1.1.2021'), findsOneWidget);
|
||||
|
||||
@@ -56,7 +56,8 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Test the widgets on the DayFormWidget', (WidgetTester tester) async {
|
||||
testWidgets('Test the widgets on the DayFormWidget',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
@@ -66,12 +67,14 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Test creating a new day', (WidgetTester tester) async {
|
||||
when(mockWorkoutPlans.addDay(any, any)).thenAnswer((_) => Future.value(Day()));
|
||||
when(mockWorkoutPlans.addDay(any, any))
|
||||
.thenAnswer((_) => Future.value(Day()));
|
||||
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text(('')), findsOneWidget, reason: 'New day has no description');
|
||||
expect(find.text(('')), findsOneWidget,
|
||||
reason: 'New day has no description');
|
||||
await tester.enterText(find.byKey(Key('field-description')), 'Leg day!');
|
||||
await tester.tap(find.byKey(Key('field-checkbox-1')));
|
||||
await tester.tap(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)));
|
||||
@@ -83,7 +86,8 @@ void main() {
|
||||
//verify(mockObserver.didPop(any, any));
|
||||
});
|
||||
|
||||
testWidgets('Tests the localization of days - EN', (WidgetTester tester) async {
|
||||
testWidgets('Tests the localization of days - EN',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
|
||||
expect(find.text('Monday'), findsOneWidget);
|
||||
@@ -91,7 +95,8 @@ void main() {
|
||||
expect(find.text('Thursday'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Tests the localization of days - DE', (WidgetTester tester) async {
|
||||
testWidgets('Tests the localization of days - DE',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen(locale: 'de'));
|
||||
|
||||
expect(find.text('Montag'), findsOneWidget);
|
||||
|
||||
@@ -44,7 +44,8 @@ void main() {
|
||||
|
||||
setUp(() {
|
||||
mockWorkoutPlans = MockWorkoutPlansProvider();
|
||||
when(mockWorkoutPlans.editWorkout(any)).thenAnswer((_) => Future.value(existingPlan));
|
||||
when(mockWorkoutPlans.editWorkout(any))
|
||||
.thenAnswer((_) => Future.value(existingPlan));
|
||||
when(mockWorkoutPlans.fetchAndSetWorkoutPlanFull(any))
|
||||
.thenAnswer((_) => Future.value(existingPlan));
|
||||
});
|
||||
@@ -69,7 +70,8 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Test the widgets on the workout form', (WidgetTester tester) async {
|
||||
testWidgets('Test the widgets on the workout form',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen(existingPlan));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
@@ -107,19 +109,22 @@ void main() {
|
||||
//expect(find.text(('New description')), findsOneWidget, reason: 'Workout plan detail page');
|
||||
});
|
||||
|
||||
testWidgets('Test creating a new workout - only name', (WidgetTester tester) async {
|
||||
testWidgets('Test creating a new workout - only name',
|
||||
(WidgetTester tester) async {
|
||||
final editWorkout = WorkoutPlan(
|
||||
id: 2,
|
||||
creationDate: newPlan.creationDate,
|
||||
name: 'New cool workout',
|
||||
);
|
||||
|
||||
when(mockWorkoutPlans.addWorkout(any)).thenAnswer((_) => Future.value(editWorkout));
|
||||
when(mockWorkoutPlans.addWorkout(any))
|
||||
.thenAnswer((_) => Future.value(editWorkout));
|
||||
|
||||
await tester.pumpWidget(createHomeScreen(newPlan));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text(('')), findsNWidgets(2), reason: 'New workout has no name or description');
|
||||
expect(find.text(('')), findsNWidgets(2),
|
||||
reason: 'New workout has no name or description');
|
||||
await tester.enterText(find.byKey(Key('field-name')), editWorkout.name);
|
||||
await tester.tap(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)));
|
||||
|
||||
@@ -128,20 +133,28 @@ void main() {
|
||||
|
||||
// Detail page
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text(('New cool workout')), findsOneWidget, reason: 'Workout plan detail page');
|
||||
expect(find.text(('New cool workout')), findsOneWidget,
|
||||
reason: 'Workout plan detail page');
|
||||
});
|
||||
|
||||
testWidgets('Test creating a new workout - name and description', (WidgetTester tester) async {
|
||||
testWidgets('Test creating a new workout - name and description',
|
||||
(WidgetTester tester) async {
|
||||
final editWorkout = WorkoutPlan(
|
||||
id: 2, creationDate: newPlan.creationDate, name: 'My workout', description: 'Get yuuuge');
|
||||
when(mockWorkoutPlans.addWorkout(any)).thenAnswer((_) => Future.value(editWorkout));
|
||||
id: 2,
|
||||
creationDate: newPlan.creationDate,
|
||||
name: 'My workout',
|
||||
description: 'Get yuuuge');
|
||||
when(mockWorkoutPlans.addWorkout(any))
|
||||
.thenAnswer((_) => Future.value(editWorkout));
|
||||
|
||||
await tester.pumpWidget(createHomeScreen(newPlan));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text(('')), findsNWidgets(2), reason: 'New workout has no name or description');
|
||||
expect(find.text(('')), findsNWidgets(2),
|
||||
reason: 'New workout has no name or description');
|
||||
await tester.enterText(find.byKey(Key('field-name')), editWorkout.name);
|
||||
await tester.enterText(find.byKey(Key('field-description')), editWorkout.description);
|
||||
await tester.enterText(
|
||||
find.byKey(Key('field-description')), editWorkout.description);
|
||||
await tester.tap(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)));
|
||||
|
||||
verifyNever(mockWorkoutPlans.editWorkout(any));
|
||||
@@ -149,6 +162,7 @@ void main() {
|
||||
|
||||
// Detail page
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text(('My workout')), findsOneWidget, reason: 'Workout plan detail page');
|
||||
expect(find.text(('My workout')), findsOneWidget,
|
||||
reason: 'Workout plan detail page');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ void main() {
|
||||
final client = MockClient();
|
||||
|
||||
return ChangeNotifierProvider<WorkoutPlansProvider>(
|
||||
create: (context) =>
|
||||
WorkoutPlansProvider(testAuthProvider, testExercisesProvider, [], client),
|
||||
create: (context) => WorkoutPlansProvider(
|
||||
testAuthProvider, testExercisesProvider, [], client),
|
||||
child: MaterialApp(
|
||||
locale: Locale(locale),
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
@@ -56,7 +56,8 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Test the widgets on the nutritional plan screen', (WidgetTester tester) async {
|
||||
testWidgets('Test the widgets on the nutritional plan screen',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
await tester.tap(find.byType(TextButton));
|
||||
await tester.pumpAndSettle();
|
||||
@@ -67,7 +68,8 @@ void main() {
|
||||
expect(find.byType(Dismissible), findsNWidgets(2));
|
||||
});
|
||||
|
||||
testWidgets('Tests the localization of times - EN', (WidgetTester tester) async {
|
||||
testWidgets('Tests the localization of times - EN',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
await tester.tap(find.byType(TextButton));
|
||||
await tester.pumpAndSettle();
|
||||
@@ -76,7 +78,8 @@ void main() {
|
||||
expect(find.text('Thursday'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Tests the localization of times - DE', (WidgetTester tester) async {
|
||||
testWidgets('Tests the localization of times - DE',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen(locale: 'de'));
|
||||
await tester.tap(find.byType(TextButton));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
@@ -45,8 +45,10 @@ void main() {
|
||||
testAuthProvider,
|
||||
testExercisesProvider,
|
||||
[
|
||||
WorkoutPlan(id: 1, creationDate: DateTime(2021, 01, 01), name: 'test 1'),
|
||||
WorkoutPlan(id: 2, creationDate: DateTime(2021, 02, 12), name: 'test 2'),
|
||||
WorkoutPlan(
|
||||
id: 1, creationDate: DateTime(2021, 01, 01), name: 'test 1'),
|
||||
WorkoutPlan(
|
||||
id: 2, creationDate: DateTime(2021, 02, 12), name: 'test 2'),
|
||||
],
|
||||
client,
|
||||
),
|
||||
@@ -62,7 +64,8 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Test the widgets on the workout plans screen', (WidgetTester tester) async {
|
||||
testWidgets('Test the widgets on the workout plans screen',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
|
||||
//debugDumpApp();
|
||||
@@ -71,7 +74,8 @@ void main() {
|
||||
expect(find.byType(ListTile), findsNWidgets(2));
|
||||
});
|
||||
|
||||
testWidgets('Test deleting an item by dragging the dismissible', (WidgetTester tester) async {
|
||||
testWidgets('Test deleting an item by dragging the dismissible',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
|
||||
await tester.drag(find.byKey(Key('1')), Offset(-500.0, 0.0));
|
||||
@@ -86,7 +90,8 @@ void main() {
|
||||
expect(find.byType(ListTile), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Test the form on the workout plan screen', (WidgetTester tester) async {
|
||||
testWidgets('Test the form on the workout plan screen',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
|
||||
expect(find.byType(PlanForm), findsNothing);
|
||||
@@ -95,14 +100,16 @@ void main() {
|
||||
expect(find.byType(WorkoutForm), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Tests the localization of dates - EN', (WidgetTester tester) async {
|
||||
testWidgets('Tests the localization of dates - EN',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
|
||||
expect(find.text('1/1/2021'), findsOneWidget);
|
||||
expect(find.text('2/12/2021'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Tests the localization of dates - DE', (WidgetTester tester) async {
|
||||
testWidgets('Tests the localization of dates - DE',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen(locale: 'de'));
|
||||
|
||||
expect(find.text('1.1.2021'), findsOneWidget);
|
||||
|
||||
@@ -74,7 +74,8 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Test the widgets on the SetFormWidget', (WidgetTester tester) async {
|
||||
testWidgets('Test the widgets on the SetFormWidget',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
@@ -86,9 +87,12 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Test creating a new set', (WidgetTester tester) async {
|
||||
when(mockWorkoutPlans.addSet(any)).thenAnswer((_) => Future.value(Set.empty()));
|
||||
when(mockWorkoutPlans.addSetting(any)).thenAnswer((_) => Future.value(Setting.empty()));
|
||||
when(mockWorkoutPlans.fetchSmartText(any, any)).thenAnswer((_) => Future.value('2 x 10'));
|
||||
when(mockWorkoutPlans.addSet(any))
|
||||
.thenAnswer((_) => Future.value(Set.empty()));
|
||||
when(mockWorkoutPlans.addSetting(any))
|
||||
.thenAnswer((_) => Future.value(Setting.empty()));
|
||||
when(mockWorkoutPlans.fetchSmartText(any, any))
|
||||
.thenAnswer((_) => Future.value('2 x 10'));
|
||||
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
@@ -18,5 +18,7 @@
|
||||
|
||||
import 'package:wger/models/body_weight/weight_entry.dart';
|
||||
|
||||
final weightEntry1 = WeightEntry(id: 1, weight: 80, date: DateTime(2021, 01, 01));
|
||||
final weightEntry2 = WeightEntry(id: 2, weight: 81, date: DateTime(2021, 01, 10));
|
||||
final weightEntry1 =
|
||||
WeightEntry(id: 1, weight: 80, date: DateTime(2021, 01, 01));
|
||||
final weightEntry2 =
|
||||
WeightEntry(id: 2, weight: 81, date: DateTime(2021, 01, 10));
|
||||
|
||||
@@ -63,7 +63,8 @@ final exercise3 = Exercise(
|
||||
uuid: 'a3b6c7bb-9d22-4119-a5fc-818584d5e9bc',
|
||||
creationDate: DateTime(2021, 4, 1),
|
||||
name: 'test exercise 3',
|
||||
description: 'The man in black fled across the desert, and the gunslinger followed',
|
||||
description:
|
||||
'The man in black fled across the desert, and the gunslinger followed',
|
||||
category: category3,
|
||||
categoryId: 3,
|
||||
muscles: [muscle1],
|
||||
|
||||
@@ -29,7 +29,8 @@ import './exercises.dart';
|
||||
const weightUnit1 = WeightUnit(id: 1, name: 'kg');
|
||||
const weightUnit2 = WeightUnit(id: 2, name: 'metric tonnes');
|
||||
|
||||
const RepetitionUnit repetitionUnit1 = RepetitionUnit(id: 1, name: 'Repetitions');
|
||||
const RepetitionUnit repetitionUnit1 =
|
||||
RepetitionUnit(id: 1, name: 'Repetitions');
|
||||
const RepetitionUnit repetitionUnit2 = RepetitionUnit(id: 2, name: 'Hours');
|
||||
|
||||
WorkoutPlan getWorkout() {
|
||||
|
||||
Reference in New Issue
Block a user