This commit is contained in:
AxelBlaz3
2021-10-14 09:08:54 +05:30
74 changed files with 975 additions and 454 deletions

View File

@@ -24,10 +24,10 @@ linter:
# These rules are documented on and in the same order as
# the Dart Lint rules page to make maintenance easier
# https://github.com/dart-lang/linter/blob/master/example/all.yaml
always_declare_return_types: false # definitely to be changed
always_declare_return_types: true
always_put_control_body_on_new_line: true
always_require_non_null_named_parameters: true
always_specify_types: false #to be changed
always_specify_types: false # decided against using it for now
annotate_overrides: true
avoid_bool_literals_in_conditional_expressions: true
avoid_classes_with_only_static_members: true
@@ -50,17 +50,17 @@ linter:
avoid_types_as_parameter_names: true
avoid_unnecessary_containers: true
avoid_unused_constructor_parameters: true
avoid_void_async: false # to be changed
avoid_void_async: false
await_only_futures: true
camel_case_extensions: true
camel_case_types: false # maybe to be changed
camel_case_types: false
cancel_subscriptions: true
cast_nullable_to_non_nullable: false # to be changed
constant_identifier_names: false
control_flow_in_finally: true
deprecated_consistency: true
directives_ordering: true
empty_catches: false # to be changed
empty_catches: false
empty_constructor_bodies: true
empty_statements: true
exhaustive_cases: true
@@ -72,7 +72,7 @@ linter:
leading_newlines_in_multiline_strings: true
library_names: true
library_prefixes: true
library_private_types_in_public_api: false # to be checked
library_private_types_in_public_api: false
list_remove_unrelated_type: true
missing_whitespace_between_adjacent_strings: false
no_adjacent_strings_in_list: true
@@ -90,7 +90,7 @@ linter:
prefer_asserts_in_initializer_lists: true
prefer_collection_literals: true
prefer_conditional_assignment: true
prefer_const_constructors: false # definitely to be changed
prefer_const_constructors: true
prefer_const_constructors_in_immutables: true
prefer_const_declarations: true
prefer_const_literals_to_create_immutables: true
@@ -115,7 +115,7 @@ linter:
prefer_null_aware_operators: true
prefer_single_quotes: true
prefer_spread_collections: true
prefer_typing_uninitialized_variables: false # to be changed
prefer_typing_uninitialized_variables: true
prefer_void_to_null: true
provide_deprecation_message: true
recursive_getters: true
@@ -127,7 +127,7 @@ linter:
throw_in_finally: true
tighten_type_of_initializing_formals: true
type_init_formals: true
unnecessary_await_in_return: false # to be changed
unnecessary_await_in_return: true
unnecessary_brace_in_string_interps: true
unnecessary_const: true
unnecessary_getters_setters: true
@@ -153,5 +153,5 @@ linter:
use_rethrow_when_possible: true
use_test_throws_matchers: true
valid_regexps: true
void_checks: true
void_checks: false

View File

@@ -70,3 +70,6 @@ const ENERGY_CARBOHYDRATES = 4;
/// kcal per gram of fat (approx)
const ENERGY_FAT = 9;
/// Flag to check for updates to the new version.
const ENABLED_UPDATE = false;

View File

@@ -60,5 +60,5 @@ String? timeToString(TimeOfDay? time) {
if (time == null) {
return null;
}
return DefaultMaterialLocalizations().formatTimeOfDay(time, alwaysUse24HourFormat: true);
return const DefaultMaterialLocalizations().formatTimeOfDay(time, alwaysUse24HourFormat: true);
}

View File

@@ -56,7 +56,7 @@ void showHttpExceptionErrorDialog(WgerHttpException exception, BuildContext cont
final List<Widget> errorList = [];
for (final key in exception.errors!.keys) {
// Error headers
errorList.add(Text(key, style: TextStyle(fontWeight: FontWeight.bold)));
errorList.add(Text(key, style: const TextStyle(fontWeight: FontWeight.bold)));
// Error messages
if (exception.errors![key] is String) {
@@ -66,7 +66,7 @@ void showHttpExceptionErrorDialog(WgerHttpException exception, BuildContext cont
errorList.add(Text(value));
}
}
errorList.add(SizedBox(height: 8));
errorList.add(const SizedBox(height: 8));
}
showDialog(

View File

@@ -495,5 +495,7 @@
"dataCopied": "Data copied to new entry",
"@dataCopied": {
"description": "Snackbar message to show on copying data to a new log entry"
}
},
"appUpdateTitle" : "Update needed",
"appUpdateContent" : "This version of the app is not compatible with the server, please update your application."
}

View File

@@ -1 +1,450 @@
{}
{
"todaysWorkout": "Vaš današnji trening",
"@todaysWorkout": {},
"mealLogged": "Obrok prijavljen u dnevnik",
"@mealLogged": {},
"time": "Vrijeme",
"@time": {
"description": "The time of a meal or workout"
},
"timeEnd": "Vrijeme završetka",
"@timeEnd": {
"description": "The end time of a workout"
},
"username": "Korisničko ime",
"@username": {},
"passwordsDontMatch": "Zaporke se ne podudaraju",
"@passwordsDontMatch": {
"description": "Error message when the user enters two different passwords during registration"
},
"passwordTooShort": "Lozinka je prekratka",
"@passwordTooShort": {
"description": "Error message when the user a password that is too short"
},
"password": "Lozinka",
"@password": {},
"confirmPassword": "Potvrdi lozinku",
"@confirmPassword": {},
"invalidEmail": "Molimo unesite valjanu adresu e-pošte",
"@invalidEmail": {
"description": "Error message when the user enters an invalid email"
},
"email": "E-mail adresa",
"@email": {},
"invalidUrl": "Unesite važeći URL",
"@invalidUrl": {
"description": "Error message when the user enters an invalid URL, e.g. in the login form"
},
"useCustomServer": "Koristite prilagođeni poslužitelj",
"@useCustomServer": {
"description": "Toggle button allowing users to switch between the default and a custom wger server"
},
"invalidUsername": "Molimo unesite važeće korisničko ime",
"@invalidUsername": {
"description": "Error message when the user enters an invalid username"
},
"customServerUrl": "URL instanca wger -a",
"@customServerUrl": {
"description": "Label in the form where the users can enter their own wger instance"
},
"customServerHint": "Unesite adresu vlastitog poslužitelja, inače će se koristiti zadana",
"@customServerHint": {
"description": "Hint text for the form where the users can enter their own wger instance"
},
"registerInstead": "Umjesto toga se registrirajte",
"@registerInstead": {},
"loginInstead": "Umjesto toga se prijavite",
"@loginInstead": {},
"labelWorkoutPlans": "Planovi vježbanja",
"@labelWorkoutPlans": {
"description": "Title for screen workout plans"
},
"labelBottomNavWorkout": "Vježbanje",
"@labelBottomNavWorkout": {
"description": "Label used in bottom navigation, use a short word"
},
"labelBottomNavNutrition": "Prehrana",
"@labelBottomNavNutrition": {
"description": "Label used in bottom navigation, use a short word"
},
"labelWorkoutLogs": "Dnevnici treninga",
"@labelWorkoutLogs": {
"description": "(Workout) logs"
},
"labelWorkoutPlan": "Plan vježbanja",
"@labelWorkoutPlan": {
"description": "Title for screen workout plan"
},
"labelDashboard": "Kontrolna ploča",
"@labelDashboard": {
"description": "Title for screen dashboard"
},
"successfullyDeleted": "Izbrisano",
"@successfullyDeleted": {
"description": "Message when an item was successfully deleted"
},
"successfullySaved": "Spremljeno",
"@successfullySaved": {
"description": "Message when an item was successfully saved"
},
"exercise": "Vježba",
"@exercise": {
"description": "An exercise for a workout"
},
"logHelpEntriesUnits": "Imajte na umu da su ovdje ucrtani samo unosi s jedinicom težine (kg ili lb) i ponavljanjima, druge kombinacije kao što su vrijeme ili do neuspjeha.",
"@logHelpEntriesUnits": {},
"description": "Opis",
"@description": {},
"name": "Naziv",
"@name": {
"description": "Name for a workout or nutritional plan"
},
"nutritionalDiary": "Dnevnik prehrane",
"@nutritionalDiary": {},
"nutritionalPlans": "Prehrambeni planovi",
"@nutritionalPlans": {},
"noNutritionalPlans": "Nemate planove prehrane",
"@noNutritionalPlans": {
"description": "Message shown when the user has no nutritional plans"
},
"anErrorOccurred": "Došlo je do pogreške!",
"@anErrorOccurred": {},
"weight": "Težina",
"@weight": {
"description": "The weight of a workout log or body weight entry"
},
"measurement": "Mjerenje",
"@measurement": {},
"measurements": "Mjerenja",
"@measurements": {
"description": "Categories for the measurements such as biceps size, body fat, etc."
},
"measurementCategoriesHelpText": "Kategorija mjerenja, kao što su \"bicepsi\" ili \"tjelesna mast\"",
"@measurementCategoriesHelpText": {},
"measurementEntriesHelpText": "Jedinica koja se koristi za mjerenje kategorije kao što je 'cm' ili '%'",
"@measurementEntriesHelpText": {},
"date": "Datum",
"@date": {
"description": "The date of a workout log or body weight entry"
},
"repetitions": "Ponavljanja",
"@repetitions": {
"description": "Repetitions for an exercise set"
},
"reps": "Ponavljanja",
"@reps": {
"description": "Shorthand for repetitions, used when space constraints are tighter"
},
"rir": "RiR",
"@rir": {
"description": "Shorthand for Repetitions In Reserve"
},
"rirNotUsed": "RiR se ne koristi",
"@rirNotUsed": {
"description": "Label used in RiR slider when the RiR value is not used/saved for the current setting or log"
},
"macronutrients": "Makronutrijenti",
"@macronutrients": {},
"planned": "Planirani",
"@planned": {
"description": "Header for the column of 'planned' nutritional values, i.e. what should be eaten"
},
"logged": "Zabilježen",
"@logged": {
"description": "Header for the column of 'logged' nutritional values, i.e. what was eaten"
},
"difference": "Razlika",
"@difference": {},
"percentEnergy": "Postotak energije",
"@percentEnergy": {},
"gPerBodyKg": "g po tjelesnom kg",
"@gPerBodyKg": {
"description": "Label used for total sums of e.g. calories or similar in grams per Kg of body weight"
},
"total": "Ukupno",
"@total": {
"description": "Label used for total sums of e.g. calories or similar"
},
"kJ": "kJ",
"@kJ": {
"description": "Energy in a meal in kilo joules, kJ"
},
"g": "g",
"@g": {
"description": "Abbreviation for gram"
},
"proteinShort": "P",
"@proteinShort": {
"description": "The first letter or short name of the word 'Protein', used in overviews"
},
"carbohydrates": "Ugljikohidrati",
"@carbohydrates": {},
"carbohydratesShort": "C",
"@carbohydratesShort": {
"description": "The first letter or short name of the word 'Carbohydrates', used in overviews"
},
"sugars": "Šećeri",
"@sugars": {},
"fat": "Masti",
"@fat": {},
"fatShort": "F",
"@fatShort": {
"description": "The first letter or short name of the word 'Fat', used in overviews"
},
"saturatedFat": "Zasićene masti",
"@saturatedFat": {},
"fibres": "Vlakna",
"@fibres": {},
"sodium": "Natrij",
"@sodium": {},
"toggleDetails": "Prikaži detalje",
"@toggleDetails": {
"description": "Switch to toggle detail / overview"
},
"aboutBugsText": "Javite se ako se nešto nije ponašalo kako ste očekivali ili ako postoji značajka za koju smatrate da nedostaje.",
"@aboutBugsText": {
"description": "Text for bugs section in the about dialog"
},
"aboutContactUsTitle": "Pozdrav!",
"@aboutContactUsTitle": {
"description": "Title for contact us section in the about dialog"
},
"enterRepetitionsOrWeight": "Molimo vas da ispunite ili ponavljanja ili težinu za barem jedan od setova",
"@enterRepetitionsOrWeight": {
"description": "Error message when the user hasn't filled in the forms for exercise sets"
},
"enterValue": "Molimo unesite vrijednost",
"@enterValue": {
"description": "Error message when the user hasn't entered a value on a required field"
},
"selectExercise": "Odaberite vježbu",
"@selectExercise": {
"description": "Error message when the user hasn't selected an exercise in the form"
},
"enterCharacters": "Unesite znakove između {min} i {max}",
"@enterCharacters": {
"description": "Error message when the user hasn't entered the correct number of characters in a form",
"type": "text",
"placeholders": {
"min": {},
"max": {}
}
},
"nrOfSets": "Setovi po vježbi: {nrOfSets}",
"@nrOfSets": {
"description": "Label shown on the slider where the user selects the nr of sets",
"type": "text",
"placeholders": {
"nrOfSets": {}
}
},
"setUnitsAndRir": "Postavite jedinice i RiR",
"@setUnitsAndRir": {
"description": "Label shown on the slider where the user can toggle showing units and RiR",
"type": "text"
},
"enterValidNumber": "Unesite važeći broj",
"@enterValidNumber": {
"description": "Error message when the user has submitted an invalid number (e.g. '3,.,.,.')"
},
"selectIngredient": "Molimo odaberite sastojak",
"@selectIngredient": {
"description": "Error message when the user hasn't selected an ingredient from the autocompleter"
},
"selectImage": "Molimo odaberite sliku",
"@selectImage": {
"description": "Label and error message when the user hasn't selected an image to save"
},
"optionsLabel": "Opcije",
"@optionsLabel": {
"description": "Label for the popup with general app options"
},
"takePicture": "Napravi fotografiju",
"@takePicture": {},
"chooseFromLibrary": "Odaberite iz biblioteke fotografija",
"@chooseFromLibrary": {},
"gallery": "Galerija",
"@gallery": {},
"addImage": "Dodajte sliku",
"@addImage": {},
"dataCopied": "Podaci kopirani u novi unos",
"@dataCopied": {
"description": "Snackbar message to show on copying data to a new log entry"
},
"usernameValidChars": "Korisničko ime može sadržavati samo slova, brojeve i specijalne znakove @, +, ., -, and _",
"@usernameValidChars": {
"description": "Error message when the user tries to register a username with forbidden characters"
},
"logHelpEntries": "Ako u jednom danu postoji više od jednog unosa s istim brojem ponavljanja, ali različitim težinama, na dijagramu je prikazan samo unos s većom težinom.",
"@logHelpEntries": {},
"addSet": "Dodaj skup",
"@addSet": {
"description": "Label for the button that adds a set (to a workout day)"
},
"addMeal": "Dodajte obrok",
"@addMeal": {},
"nutritionalPlan": "Plan prehrane",
"@nutritionalPlan": {},
"useDefaultServer": "Koristi zadani poslužitelj",
"@useDefaultServer": {
"description": "Toggle button allowing users to switch between the default and a custom wger server"
},
"logout": "Odjavi se",
"@logout": {
"description": "Text for logout button"
},
"login": "Prijavi se",
"@login": {
"description": "Text for login button"
},
"register": "Registracija",
"@register": {
"description": "Text for registration button"
},
"reset": "Poništi",
"@reset": {
"description": "Button text allowing the user to reset the entered values to the default"
},
"jumpTo": "Skoči na",
"@jumpTo": {
"description": "Imperative. Label used in popup allowing the user to jump to a specific exercise while in the gym mode"
},
"save": "Spremi",
"@save": {},
"energyShort": "E",
"@energyShort": {
"description": "The first letter or short name of the word 'Energy', used in overviews"
},
"addIngredient": "Dodajte sastojak",
"@addIngredient": {},
"logMeal": "Prijavite ovaj obrok",
"@logMeal": {},
"value": "Vrijednost",
"@value": {
"description": "The value of a measurement entry"
},
"start": "Početak",
"@start": {
"description": "Label on button to start the gym mode (i.e., an imperative)"
},
"timeStart": "Vrijeme početka",
"@timeStart": {
"description": "The starting time of a workout"
},
"timeStartAhead": "Vrijeme početka ne može biti ispred vremena završetka",
"@timeStartAhead": {},
"ingredient": "Sastojak",
"@ingredient": {},
"energy": "Energija",
"@energy": {
"description": "Energy in a meal, ingredient etc. e.g. in kJ"
},
"protein": "Proteini",
"@protein": {},
"goToToday": "Idite na danas",
"@goToToday": {
"description": "Label on button to jump back to 'today' in the calendar widget"
},
"kcal": "Kcal",
"@kcal": {
"description": "Energy in a meal in kilocalories, kcal"
},
"unit": "Jedinica",
"@unit": {
"description": "The unit used for a repetition (kg, time, etc.)"
},
"edit": "Uredi",
"@edit": {},
"confirmDelete": "Jeste li sigurni da želite izbrisati '{toDelete}'?",
"@confirmDelete": {
"description": "Confirmation text before the user deletes an object",
"type": "text",
"placeholders": {
"toDelete": {}
}
},
"newNutritionalPlan": "Novi plan prehrane",
"@newNutritionalPlan": {},
"noWorkoutPlans": "Nemate planove vježbanja",
"@noWorkoutPlans": {
"description": "Message shown when the user has no workout plans"
},
"amount": "Iznos",
"@amount": {
"description": "The amount (e.g. in grams) of an ingredient in a meal"
},
"newEntry": "Novi unos",
"@newEntry": {
"description": "Title when adding a new entry such as a weight or log entry"
},
"noWeightEntries": "Nemate unosa težine",
"@noWeightEntries": {
"description": "Message shown when the user has no logged weight entries"
},
"loadingText": "Učitavanje...",
"@loadingText": {
"description": "Text to show when entries are being loaded in the background: Loading..."
},
"delete": "Izbrisati",
"@delete": {},
"goToDetailPage": "Idi na stranicu s detaljima",
"@goToDetailPage": {},
"aboutDescription": "Hvala vam što koristite wger! wger je suradnički projekt otvorenog koda koji su izradili ljubitelji fitnesa iz cijelog svijeta.",
"@aboutDescription": {
"description": "Text in the about dialog"
},
"aboutSourceTitle": "Izvorni kod",
"@aboutSourceTitle": {
"description": "Title for source code section in the about dialog"
},
"aboutBugsTitle": "Imate li problem ili ideju?",
"@aboutBugsTitle": {
"description": "Title for bugs section in the about dialog"
},
"aboutContactUsText": "Ako želite razgovarati s nama, skočite na Discord poslužitelja i kontaktirajte nas",
"@aboutContactUsText": {
"description": "Text for contact us section in the about dialog"
},
"aboutSourceText": "Preuzmite izvorni kod ove aplikacije i njezinog poslužitelj na githubu",
"@aboutSourceText": {
"description": "Text for source code section in the about dialog"
},
"aboutTranslationTitle": "Prijevod",
"@aboutTranslationTitle": {
"description": "Title for translation section in the about dialog"
},
"aboutTranslationText": "Ova je aplikacija prevedena preko weblatea. Ako i vi želite pomoći, kliknite vezu i počnite prevoditi",
"@aboutTranslationText": {
"description": "Text for translation section in the about dialog"
},
"calendar": "Kalendar",
"@calendar": {},
"musclesSecondary": "Sekundarni mišići",
"@musclesSecondary": {
"description": "secondary muscles trained by an exercise"
},
"equipment": "Oprema",
"@equipment": {
"description": "Equipment needed to perform an exercise"
},
"supersetWith": "nadskup sa",
"@supersetWith": {
"description": "Text used between exercise cards when adding a new set. Translate as something like 'in a superset with'"
},
"category": "Kategorija",
"@category": {
"description": "Category for an exercise, ingredient, etc."
},
"newWorkout": "Novi plan vježbanja",
"@newWorkout": {
"description": "Header when adding a new workout"
},
"searchExercise": "Pretražite vježbe za dodavanje",
"@searchExercise": {
"description": "Label on set form. Selected exercises are added to the set"
},
"muscles": "Mišići",
"@muscles": {
"description": "(main) muscles trained by an exercise"
}
}

