diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..074f5899 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "dart.lineLength": 100 +} \ No newline at end of file diff --git a/AUTHORS.md b/AUTHORS.md index c33249f4..9f66cb2a 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -1,52 +1,47 @@ # Authors - ## Developers -* Roland Geider – -* Dylan Aird - -* Jannik Norden - -* Arun Muralidharan - -* Khushbu Bora - -* Patrick Witter - -* Tomer Ben-Rachel - -* Thilina Herath - +- Roland Geider – +- Dylan Aird - +- Jannik Norden - +- Arun Muralidharan - +- Khushbu Bora - +- Patrick Witter - +- Tomer Ben-Rachel - +- Thilina Herath - +- Marko Milosevic - ## Translators -* German +- German - * mondstern (2) - * J. Lavoie (19) - * Roland Geider (142) + - mondstern (2) + - J. Lavoie (19) + - Roland Geider (142) +- English -* English + - Roland Geider (3) + - Allan Nordhøy (8) - * Roland Geider (3) - * Allan Nordhøy (8) +- Italian + - mondstern (2) + - DT (4) + - J. Lavoie (24) + - Stefano Rossi (120) -* Italian +- Spanish - * mondstern (2) - * DT (4) - * J. Lavoie (24) - * Stefano Rossi (120) + - Roland Geider (1) + - martingetzel (119) +- French -* Spanish + - J. Lavoie (92) + - Stefano Rossi (94) - * Roland Geider (1) - * martingetzel (119) +- Norwegian Bokmål - -* French - - * J. Lavoie (92) - * Stefano Rossi (94) - - -* Norwegian Bokmål - - * Allan Nordhøy (98) \ No newline at end of file + - Allan Nordhøy (98) diff --git a/lib/helpers/ui.dart b/lib/helpers/ui.dart index 4975a9ad..bc0ecd58 100644 --- a/lib/helpers/ui.dart +++ b/lib/helpers/ui.dart @@ -20,7 +20,11 @@ import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; import 'package:wger/exceptions/http_exception.dart'; +import 'package:wger/models/exercises/exercise.dart'; +import 'package:wger/models/workouts/log.dart'; +import 'package:wger/providers/workout_plans.dart'; void showErrorDialog(dynamic exception, BuildContext context) { log('showErrorDialog: '); @@ -88,3 +92,46 @@ void showHttpExceptionErrorDialog(WgerHttpException exception, BuildContext cont // unless this dummy call is present showDialog(context: context, builder: (context) => Container()); } + +dynamic showDeleteDialog(BuildContext context, String confirmDeleteName, Log log, Exercise exercise, + Map> _exerciseData) async { + final res = await showDialog( + context: context, + builder: (BuildContext contextDialog) { + return AlertDialog( + content: Text( + AppLocalizations.of(context).confirmDelete(confirmDeleteName), + ), + actions: [ + TextButton( + child: Text(MaterialLocalizations.of(context).cancelButtonLabel), + onPressed: () => Navigator.of(contextDialog).pop(), + ), + TextButton( + child: Text( + AppLocalizations.of(context).delete, + style: TextStyle(color: Theme.of(context).errorColor), + ), + onPressed: () { + _exerciseData[exercise]!.removeWhere((el) => el.id == log.id); + Provider.of(context, listen: false).deleteLog( + log, + ); + + Navigator.of(contextDialog).pop(); + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + AppLocalizations.of(context).successfullyDeleted, + textAlign: TextAlign.center, + ), + ), + ); + }, + ), + ], + ); + }); + return res; +} diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 2839bd82..f200d9fa 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -489,5 +489,25 @@ "description": "Header for the column of 'planned' nutritional values, i.e. what should be eaten" }, "macronutrients": "Makronährstoffe", - "@macronutrients": {} + "@macronutrients": {}, + "value": "Wert", + "@value": { + "description": "The value of a measurement entry" + }, + "measurementCategoriesHelpText": "Messkategorie, z. B. \"Bizeps\" oder \"Körperfett\"", + "@measurementCategoriesHelpText": {}, + "measurementEntriesHelpText": "Die Einheit, die verwendet wird, um die Kategorie zu messen, wie z.B. 'cm' oder '%'", + "@measurementEntriesHelpText": {}, + "fatShort": "F", + "@fatShort": { + "description": "The first letter or short name of the word 'Fat', used in overviews" + }, + "energyShort": "E", + "@energyShort": { + "description": "The first letter or short name of the word 'Energy', used in overviews" + }, + "proteinShort": "P", + "@proteinShort": { + "description": "The first letter or short name of the word 'Protein', used in overviews" + } } diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 170b4c96..ffe9d13d 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -439,5 +439,45 @@ "difference": "Diferencia", "@difference": {}, "macronutrients": "Macronutrientes", - "@macronutrients": {} + "@macronutrients": {}, + "timeStartAhead": "La hora de inicio no puede ser anterior a la hora de finalización", + "@timeStartAhead": {}, + "measurements": "Medidas", + "@measurements": { + "description": "Categories for the measurements such as biceps size, body fat, etc." + }, + "measurement": "Medida", + "@measurement": {}, + "measurementCategoriesHelpText": "Categoría de medición, como \"bíceps\" o \"grasa corporal", + "@measurementCategoriesHelpText": {}, + "measurementEntriesHelpText": "La unidad utilizada para medir la categoría, como p.ej. \"cm\" o \"%\"", + "@measurementEntriesHelpText": {}, + "value": "Valor", + "@value": { + "description": "The value of a measurement entry" + }, + "dataCopied": "Datos copiados a la nueva entrada", + "@dataCopied": { + "description": "Snackbar message to show on copying data to a new log entry" + }, + "energyShort": "E", + "@energyShort": { + "description": "The first letter or short name of the word 'Energy', used in overviews" + }, + "searchExercise": "Busca ejercicio para añadirlo", + "@searchExercise": { + "description": "Label on set form. Selected exercises are added to the set" + }, + "proteinShort": "P", + "@proteinShort": { + "description": "The first letter or short name of the word 'Protein', used in overviews" + }, + "carbohydratesShort": "C", + "@carbohydratesShort": { + "description": "The first letter or short name of the word 'Carbohydrates', used in overviews" + }, + "fatShort": "G", + "@fatShort": { + "description": "The first letter or short name of the word 'Fat', used in overviews" + } } diff --git a/lib/providers/workout_plans.dart b/lib/providers/workout_plans.dart index b95ddb23..969377ab 100644 --- a/lib/providers/workout_plans.dart +++ b/lib/providers/workout_plans.dart @@ -506,4 +506,17 @@ class WorkoutPlansProvider extends WgerBaseProvider with ChangeNotifier { notifyListeners(); return newLog; } + + /*Future editLog(Log log) async { + await patch(log.toJson(), makeUrl(_logsUrlPath, id: log.id)); + notifyListeners(); + }*/ + + Future deleteLog(Log log) async { + await deleteRequest(_logsUrlPath, log.id!); + for (final workout in _workoutPlans) { + workout.logs.removeWhere((element) => element.id == log.id); + } + notifyListeners(); + } } diff --git a/lib/widgets/workouts/log.dart b/lib/widgets/workouts/log.dart index 1b2b7309..cb245adb 100644 --- a/lib/widgets/workouts/log.dart +++ b/lib/widgets/workouts/log.dart @@ -20,6 +20,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; +import 'package:wger/helpers/ui.dart'; import 'package:wger/models/exercises/exercise.dart'; import 'package:wger/models/workouts/log.dart'; import 'package:wger/models/workouts/session.dart'; @@ -53,32 +54,61 @@ class ExerciseLogChart extends StatelessWidget { } } -class DayLogWidget extends StatelessWidget { +class DayLogWidget extends StatefulWidget { final DateTime _date; final WorkoutSession? _session; final Map> _exerciseData; const DayLogWidget(this._date, this._exerciseData, this._session); + @override + _DayLogWidgetState createState() => _DayLogWidgetState(); +} + +class _DayLogWidgetState extends State { + @override + void initState() { + super.initState(); + } + @override Widget build(BuildContext context) { return Card( child: Column( children: [ Text( - DateFormat.yMd(Localizations.localeOf(context).languageCode).format(_date), + DateFormat.yMd(Localizations.localeOf(context).languageCode).format(widget._date), style: Theme.of(context).textTheme.headline5, ), - if (_session != null) const Text('Session data here'), - ..._exerciseData.keys.map((exercise) { + if (widget._session != null) const Text('Session data here'), + ...widget._exerciseData.keys.map((exercise) { return Column( children: [ - Text( - exercise.name, - style: Theme.of(context).textTheme.headline6, - ), - ..._exerciseData[exercise]!.map((log) => Text(log.singleLogRepTextNoNl)).toList(), - ExerciseLogChart(exercise, _date), + if (widget._exerciseData[exercise]!.isNotEmpty) + Text( + exercise.name, + style: Theme.of(context).textTheme.headline6, + ) + else + Container(), + ...widget._exerciseData[exercise]! + .map( + (log) => Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(log.singleLogRepTextNoNl), + IconButton( + icon: Icon(Icons.delete), + onPressed: () async { + showDeleteDialog( + context, exercise.name, log, exercise, widget._exerciseData); + }, + ), + ], + ), + ) + .toList(), + ExerciseLogChart(exercise, widget._date), const SizedBox(height: 30), ], );