View File

@@ -38,6 +38,7 @@ import 'package:wger/screens/nutritional_diary_screen.dart';
import 'package:wger/screens/nutritional_plan_screen.dart';
import 'package:wger/screens/nutritional_plans_screen.dart';
import 'package:wger/screens/splash_screen.dart';
import 'package:wger/screens/update_app_screen.dart';
import 'package:wger/screens/weight_screen.dart';
import 'package:wger/screens/workout_plan_screen.dart';
import 'package:wger/screens/workout_plans_screen.dart';
@@ -103,7 +104,13 @@ class MyApp extends StatelessWidget {
title: 'wger',
theme: wgerTheme,
home: auth.isAuth
? HomeTabsScreen()
? FutureBuilder(
future: auth.neededApplicationUpdate(),
builder: (ctx, snapshot) =>
snapshot.connectionState == ConnectionState.done && snapshot.data == true
? UpdateAppScreen()
: HomeTabsScreen(),
)
: FutureBuilder(
future: auth.tryAutoLogin(),
builder: (ctx, authResultSnapshot) =>

View File

@@ -55,5 +55,6 @@ class MeasurementCategory extends Equatable {
List<Object?> get props => [id, name, unit, entries];
// Helper function which makes the entries list of the toJson output null, as it isn't needed
//ignore: always_declare_return_types
static _nullValue(_) => null;
}

View File

@@ -16,6 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import 'dart:ui';
class NutritionalValues {
double energy = 0;
double protein = 0;
@@ -44,7 +46,7 @@ class NutritionalValues {
return energy * 4.184;
}
add(NutritionalValues data) {
void add(NutritionalValues data) {
energy += data.energy;
protein += data.protein;
carbohydrates += data.carbohydrates;
@@ -69,7 +71,7 @@ class NutritionalValues {
}
@override
//ignore: hash_and_equals
//ignore: avoid_equals_and_hash_code_on_mutable_classes
bool operator ==(other) {
return other is NutritionalValues &&
energy == other.energy &&
@@ -86,6 +88,11 @@ class NutritionalValues {
String toString() {
return 'e: $energy, p: $protein, c: $carbohydrates, cS: $carbohydratesSugar, f: $fat, fS: $fatSaturated, fi: $fibres, s: $sodium';
}
@override
//ignore: avoid_equals_and_hash_code_on_mutable_classes
int get hashCode => hashValues(
energy, protein, carbohydrates, carbohydratesSugar, fat, fatSaturated, fibres, sodium);
}
class BaseNutritionalValues {

View File

@@ -120,6 +120,7 @@ class Log {
/// Two logs are considered equal if their content is equal. This is used e.g.
/// in lists where we want to have unique values
@override
//ignore: avoid_equals_and_hash_code_on_mutable_classes
bool operator ==(o) {
return o is Log &&
exerciseId == o.exerciseId &&
@@ -131,6 +132,7 @@ class Log {
}
@override
//ignore: avoid_equals_and_hash_code_on_mutable_classes
int get hashCode => hashValues(exerciseId, weight, weightUnitId, reps, repetitionUnitId, rir);
//@override

View File

@@ -68,7 +68,7 @@ class WorkoutSession {
factory WorkoutSession.fromJson(Map<String, dynamic> json) => _$WorkoutSessionFromJson(json);
Map<String, dynamic> toJson() => _$WorkoutSessionToJson(this);
get impressionAsString {
String? get impressionAsString {
return IMPRESSION_MAP[impression];
}
}

View File

@@ -28,6 +28,7 @@ import 'package:flutter/widgets.dart';
import 'package:http/http.dart' as http;
import 'package:package_info/package_info.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:version/version.dart';
import 'package:wger/exceptions/http_exception.dart';
import 'package:wger/helpers/consts.dart';
@@ -76,6 +77,18 @@ class AuthProvider with ChangeNotifier {
applicationVersion = packageInfo;
}
/// Checking if there is a new version of the application.
Future<bool> neededApplicationUpdate() async {
if (!ENABLED_UPDATE) {
return false;
}
final response = await http.get(makeUri(serverUrl!, 'min-app-version'));
final applicationLatestVersion = json.decode(response.body);
final currentVersion = Version.parse(applicationVersion!.version);
final latestAppVersion = Version.parse(applicationLatestVersion);
return latestAppVersion > currentVersion;
}
/// Registers a new user
Future<void> register(
{required String username,

View File

@@ -36,7 +36,7 @@ class BodyWeightProvider extends WgerBaseProvider with ChangeNotifier {
}
/// Clears all lists
clear() {
void clear() {
_entries = [];
}

View File

@@ -41,14 +41,14 @@ class ExercisesProvider extends WgerBaseProvider with ChangeNotifier {
static const daysToCache = 7;
static const _exerciseInfoUrlPath = 'exerciseinfo';
static const _exerciseSearchPath = 'exercise/search';
static const exerciseInfoUrlPath = 'exerciseinfo';
static const exerciseSearchPath = 'exercise/search';
static const _exerciseCommentUrlPath = 'exercisecomment';
static const _exerciseImagesUrlPath = 'exerciseimage';
static const _categoriesUrlPath = 'exercisecategory';
static const _musclesUrlPath = 'muscle';
static const _equipmentUrlPath = 'equipment';
static const exerciseCommentUrlPath = 'exercisecomment';
static const exerciseImagesUrlPath = 'exerciseimage';
static const categoriesUrlPath = 'exercisecategory';
static const musclesUrlPath = 'muscle';
static const equipmentUrlPath = 'equipment';
final List<Exercise> _exercises;
final List<ExerciseCategory> _categories = [];
@@ -65,7 +65,7 @@ class ExercisesProvider extends WgerBaseProvider with ChangeNotifier {
}
Future<void> fetchAndSetCategories() async {
final response = await client.get(makeUrl(_categoriesUrlPath));
final response = await client.get(makeUrl(categoriesUrlPath));
final categories = json.decode(response.body) as Map<String, dynamic>;
try {
for (final category in categories['results']) {
@@ -77,7 +77,7 @@ class ExercisesProvider extends WgerBaseProvider with ChangeNotifier {
}
Future<void> fetchAndSetMuscles() async {
final response = await client.get(makeUrl(_musclesUrlPath));
final response = await client.get(makeUrl(musclesUrlPath));
final muscles = json.decode(response.body) as Map<String, dynamic>;
try {
for (final muscle in muscles['results']) {
@@ -89,7 +89,7 @@ class ExercisesProvider extends WgerBaseProvider with ChangeNotifier {
}
Future<void> fetchAndSetEquipment() async {
final response = await client.get(makeUrl(_equipmentUrlPath));
final response = await client.get(makeUrl(equipmentUrlPath));
final equipments = json.decode(response.body) as Map<String, dynamic>;
try {
for (final equipment in equipments['results']) {
@@ -111,7 +111,7 @@ class ExercisesProvider extends WgerBaseProvider with ChangeNotifier {
} on StateError {
// Get exercise from the server and save to cache
final data = await fetch(makeUrl(_exerciseInfoUrlPath, id: exerciseId));
final data = await fetch(makeUrl(exerciseInfoUrlPath, id: exerciseId));
final exercise = Exercise.fromJson(data);
_exercises.add(exercise);
final prefs = await SharedPreferences.getInstance();
@@ -145,7 +145,7 @@ class ExercisesProvider extends WgerBaseProvider with ChangeNotifier {
final response = await client.get(
makeUrl(
_exerciseInfoUrlPath,
exerciseInfoUrlPath,
query: {'limit': '1000'},
),
headers: {
@@ -160,7 +160,7 @@ class ExercisesProvider extends WgerBaseProvider with ChangeNotifier {
// Save the result to the cache
final exerciseData = {
'date': DateTime.now().toIso8601String(),
'expiresIn': DateTime.now().add(Duration(days: daysToCache)).toIso8601String(),
'expiresIn': DateTime.now().add(const 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(),
@@ -188,7 +188,7 @@ class ExercisesProvider extends WgerBaseProvider with ChangeNotifier {
// Send the request
final response = await client.get(
makeUrl(
_exerciseSearchPath,
exerciseSearchPath,
query: {'term': name, 'language': languageCode},
),
headers: <String, String>{

View File

@@ -37,7 +37,7 @@ class GalleryProvider extends WgerBaseProvider with ChangeNotifier {
super(auth, client);
/// Clears all lists
clear() {
void clear() {
images = [];
}

View File

@@ -54,7 +54,7 @@ class NutritionPlansProvider extends WgerBaseProvider with ChangeNotifier {
}
/// Clears all lists
clear() {
void clear() {
_plans = [];
_ingredients = [];
}
@@ -292,7 +292,7 @@ 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(const Duration(days: DAYS_TO_CACHE)).toIso8601String(),
'ingredients': []
};
prefs.setString('ingredientData', json.encode(ingredientData));

View File

@@ -68,7 +68,7 @@ class WorkoutPlansProvider extends WgerBaseProvider with ChangeNotifier {
}
/// Clears all lists
clear() {
void clear() {
_currentPlan = null;
_workoutPlans = [];
_weightUnits = [];
@@ -353,7 +353,7 @@ 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(const Duration(days: DAYS_TO_CACHE)).toIso8601String(),
'repetitionUnits': _repetitionUnit.map((e) => e.toJson()).toList(),
'weightUnit': _weightUnits.map((e) => e.toJson()).toList(),
};

View File

@@ -51,15 +51,15 @@ class AuthScreen extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(padding: EdgeInsets.symmetric(vertical: 20)),
Image(
const Padding(padding: EdgeInsets.symmetric(vertical: 20)),
const Image(
image: AssetImage('assets/images/logo-white.png'),
width: 120,
),
Container(
margin: EdgeInsets.only(bottom: 20.0),
padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 94.0),
child: Text(
margin: const EdgeInsets.only(bottom: 20.0),
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 94.0),
child: const Text(
'WGER',
style: TextStyle(
color: Colors.white,
@@ -69,7 +69,7 @@ class AuthScreen extends StatelessWidget {
),
),
),
Flexible(
const Flexible(
//flex: deviceSize.width > 600 ? 2 : 1,
child: AuthCard(),
),
@@ -201,7 +201,7 @@ class _AuthCardState extends State<AuthCard> {
elevation: 8.0,
child: Container(
width: deviceSize.width * 0.75,
padding: EdgeInsets.all(16.0),
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: SingleChildScrollView(
@@ -209,7 +209,7 @@ class _AuthCardState extends State<AuthCard> {
child: Column(
children: <Widget>[
TextFormField(
key: Key('inputUsername'),
key: const Key('inputUsername'),
decoration: InputDecoration(
labelText: AppLocalizations.of(context).username,
errorMaxLines: 2,
@@ -233,7 +233,7 @@ class _AuthCardState extends State<AuthCard> {
),
if (_authMode == AuthMode.Signup)
TextFormField(
key: Key('inputEmail'),
key: const Key('inputEmail'),
decoration: InputDecoration(labelText: AppLocalizations.of(context).email),
autofillHints: const [AutofillHints.email],
controller: _emailController,
@@ -270,7 +270,7 @@ class _AuthCardState extends State<AuthCard> {
),
if (_authMode == AuthMode.Signup)
TextFormField(
key: Key('inputPassword2'),
key: const Key('inputPassword2'),
decoration:
InputDecoration(labelText: AppLocalizations.of(context).confirmPassword),
controller: _password2Controller,
@@ -294,7 +294,7 @@ class _AuthCardState extends State<AuthCard> {
Flexible(
flex: 3,
child: TextFormField(
key: Key('inputServer'),
key: const Key('inputServer'),
decoration: InputDecoration(
labelText: AppLocalizations.of(context).customServerUrl,
helperText: AppLocalizations.of(context).customServerHint,
@@ -319,7 +319,7 @@ class _AuthCardState extends State<AuthCard> {
},
),
),
SizedBox(
const SizedBox(
width: 20,
),
Column(
@@ -337,14 +337,14 @@ class _AuthCardState extends State<AuthCard> {
],
),
),
SizedBox(
const SizedBox(
height: 20,
),
if (_isLoading)
CircularProgressIndicator()
const CircularProgressIndicator()
else
ElevatedButton(
key: Key('actionButton'),
key: const Key('actionButton'),
child: Text(_authMode == AuthMode.Login
? AppLocalizations.of(context).login
: AppLocalizations.of(context).register),
@@ -353,7 +353,7 @@ class _AuthCardState extends State<AuthCard> {
},
),
TextButton(
key: Key('toggleActionButton'),
key: const Key('toggleActionButton'),
child: Text(
_authMode == AuthMode.Login
? AppLocalizations.of(context).registerInstead.toUpperCase()
@@ -365,7 +365,7 @@ class _AuthCardState extends State<AuthCard> {
child: Text(_hideCustomServer
? AppLocalizations.of(context).useCustomServer
: AppLocalizations.of(context).useDefaultServer),
key: Key('toggleCustomServerButton'),
key: const Key('toggleCustomServerButton'),
onPressed: () {
setState(() {
_hideCustomServer = !_hideCustomServer;

View File

@@ -41,7 +41,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
DashboardWorkoutWidget(),
DashboardNutritionWidget(),
DashboardWeightWidget(),
DashboardCalendarWidget(),
const DashboardCalendarWidget(),
],
),
),

View File

@@ -51,7 +51,7 @@ class GalleryScreen extends StatelessWidget {
},
),
body: Consumer<GalleryProvider>(
builder: (context, workoutProvider, child) => Gallery(),
builder: (context, workoutProvider, child) => const Gallery(),
),
);
}

View File

@@ -66,7 +66,7 @@ class _HomeTabsScreenState extends State<HomeTabsScreen> with SingleTickerProvid
WorkoutPlansScreen(),
NutritionScreen(),
WeightScreen(),
GalleryScreen(),
const GalleryScreen(),
];
/// Load initial data from the server
@@ -152,26 +152,26 @@ class _HomeTabsScreenState extends State<HomeTabsScreen> with SingleTickerProvid
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.dashboard),
icon: const Icon(Icons.dashboard),
label: AppLocalizations.of(context).labelDashboard,
),
BottomNavigationBarItem(
icon: Icon(Icons.fitness_center),
icon: const Icon(Icons.fitness_center),
label: AppLocalizations.of(context).labelBottomNavWorkout,
),
BottomNavigationBarItem(
icon: Icon(Icons.restaurant),
icon: const Icon(Icons.restaurant),
label: AppLocalizations.of(context).labelBottomNavNutrition,
),
BottomNavigationBarItem(
icon: FaIcon(
icon: const FaIcon(
FontAwesomeIcons.weight,
size: 20,
),
label: AppLocalizations.of(context).weight,
),
BottomNavigationBarItem(
icon: Icon(Icons.photo_library),
icon: const Icon(Icons.photo_library),
label: AppLocalizations.of(context).gallery,
),
],

View File

@@ -34,9 +34,8 @@ enum NutritionalPlanOptions {
class NutritionalPlanScreen extends StatelessWidget {
static const routeName = '/nutritional-plan-detail';
Future<NutritionalPlan> _loadFullPlan(BuildContext context, int planId) async {
return await Provider.of<NutritionPlansProvider>(context, listen: false)
.fetchAndSetPlanFull(planId);
Future<NutritionalPlan> _loadFullPlan(BuildContext context, int planId) {
return Provider.of<NutritionPlansProvider>(context, listen: false).fetchAndSetPlanFull(planId);
}
@override
@@ -53,7 +52,7 @@ class NutritionalPlanScreen extends StatelessWidget {
pinned: true,
actions: [
PopupMenuButton<NutritionalPlanOptions>(
icon: Icon(Icons.more_vert),
icon: const Icon(Icons.more_vert),
onSelected: (value) {
// Edit
if (value == NutritionalPlanOptions.edit) {
@@ -90,7 +89,7 @@ class NutritionalPlanScreen extends StatelessWidget {
],
flexibleSpace: FlexibleSpaceBar(
title: Text(_nutritionalPlan.description),
background: Image(
background: const Image(
image: AssetImage('assets/images/backgrounds/nutritional_plans.jpg'),
fit: BoxFit.cover,
),
@@ -103,7 +102,7 @@ class NutritionalPlanScreen extends StatelessWidget {
? SliverList(
delegate: SliverChildListDelegate(
[
SizedBox(
const SizedBox(
height: 200,
child: Center(
child: CircularProgressIndicator(),

View File

@@ -21,7 +21,7 @@ import 'package:flutter/material.dart';
class SplashScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
return const Scaffold(
body: Center(
child: Text('Loading...'),
),

View File

@@ -0,0 +1,36 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* Copyright (C) 2020, 2021 wger Team
*
* wger Workout Manager is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class UpdateAppScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: AlertDialog(
title: Text(
AppLocalizations.of(context).appUpdateTitle,
style: Theme.of(context).textTheme.headline5,
),
content: Text(AppLocalizations.of(context).appUpdateContent),
actions: null,
),
);
}
}

View File

@@ -52,8 +52,8 @@ class _WorkoutPlanScreenState extends State<WorkoutPlanScreen> {
});
}
Future<WorkoutPlan> _loadFullWorkout(BuildContext context, int planId) async {
return await Provider.of<WorkoutPlansProvider>(context, listen: false)
Future<WorkoutPlan> _loadFullWorkout(BuildContext context, int planId) {
return Provider.of<WorkoutPlansProvider>(context, listen: false)
.fetchAndSetWorkoutPlanFull(planId);
}
@@ -79,14 +79,14 @@ class _WorkoutPlanScreenState extends State<WorkoutPlanScreen> {
pinned: true,
flexibleSpace: FlexibleSpaceBar(
title: Text(workoutPlan.name),
background: Image(
background: const Image(
image: AssetImage('assets/images/backgrounds/workout_plans.jpg'),
fit: BoxFit.cover,
),
),
actions: [
PopupMenuButton<WorkoutOptions>(
icon: Icon(Icons.more_vert),
icon: const Icon(Icons.more_vert),
onSelected: (value) {
// Edit
if (value == WorkoutOptions.edit) {
@@ -130,7 +130,7 @@ class _WorkoutPlanScreenState extends State<WorkoutPlanScreen> {
delegate: SliverChildListDelegate(
[
if (snapshot.connectionState == ConnectionState.waiting)
SizedBox(
const SizedBox(
height: 200,
child: Center(
child: CircularProgressIndicator(),

View File

@@ -66,8 +66,8 @@ final ThemeData wgerTheme = ThemeData(
* Text theme
*/
textTheme: TextTheme(
headline1: TextStyle(fontFamily: 'OpenSansLight', color: Colors.black),
headline2: TextStyle(fontFamily: 'OpenSansLight', color: Colors.black),
headline1: const TextStyle(fontFamily: 'OpenSansLight', color: Colors.black),
headline2: const TextStyle(fontFamily: 'OpenSansLight', color: Colors.black),
headline3: TextStyle(
fontSize: materialSizes['h3']! * 0.8,
fontFamily: 'OpenSansBold',
@@ -102,7 +102,7 @@ final ThemeData wgerTheme = ThemeData(
style: OutlinedButton.styleFrom(
primary: wgerPrimaryButtonColor,
visualDensity: VisualDensity.compact,
side: BorderSide(color: wgerPrimaryButtonColor),
side: const BorderSide(color: wgerPrimaryButtonColor),
),
),
elevatedButtonTheme: ElevatedButtonThemeData(
@@ -114,7 +114,7 @@ final ThemeData wgerTheme = ThemeData(
/*
* Forms, etc.
*/
sliderTheme: SliderThemeData(
sliderTheme: const SliderThemeData(
activeTrackColor: wgerPrimaryButtonColor,
thumbColor: wgerPrimaryColor,
),

View File

@@ -33,12 +33,12 @@ class AppDrawer extends StatelessWidget {
child: Column(
children: [
AppBar(
title: Text('wger'),
title: const Text('wger'),
automaticallyImplyLeading: false,
),
ListTile(
//dense: true,
leading: Icon(Icons.exit_to_app),
leading: const Icon(Icons.exit_to_app),
title: Text(AppLocalizations.of(context).logout),
onTap: () {
Provider.of<AuthProvider>(context, listen: false).logout();

View File

@@ -29,7 +29,7 @@ class WgerAboutListTile extends StatelessWidget {
return AboutListTile(
//dense: true,
icon: Icon(Icons.info),
icon: const Icon(Icons.info),
applicationName: 'wger',
applicationVersion: 'App: ${authProvider.applicationVersion!.version}\n'
'Server: ${authProvider.serverVersion}',
@@ -43,17 +43,17 @@ class WgerAboutListTile extends StatelessWidget {
),
aboutBoxChildren: [
SizedBox(height: 10),
const SizedBox(height: 10),
Text(AppLocalizations.of(context).aboutDescription),
SizedBox(height: 20),
const SizedBox(height: 20),
ListTile(
leading: Icon(Icons.code),
leading: const Icon(Icons.code),
title: Text(AppLocalizations.of(context).aboutSourceTitle),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(AppLocalizations.of(context).aboutSourceText),
Text(
const Text(
'https://github.com/wger-project',
style: TextStyle(color: Colors.blue),
),
@@ -62,15 +62,15 @@ class WgerAboutListTile extends StatelessWidget {
contentPadding: EdgeInsets.zero,
onTap: () async => launchURL('https://github.com/wger-project', context),
),
SizedBox(height: 10),
const SizedBox(height: 10),
ListTile(
leading: Icon(Icons.bug_report),
leading: const Icon(Icons.bug_report),
title: Text(AppLocalizations.of(context).aboutBugsTitle),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(AppLocalizations.of(context).aboutBugsText),
Text(
const Text(
'https://github.com/wger-project/flutter/issues/new/choose',
style: TextStyle(color: Colors.blue),
)
@@ -80,15 +80,15 @@ class WgerAboutListTile extends StatelessWidget {
onTap: () async =>
launchURL('https://github.com/wger-project/flutter/issues/new/choose', context),
),
SizedBox(height: 10),
const SizedBox(height: 10),
ListTile(
leading: Icon(Icons.chat),
leading: const Icon(Icons.chat),
title: Text(AppLocalizations.of(context).aboutContactUsTitle),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(AppLocalizations.of(context).aboutContactUsText),
Text(
const Text(
'https://discord.gg/rPWFv6W',
style: TextStyle(color: Colors.blue),
),
@@ -97,15 +97,15 @@ class WgerAboutListTile extends StatelessWidget {
contentPadding: EdgeInsets.zero,
onTap: () async => launchURL('https://discord.gg/rPWFv6W', context),
),
SizedBox(height: 10),
const SizedBox(height: 10),
ListTile(
leading: Icon(Icons.translate),
leading: const Icon(Icons.translate),
title: Text(AppLocalizations.of(context).aboutTranslationTitle),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(AppLocalizations.of(context).aboutTranslationText),
Text(
const Text(
'https://hosted.weblate.org/engage/wger/',
style: TextStyle(color: Colors.blue),
),

View File

@@ -57,10 +57,10 @@ class WgerAppBar extends StatelessWidget with PreferredSizeWidget {
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Divider(),
const Divider(),
ListTile(
//dense: true,
leading: Icon(Icons.exit_to_app),
leading: const Icon(Icons.exit_to_app),
title: Text(AppLocalizations.of(context).logout),
onTap: () {
Provider.of<AuthProvider>(context, listen: false).logout();
@@ -84,5 +84,5 @@ class WgerAppBar extends StatelessWidget with PreferredSizeWidget {
}
@override
Size get preferredSize => Size.fromHeight(kToolbarHeight);
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
}

View File

@@ -30,10 +30,10 @@ class MeasurementChartEntry {
/// Weight chart widget
class MeasurementChartWidget extends StatelessWidget {
final List<MeasurementChartEntry> _entries;
late String unit;
final String unit;
/// [_entries] is a list of [MeasurementChartEntry]
MeasurementChartWidget(this._entries, {this.unit = 'kg'});
const MeasurementChartWidget(this._entries, {this.unit = 'kg'});
@override
Widget build(BuildContext context) {
@@ -51,7 +51,7 @@ class MeasurementChartWidget extends StatelessWidget {
],
defaultRenderer: charts.LineRendererConfig(includePoints: true),
primaryMeasureAxis: charts.NumericAxisSpec(
tickProviderSpec: charts.BasicNumericTickProviderSpec(zeroBound: false),
tickProviderSpec: const charts.BasicNumericTickProviderSpec(zeroBound: false),
tickFormatterSpec: unitTickFormatter,
),
);

View File

@@ -21,24 +21,19 @@ import 'package:wger/theme/theme.dart';
class MutedText extends StatelessWidget {
final String _text;
TextAlign _textAlign = TextAlign.left;
final TextAlign textAlign;
MutedText(
const MutedText(
this._text, {
Key? key,
TextAlign? textAlign,
}) : super(key: key) {
if (textAlign != null) {
_textAlign = textAlign;
}
}
this.textAlign = TextAlign.left,
});
@override
Widget build(BuildContext context) {
return Text(
_text,
style: TextStyle(color: wgerTextMuted),
textAlign: _textAlign,
style: const TextStyle(color: wgerTextMuted),
textAlign: textAlign,
);
}
}

View File

@@ -46,11 +46,11 @@ class Event {
Event(this._type, this._description);
get description {
String get description {
return _description;
}
get type {
EventType get type {
return _type;
}
}
@@ -217,14 +217,14 @@ class _DashboardCalendarWidgetState extends State<DashboardCalendarWidget>
AppLocalizations.of(context).calendar,
style: Theme.of(context).textTheme.headline4,
),
leading: Icon(
leading: const Icon(
Icons.calendar_today_outlined,
color: Colors.black,
),
),
TableCalendar<Event>(
locale: Localizations.localeOf(context).languageCode,
firstDay: DateTime.now().subtract(Duration(days: 1000)),
firstDay: DateTime.now().subtract(const Duration(days: 1000)),
lastDay: DateTime.now(),
focusedDay: _focusedDay,
selectedDayPredicate: (day) => isSameDay(_selectedDay, day),
@@ -267,9 +267,8 @@ class _DashboardCalendarWidgetState extends State<DashboardCalendarWidget>
case EventType.measurement:
return AppLocalizations.of(context).measurement;
}
return event.description.toString();
})()),
subtitle: Text(event.description.toString()),
subtitle: Text(event.description),
//onTap: () => print('$event tapped!'),
))
.toList()

View File

@@ -71,7 +71,7 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
Expanded(
child: Text(
meal.time!.format(context),
style: TextStyle(fontWeight: FontWeight.bold),
style: const TextStyle(fontWeight: FontWeight.bold),
//textAlign: TextAlign.left,
),
),
@@ -81,19 +81,19 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
children: [
MutedText(
'${AppLocalizations.of(context).energyShort} ${meal.nutritionalValues.energy.toStringAsFixed(0)}${AppLocalizations.of(context).kcal}'),
MutedText(' / '),
const MutedText(' / '),
MutedText(
'${AppLocalizations.of(context).proteinShort} ${meal.nutritionalValues.protein.toStringAsFixed(0)}${AppLocalizations.of(context).g}'),
MutedText(' / '),
const MutedText(' / '),
MutedText(
'${AppLocalizations.of(context).carbohydratesShort} ${meal.nutritionalValues.carbohydrates.toStringAsFixed(0)}${AppLocalizations.of(context).g}'),
MutedText(' / '),
const MutedText(' / '),
MutedText(
'${AppLocalizations.of(context).fatShort} ${meal.nutritionalValues.fat.toStringAsFixed(0)}${AppLocalizations.of(context).g} '),
],
),
IconButton(
icon: Icon(Icons.history_edu),
icon: const Icon(Icons.history_edu),
color: wgerPrimaryButtonColor,
onPressed: () {
Provider.of<NutritionPlansProvider>(context, listen: false).logMealToDiary(meal);
@@ -110,7 +110,7 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
],
),
);
out.add(SizedBox(height: 5));
out.add(const SizedBox(height: 5));
if (_showDetail) {
for (final item in meal.mealItems) {
@@ -126,7 +126,7 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
overflow: TextOverflow.ellipsis,
),
),
SizedBox(width: 5),
const SizedBox(width: 5),
Text('${item.amount.toStringAsFixed(0)} ${AppLocalizations.of(context).g}'),
],
),
@@ -134,9 +134,9 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
),
);
}
out.add(SizedBox(height: 10));
out.add(const SizedBox(height: 10));
}
out.add(Divider());
out.add(const Divider());
}
return out;
@@ -144,10 +144,10 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
Widget getTrailing() {
if (!_hasContent) {
return Text('');
return const Text('');
}
return _showDetail ? Icon(Icons.expand_less) : Icon(Icons.expand_more);
return _showDetail ? const Icon(Icons.expand_less) : const Icon(Icons.expand_more);
}
@override
@@ -166,7 +166,7 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
.format(_plan!.creationDate)
: '',
),
leading: Icon(
leading: const Icon(
Icons.restaurant,
color: Colors.black,
),
@@ -179,12 +179,12 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
),
if (_hasContent)
Container(
padding: EdgeInsets.only(left: 10),
padding: const EdgeInsets.only(left: 10),
child: Column(
children: [
...getContent(),
Container(
padding: EdgeInsets.all(15),
padding: const EdgeInsets.all(15),
height: 180,
child: NutritionalPlanPieChartWidget(_plan!.nutritionalValues),
)
@@ -236,12 +236,12 @@ class _DashboardWeightWidgetState extends State<DashboardWeightWidget> {
AppLocalizations.of(context).weight,
style: Theme.of(context).textTheme.headline4,
),
leading: FaIcon(
leading: const FaIcon(
FontAwesomeIcons.weight,
color: Colors.black,
),
trailing: IconButton(
icon: Icon(Icons.add),
icon: const Icon(Icons.add),
onPressed: () async {
Navigator.pushNamed(
context,
@@ -260,7 +260,7 @@ class _DashboardWeightWidgetState extends State<DashboardWeightWidget> {
Column(
children: [
Container(
padding: EdgeInsets.all(15),
padding: const EdgeInsets.all(15),
height: 180,
child: MeasurementChartWidget(weightEntriesData.items
.map((e) => MeasurementChartEntry(e.weight, e.date))
@@ -312,10 +312,10 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
Widget getTrailing() {
if (!_hasContent) {
return Text('');
return const Text('');
}
return _showDetail ? Icon(Icons.expand_less) : Icon(Icons.expand_more);
return _showDetail ? const Icon(Icons.expand_less) : const Icon(Icons.expand_more);
}
List<Widget> getContent() {
@@ -333,7 +333,7 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
Expanded(
child: Text(
day.description,
style: TextStyle(fontWeight: FontWeight.bold),
style: const TextStyle(fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
),
),
@@ -342,7 +342,7 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
textAlign: TextAlign.right,
),
IconButton(
icon: Icon(Icons.play_arrow),
icon: const Icon(Icons.play_arrow),
color: wgerPrimaryButtonColor,
onPressed: () {
Navigator.of(context).pushNamed(GymModeScreen.routeName, arguments: day);
@@ -366,11 +366,11 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(s.exerciseObj.name),
SizedBox(width: 10),
const SizedBox(width: 10),
MutedText(set.getSmartRepr(s.exerciseObj).join('\n')),
],
),
SizedBox(height: 10),
const SizedBox(height: 10),
],
)
: Container();
@@ -379,7 +379,7 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
),
));
}
out.add(Divider());
out.add(const Divider());
}
return out;
@@ -401,7 +401,7 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
.format(_workoutPlan!.creationDate)
: '',
),
leading: Icon(
leading: const Icon(
Icons.fitness_center_outlined,
color: Colors.black,
),
@@ -414,7 +414,7 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
),
if (_hasContent)
Container(
padding: EdgeInsets.only(left: 10),
padding: const EdgeInsets.only(left: 10),
child: Column(
children: [
...getContent(),

View File

@@ -40,7 +40,7 @@ class ExerciseDetail extends StatelessWidget {
style: Theme.of(context).textTheme.headline6,
),
Text(_exercise.categoryObj.name),
SizedBox(height: 8),
const SizedBox(height: 8),
// Equipment
Text(
@@ -49,8 +49,8 @@ class ExerciseDetail extends StatelessWidget {
),
if (_exercise.equipment.isNotEmpty)
Text(_exercise.equipment.map((e) => e.name).toList().join('\n')),
if (_exercise.equipment.isEmpty) Text('-/-'),
SizedBox(height: 8),
if (_exercise.equipment.isEmpty) const Text('-/-'),
const SizedBox(height: 8),
// Muscles
Text(
@@ -59,8 +59,8 @@ class ExerciseDetail extends StatelessWidget {
),
if (_exercise.muscles.isNotEmpty)
Text(_exercise.muscles.map((e) => e.name).toList().join('\n')),
if (_exercise.muscles.isEmpty) Text('-/-'),
SizedBox(height: 8),
if (_exercise.muscles.isEmpty) const Text('-/-'),
const SizedBox(height: 8),
// Muscles secondary
Text(
@@ -69,8 +69,8 @@ class ExerciseDetail extends StatelessWidget {
),
if (_exercise.musclesSecondary.isNotEmpty)
Text(_exercise.musclesSecondary.map((e) => e.name).toList().join('\n')),
if (_exercise.musclesSecondary.isEmpty) Text('-/-'),
SizedBox(height: 8),
if (_exercise.musclesSecondary.isEmpty) const Text('-/-'),
const SizedBox(height: 8),
// Description
Text(
@@ -78,7 +78,7 @@ class ExerciseDetail extends StatelessWidget {
style: Theme.of(context).textTheme.headline6,
),
Html(data: _exercise.description),
SizedBox(height: 8),
const SizedBox(height: 8),
],
),
);

View File

@@ -30,11 +30,11 @@ class ExerciseImageWidget extends StatelessWidget {
Widget build(BuildContext context) {
return image != null
? FadeInImage(
placeholder: AssetImage('assets/images/placeholder.png'),
placeholder: const AssetImage('assets/images/placeholder.png'),
image: NetworkImage(image!.url),
fit: BoxFit.cover,
)
: Image(
: const Image(
image: AssetImage('assets/images/placeholder.png'),
color: Color.fromRGBO(255, 255, 255, 0.3),
colorBlendMode: BlendMode.modulate);

View File

@@ -28,7 +28,7 @@ import 'package:wger/models/gallery/image.dart' as gallery;
import 'package:wger/providers/gallery.dart';
class ImageForm extends StatefulWidget {
late gallery.Image _image;
late final gallery.Image _image;
ImageForm([gallery.Image? image]) {
_image = image ?? gallery.Image.emtpy();
@@ -84,8 +84,8 @@ class _ImageFormState extends State<ImageForm> {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(AppLocalizations.of(context).selectImage),
SizedBox(height: 8),
Icon(Icons.photo_camera),
const SizedBox(height: 8),
const Icon(Icons.photo_camera),
],
);
}
@@ -112,7 +112,7 @@ class _ImageFormState extends State<ImageForm> {
Navigator.of(context).pop();
_showPicker(ImageSource.camera);
},
leading: Icon(Icons.photo_camera),
leading: const Icon(Icons.photo_camera),
title: Text(AppLocalizations.of(context).takePicture),
),
ListTile(
@@ -120,7 +120,7 @@ class _ImageFormState extends State<ImageForm> {
Navigator.of(context).pop();
_showPicker(ImageSource.gallery);
},
leading: Icon(Icons.photo_library),
leading: const Icon(Icons.photo_library),
title: Text(AppLocalizations.of(context).chooseFromLibrary))
],
),
@@ -132,10 +132,10 @@ class _ImageFormState extends State<ImageForm> {
),
),
TextFormField(
key: Key('field-date'),
key: const Key('field-date'),
decoration: InputDecoration(
labelText: AppLocalizations.of(context).date,
suffixIcon: Icon(Icons.calendar_today_outlined),
suffixIcon: const Icon(Icons.calendar_today_outlined),
),
readOnly: true, // Stop keyboard from appearing
controller: dateController,
@@ -165,7 +165,7 @@ class _ImageFormState extends State<ImageForm> {
},
),
TextFormField(
key: Key('field-description'),
key: const Key('field-description'),
decoration: InputDecoration(labelText: AppLocalizations.of(context).description),
minLines: 3,
maxLines: 10,
@@ -175,7 +175,7 @@ class _ImageFormState extends State<ImageForm> {
},
),
ElevatedButton(
key: Key(SUBMIT_BUTTON_KEY_NAME),
key: const Key(SUBMIT_BUTTON_KEY_NAME),
child: Text(AppLocalizations.of(context).save),
onPressed: () async {
// Validate and save

View File

@@ -48,7 +48,7 @@ class Gallery extends StatelessWidget {
builder: (context) => Material(
child: Container(
key: Key('image-${currentImage.id}-detail'),
padding: EdgeInsets.all(10),
padding: const EdgeInsets.all(10),
color: Colors.white,
child: Column(
children: [
@@ -68,14 +68,14 @@ class Gallery extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
icon: Icon(Icons.delete),
icon: const Icon(Icons.delete),
onPressed: () {
Provider.of<GalleryProvider>(context, listen: false)
.deleteImage(currentImage);
Navigator.of(context).pop();
}),
IconButton(
icon: Icon(Icons.edit),
icon: const Icon(Icons.edit),
onPressed: () {
Navigator.pushNamed(
context,
@@ -98,7 +98,7 @@ class Gallery extends StatelessWidget {
},
child: FadeInImage(
key: Key('image-${currentImage.id}'),
placeholder: AssetImage('assets/images/placeholder.png'),
placeholder: const AssetImage('assets/images/placeholder.png'),
image: NetworkImage(currentImage.url!),
fit: BoxFit.cover,
),

View File

@@ -49,7 +49,7 @@ class CategoriesList extends StatelessWidget {
),
Container(
color: Colors.white,
padding: EdgeInsets.all(10),
padding: const EdgeInsets.all(10),
height: 220,
child: MeasurementChartWidget(
currentCategory.entries
@@ -58,7 +58,7 @@ class CategoriesList extends StatelessWidget {
unit: currentCategory.unit,
),
),
Divider(),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
@@ -82,7 +82,7 @@ class CategoriesList extends StatelessWidget {
),
);
},
icon: Icon(Icons.add),
icon: const Icon(Icons.add),
),
],
),

View File

@@ -38,7 +38,7 @@ class EntriesList extends StatelessWidget {
return Column(children: [
Container(
color: Theme.of(context).cardColor,
padding: EdgeInsets.all(10),
padding: const EdgeInsets.all(10),
height: 220,
child: MeasurementChartWidget(
_category.entries.map((e) => MeasurementChartEntry(e.value, e.date)).toList(),
@@ -89,12 +89,12 @@ class EntriesList extends StatelessWidget {
secondaryBackground: Container(
color: Theme.of(context).errorColor,
alignment: Alignment.centerRight,
padding: EdgeInsets.only(right: 20),
margin: EdgeInsets.symmetric(
padding: const EdgeInsets.only(right: 20),
margin: const EdgeInsets.symmetric(
horizontal: 4,
vertical: 4,
),
child: Icon(
child: const Icon(
Icons.delete,
color: Colors.white,
),
@@ -102,12 +102,12 @@ class EntriesList extends StatelessWidget {
background: Container(
color: wgerPrimaryButtonColor,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 20),
margin: EdgeInsets.symmetric(
padding: const EdgeInsets.only(left: 20),
margin: const EdgeInsets.symmetric(
horizontal: 4,
vertical: 4,
),
child: Icon(
child: const Icon(
Icons.edit,
color: Colors.white,
),

View File

@@ -32,7 +32,7 @@ class MeasurementCategoryForm extends StatelessWidget {
final nameController = TextEditingController();
final unitController = TextEditingController();
Map<String, dynamic> categoryData = {'id': null, 'name': '', 'unit': ''};
final Map<String, dynamic> categoryData = {'id': null, 'name': '', 'unit': ''};
MeasurementCategoryForm([MeasurementCategory? category]) {
//this._category = category ?? MeasurementCategory();
@@ -130,7 +130,7 @@ class MeasurementEntryForm extends StatelessWidget {
final _dateController = TextEditingController();
final _notesController = TextEditingController();
late Map<String, dynamic> _entryData;
late final Map<String, dynamic> _entryData;
MeasurementEntryForm(this._categoryId, [MeasurementEntry? entry]) {
_entryData = {

View File

@@ -31,7 +31,7 @@ import 'package:wger/providers/nutrition.dart';
import 'package:wger/screens/nutritional_plan_screen.dart';
class MealForm extends StatelessWidget {
late Meal _meal;
late final Meal _meal;
final int _planId;
final _form = GlobalKey<FormState>();
@@ -47,13 +47,13 @@ class MealForm extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(20),
margin: const EdgeInsets.all(20),
child: Form(
key: _form,
child: Column(
children: [
TextFormField(
key: Key('field-time'),
key: const Key('field-time'),
decoration: InputDecoration(labelText: AppLocalizations.of(context).time),
controller: _timeController,
onTap: () async {
@@ -75,7 +75,7 @@ class MealForm extends StatelessWidget {
),
TextFormField(
maxLength: 25,
key: Key('field-name'),
key: const Key('field-name'),
decoration: InputDecoration(labelText: AppLocalizations.of(context).name),
controller: _nameController,
onSaved: (newValue) {
@@ -84,7 +84,7 @@ class MealForm extends StatelessWidget {
onFieldSubmitted: (_) {},
),
ElevatedButton(
key: Key(SUBMIT_BUTTON_KEY_NAME),
key: const Key(SUBMIT_BUTTON_KEY_NAME),
child: Text(AppLocalizations.of(context).save),
onPressed: () async {
if (!_form.currentState!.validate()) {
@@ -114,7 +114,7 @@ class MealForm extends StatelessWidget {
class MealItemForm extends StatelessWidget {
final Meal _meal;
late MealItem _mealItem;
late final MealItem _mealItem;
MealItemForm(this._meal, [mealItem]) {
_mealItem = mealItem ?? MealItem.empty();
@@ -128,7 +128,7 @@ class MealItemForm extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(20),
margin: const EdgeInsets.all(20),
child: Form(
key: _form,
child: Column(
@@ -210,7 +210,7 @@ class MealItemForm extends StatelessWidget {
class PlanForm extends StatelessWidget {
final _form = GlobalKey<FormState>();
final _descriptionController = TextEditingController();
late NutritionalPlan _plan;
late final NutritionalPlan _plan;
PlanForm([NutritionalPlan? plan]) {
_plan = plan ?? NutritionalPlan.empty();
@@ -225,7 +225,7 @@ class PlanForm extends StatelessWidget {
children: [
// Description
TextFormField(
key: Key('field-description'),
key: const Key('field-description'),
decoration: InputDecoration(labelText: AppLocalizations.of(context).description),
controller: _descriptionController,
onFieldSubmitted: (_) {},
@@ -234,7 +234,7 @@ class PlanForm extends StatelessWidget {
},
),
ElevatedButton(
key: Key(SUBMIT_BUTTON_KEY_NAME),
key: const Key(SUBMIT_BUTTON_KEY_NAME),
child: Text(AppLocalizations.of(context).save),
onPressed: () async {
// Validate and save the current values to the weightEntry

View File

@@ -51,7 +51,7 @@ class _MealWidgetState extends State<MealWidget> {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(3),
padding: const EdgeInsets.all(3),
child: Card(
child: Column(
children: [
@@ -77,7 +77,7 @@ class _MealWidgetState extends State<MealWidget> {
),
);
},
icon: Icon(Icons.delete),
icon: const Icon(Icons.delete),
),
if (widget._meal.mealItems.isNotEmpty)
Ink(
@@ -113,11 +113,11 @@ class _MealWidgetState extends State<MealWidget> {
),
);
},
icon: Icon(Icons.edit),
icon: const Icon(Icons.edit),
),
],
),
Divider(),
const Divider(),
...widget._meal.mealItems.map((item) => MealItemWidget(item, _expanded)).toList(),
OutlinedButton(
child: Text(AppLocalizations.of(context).addIngredient),
@@ -159,7 +159,7 @@ class MealItemWidget extends StatelessWidget {
final values = _item.nutritionalValues;
return Container(
padding: EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -175,7 +175,7 @@ class MealItemWidget extends StatelessWidget {
)),
if (_expanded)
IconButton(
icon: Icon(Icons.delete),
icon: const Icon(Icons.delete),
iconSize: ICON_SIZE_SMALL,
onPressed: () {
// Delete the meal item
@@ -204,7 +204,7 @@ class MealItemWidget extends StatelessWidget {
class DismissibleMealHeader extends StatelessWidget {
final bool _expanded;
final _toggle;
final Function _toggle;
const DismissibleMealHeader(
this._expanded,
@@ -221,7 +221,7 @@ class DismissibleMealHeader extends StatelessWidget {
direction: DismissDirection.startToEnd,
child: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(color: Colors.white),
decoration: const BoxDecoration(color: Colors.white),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -240,7 +240,7 @@ class DismissibleMealHeader extends StatelessWidget {
),
IconButton(
visualDensity: VisualDensity.compact,
icon: _expanded ? Icon(Icons.unfold_less) : Icon(Icons.unfold_more),
icon: _expanded ? const Icon(Icons.unfold_less) : const Icon(Icons.unfold_more),
onPressed: () {
_toggle();
},
@@ -253,15 +253,15 @@ class DismissibleMealHeader extends StatelessWidget {
background: Container(
color: wgerPrimaryButtonColor, //Theme.of(context).primaryColor,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 10),
padding: const EdgeInsets.only(left: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
AppLocalizations.of(context).logMeal,
style: TextStyle(color: Colors.white),
style: const TextStyle(color: Colors.white),
),
Icon(
const Icon(
Icons.history_edu,
color: Colors.white,
),

View File

@@ -41,7 +41,7 @@ class NutritionalDiaryDetailWidget extends StatelessWidget {
) {
return Table(
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
border: TableBorder(
border: const TableBorder(
horizontalInside: BorderSide(width: 1, color: wgerTextMuted),
),
columnWidths: const {0: FractionColumnWidth(0.4)},
@@ -52,20 +52,20 @@ class NutritionalDiaryDetailWidget extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: tablePadding),
child: Text(
AppLocalizations.of(context).macronutrients,
style: TextStyle(fontWeight: FontWeight.bold),
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
Text(
AppLocalizations.of(context).planned,
style: TextStyle(fontWeight: FontWeight.bold),
style: const TextStyle(fontWeight: FontWeight.bold),
),
Text(
AppLocalizations.of(context).logged,
style: TextStyle(fontWeight: FontWeight.bold),
style: const TextStyle(fontWeight: FontWeight.bold),
),
Text(
AppLocalizations.of(context).difference,
style: TextStyle(fontWeight: FontWeight.bold),
style: const TextStyle(fontWeight: FontWeight.bold),
),
],
),
@@ -177,9 +177,9 @@ class NutritionalDiaryDetailWidget extends StatelessWidget {
children: [
Text(
DateFormat.Hm(Localizations.localeOf(context).languageCode).format(log.datetime),
style: TextStyle(fontWeight: FontWeight.bold),
style: const TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(width: 8),
const SizedBox(width: 8),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@@ -188,9 +188,9 @@ class NutritionalDiaryDetailWidget extends StatelessWidget {
'${log.amount.toStringAsFixed(0)}${AppLocalizations.of(context).g} ${log.ingredientObj.name}',
overflow: TextOverflow.ellipsis,
),
SizedBox(height: 4),
const SizedBox(height: 4),
...getMutedNutritionalValues(values, context),
SizedBox(height: 12),
const SizedBox(height: 12),
],
),
),
@@ -199,7 +199,7 @@ class NutritionalDiaryDetailWidget extends StatelessWidget {
Provider.of<NutritionPlansProvider>(context, listen: false)
.deleteLog(log.id!, _nutritionalPlan.id!);
},
icon: Icon(Icons.delete_outline)),
icon: const Icon(Icons.delete_outline)),
],
);
}).toList();
@@ -212,7 +212,7 @@ class NutritionalDiaryDetailWidget extends StatelessWidget {
final logs = _nutritionalPlan.getLogsForDate(_date);
if (valuesDate == null) {
return Text('');
return const Text('');
}
return Column(
@@ -221,7 +221,7 @@ class NutritionalDiaryDetailWidget extends StatelessWidget {
child: Column(
children: [
Container(
padding: EdgeInsets.all(15),
padding: const EdgeInsets.all(15),
height: 220,
child: NutritionalPlanPieChartWidget(valuesDate),
),
@@ -232,7 +232,7 @@ class NutritionalDiaryDetailWidget extends StatelessWidget {
],
),
),
SizedBox(height: 15),
const SizedBox(height: 15),
...getEntriesTable(logs, context),
],
);

View File

@@ -47,7 +47,7 @@ class NutritionalPlanDetailWidget extends StatelessWidget {
return SliverList(
delegate: SliverChildListDelegate(
[
SizedBox(height: 10),
const SizedBox(height: 10),
..._nutritionalPlan.meals.map((meal) => MealWidget(meal)).toList(),
Padding(
padding: const EdgeInsets.all(8.0),
@@ -66,7 +66,7 @@ class NutritionalPlanDetailWidget extends StatelessWidget {
),
),
Container(
padding: EdgeInsets.all(15),
padding: const EdgeInsets.all(15),
height: 220,
child: NutritionalPlanPieChartWidget(nutritionalValues),
),
@@ -74,7 +74,7 @@ class NutritionalPlanDetailWidget extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Table(
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
border: TableBorder(
border: const TableBorder(
horizontalInside: BorderSide(width: 1, color: wgerTextMuted),
),
columnWidths: const {0: FractionColumnWidth(0.4)},
@@ -85,20 +85,20 @@ class NutritionalPlanDetailWidget extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: tablePadding),
child: Text(
AppLocalizations.of(context).macronutrients,
style: TextStyle(fontWeight: FontWeight.bold),
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
Text(
AppLocalizations.of(context).total,
style: TextStyle(fontWeight: FontWeight.bold),
style: const TextStyle(fontWeight: FontWeight.bold),
),
Text(
AppLocalizations.of(context).percentEnergy,
style: TextStyle(fontWeight: FontWeight.bold),
style: const TextStyle(fontWeight: FontWeight.bold),
),
Text(
AppLocalizations.of(context).gPerBodyKg,
style: TextStyle(fontWeight: FontWeight.bold),
style: const TextStyle(fontWeight: FontWeight.bold),
),
],
),
@@ -112,8 +112,8 @@ class NutritionalPlanDetailWidget extends StatelessWidget {
nutritionalValues.energy.toStringAsFixed(0) +
AppLocalizations.of(context).kcal,
),
Text(''),
Text(''),
const Text(''),
const Text(''),
],
),
TableRow(
@@ -148,8 +148,8 @@ class NutritionalPlanDetailWidget extends StatelessWidget {
),
Text(nutritionalValues.carbohydratesSugar.toStringAsFixed(0) +
AppLocalizations.of(context).g),
Text(''),
Text(''),
const Text(''),
const Text(''),
],
),
TableRow(
@@ -171,8 +171,8 @@ class NutritionalPlanDetailWidget extends StatelessWidget {
),
Text(nutritionalValues.fatSaturated.toStringAsFixed(0) +
AppLocalizations.of(context).g),
Text(''),
Text(''),
const Text(''),
const Text(''),
],
),
TableRow(
@@ -183,8 +183,8 @@ class NutritionalPlanDetailWidget extends StatelessWidget {
),
Text(nutritionalValues.fibres.toStringAsFixed(0) +
AppLocalizations.of(context).g),
Text(''),
Text(''),
const Text(''),
const Text(''),
],
),
TableRow(
@@ -195,21 +195,21 @@ class NutritionalPlanDetailWidget extends StatelessWidget {
),
Text(nutritionalValues.sodium.toStringAsFixed(0) +
AppLocalizations.of(context).g),
Text(''),
Text(''),
const Text(''),
const Text(''),
],
),
],
),
),
Padding(padding: const EdgeInsets.all(8.0)),
const Padding(padding: EdgeInsets.all(8.0)),
Text(
AppLocalizations.of(context).nutritionalDiary,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline6,
),
Container(
padding: EdgeInsets.all(15),
padding: const EdgeInsets.all(15),
height: 220,
child: NutritionalDiaryChartWidget(nutritionalPlan: _nutritionalPlan),
),

View File

@@ -80,12 +80,12 @@ class NutritionalPlansList extends StatelessWidget {
background: Container(
color: Theme.of(context).errorColor,
alignment: Alignment.centerRight,
padding: EdgeInsets.only(right: 20),
margin: EdgeInsets.symmetric(
padding: const EdgeInsets.only(right: 20),
margin: const EdgeInsets.symmetric(
horizontal: 4,
vertical: 4,
),
child: Icon(
child: const Icon(
Icons.delete,
color: Colors.white,
),

View File

@@ -36,7 +36,7 @@ class WeightEntriesList extends StatelessWidget {
children: [
Container(
color: Theme.of(context).cardColor,
padding: EdgeInsets.all(15),
padding: const EdgeInsets.all(15),
height: 220,
child: MeasurementChartWidget(
_weightProvider.items.map((e) => MeasurementChartEntry(e.weight, e.date)).toList()),
@@ -50,7 +50,7 @@ class WeightEntriesList extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(AppLocalizations.of(context).measurements),
Icon(Icons.chevron_right)
const Icon(Icons.chevron_right)
],
)),
Expanded(
@@ -95,12 +95,12 @@ class WeightEntriesList extends StatelessWidget {
secondaryBackground: Container(
color: Theme.of(context).errorColor,
alignment: Alignment.centerRight,
padding: EdgeInsets.only(right: 20),
margin: EdgeInsets.symmetric(
padding: const EdgeInsets.only(right: 20),
margin: const EdgeInsets.symmetric(
horizontal: 4,
vertical: 4,
),
child: Icon(
child: const Icon(
Icons.delete,
color: Colors.white,
),
@@ -108,12 +108,12 @@ class WeightEntriesList extends StatelessWidget {
background: Container(
color: wgerPrimaryButtonColor,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 20),
margin: EdgeInsets.symmetric(
padding: const EdgeInsets.only(left: 20),
margin: const EdgeInsets.symmetric(
horizontal: 4,
vertical: 4,
),
child: Icon(
child: const Icon(
Icons.edit,
color: Colors.white,
),

View File

@@ -31,7 +31,7 @@ class WeightForm extends StatelessWidget {
final dateController = TextEditingController();
final weightController = TextEditingController();
late WeightEntry _weightEntry;
late final WeightEntry _weightEntry;
WeightForm([WeightEntry? weightEntry]) {
_weightEntry = weightEntry ?? WeightEntry(date: DateTime.now());
@@ -50,7 +50,7 @@ class WeightForm extends StatelessWidget {
readOnly: true, // Stop keyboard from appearing
decoration: InputDecoration(
labelText: AppLocalizations.of(context).date,
suffixIcon: Icon(Icons.calendar_today_outlined),
suffixIcon: const Icon(Icons.calendar_today_outlined),
),
enableInteractiveSelection: false,
controller: dateController,

View File

@@ -30,7 +30,7 @@ class TimeSeriesLog {
}
class LogChartWidget extends StatelessWidget {
final _data;
final Map _data;
final DateTime _currentDate;
const LogChartWidget(this._data, this._currentDate);
@@ -55,7 +55,7 @@ class LogChartWidget extends StatelessWidget {
);
}),
],
primaryMeasureAxis: charts.NumericAxisSpec(
primaryMeasureAxis: const charts.NumericAxisSpec(
tickProviderSpec: charts.BasicNumericTickProviderSpec(zeroBound: false),
),
behaviors: [

View File

@@ -33,12 +33,12 @@ import 'package:wger/widgets/exercises/images.dart';
import 'package:wger/widgets/workouts/forms.dart';
class SettingWidget extends StatelessWidget {
Set set;
Setting setting;
final Set set;
final Setting setting;
final bool expanded;
final toggle;
final Function toggle;
SettingWidget({
const SettingWidget({
required this.set,
required this.setting,
required this.expanded,
@@ -118,7 +118,7 @@ class _WorkoutDayWidgetState extends State<WorkoutDayWidget> {
if (_expanded)
IconButton(
visualDensity: VisualDensity.compact,
icon: Icon(Icons.delete),
icon: const Icon(Icons.delete),
iconSize: ICON_SIZE_SMALL,
onPressed: () {
Provider.of<WorkoutPlansProvider>(context, listen: false).deleteSet(set);
@@ -138,14 +138,14 @@ class _WorkoutDayWidgetState extends State<WorkoutDayWidget> {
),
)
.toList(),
Divider(),
const Divider(),
],
),
),
if (_expanded)
ReorderableDragStartListener(
index: index,
child: IconButton(
child: const IconButton(
icon: Icon(Icons.drag_handle),
onPressed: null,
),
@@ -178,7 +178,7 @@ class _WorkoutDayWidgetState extends State<WorkoutDayWidget> {
widget._day,
);
},
icon: Icon(Icons.delete),
icon: const Icon(Icons.delete),
),
if (widget._day.sets.isNotEmpty)
Ink(
@@ -212,13 +212,13 @@ class _WorkoutDayWidgetState extends State<WorkoutDayWidget> {
),
);
},
icon: Icon(Icons.edit),
icon: const Icon(Icons.edit),
),
],
),
Divider(),
const Divider(),
ReorderableListView(
physics: NeverScrollableScrollPhysics(),
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
buildDefaultDragHandles: false,
onReorder: (_oldIndex, _newIndex) async {
@@ -265,7 +265,7 @@ class _WorkoutDayWidgetState extends State<WorkoutDayWidget> {
class DayHeaderDismissible extends StatelessWidget {
final Day _day;
final bool _expanded;
final _toggle;
final Function _toggle;
const DayHeaderDismissible({
required Day day,
@@ -282,7 +282,7 @@ class DayHeaderDismissible extends StatelessWidget {
direction: DismissDirection.startToEnd,
child: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(color: Colors.white),
decoration: const BoxDecoration(color: Colors.white),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@@ -300,7 +300,7 @@ class DayHeaderDismissible extends StatelessWidget {
),
),
IconButton(
icon: _expanded ? Icon(Icons.unfold_less) : Icon(Icons.unfold_more),
icon: _expanded ? const Icon(Icons.unfold_less) : const Icon(Icons.unfold_more),
onPressed: () {
_toggle();
},
@@ -311,15 +311,15 @@ class DayHeaderDismissible extends StatelessWidget {
background: Container(
color: wgerPrimaryButtonColor, //Theme.of(context).primaryColor,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 10),
padding: const EdgeInsets.only(left: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
AppLocalizations.of(context).gymMode,
style: TextStyle(color: Colors.white),
style: const TextStyle(color: Colors.white),
),
Icon(
const Icon(
Icons.play_arrow,
color: Colors.white,
),

View File

@@ -35,7 +35,7 @@ import 'package:wger/theme/theme.dart';
import 'package:wger/widgets/exercises/images.dart';
class WorkoutForm extends StatelessWidget {
WorkoutPlan _plan;
final WorkoutPlan _plan;
final _form = GlobalKey<FormState>();
WorkoutForm(this._plan);
@@ -55,7 +55,7 @@ class WorkoutForm extends StatelessWidget {
child: Column(
children: [
TextFormField(
key: Key('field-name'),
key: const Key('field-name'),
decoration: InputDecoration(labelText: AppLocalizations.of(context).name),
controller: workoutNameController,
validator: (value) {
@@ -72,7 +72,7 @@ class WorkoutForm extends StatelessWidget {
},
),
TextFormField(
key: Key('field-description'),
key: const Key('field-description'),
decoration: InputDecoration(labelText: AppLocalizations.of(context).description),
minLines: 3,
maxLines: 10,
@@ -91,7 +91,7 @@ class WorkoutForm extends StatelessWidget {
},
),
ElevatedButton(
key: Key(SUBMIT_BUTTON_KEY_NAME),
key: const Key(SUBMIT_BUTTON_KEY_NAME),
child: Text(AppLocalizations.of(context).save),
onPressed: () async {
// Validate and save
@@ -106,11 +106,12 @@ class WorkoutForm extends StatelessWidget {
await Provider.of<WorkoutPlansProvider>(context, listen: false).editWorkout(_plan);
Navigator.of(context).pop();
} else {
_plan = await Provider.of<WorkoutPlansProvider>(context, listen: false)
.addWorkout(_plan);
final WorkoutPlan newPlan =
await Provider.of<WorkoutPlansProvider>(context, listen: false)
.addWorkout(_plan);
Navigator.of(context).pushReplacementNamed(
WorkoutPlanScreen.routeName,
arguments: _plan,
arguments: newPlan,
);
}
},
@@ -157,7 +158,7 @@ class _DayCheckboxState extends State<DayCheckbox> {
class DayFormWidget extends StatefulWidget {
final WorkoutPlan workout;
final dayController = TextEditingController();
Day _day = Day();
late final Day _day;
DayFormWidget(this.workout, [Day? day]) {
_day = day ?? Day();
@@ -181,7 +182,7 @@ class _DayFormWidgetState extends State<DayFormWidget> {
child: ListView(
children: [
TextFormField(
key: Key('field-description'),
key: const Key('field-description'),
decoration: InputDecoration(
labelText: AppLocalizations.of(context).description,
helperText: AppLocalizations.of(context).dayDescriptionHelp,
@@ -204,10 +205,10 @@ class _DayFormWidgetState extends State<DayFormWidget> {
return null;
},
),
SizedBox(height: 10),
const SizedBox(height: 10),
...Day.weekdays.keys.map((dayNr) => DayCheckbox(dayNr, widget._day)).toList(),
ElevatedButton(
key: Key(SUBMIT_BUTTON_KEY_NAME),
key: const Key(SUBMIT_BUTTON_KEY_NAME),
child: Text(AppLocalizations.of(context).save),
onPressed: () async {
if (!_form.currentState!.validate()) {
@@ -233,11 +234,11 @@ class _DayFormWidgetState extends State<DayFormWidget> {
await showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text('An error occurred!'),
content: Text('Something went wrong.'),
title: const Text('An error occurred!'),
content: const Text('Something went wrong.'),
actions: [
TextButton(
child: Text('Okay'),
child: const Text('Okay'),
onPressed: () {
Navigator.of(ctx).pop();
},
@@ -256,7 +257,7 @@ class _DayFormWidgetState extends State<DayFormWidget> {
class SetFormWidget extends StatefulWidget {
final Day _day;
late Set _set;
late final Set _set;
SetFormWidget(this._day, [Set? set]) {
_set = set ?? Set.withData(day: _day.id, order: _day.sets.length, sets: 4);
@@ -316,7 +317,7 @@ class _SetFormWidgetState extends State<SetFormWidget> {
child: ListView(
children: [
Container(
padding: EdgeInsets.only(top: 10),
padding: const EdgeInsets.only(top: 10),
color: wgerPrimaryColorLight,
child: Column(
//crossAxisAlignment: CrossAxisAlignment.start,
@@ -355,14 +356,14 @@ class _SetFormWidgetState extends State<SetFormWidget> {
children: [
Card(
child: TypeAheadFormField(
key: Key('field-typeahead'),
key: const Key('field-typeahead'),
textFieldConfiguration: TextFieldConfiguration(
controller: _exercisesController,
decoration: InputDecoration(
labelText: AppLocalizations.of(context).searchExercise,
prefixIcon: Icon(Icons.search),
prefixIcon: const Icon(Icons.search),
suffixIcon: IconButton(
icon: Icon(Icons.help),
icon: const Icon(Icons.help),
onPressed: () {
showDialog(
context: context,
@@ -371,7 +372,7 @@ class _SetFormWidgetState extends State<SetFormWidget> {
mainAxisSize: MainAxisSize.min,
children: [
Text(AppLocalizations.of(context).selectExercises),
SizedBox(height: 10),
const SizedBox(height: 10),
Text(AppLocalizations.of(context).sameRepetitions)
],
),
@@ -390,9 +391,8 @@ class _SetFormWidgetState extends State<SetFormWidget> {
errorMaxLines: 2,
),
),
suggestionsCallback: (pattern) async {
return await Provider.of<ExercisesProvider>(context, listen: false)
.searchExercise(
suggestionsCallback: (pattern) {
return Provider.of<ExercisesProvider>(context, listen: false).searchExercise(
pattern,
Localizations.localeOf(context).languageCode,
);
@@ -439,7 +439,7 @@ class _SetFormWidgetState extends State<SetFormWidget> {
},
),
),
SizedBox(height: 10),
const SizedBox(height: 10),
TextFormField(
decoration: InputDecoration(
labelText: AppLocalizations.of(context).comment,
@@ -458,7 +458,7 @@ class _SetFormWidgetState extends State<SetFormWidget> {
widget._set.comment = newValue!;
},
),
SizedBox(height: 10),
const SizedBox(height: 10),
...widget._set.exercisesObj.asMap().entries.map((entry) {
final index = entry.key;
final exercise = entry.value;
@@ -476,21 +476,21 @@ class _SetFormWidgetState extends State<SetFormWidget> {
removeExercise,
),
if (showSupersetInfo)
Padding(
padding: const EdgeInsets.all(3.0),
const Padding(
padding: EdgeInsets.all(3.0),
child: Text('+'),
),
if (showSupersetInfo) Text(AppLocalizations.of(context).supersetWith),
if (showSupersetInfo)
Padding(
padding: const EdgeInsets.all(3.0),
const Padding(
padding: EdgeInsets.all(3.0),
child: Text('+'),
),
],
);
}).toList(),
ElevatedButton(
key: Key(SUBMIT_BUTTON_KEY_NAME),
key: const Key(SUBMIT_BUTTON_KEY_NAME),
child: Text(AppLocalizations.of(context).save),
onPressed: () async {
final isValid = _formKey.currentState!.validate();
@@ -537,7 +537,7 @@ class _SetFormWidgetState extends State<SetFormWidget> {
class ExerciseSetting extends StatelessWidget {
final Exercise _exercise;
int _numberOfSets = 4;
late final int _numberOfSets;
final bool _detailed;
final Function removeExercise;
final List<Setting> _settings;
@@ -573,7 +573,7 @@ class ExerciseSetting extends StatelessWidget {
flex: 2,
child: RepsInputWidget(setting, _detailed),
),
SizedBox(width: 4),
const SizedBox(width: 4),
Flexible(
flex: 3,
child: RepetitionUnitInputWidget(setting),
@@ -587,7 +587,7 @@ class ExerciseSetting extends StatelessWidget {
flex: 2,
child: WeightInputWidget(setting, _detailed),
),
SizedBox(width: 4),
const SizedBox(width: 4),
Flexible(
flex: 3,
child: WeightUnitInputWidget(setting, key: Key(i.toString())),
@@ -598,7 +598,7 @@ class ExerciseSetting extends StatelessWidget {
flex: 2,
child: RiRInputWidget(setting),
),
SizedBox(height: 15),
const SizedBox(height: 15),
],
),
);
@@ -611,11 +611,11 @@ class ExerciseSetting extends StatelessWidget {
children: [
Text(
AppLocalizations.of(context).setNr(i + 1),
style: TextStyle(fontWeight: FontWeight.bold),
style: const TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(width: 10),
const SizedBox(width: 10),
Flexible(child: RepsInputWidget(setting, _detailed)),
SizedBox(width: 4),
const SizedBox(width: 4),
Flexible(child: WeightInputWidget(setting, _detailed)),
],
),
@@ -643,12 +643,12 @@ class ExerciseSetting extends StatelessWidget {
contentPadding: EdgeInsets.zero,
leading: ExerciseImageWidget(image: _exercise.getMainImage),
trailing: IconButton(
icon: Icon(Icons.delete),
icon: const Icon(Icons.delete),
onPressed: () {
removeExercise(_exercise);
}),
),
Divider(),
const Divider(),
//ExerciseImage(imageUrl: _exercise.images.first.url),
if (!_detailed)

View File

@@ -44,7 +44,7 @@ import 'package:wger/widgets/workouts/forms.dart';
class GymMode extends StatefulWidget {
final Day _workoutDay;
late TimeOfDay _start;
late final TimeOfDay _start;
GymMode(this._workoutDay) {
_start = TimeOfDay.now();
@@ -181,7 +181,7 @@ class StartPage extends StatelessWidget {
_controller,
exercisePages: _exercisePages,
),
Divider(),
const Divider(),
Expanded(
child: ListView(
children: [
@@ -197,7 +197,7 @@ class StartPage extends StatelessWidget {
style: Theme.of(context).textTheme.headline6,
),
...set.getSmartRepr(s.exerciseObj).map((e) => Text(e)).toList(),
SizedBox(height: 15),
const SizedBox(height: 15),
],
);
}).toList(),
@@ -211,7 +211,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: const Duration(milliseconds: 200), curve: Curves.bounceIn);
},
),
NavigationFooter(
@@ -290,7 +291,7 @@ class _LogPageState extends State<LogPage> {
return Row(
children: [
IconButton(
icon: Icon(
icon: const Icon(
Icons.remove,
color: Colors.black,
),
@@ -328,7 +329,7 @@ class _LogPageState extends State<LogPage> {
),
),
IconButton(
icon: Icon(
icon: const Icon(
Icons.add,
color: Colors.black,
),
@@ -348,7 +349,7 @@ class _LogPageState extends State<LogPage> {
return Row(
children: [
IconButton(
icon: Icon(
icon: const Icon(
Icons.remove,
color: Colors.black,
),
@@ -396,7 +397,7 @@ class _LogPageState extends State<LogPage> {
),
),
IconButton(
icon: Icon(
icon: const Icon(
Icons.add,
color: Colors.black,
),
@@ -429,7 +430,7 @@ class _LogPageState extends State<LogPage> {
Row(
children: [
Flexible(child: getRepsWidget()),
SizedBox(width: 8),
const SizedBox(width: 8),
Flexible(child: getWeightWidget()),
],
),
@@ -438,7 +439,7 @@ class _LogPageState extends State<LogPage> {
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Flexible(child: getRepsWidget()),
SizedBox(width: 8),
const SizedBox(width: 8),
Flexible(child: RepetitionUnitInputWidget(widget._log)),
],
),
@@ -447,7 +448,7 @@ class _LogPageState extends State<LogPage> {
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Flexible(child: getWeightWidget()),
SizedBox(width: 8),
const SizedBox(width: 8),
Flexible(child: WeightUnitInputWidget(widget._log))
],
),
@@ -464,7 +465,7 @@ class _LogPageState extends State<LogPage> {
ElevatedButton(
child: (!_isSaving)
? Text(AppLocalizations.of(context).save)
: Container(
: const SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(
@@ -488,7 +489,7 @@ class _LogPageState extends State<LogPage> {
.addLog(widget._log);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
duration: Duration(seconds: 2), // default is 4
duration: const Duration(seconds: 2), // default is 4
content: Text(
AppLocalizations.of(context).successfullySaved,
textAlign: TextAlign.center,
@@ -527,7 +528,7 @@ class _LogPageState extends State<LogPage> {
title: Text(log.singleLogRepTextNoNl),
subtitle:
Text(DateFormat.yMd(Localizations.localeOf(context).languageCode).format(log.date)),
trailing: Icon(Icons.copy),
trailing: const Icon(Icons.copy),
onTap: () {
setState(() {
// Text field
@@ -544,7 +545,7 @@ class _LogPageState extends State<LogPage> {
.showSnackBar(SnackBar(content: Text(AppLocalizations.of(context).dataCopied)));
});
},
contentPadding: EdgeInsets.symmetric(horizontal: 40),
contentPadding: const EdgeInsets.symmetric(horizontal: 40),
);
}).toList(),
],
@@ -576,9 +577,9 @@ class _LogPageState extends State<LogPage> {
(key) => Row(
children: [
Text(groupedPlates[key].toString()),
Text('×'),
const Text('×'),
Container(
decoration: BoxDecoration(
decoration: const BoxDecoration(
color: wgerPrimaryColorLight,
shape: BoxShape.circle,
),
@@ -591,13 +592,13 @@ class _LogPageState extends State<LogPage> {
alignment: Alignment.center,
child: Text(
key.toString(),
style: TextStyle(fontWeight: FontWeight.bold),
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
),
),
),
SizedBox(width: 10),
const SizedBox(width: 10),
],
),
)
@@ -606,7 +607,7 @@ class _LogPageState extends State<LogPage> {
)
: MutedText(AppLocalizations.of(context).plateCalculatorNotDivisible),
),
SizedBox(height: 3),
const SizedBox(height: 3),
],
);
}
@@ -632,7 +633,7 @@ class _LogPageState extends State<LogPage> {
widget._set.comment,
textAlign: TextAlign.center,
),
SizedBox(height: 10),
const SizedBox(height: 10),
Expanded(
child: (widget._workoutPlan.filterLogsByExercise(widget._exercise).isNotEmpty)
? getPastLogs()
@@ -675,10 +676,10 @@ class ExerciseOverview extends StatelessWidget {
_controller,
exercisePages: _exercisePages,
),
Divider(),
const Divider(),
Expanded(
child: ListView(
padding: EdgeInsets.symmetric(horizontal: 15),
padding: const EdgeInsets.symmetric(horizontal: 15),
children: [
Text(
_exercise.categoryObj.name,
@@ -762,7 +763,7 @@ class _SessionPageState extends State<SessionPage> {
widget._controller,
exercisePages: widget._exercisePages,
),
Divider(),
const Divider(),
Expanded(child: Container()),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
@@ -850,7 +851,7 @@ class _SessionPageState extends State<SessionPage> {
return null;
}),
),
SizedBox(width: 10),
const SizedBox(width: 10),
Flexible(
child: TextFormField(
decoration:
@@ -1008,7 +1009,7 @@ class NavigationFooter extends StatelessWidget {
children: [
if (showPrevious)
IconButton(
icon: Icon(Icons.chevron_left),
icon: const Icon(Icons.chevron_left),
onPressed: () {
_controller.previousPage(
duration: DEFAULT_ANIMATION_DURATION,
@@ -1017,17 +1018,17 @@ class NavigationFooter extends StatelessWidget {
},
)
else
SizedBox(width: 48),
const SizedBox(width: 48),
Expanded(
child: LinearProgressIndicator(
minHeight: 1.5,
value: _ratioCompleted,
valueColor: AlwaysStoppedAnimation<Color>(wgerPrimaryColor),
valueColor: const AlwaysStoppedAnimation<Color>(wgerPrimaryColor),
),
),
if (showNext)
IconButton(
icon: Icon(Icons.chevron_right),
icon: const Icon(Icons.chevron_right),
onPressed: () {
_controller.nextPage(
duration: DEFAULT_ANIMATION_DURATION,
@@ -1036,7 +1037,7 @@ class NavigationFooter extends StatelessWidget {
},
)
else
SizedBox(width: 48),
const SizedBox(width: 48),
],
);
}
@@ -1045,9 +1046,9 @@ class NavigationFooter extends StatelessWidget {
class NavigationHeader extends StatelessWidget {
final PageController _controller;
final String _title;
Map<String, int> exercisePages;
final Map<String, int> exercisePages;
NavigationHeader(
const NavigationHeader(
this._title,
this._controller, {
required this.exercisePages,
@@ -1066,7 +1067,7 @@ class NavigationHeader extends StatelessWidget {
...exercisePages.keys.map((e) {
return ListTile(
title: Text(e),
trailing: Icon(Icons.chevron_right),
trailing: const Icon(Icons.chevron_right),
onTap: () {
_controller.animateToPage(
exercisePages[e]!,
@@ -1096,7 +1097,7 @@ class NavigationHeader extends StatelessWidget {
return Row(
children: [
IconButton(
icon: Icon(Icons.close),
icon: const Icon(Icons.close),
onPressed: () {
Navigator.of(context).pop();
},
@@ -1112,7 +1113,7 @@ class NavigationHeader extends StatelessWidget {
),
),
IconButton(
icon: Icon(Icons.menu),
icon: const Icon(Icons.menu),
onPressed: () {
showDialog(
context: context,

View File

@@ -46,9 +46,9 @@ class ExerciseLogChart extends StatelessWidget {
future: _getChartEntries(context),
builder: (context, AsyncSnapshot<Map<String, dynamic>> snapshot) => SizedBox(
height: 150,
child: snapshot.connectionState == ConnectionState.waiting
? Center(child: CircularProgressIndicator())
: LogChartWidget(snapshot.data, _currentDate),
child: snapshot.connectionState == ConnectionState.waiting && snapshot.hasData
? const Center(child: CircularProgressIndicator())
: LogChartWidget(snapshot.data!, _currentDate),
),
);
}
@@ -80,7 +80,7 @@ class _DayLogWidgetState extends State<DayLogWidget> {
DateFormat.yMd(Localizations.localeOf(context).languageCode).format(widget._date),
style: Theme.of(context).textTheme.headline5,
),
if (widget._session != null) Text('Session data here'),
if (widget._session != null) const Text('Session data here'),
...widget._exerciseData.keys.map((exercise) {
return Column(
children: [
@@ -109,7 +109,7 @@ class _DayLogWidgetState extends State<DayLogWidget> {
)
.toList(),
ExerciseLogChart(exercise, widget._date),
SizedBox(height: 30),
const SizedBox(height: 30),
],
);
}).toList()

View File

@@ -30,7 +30,7 @@ import 'package:wger/widgets/workouts/log.dart';
class WorkoutLogs extends StatefulWidget {
final WorkoutPlan _workoutPlan;
final _changeMode;
final Function _changeMode;
const WorkoutLogs(this._workoutPlan, this._changeMode);
@override
@@ -168,7 +168,7 @@ class _WorkoutLogCalendarState extends State<WorkoutLogCalendar> {
children: [
TableCalendar(
locale: Localizations.localeOf(context).languageCode,
firstDay: DateTime.now().subtract(Duration(days: 1000)),
firstDay: DateTime.now().subtract(const Duration(days: 1000)),
lastDay: DateTime.now(),
focusedDay: _focusedDay,
selectedDayPredicate: (day) => isSameDay(_selectedDay, day),

View File

@@ -26,7 +26,7 @@ import 'package:wger/widgets/workouts/forms.dart';
class WorkoutPlanDetail extends StatefulWidget {
final WorkoutPlan _workoutPlan;
final _changeMode;
final Function _changeMode;
const WorkoutPlanDetail(this._workoutPlan, this._changeMode);
@override

View File

@@ -83,12 +83,12 @@ class WorkoutPlansList extends StatelessWidget {
background: Container(
color: Theme.of(context).errorColor,
alignment: Alignment.centerRight,
padding: EdgeInsets.only(right: 20),
margin: EdgeInsets.symmetric(
padding: const EdgeInsets.only(right: 20),
margin: const EdgeInsets.symmetric(
horizontal: 4,
vertical: 4,
),
child: Icon(
child: const Icon(
Icons.delete,
color: Colors.white,
),

View File

@@ -28,7 +28,7 @@ packages:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.5"
version: "3.1.6"
args:
dependency: transitive
description:
@@ -175,7 +175,7 @@ packages:
name: cli_util
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.4"
version: "0.3.5"
clock:
dependency: transitive
description:
@@ -224,7 +224,7 @@ packages:
name: csslib
url: "https://pub.dartlang.org"
source: hosted
version: "0.17.0"
version: "0.17.1"
cupertino_icons:
dependency: "direct main"
description:
@@ -292,7 +292,7 @@ packages:
name: flutter_html
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
version: "2.1.5"
flutter_keyboard_visibility:
dependency: transitive
description:
@@ -440,7 +440,7 @@ packages:
name: image
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.7"
version: "3.0.8"
image_picker:
dependency: "direct main"
description:
@@ -692,7 +692,7 @@ packages:
name: rive
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.28"
version: "0.7.30"
shared_preferences:
dependency: "direct main"
description:
@@ -894,6 +894,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
version:
dependency: "direct main"
description:
name: version
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
video_player:
dependency: transitive
description:

View File

@@ -44,6 +44,7 @@ dependencies:
image_picker: ^0.8.4
intl: ^0.17.0
json_annotation: ^4.0.1
version: ^2.0.0
package_info: ^2.0.2
provider: ^5.0.0
rive: ^0.7.28

View File

@@ -37,7 +37,7 @@ void main() {
builder: (ctx, auth, _) => MaterialApp(
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
locale: Locale('en'),
locale: const Locale('en'),
home: AuthScreen(),
),
),
@@ -68,14 +68,14 @@ void main() {
expect(find.text('LOGIN INSTEAD'), findsNothing);
// Check that the correct widgets are shown
expect(find.byKey(Key('inputUsername')), findsOneWidget);
expect(find.byKey(Key('inputEmail')), findsNothing);
expect(find.byKey(Key('inputPassword')), findsOneWidget);
expect(find.byKey(Key('inputServer')), findsNothing);
expect(find.byKey(Key('inputPassword2')), findsNothing);
expect(find.byKey(Key('actionButton')), findsOneWidget);
expect(find.byKey(Key('toggleActionButton')), findsOneWidget);
expect(find.byKey(Key('toggleCustomServerButton')), findsOneWidget);
expect(find.byKey(const Key('inputUsername')), findsOneWidget);
expect(find.byKey(const Key('inputEmail')), findsNothing);
expect(find.byKey(const Key('inputPassword')), findsOneWidget);
expect(find.byKey(const Key('inputServer')), findsNothing);
expect(find.byKey(const Key('inputPassword2')), findsNothing);
expect(find.byKey(const Key('actionButton')), findsOneWidget);
expect(find.byKey(const Key('toggleActionButton')), findsOneWidget);
expect(find.byKey(const Key('toggleCustomServerButton')), findsOneWidget);
}, skip: true); // TODO(x): skipped because of technical problems:
// either the provider wasn't found or, if the call was removed, the
// localization data could not be loaded...
@@ -83,7 +83,7 @@ void main() {
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')));
await tester.tap(find.byKey(const Key('toggleActionButton')));
// Rebuild the widget after the state has changed.
await tester.pump();
@@ -91,12 +91,12 @@ void main() {
expect(find.text('LOGIN INSTEAD'), findsOneWidget);
// Check that the correct widgets are shown
expect(find.byKey(Key('inputUsername')), findsOneWidget);
expect(find.byKey(Key('inputEmail')), findsOneWidget);
expect(find.byKey(Key('inputPassword')), findsOneWidget);
expect(find.byKey(Key('inputServer')), findsOneWidget);
expect(find.byKey(Key('inputPassword2')), findsOneWidget);
expect(find.byKey(Key('actionButton')), findsOneWidget);
expect(find.byKey(Key('toggleActionButton')), findsOneWidget);
expect(find.byKey(const Key('inputUsername')), findsOneWidget);
expect(find.byKey(const Key('inputEmail')), findsOneWidget);
expect(find.byKey(const Key('inputPassword')), findsOneWidget);
expect(find.byKey(const Key('inputServer')), findsOneWidget);
expect(find.byKey(const Key('inputPassword2')), findsOneWidget);
expect(find.byKey(const Key('actionButton')), findsOneWidget);
expect(find.byKey(const Key('toggleActionButton')), findsOneWidget);
}, skip: true);
}

View File

@@ -22,8 +22,8 @@ import 'package:wger/helpers/misc.dart';
void main() {
test('Test the TimeOfDayExtension', () {
final time1 = TimeOfDay(hour: 00, minute: 00);
final time2 = TimeOfDay(hour: 23, minute: 59);
const time1 = TimeOfDay(hour: 00, minute: 00);
const time2 = TimeOfDay(hour: 23, minute: 59);
expect(time2.toMinutes(), 23 * 60 + 59);
expect(time1.isAfter(time2), false);

View File

@@ -58,16 +58,16 @@ void main() {
expect(find.byType(TextFormField), findsNWidgets(2));
expect(find.text('A very cool image from the gym'), findsOneWidget);
expect(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)), findsOneWidget);
expect(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME)), findsOneWidget);
// Date can only be edited via the datepicker
await tester.tap(find.byKey(Key('field-date')));
await tester.tap(find.byKey(const Key('field-date')));
await tester.pump();
await tester.tap(find.text('OK'));
await tester.tap(find.text('15'), warnIfMissed: false);
await tester.pump();
await tester.tap(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)));
await tester.tap(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME)));
verifyNever(mockGalleryProvider.addImage(any, any));
verify(mockGalleryProvider.editImage(any, any));

View File

@@ -46,7 +46,7 @@ void main() {
locale: Locale(locale),
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
home: Gallery(),
home: const Gallery(),
routes: {
FormScreen.routeName: (ctx) => FormScreen(),
},
@@ -63,11 +63,11 @@ void main() {
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')));
await tester.tap(find.byKey(const Key('image-1')));
await tester.pumpAndSettle();
// Detail dialog opens
expect(find.byKey(Key('image-1-detail')), findsOneWidget);
expect(find.byKey(const Key('image-1-detail')), findsOneWidget);
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);
@@ -84,7 +84,7 @@ void main() {
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.tap(find.byKey(const Key('image-1')));
await tester.pumpAndSettle();
expect(find.text('5/30/2021'), findsOneWidget);
@@ -92,7 +92,7 @@ void main() {
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.tap(find.byKey(const Key('image-1')));
await tester.pumpAndSettle();
expect(find.text('30.5.2021'), findsOneWidget);

View File

@@ -96,7 +96,7 @@ void main() {
expect(find.byIcon(Icons.menu), findsOneWidget);
expect(find.byIcon(Icons.chevron_left), findsOneWidget);
expect(find.byIcon(Icons.chevron_right), findsOneWidget);
await tester.drag(find.byType(ExerciseOverview), Offset(-500.0, 0.0));
await tester.drag(find.byType(ExerciseOverview), const Offset(-500.0, 0.0));
await tester.pumpAndSettle();
//
@@ -127,7 +127,7 @@ void main() {
expect(find.byType(RepetitionUnitInputWidget), findsOneWidget);
expect(find.byType(WeightUnitInputWidget), findsOneWidget);
expect(find.byType(RiRInputWidget), findsOneWidget);
await tester.drag(find.byType(LogPage), Offset(-500.0, 0.0));
await tester.drag(find.byType(LogPage), const Offset(-500.0, 0.0));
await tester.pumpAndSettle();
//
@@ -148,7 +148,7 @@ void main() {
expect(find.text('test exercise 1'), findsOneWidget);
expect(find.byType(LogPage), findsOneWidget);
expect(find.byType(Form), findsOneWidget);
await tester.drag(find.byType(LogPage), Offset(-500.0, 0.0));
await tester.drag(find.byType(LogPage), const Offset(-500.0, 0.0));
await tester.pumpAndSettle();
//

View File

@@ -54,7 +54,7 @@ void main() {
home: TextButton(
onPressed: () => key.currentState!.push(
MaterialPageRoute<void>(
settings: RouteSettings(arguments: 1),
settings: const RouteSettings(arguments: 1),
builder: (_) => MeasurementEntriesScreen(),
),
),

View File

@@ -34,11 +34,11 @@ void main() {
);
const int tCategoryId = 1;
final MeasurementCategory tMeasurementCategory =
const MeasurementCategory tMeasurementCategory =
MeasurementCategory(id: 1, name: 'Strength', unit: 'kN');
final List<MeasurementCategory> tMeasurementCategories = [
MeasurementCategory(id: 1, name: 'Strength', unit: 'kN'),
MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm')
const MeasurementCategory(id: 1, name: 'Strength', unit: 'kN'),
const MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm')
];
final Map<String, dynamic> tMeasurementCategoriesMap =
jsonDecode(fixture('measurement_categories.json'));
@@ -160,7 +160,7 @@ void main() {
notes: '',
)
]),
MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm')
const MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm')
];
// act
@@ -172,16 +172,16 @@ void main() {
});
group('addCategory()', () {
final MeasurementCategory tMeasurementCategoryWithoutId =
const MeasurementCategory tMeasurementCategoryWithoutId =
MeasurementCategory(id: null, name: 'Strength', unit: 'kN');
final Map<String, dynamic> tMeasurementCategoryMap =
jsonDecode(fixture('measurement_category.json'));
final Map<String, dynamic> tMeasurementCategoryMapWithoutId =
jsonDecode(fixture('measurement_category_without_id_to_json.json'));
final List<MeasurementCategory> tMeasurementCategoriesAdded = [
MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm'),
MeasurementCategory(id: 1, name: 'Strength', unit: 'kN'),
MeasurementCategory(id: 1, name: 'Strength', unit: 'kN'),
const MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm'),
const MeasurementCategory(id: 1, name: 'Strength', unit: 'kN'),
const MeasurementCategory(id: 1, name: 'Strength', unit: 'kN'),
];
setUp(() {
when(mockWgerBaseProvider.post(any, any))
@@ -222,7 +222,7 @@ void main() {
.thenAnswer((realInvocation) => Future.value(Response('', 200)));
final List<MeasurementCategory> tMeasurementCategoriesOneDeleted = [
MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm')
const MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm')
];
// act
@@ -235,8 +235,7 @@ void main() {
test('should throw a NoSuchEntryException if no category is found', () {
// act & assert
expect(() async => await measurementProvider.deleteCategory(83),
throwsA(isA<NoSuchEntryException>()));
expect(() => measurementProvider.deleteCategory(83), throwsA(isA<NoSuchEntryException>()));
});
test(
@@ -246,7 +245,7 @@ void main() {
when(mockWgerBaseProvider.deleteRequest(any, any)).thenThrow(WgerHttpException('{}'));
// act & assert
expect(() async => await measurementProvider.deleteCategory(tCategoryId),
expect(() async => measurementProvider.deleteCategory(tCategoryId),
throwsA(isA<WgerHttpException>()));
expect(measurementProvider.categories, tMeasurementCategories);
});
@@ -267,8 +266,8 @@ void main() {
test('should add the new MeasurementCategory and remove the old one', () async {
// arrange
final List<MeasurementCategory> tMeasurementCategoriesEdited = [
MeasurementCategory(id: 1, name: 'Triceps', unit: 'm'),
MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm'),
const MeasurementCategory(id: 1, name: 'Triceps', unit: 'm'),
const MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm'),
];
// act
@@ -300,7 +299,7 @@ void main() {
// act & assert
expect(
() async => await measurementProvider.editCategory(
() => measurementProvider.editCategory(
tCategoryId, tCategoryEditedName, tCategoryEditedUnit),
throwsA(isA<WgerHttpException>()));
expect(measurementProvider.categories, tMeasurementCategories);
@@ -342,7 +341,7 @@ void main() {
),
tMeasurementEntry
]),
MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm')
const MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm')
];
setUp(() async {
@@ -402,7 +401,7 @@ void main() {
.thenAnswer((realInvocation) => Future.value(measurementEntryMapWrongCategory));
// act & assert
expect(() async => await measurementProvider.addEntry(tMeasurementEntryWrongCategory),
expect(() => measurementProvider.addEntry(tMeasurementEntryWrongCategory),
throwsA(isA<NoSuchEntryException>()));
});
});
@@ -419,7 +418,7 @@ void main() {
notes: 'Some important notes',
),
]),
MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm')
const MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm')
];
setUp(() async {
@@ -440,7 +439,7 @@ void main() {
test("should throw a NoSuchEntryException if the category isn't found", () {
// act & assert
expect(() async => await measurementProvider.deleteEntry(tEntryId, 83),
expect(() async => measurementProvider.deleteEntry(tEntryId, 83),
throwsA(isA<NoSuchEntryException>()));
});
@@ -448,7 +447,7 @@ void main() {
"should throw a NoSuchEntryException if the entry in the categories entries List isn't found",
() {
// act & assert
expect(() async => await measurementProvider.deleteEntry(83, tCategoryId),
expect(() => measurementProvider.deleteEntry(83, tCategoryId),
throwsA(isA<NoSuchEntryException>()));
});
@@ -481,12 +480,12 @@ void main() {
notes: '',
),
]),
MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm')
const MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm')
];
when(mockWgerBaseProvider.deleteRequest(any, any)).thenThrow(WgerHttpException('{}'));
// act & assert
expect(() async => await measurementProvider.deleteEntry(tEntryId, tCategoryId),
expect(() async => measurementProvider.deleteEntry(tEntryId, tCategoryId),
throwsA(isA<WgerHttpException>()));
expect(measurementProvider.categories, tMeasurementCategories);
});
@@ -530,7 +529,7 @@ void main() {
notes: '',
)
]),
MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm')
const MeasurementCategory(id: 2, name: 'Biceps', unit: 'cm')
];
// act
@@ -549,7 +548,7 @@ void main() {
test("should throw a NoSuchEntryException if category doesn't exist", () {
// act & assert
expect(
() async => await measurementProvider.editEntry(
() => measurementProvider.editEntry(
tEntryId,
83,
tEntryEditedValue,
@@ -562,7 +561,7 @@ void main() {
test("should throw a NoSuchEntryException if entry doesn't exist", () {
// act & assert
expect(
() async => await measurementProvider.editEntry(
() => measurementProvider.editEntry(
83,
tCategoryId,
tEntryEditedValue,

View File

@@ -74,7 +74,7 @@ void main() {
expect(find.byType(TextFormField), findsNWidgets(2));
expect(find.byType(ElevatedButton), findsOneWidget);
expect(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)), findsOneWidget);
expect(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME)), findsOneWidget);
});
testWidgets('Test editing an existing meal', (WidgetTester tester) async {
@@ -88,14 +88,14 @@ void main() {
);
expect(
find.text(('Initial Name 1')),
find.text('Initial Name 1'),
findsOneWidget,
reason: 'Time of existing meal is filled in',
);
await tester.enterText(find.byKey(Key('field-time')), '12:34');
await tester.enterText(find.byKey(Key('field-name')), 'test meal');
await tester.tap(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)));
await tester.enterText(find.byKey(const Key('field-time')), '12:34');
await tester.enterText(find.byKey(const Key('field-name')), 'test meal');
await tester.tap(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME)));
// Correct method was called
verify(mockNutrition.editMeal(any));
@@ -112,9 +112,9 @@ void main() {
reason: 'Current time is filled in',
);
await tester.enterText(find.byKey(Key('field-time')), '08:00');
await tester.enterText(find.byKey(Key('field-name')), 'test meal');
await tester.tap(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)));
await tester.enterText(find.byKey(const Key('field-time')), '08:00');
await tester.enterText(find.byKey(const Key('field-name')), 'test meal');
await tester.tap(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME)));
// Correct method was called
verifyNever(mockNutrition.editMeal(any));

View File

@@ -74,7 +74,7 @@ void main() {
expect(find.byType(TextFormField), findsOneWidget);
expect(find.byType(ElevatedButton), findsOneWidget);
expect(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)), findsOneWidget);
expect(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME)), findsOneWidget);
});
testWidgets('Test editing an existing nutritional plan', (WidgetTester tester) async {
@@ -86,8 +86,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.tap(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)));
await tester.enterText(find.byKey(const Key('field-description')), 'New description');
await tester.tap(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME)));
// Correct method was called
verify(mockNutrition.editPlan(any));
@@ -112,8 +112,8 @@ void main() {
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');
await tester.tap(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)));
await tester.enterText(find.byKey(const Key('field-description')), 'New cool plan');
await tester.tap(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME)));
// Correct method was called
verifyNever(mockNutrition.editPlan(any));

View File

@@ -72,7 +72,7 @@ void main() {
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));
await tester.drag(find.byKey(const Key('1')), const Offset(-500.0, 0.0));
await tester.pumpAndSettle();
// Confirmation dialog

View File

@@ -24,8 +24,8 @@ import 'package:wger/models/workouts/weight_unit.dart';
void main() {
group('Test the singleSettingRepText method', () {
test('Default rep and weight units, no RiR', () async {
final repUnit = RepetitionUnit(id: 1, name: 'mol');
final weightUnit = WeightUnit(id: 1, name: 'mg');
const repUnit = RepetitionUnit(id: 1, name: 'mol');
const weightUnit = WeightUnit(id: 1, name: 'mg');
final setting = Setting.empty();
setting.reps = 2;
@@ -37,8 +37,8 @@ void main() {
});
test('Default rep and weight units', () async {
final repUnit = RepetitionUnit(id: 1, name: 'mol');
final weightUnit = WeightUnit(id: 1, name: 'mg');
const repUnit = RepetitionUnit(id: 1, name: 'mol');
const weightUnit = WeightUnit(id: 1, name: 'mg');
final setting = Setting.empty();
setting.reps = 2;
@@ -50,8 +50,8 @@ void main() {
});
test('No weight, default rep and weight units', () async {
final repUnit = RepetitionUnit(id: 1, name: 'mol');
final weightUnit = WeightUnit(id: 1, name: 'mg');
const repUnit = RepetitionUnit(id: 1, name: 'mol');
const weightUnit = WeightUnit(id: 1, name: 'mg');
final setting = Setting.empty();
setting.reps = 2;
@@ -63,8 +63,8 @@ void main() {
});
test('Custom rep and weight units, no RiR', () async {
final repUnit = RepetitionUnit(id: 2, name: 'mol');
final weightUnit = WeightUnit(id: 2, name: 'mg');
const repUnit = RepetitionUnit(id: 2, name: 'mol');
const weightUnit = WeightUnit(id: 2, name: 'mg');
final setting = Setting.empty();
setting.reps = 2;
@@ -76,8 +76,8 @@ void main() {
});
test('Custom rep and weight units, RiR', () async {
final repUnit = RepetitionUnit(id: 2, name: 'mol');
final weightUnit = WeightUnit(id: 2, name: 'mg');
const repUnit = RepetitionUnit(id: 2, name: 'mol');
const weightUnit = WeightUnit(id: 2, name: 'mg');
final setting = Setting.empty();
setting.reps = 2;

View File

@@ -80,7 +80,7 @@ void main() {
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));
await tester.drag(find.byKey(const Key('1')), const Offset(-500.0, 0.0));
await tester.pumpAndSettle();
expect(find.byType(ListTile), findsOneWidget);
});

View File

@@ -72,9 +72,9 @@ void main() {
await tester.pumpAndSettle();
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)));
await tester.enterText(find.byKey(const Key('field-description')), 'Leg day!');
await tester.tap(find.byKey(const Key('field-checkbox-1')));
await tester.tap(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME)));
verify(mockWorkoutPlans.addDay(any, any));

View File

@@ -91,8 +91,8 @@ void main() {
findsOneWidget,
reason: 'Description of existing workout plan',
);
await tester.enterText(find.byKey(Key('field-name')), 'New description');
await tester.tap(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)));
await tester.enterText(find.byKey(const Key('field-name')), 'New description');
await tester.tap(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME)));
// Correct method was called
verify(mockWorkoutPlans.editWorkout(any));
@@ -120,8 +120,8 @@ void main() {
await tester.pumpAndSettle();
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)));
await tester.enterText(find.byKey(const Key('field-name')), editWorkout.name);
await tester.tap(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME)));
verifyNever(mockWorkoutPlans.editWorkout(any));
verify(mockWorkoutPlans.addWorkout(any));
@@ -140,9 +140,9 @@ void main() {
await tester.pumpAndSettle();
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.tap(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)));
await tester.enterText(find.byKey(const Key('field-name')), editWorkout.name);
await tester.enterText(find.byKey(const Key('field-description')), editWorkout.description);
await tester.tap(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME)));
verifyNever(mockWorkoutPlans.editWorkout(any));
verify(mockWorkoutPlans.addWorkout(any));

View File

@@ -74,7 +74,7 @@ void main() {
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));
await tester.drag(find.byKey(const Key('1')), const Offset(-500.0, 0.0));
await tester.pumpAndSettle();
// Confirmation dialog

View File

@@ -81,7 +81,7 @@ void main() {
expect(find.byType(TypeAheadFormField), findsOneWidget);
expect(find.byType(Slider), findsOneWidget);
//expect(find.byType(SwitchListTile), findsOneWidget);
expect(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)), findsOneWidget);
expect(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME)), findsOneWidget);
expect(find.byType(ElevatedButton), findsOneWidget);
});
@@ -93,10 +93,10 @@ void main() {
await tester.pumpWidget(createHomeScreen());
await tester.pumpAndSettle();
await tester.enterText(find.byKey(Key('field-typeahead')), 'exercise');
await tester.enterText(find.byKey(const Key('field-typeahead')), 'exercise');
await tester.pumpAndSettle();
await tester.tap(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)));
await tester.tap(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME)));
//verify(mockWorkoutPlans.addSet(any));
//verify(mockWorkoutPlans.addSettinbg(any));

View File

@@ -85,7 +85,7 @@ NutritionalPlan getNutritionalPlan() {
final meal1 = Meal(
id: 1,
plan: 1,
time: TimeOfDay(hour: 17, minute: 0),
time: const TimeOfDay(hour: 17, minute: 0),
name: 'Initial Name 1',
);
meal1.mealItems = [mealItem1, mealItem2];
@@ -93,7 +93,7 @@ NutritionalPlan getNutritionalPlan() {
final meal2 = Meal(
id: 2,
plan: 1,
time: TimeOfDay(hour: 22, minute: 5),
time: const TimeOfDay(hour: 22, minute: 5),
name: 'Initial Name 2',
);
meal2.mealItems = [mealItem3];