From ace3e8bfe6c3d90f2b1377387bb94ce55fc816bf Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Fri, 27 Nov 2020 22:16:19 +0100 Subject: [PATCH 01/13] Add about dialog placeholder --- lib/widgets/app_drawer.dart | 52 +++++++++++++++++++++++++++++++++++-- pubspec.lock | 44 ++++++++++++++++++++++++++++++- pubspec.yaml | 1 + 3 files changed, 94 insertions(+), 3 deletions(-) diff --git a/lib/widgets/app_drawer.dart b/lib/widgets/app_drawer.dart index bd01c6d3..095ac3ed 100644 --- a/lib/widgets/app_drawer.dart +++ b/lib/widgets/app_drawer.dart @@ -1,5 +1,7 @@ +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; import 'package:wger/locale/locales.dart'; import 'package:wger/providers/auth.dart'; import 'package:wger/screens/dashboard.dart'; @@ -58,8 +60,20 @@ class AppDrawer extends StatelessWidget { leading: Icon(Icons.edit), title: Text('Options'), onTap: () { - Navigator.of(context).pop(); - Navigator.of(context).pushReplacementNamed(WeightScreen.routeName); + showDialog( + context: context, + builder: (context) => AlertDialog( + content: Text("Would show options dialog"), + actions: [ + TextButton( + child: Text( + "Close", + ), + onPressed: () => Navigator.of(context).pop(), + ), + ], + ), + ); }, ), Divider(), @@ -72,6 +86,40 @@ class AppDrawer extends StatelessWidget { Navigator.of(context).pushReplacementNamed('/'); }, ), + Divider(), + AboutListTile( + icon: Icon(Icons.info), + applicationName: 'wger', + applicationVersion: '0.0.1 alpha', + applicationLegalese: '\u{a9} 2020 The wger team', + applicationIcon: Image.asset( + 'assets/images/logo.png', + width: 60, + ), + aboutBoxChildren: [ + RichText( + text: TextSpan( + style: TextStyle(fontSize: 16, color: Colors.black), + children: [ + TextSpan( + text: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, ' + 'sed diam nonumy eirmod tempor invidunt ut labore et dolore ' + 'magna aliquyam erat, sed diam voluptua. At vero eos et accusam ' + 'et justo duo dolores et ea rebum.\n', + ), + TextSpan( + text: 'https://github.com/wger-project/wger', + style: TextStyle(color: Colors.blue), + recognizer: TapGestureRecognizer() + ..onTap = () { + launch('https://github.com/wger-project/wger'); + }, + ) + ], + ), + ), + ], + ), ], ), ); diff --git a/pubspec.lock b/pubspec.lock index 0c722804..3f36107e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -621,6 +621,48 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0-nullsafety.3" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + url: "https://pub.dartlang.org" + source: hosted + version: "5.7.10" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+4" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+9" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.9" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.5+1" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+3" vector_math: dependency: transitive description: @@ -672,4 +714,4 @@ packages: version: "2.2.1" sdks: dart: ">=2.10.0-110 <2.11.0" - flutter: ">=1.16.0 <2.0.0" + flutter: ">=1.22.0 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index d9753bdf..ad935729 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -33,6 +33,7 @@ dependencies: flutter_calendar_carousel: ^1.5.1 cupertino_icons: ^1.0.0 json_serializable: ^3.5.0 + url_launcher: ^5.7.10 dev_dependencies: flutter_test: From f87505fc79280d03aef826c5a075143555809ebd Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Sat, 28 Nov 2020 12:03:18 +0100 Subject: [PATCH 02/13] Make workout day header dismissible, with placeholder actions --- lib/screens/workout_plan_screen.dart | 23 +---- lib/widgets/workouts/day.dart | 144 +++++++++++++++++++++++---- 2 files changed, 127 insertions(+), 40 deletions(-) diff --git a/lib/screens/workout_plan_screen.dart b/lib/screens/workout_plan_screen.dart index f2a4b3f9..6b0b5952 100644 --- a/lib/screens/workout_plan_screen.dart +++ b/lib/screens/workout_plan_screen.dart @@ -24,12 +24,12 @@ class _WorkoutPlanScreenState extends State { title: Text(AppLocalizations.of(context).labelWorkoutPlan), actions: [ IconButton( - icon: Icon(Icons.bar_chart), + icon: Icon(Icons.menu), onPressed: () { showDialog( context: context, builder: (context) => AlertDialog( - content: Text("Would open weight log form"), + content: Text("Would open options"), actions: [ TextButton( child: Text( @@ -53,25 +53,6 @@ class _WorkoutPlanScreenState extends State { return Scaffold( appBar: getAppBar(), //drawer: AppDrawer(), - floatingActionButton: FloatingActionButton( - child: const Icon(Icons.play_arrow), - onPressed: () { - showDialog( - context: context, - builder: (context) => AlertDialog( - content: Text("Would start gym mode"), - actions: [ - TextButton( - child: Text( - "Cancel", - ), - onPressed: () => Navigator.of(context).pop(), - ), - ], - ), - ); - }, - ), body: FutureBuilder( future: _loadWorkoutPlanDetail(context, workoutPlan.id), builder: (context, AsyncSnapshot snapshot) => diff --git a/lib/widgets/workouts/day.dart b/lib/widgets/workouts/day.dart index ceab9355..889cca91 100644 --- a/lib/widgets/workouts/day.dart +++ b/lib/widgets/workouts/day.dart @@ -1,3 +1,19 @@ +/* + * This file is part of wger Workout Manager. + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + */ + import 'package:flutter/material.dart'; import 'package:wger/locale/locales.dart'; import 'package:wger/models/workouts/day.dart'; @@ -64,20 +80,7 @@ class WorkoutDayWidget extends StatelessWidget { return Card( child: Column( children: [ - Container( - decoration: BoxDecoration(color: Colors.black12), - padding: const EdgeInsets.symmetric(vertical: 10), - width: double.infinity, - child: Column( - children: [ - Text( - _day.description, - style: Theme.of(context).textTheme.headline6, - ), - Text(_day.getDaysText), - ], - ), - ), + DayHeaderDismissible(day: _day), ..._day.sets .map( (set) => getSetRow(set), @@ -87,11 +90,11 @@ class WorkoutDayWidget extends StatelessWidget { child: Text('Add exercise to day'), onPressed: () { showModalBottomSheet( - context: context, - builder: (BuildContext context) { - return SetFormWidget( - formKey: _formKey, exercisesController: exercisesController); - }); + context: context, + builder: (BuildContext context) { + return SetFormWidget(formKey: _formKey, exercisesController: exercisesController); + }, + ); }, ), Padding( @@ -103,6 +106,109 @@ class WorkoutDayWidget extends StatelessWidget { } } +class DayHeaderDismissible extends StatelessWidget { + const DayHeaderDismissible({ + Key key, + @required Day day, + }) : _day = day, + super(key: key); + + final Day _day; + + @override + Widget build(BuildContext context) { + return Dismissible( + key: Key(_day.id.toString()), + child: Container( + decoration: BoxDecoration(color: Colors.black12), + padding: const EdgeInsets.symmetric(vertical: 10), + width: double.infinity, + child: Column( + children: [ + Text( + _day.description, + style: Theme.of(context).textTheme.headline6, + ), + Text(_day.getDaysText), + ], + ), + ), + secondaryBackground: Container( + color: Theme.of(context).primaryColor, + padding: EdgeInsets.only(right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Icon( + Icons.bar_chart, + color: Colors.white, + ), + Text( + 'Log weights', + style: TextStyle(color: Colors.white), + ), + ], + ), + ), + background: Container( + color: Theme.of(context).accentColor, + alignment: Alignment.centerLeft, + padding: EdgeInsets.only(left: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + 'Gym mode', + style: TextStyle(color: Colors.white), + ), + Icon( + Icons.play_arrow, + color: Colors.white, + ), + ], + ), + ), + confirmDismiss: (direction) async { + // Weight log + if (direction == DismissDirection.endToStart) { + showDialog( + context: context, + builder: (context) => AlertDialog( + content: Text('Would open weight log form for this day'), + actions: [ + TextButton( + child: Text( + "Close", + ), + onPressed: () => Navigator.of(context).pop(), + ), + ], + ), + ); + + // Gym mode + } else { + showDialog( + context: context, + builder: (context) => AlertDialog( + content: Text('Would start gym mode for this day'), + actions: [ + TextButton( + child: Text( + "Close", + ), + onPressed: () => Navigator.of(context).pop(), + ), + ], + ), + ); + } + return false; + }, + ); + } +} + class SetFormWidget extends StatefulWidget { const SetFormWidget({ Key key, From 9b41f0e72ffcd18eefeddaa984c5c233b0914e41 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Wed, 2 Dec 2020 13:42:12 +0100 Subject: [PATCH 03/13] Add auth screen widget test --- lib/screens/auth_screen.dart | 13 ++++++--- test/auth_screen_test.dart | 51 ++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 test/auth_screen_test.dart diff --git a/lib/screens/auth_screen.dart b/lib/screens/auth_screen.dart index 898d9e70..4b5ca7b5 100644 --- a/lib/screens/auth_screen.dart +++ b/lib/screens/auth_screen.dart @@ -62,7 +62,7 @@ class AuthScreen extends StatelessWidget { ), ), Flexible( - flex: deviceSize.width > 600 ? 2 : 1, + //flex: deviceSize.width > 600 ? 2 : 1, child: AuthCard(), ), ], @@ -195,6 +195,7 @@ class _AuthCardState extends State { child: Column( children: [ TextFormField( + key: Key('inputUsername'), decoration: InputDecoration(labelText: 'Username'), controller: _usernameController, textInputAction: TextInputAction.next, @@ -211,6 +212,7 @@ class _AuthCardState extends State { ), if (_authMode == AuthMode.Signup) TextFormField( + key: Key('inputEmail'), decoration: InputDecoration(labelText: 'E-Mail'), controller: _emailController, keyboardType: TextInputType.emailAddress, @@ -226,6 +228,7 @@ class _AuthCardState extends State { }, ), TextFormField( + key: Key('inputPassword'), decoration: InputDecoration(labelText: 'Password'), obscureText: true, controller: _passwordController, @@ -244,6 +247,7 @@ class _AuthCardState extends State { ), if (_authMode == AuthMode.Signup) TextFormField( + key: Key('inputPassword2'), decoration: InputDecoration(labelText: 'Confirm Password'), controller: _password2Controller, enabled: _authMode == AuthMode.Signup, @@ -258,6 +262,7 @@ class _AuthCardState extends State { : null, ), TextFormField( + key: Key('inputServer'), decoration: InputDecoration(labelText: 'Server URL'), controller: _serverUrlController, validator: (value) { @@ -277,11 +282,13 @@ class _AuthCardState extends State { CircularProgressIndicator() else ElevatedButton( - child: Text(_authMode == AuthMode.Login ? 'LOGIN' : 'SIGN UP'), + key: Key('actionButton'), + child: Text(_authMode == AuthMode.Login ? 'LOGIN' : 'REGISTER'), onPressed: _submit, ), TextButton( - child: Text('${_authMode == AuthMode.Login ? 'SIGNUP' : 'LOGIN'} INSTEAD'), + key: Key('toggleActionButton'), + child: Text('${_authMode == AuthMode.Login ? 'REGISTER' : 'LOGIN'} INSTEAD'), onPressed: _switchAuthMode, ), ], diff --git a/test/auth_screen_test.dart b/test/auth_screen_test.dart new file mode 100644 index 00000000..1cf96cb9 --- /dev/null +++ b/test/auth_screen_test.dart @@ -0,0 +1,51 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:wger/screens/auth_screen.dart'; + +void main() { + testWidgets('Test the widgets on the auth screen, login mode', (WidgetTester tester) async { + // Wrap screen in material app so that the media query gets a context + await tester.pumpWidget(MaterialApp(home: AuthScreen())); + expect(find.text('WGER'), findsOneWidget); + + // Verify that the correct buttons and input fields are shown: login + expect(find.text('REGISTER INSTEAD'), findsOneWidget); + 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')), findsOneWidget); + expect(find.byKey(Key('inputPassword2')), findsNothing); + expect(find.byKey(Key('actionButton')), findsOneWidget); + expect(find.byKey(Key('toggleActionButton')), findsOneWidget); + }); + + 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'))); + + // Rebuild the widget after the state has changed. + await tester.pump(); + expect(find.text('REGISTER INSTEAD'), findsNothing); + 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); + }); +} From a63a4e7544348e239be201a04dc5d0e0bc2b223b Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Fri, 4 Dec 2020 18:26:11 +0100 Subject: [PATCH 04/13] Add chart to weight screen --- lib/theme/theme.dart | 5 ++ lib/widgets/weight/entries_list.dart | 119 ++++++++++++++++----------- pubspec.lock | 14 ++++ pubspec.yaml | 1 + 4 files changed, 92 insertions(+), 47 deletions(-) diff --git a/lib/theme/theme.dart b/lib/theme/theme.dart index ca41f539..b57687f0 100644 --- a/lib/theme/theme.dart +++ b/lib/theme/theme.dart @@ -1,9 +1,14 @@ +import 'package:charts_flutter/flutter.dart' as charts; import 'package:flutter/material.dart'; const Color wgerPrimaryColor = Color(0xff2a4c7d); const Color wgerPrimaryButtonColor = Color(0xff266dd3); const Color wgerSecondaryColor = Color(0xffe63946); +// Chart colors +const charts.Color wgerChartPrimaryColor = charts.Color(r: 0x2a, g: 0x4c, b: 0x7d); +const charts.Color wgerChartSecondaryColor = charts.Color(r: 0xe6, g: 0x39, b: 0x46); + final ThemeData wgerTheme = ThemeData( /* * General stuff diff --git a/lib/widgets/weight/entries_list.dart b/lib/widgets/weight/entries_list.dart index 75a3e986..67c25c46 100644 --- a/lib/widgets/weight/entries_list.dart +++ b/lib/widgets/weight/entries_list.dart @@ -1,62 +1,87 @@ +import 'package:charts_flutter/flutter.dart' as charts; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; +import 'package:wger/models/body_weight/weight_entry.dart'; import 'package:wger/providers/body_weight.dart'; +import 'package:wger/theme/theme.dart'; class WeightEntriesList extends StatelessWidget { @override Widget build(BuildContext context) { final weightEntriesData = Provider.of(context); - return ListView.builder( - padding: const EdgeInsets.all(10.0), - itemCount: weightEntriesData.items.length, - itemBuilder: (context, index) { - final currentEntry = weightEntriesData.items[index]; - return Dismissible( - key: Key(currentEntry.id.toString()), - onDismissed: (direction) { - // Delete workout from DB - Provider.of(context, listen: false).deleteEntry(currentEntry.id); + return Column( + children: [ + Container( + padding: EdgeInsets.all(15), + height: 220, + child: charts.TimeSeriesChart( + [ + charts.Series( + id: 'Weight', + colorFn: (_, __) => wgerChartSecondaryColor, + domainFn: (WeightEntry weightEntry, _) => weightEntry.date, + measureFn: (WeightEntry weightEntry, _) => weightEntry.weight, + data: weightEntriesData.items, + ) + ], + defaultRenderer: new charts.LineRendererConfig(includePoints: true), + ), + ), + Expanded( + child: ListView.builder( + padding: const EdgeInsets.all(10.0), + itemCount: weightEntriesData.items.length, + itemBuilder: (context, index) { + final currentEntry = weightEntriesData.items[index]; + return Dismissible( + key: Key(currentEntry.id.toString()), + onDismissed: (direction) { + // Delete workout from DB + Provider.of(context, listen: false).deleteEntry(currentEntry.id); - // and inform the user - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - "Weight entry for the ${currentEntry.date}", - textAlign: TextAlign.center, + // and inform the user + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + "Weight entry for the ${currentEntry.date}", + textAlign: TextAlign.center, + ), + ), + ); + }, + background: Container( + color: Theme.of(context).errorColor, + alignment: Alignment.centerRight, + padding: EdgeInsets.only(right: 20), + margin: EdgeInsets.symmetric( + horizontal: 4, + vertical: 4, + ), + child: Icon( + Icons.delete, + color: Colors.white, + ), ), - ), - ); - }, - background: Container( - color: Theme.of(context).errorColor, - alignment: Alignment.centerRight, - padding: EdgeInsets.only(right: 20), - margin: EdgeInsets.symmetric( - horizontal: 4, - vertical: 4, - ), - child: Icon( - Icons.delete, - color: Colors.white, - ), + direction: DismissDirection.endToStart, + child: Card( + child: ListTile( + //onTap: () => Navigator.of(context).pushNamed( + // WorkoutPlanScreen.routeName, + // arguments: currentPlan, + //), + onTap: () {}, + title: Text( + DateFormat('dd.MM.yyyy').format(currentEntry.date).toString(), + ), + subtitle: Text('${currentEntry.weight} kg'), + ), + ), + ); + }, ), - direction: DismissDirection.endToStart, - child: Card( - child: ListTile( - //onTap: () => Navigator.of(context).pushNamed( - // WorkoutPlanScreen.routeName, - // arguments: currentPlan, - //), - onTap: () {}, - title: Text( - DateFormat('dd.MM.yyyy').format(currentEntry.date).toString(), - ), - subtitle: Text('${currentEntry.weight} kg'), - ), - ), - ); - }, + ), + ], ); } } diff --git a/pubspec.lock b/pubspec.lock index c6dd2109..60cb90c9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -113,6 +113,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0-nullsafety.1" + charts_common: + dependency: transitive + description: + name: charts_common + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.0" + charts_flutter: + dependency: "direct main" + description: + name: charts_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.0" checked_yaml: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 158ed02c..3fedc951 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -34,6 +34,7 @@ dependencies: cupertino_icons: ^1.0.0 json_serializable: ^3.5.0 url_launcher: ^5.7.10 + charts_flutter: ^0.9.0 dev_dependencies: flutter_test: From f84ddcad781c62d8b669efae362e0ff685be8b13 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Sat, 5 Dec 2020 12:52:00 +0100 Subject: [PATCH 05/13] Show error message when adding weight entries doesn't work --- lib/helpers/json.dart | 10 +++ lib/helpers/ui.dart | 71 ++++++++++++++++++++++ lib/l10n/intl_messages.arb | 48 ++++++++++++++- lib/locale/locales.dart | 16 +++++ lib/models/body_weight/weight_entry.dart | 2 +- lib/models/body_weight/weight_entry.g.dart | 2 +- lib/models/workouts/setting.g.dart | 4 +- lib/providers/body_weight.dart | 10 ++- lib/screens/weight_screen.dart | 22 ++++--- lib/widgets/weight/entries_list.dart | 3 +- 10 files changed, 170 insertions(+), 18 deletions(-) create mode 100644 lib/helpers/ui.dart diff --git a/lib/helpers/json.dart b/lib/helpers/json.dart index 8488dab3..5ac728b6 100644 --- a/lib/helpers/json.dart +++ b/lib/helpers/json.dart @@ -1,3 +1,5 @@ +import 'package:intl/intl.dart'; + num toNum(String e) { return num.parse(e); } @@ -5,3 +7,11 @@ num toNum(String e) { String toString(num e) { return e.toString(); } + +/* + * Converts a datetime to ISO8601 date format, but only the date. + * Needed e.g. when the wger api only expects a date and no time information. + */ +String toDate(DateTime dateTime) { + return DateFormat('yyyy-MM-dd').format(dateTime).toString(); +} diff --git a/lib/helpers/ui.dart b/lib/helpers/ui.dart new file mode 100644 index 00000000..4a53d387 --- /dev/null +++ b/lib/helpers/ui.dart @@ -0,0 +1,71 @@ +/* + * This file is part of wger Workout Manager. + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + */ + +import 'package:flutter/material.dart'; +import 'package:wger/locale/locales.dart'; +import 'package:wger/models/http_exception.dart'; + +void showErrorDialog(String message, BuildContext context) { + showDialog( + context: context, + builder: (ctx) => AlertDialog( + title: Text('An Error Occurred!'), + content: Text(message), + actions: [ + TextButton( + child: Text('Dismiss'), + onPressed: () { + Navigator.of(ctx).pop(); + }, + ) + ], + ), + ); +} + +void showHttpExceptionErrorDialog(HttpException exception, BuildContext context) { + List errorList = []; + for (var key in exception.errors.keys) { + // Error headers + errorList.add(Text(key, style: TextStyle(fontWeight: FontWeight.bold))); + + // Error messages + for (var value in exception.errors[key]) { + errorList.add(Text(value)); + } + } + + showDialog( + context: context, + builder: (ctx) => AlertDialog( + title: Text(AppLocalizations.of(context).anErrorOccurred), + content: Container( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [...errorList], + ), + ), + actions: [ + TextButton( + child: Text(AppLocalizations.of(context).dismiss), + onPressed: () { + Navigator.of(ctx).pop(); + }, + ) + ], + ), + ); +} diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index 78160dbb..129bc28e 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,23 +1,53 @@ { - "@@last_modified": "2020-11-21T20:55:11.028883", + "@@last_modified": "2020-12-05T11:28:38.887425", "labelWorkoutPlans": "Workout plans", "@labelWorkoutPlans": { "description": "Title for screen workout plans", "type": "text", "placeholders": {} }, - "newWorkout": "new Workout", + "newWorkout": "New Workout", "@newWorkout": { "description": "Header when adding a new workout", "type": "text", "placeholders": {} }, - "description": "description", + "newDay": "New day", + "@newDay": { + "description": "Header when adding a new day to a workout", + "type": "text", + "placeholders": {} + }, + "newSet": "New set", + "@newSet": { + "description": "Header when adding a new set to a workout day", + "type": "text", + "placeholders": {} + }, + "description": "Description", "@description": { "description": "Description of a workout, nutritional plan, etc.", "type": "text", "placeholders": {} }, + "save": "Save", + "@save": { + "description": "Saving a new entry in the DB", + "type": "text", + "placeholders": {} + }, + "cancel": "Cancel", + "@cancel": { + "description": "Cancelling an action", + "type": "text", + "placeholders": {} + }, + "add": "Add", + "@add": { + "description": "Label for a button etc.", + "type": "text", + "placeholders": {} + }, "labelWorkoutPlan": "Workout plan", "@labelWorkoutPlan": { "description": "Title for screen workout plan", @@ -29,5 +59,17 @@ "description": "Title for screen dashboard", "type": "text", "placeholders": {} + }, + "anErrorOccurred": "An Error Occurred!", + "@anErrorOccurred": { + "description": "Title for error popups", + "type": "text", + "placeholders": {} + }, + "dismiss": "Dismiss", + "@dismiss": { + "description": "Button to close a dialog", + "type": "text", + "placeholders": {} } } \ No newline at end of file diff --git a/lib/locale/locales.dart b/lib/locale/locales.dart index fd4c18fa..3fa01c1f 100644 --- a/lib/locale/locales.dart +++ b/lib/locale/locales.dart @@ -96,6 +96,22 @@ class AppLocalizations { desc: 'Title for screen dashboard', ); } + + String get anErrorOccurred { + return Intl.message( + 'An Error Occurred!', + name: 'anErrorOccurred', + desc: 'Title for error popups', + ); + } + + String get dismiss { + return Intl.message( + 'Dismiss', + name: 'dismiss', + desc: 'Button to close a dialog', + ); + } } class AppLocalizationsDelegate extends LocalizationsDelegate { diff --git a/lib/models/body_weight/weight_entry.dart b/lib/models/body_weight/weight_entry.dart index c81f7845..6dfcd7d8 100644 --- a/lib/models/body_weight/weight_entry.dart +++ b/lib/models/body_weight/weight_entry.dart @@ -12,7 +12,7 @@ class WeightEntry { @JsonKey(required: true, fromJson: toNum, toJson: toString) final num weight; - @JsonKey(required: true) + @JsonKey(required: true, toJson: toDate) final DateTime date; WeightEntry({ diff --git a/lib/models/body_weight/weight_entry.g.dart b/lib/models/body_weight/weight_entry.g.dart index 7b756212..ac56a8f6 100644 --- a/lib/models/body_weight/weight_entry.g.dart +++ b/lib/models/body_weight/weight_entry.g.dart @@ -19,5 +19,5 @@ Map _$WeightEntryToJson(WeightEntry instance) => { 'id': instance.id, 'weight': toString(instance.weight), - 'date': instance.date?.toIso8601String(), + 'date': toDate(instance.date), }; diff --git a/lib/models/workouts/setting.g.dart b/lib/models/workouts/setting.g.dart index 22680f26..33674f7d 100644 --- a/lib/models/workouts/setting.g.dart +++ b/lib/models/workouts/setting.g.dart @@ -28,9 +28,7 @@ Setting _$SettingFromJson(Map json) { json['repetition_unit'] as Map), reps: json['reps'] as int, weight: (json['weight'] as num)?.toDouble(), - weightUnit: json['weight_unit'] == null - ? null - : WeightUnit.fromJson(json['weight_unit'] as Map), + weightUnit: json['weight_unit'], comment: json['comment'] as String, repsText: json['repsText'] as String, ); diff --git a/lib/providers/body_weight.dart b/lib/providers/body_weight.dart index 8090c905..cd5d0a36 100644 --- a/lib/providers/body_weight.dart +++ b/lib/providers/body_weight.dart @@ -1,9 +1,9 @@ import 'dart:convert'; -import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:wger/models/body_weight/weight_entry.dart'; +import 'package:wger/models/http_exception.dart'; import 'package:wger/providers/auth.dart'; class BodyWeight with ChangeNotifier { @@ -63,12 +63,18 @@ class BodyWeight with ChangeNotifier { }, body: json.encode(entry.toJson()), ); + + // Something wrong with our request + if (response.statusCode >= 400) { + throw HttpException(json.decode(response.body)); + } + + // Create entry and return WeightEntry weightEntry = WeightEntry.fromJson(json.decode(response.body)); _entries.insert(0, weightEntry); notifyListeners(); return weightEntry; } catch (error) { - log(error.toString()); throw error; } } diff --git a/lib/screens/weight_screen.dart b/lib/screens/weight_screen.dart index 539b8b58..4f1b7fda 100644 --- a/lib/screens/weight_screen.dart +++ b/lib/screens/weight_screen.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:wger/helpers/ui.dart'; import 'package:wger/models/body_weight/weight_entry.dart'; +import 'package:wger/models/http_exception.dart'; import 'package:wger/providers/body_weight.dart'; import 'package:wger/widgets/app_drawer.dart'; import 'package:wger/widgets/weight/entries_list.dart'; @@ -30,13 +32,19 @@ class WeightScreen extends StatelessWidget { appBar: getAppBar(), drawer: AppDrawer(), floatingActionButton: FloatingActionButton( - onPressed: () { - Provider.of(context, listen: false).addEntry( - WeightEntry( - date: DateTime.now(), - weight: 80, - ), - ); + onPressed: () async { + try { + await Provider.of(context, listen: false).addEntry( + WeightEntry( + date: DateTime.now(), + weight: 80, + ), + ); + } on HttpException catch (error) { + showHttpExceptionErrorDialog(error, context); + } catch (error) { + showErrorDialog(error, context); + } }, child: const Icon(Icons.add), ), diff --git a/lib/widgets/weight/entries_list.dart b/lib/widgets/weight/entries_list.dart index 67c25c46..d0d670b2 100644 --- a/lib/widgets/weight/entries_list.dart +++ b/lib/widgets/weight/entries_list.dart @@ -28,6 +28,7 @@ class WeightEntriesList extends StatelessWidget { defaultRenderer: new charts.LineRendererConfig(includePoints: true), ), ), + Divider(), Expanded( child: ListView.builder( padding: const EdgeInsets.all(10.0), @@ -44,7 +45,7 @@ class WeightEntriesList extends StatelessWidget { Scaffold.of(context).showSnackBar( SnackBar( content: Text( - "Weight entry for the ${currentEntry.date}", + "Deleted weight entry for the ${DateFormat('dd.MM.yyyy').format(currentEntry.date).toString()}", textAlign: TextAlign.center, ), ), From 1d5e61552fb8af45e46c8e0f600e37a4fb0439c7 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Sun, 6 Dec 2020 14:46:23 +0100 Subject: [PATCH 06/13] Improvements to weight edit form --- lib/helpers/json.dart | 3 + lib/helpers/ui.dart | 17 +++- lib/locale/locales.dart | 24 +++++ lib/models/body_weight/weight_entry.dart | 11 +-- lib/providers/body_weight.dart | 5 +- lib/screens/auth_screen.dart | 33 +------ lib/screens/weight_screen.dart | 113 ++++++++++++++++++++--- test/utils.dart | 26 ++++++ test/weight_provider_test.dart | 21 ++--- 9 files changed, 183 insertions(+), 70 deletions(-) create mode 100644 test/utils.dart diff --git a/lib/helpers/json.dart b/lib/helpers/json.dart index 5ac728b6..140ae58b 100644 --- a/lib/helpers/json.dart +++ b/lib/helpers/json.dart @@ -13,5 +13,8 @@ String toString(num e) { * Needed e.g. when the wger api only expects a date and no time information. */ String toDate(DateTime dateTime) { + if (dateTime == null) { + return null; + } return DateFormat('yyyy-MM-dd').format(dateTime).toString(); } diff --git a/lib/helpers/ui.dart b/lib/helpers/ui.dart index 4a53d387..3d95f756 100644 --- a/lib/helpers/ui.dart +++ b/lib/helpers/ui.dart @@ -14,16 +14,22 @@ * You should have received a copy of the GNU General Public License */ +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:wger/locale/locales.dart'; import 'package:wger/models/http_exception.dart'; -void showErrorDialog(String message, BuildContext context) { +void showErrorDialog(dynamic exception, BuildContext context) { + log('showErrorDialog: '); + log(exception.toString()); + log('====================='); + showDialog( context: context, builder: (ctx) => AlertDialog( title: Text('An Error Occurred!'), - content: Text(message), + content: Text(exception.toString()), actions: [ TextButton( child: Text('Dismiss'), @@ -37,6 +43,11 @@ void showErrorDialog(String message, BuildContext context) { } void showHttpExceptionErrorDialog(HttpException exception, BuildContext context) { + log('showHttpExceptionErrorDialog: '); + log(exception.toString()); + log('-------------------'); + + //Navigator.of(context).pop(); List errorList = []; for (var key in exception.errors.keys) { // Error headers @@ -47,7 +58,7 @@ void showHttpExceptionErrorDialog(HttpException exception, BuildContext context) errorList.add(Text(value)); } } - + //GlobalKey(debugLabel: 'wgerApp').currentContext showDialog( context: context, builder: (ctx) => AlertDialog( diff --git a/lib/locale/locales.dart b/lib/locale/locales.dart index 3fa01c1f..e38f882d 100644 --- a/lib/locale/locales.dart +++ b/lib/locale/locales.dart @@ -112,6 +112,30 @@ class AppLocalizations { desc: 'Button to close a dialog', ); } + + String get weight { + return Intl.message( + 'Weight', + name: 'weight', + desc: 'The weight of a workout log or body weight entry', + ); + } + + String get date { + return Intl.message( + 'Date', + name: 'date', + desc: 'The date of a workout log or body weight entry', + ); + } + + String get newEntry { + return Intl.message( + 'New entry', + name: 'newEntry', + desc: 'Header when adding a new entry such as a weight or log entry', + ); + } } class AppLocalizationsDelegate extends LocalizationsDelegate { diff --git a/lib/models/body_weight/weight_entry.dart b/lib/models/body_weight/weight_entry.dart index 6dfcd7d8..ab240e7a 100644 --- a/lib/models/body_weight/weight_entry.dart +++ b/lib/models/body_weight/weight_entry.dart @@ -1,4 +1,3 @@ -import 'package:flutter/foundation.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:wger/helpers/json.dart'; @@ -10,15 +9,15 @@ class WeightEntry { final int id; @JsonKey(required: true, fromJson: toNum, toJson: toString) - final num weight; + num weight; @JsonKey(required: true, toJson: toDate) - final DateTime date; + DateTime date; WeightEntry({ - @required this.id, - @required this.weight, - @required this.date, + this.id, + this.weight, + this.date, }); // Boilerplate diff --git a/lib/providers/body_weight.dart b/lib/providers/body_weight.dart index cd5d0a36..76eb80f7 100644 --- a/lib/providers/body_weight.dart +++ b/lib/providers/body_weight.dart @@ -34,7 +34,7 @@ class BodyWeight with ChangeNotifier { // Send the request final response = await client.get( - _url, + _url + '?ordering=-date', headers: {'Authorization': 'Token ${_auth.token}'}, ); @@ -71,7 +71,8 @@ class BodyWeight with ChangeNotifier { // Create entry and return WeightEntry weightEntry = WeightEntry.fromJson(json.decode(response.body)); - _entries.insert(0, weightEntry); + _entries.add(weightEntry); + _entries.sort((a, b) => a.date.compareTo(b.date)); notifyListeners(); return weightEntry; } catch (error) { diff --git a/lib/screens/auth_screen.dart b/lib/screens/auth_screen.dart index 4b5ca7b5..f21c4a7e 100644 --- a/lib/screens/auth_screen.dart +++ b/lib/screens/auth_screen.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:wger/helpers/ui.dart'; import '../models/http_exception.dart'; import '../providers/auth.dart'; @@ -100,24 +101,6 @@ class _AuthCardState extends State { final _emailController = TextEditingController(); final _serverUrlController = TextEditingController(text: 'http://10.0.2.2:8000'); - void _showErrorDialog(String message) { - showDialog( - context: context, - builder: (ctx) => AlertDialog( - title: Text('An Error Occurred!'), - content: Text(message), - actions: [ - TextButton( - child: Text('Dismiss'), - onPressed: () { - Navigator.of(ctx).pop(); - }, - ) - ], - ), - ); - } - void _submit() async { if (!_formKey.currentState.validate()) { // Invalid! @@ -142,19 +125,9 @@ class _AuthCardState extends State { } } on HttpException catch (error) { - var errorMessage = 'Authentication Failed'; - - if (error.errors.containsKey('username')) { - errorMessage = "Username: " + error.errors['username'].join('\n\n'); - } else if (error.errors.containsKey('password')) { - errorMessage = "Password: " + error.errors['password'].join('\n\n'); - } else if (error.errors.containsKey('detail')) { - errorMessage = error.errors['detail']; - } - _showErrorDialog(errorMessage); + showHttpExceptionErrorDialog(error, context); } catch (error) { - String errorMessage = error.toString(); - _showErrorDialog(errorMessage); + showErrorDialog(error, context); } setState(() { diff --git a/lib/screens/weight_screen.dart b/lib/screens/weight_screen.dart index 4f1b7fda..935d6b37 100644 --- a/lib/screens/weight_screen.dart +++ b/lib/screens/weight_screen.dart @@ -1,19 +1,31 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:wger/helpers/json.dart'; import 'package:wger/helpers/ui.dart'; +import 'package:wger/locale/locales.dart'; import 'package:wger/models/body_weight/weight_entry.dart'; import 'package:wger/models/http_exception.dart'; import 'package:wger/providers/body_weight.dart'; import 'package:wger/widgets/app_drawer.dart'; import 'package:wger/widgets/weight/entries_list.dart'; -class WeightScreen extends StatelessWidget { +class WeightScreen extends StatefulWidget { static const routeName = '/weight'; + @override + _WeightScreenState createState() => _WeightScreenState(); +} + +class _WeightScreenState extends State { Future _refreshWeightEntries(BuildContext context) async { await Provider.of(context, listen: false).fetchAndSetEntries(); } + final dateController = TextEditingController(text: toDate(DateTime.now()).toString()); + final weightController = TextEditingController(); + WeightEntry weightEntry = WeightEntry(); + final _form = GlobalKey(); + Widget getAppBar() { return AppBar( title: Text('Weight'), @@ -32,21 +44,10 @@ class WeightScreen extends StatelessWidget { appBar: getAppBar(), drawer: AppDrawer(), floatingActionButton: FloatingActionButton( - onPressed: () async { - try { - await Provider.of(context, listen: false).addEntry( - WeightEntry( - date: DateTime.now(), - weight: 80, - ), - ); - } on HttpException catch (error) { - showHttpExceptionErrorDialog(error, context); - } catch (error) { - showErrorDialog(error, context); - } - }, child: const Icon(Icons.add), + onPressed: () async { + await showWeightEntrySheet(context); + }, ), body: FutureBuilder( future: _refreshWeightEntries(context), @@ -61,4 +62,86 @@ class WeightScreen extends StatelessWidget { ), ); } + + showWeightEntrySheet(BuildContext context) async { + showModalBottomSheet( + context: context, + builder: (BuildContext ctx) { + return Container( + margin: EdgeInsets.all(20), + child: Form( + key: _form, + child: Column( + children: [ + Text( + AppLocalizations.of(ctx).newEntry, + style: Theme.of(ctx).textTheme.headline6, + ), + + // Weight date + TextFormField( + decoration: InputDecoration(labelText: AppLocalizations.of(ctx).date), + controller: dateController, + onTap: () async { + // Stop keyboard from appearing + FocusScope.of(ctx).requestFocus(new FocusNode()); + + // Show Date Picker Here + var pickedDate = await showDatePicker( + context: ctx, + initialDate: DateTime.now(), + firstDate: DateTime(DateTime.now().year - 10), + lastDate: DateTime.now(), + ); + + dateController.text = toDate(pickedDate); + }, + onSaved: (newValue) { + weightEntry.date = DateTime.parse(newValue); + }, + onFieldSubmitted: (_) {}, + ), + + // Weight + TextFormField( + decoration: InputDecoration(labelText: AppLocalizations.of(ctx).weight), + controller: weightController, + keyboardType: TextInputType.number, + onFieldSubmitted: (_) {}, + onSaved: (newValue) { + weightEntry.weight = double.parse(newValue); + }, + ), + ElevatedButton( + child: Text(AppLocalizations.of(ctx).save), + onPressed: () async { + // Validate and save the current values to the weightEntry + final isValid = _form.currentState.validate(); + if (!isValid) { + return; + } + _form.currentState.save(); + + // Save the entry on the server + try { + await Provider.of(ctx, listen: false).addEntry(weightEntry); + + // Saving was successful, reset the data + weightController.clear(); + dateController.clear(); + weightEntry = WeightEntry(); + } on HttpException catch (error) { + showHttpExceptionErrorDialog(error, ctx); + } catch (error) { + showErrorDialog(error, context); + } + Navigator.of(ctx).pop(); + }, + ), + ], + ), + ), + ); + }); + } } diff --git a/test/utils.dart b/test/utils.dart new file mode 100644 index 00000000..d0f47905 --- /dev/null +++ b/test/utils.dart @@ -0,0 +1,26 @@ +/* + * This file is part of wger Workout Manager. + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + */ + +import 'package:http/http.dart' as http; +import 'package:mockito/mockito.dart'; +import 'package:wger/providers/auth.dart'; + +class MockClient extends Mock implements http.Client {} + +// Test Auth provider +final Auth testAuth = Auth() + ..token = 'FooBar' + ..serverUrl = 'https://localhost'; diff --git a/test/weight_provider_test.dart b/test/weight_provider_test.dart index e029f848..9ad6f4b0 100644 --- a/test/weight_provider_test.dart +++ b/test/weight_provider_test.dart @@ -2,16 +2,9 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:http/http.dart' as http; import 'package:mockito/mockito.dart'; import 'package:wger/models/body_weight/weight_entry.dart'; -import 'package:wger/providers/auth.dart'; import 'package:wger/providers/body_weight.dart'; -// Create a MockClient -class MockClient extends Mock implements http.Client {} - -// Test Auth provider -final Auth auth = Auth() - ..token = 'FooBar' - ..serverUrl = 'https://localhost'; +import 'utils.dart'; void main() { group('fetchPost', () { @@ -21,7 +14,7 @@ void main() { // Mock the server response when(client.get( 'https://localhost/api/v2/weightentry/', - headers: {'Authorization': 'Token ${auth.token}'}, + headers: {'Authorization': 'Token ${testAuth.token}'}, )).thenAnswer((_) async => http.Response( '{"results": [{"id": 1, "date": "2021-01-01", "weight": "80.00"}, ' '{"id": 2, "date": "2021-01-10", "weight": "99"},' @@ -29,7 +22,7 @@ void main() { 200)); // Load the entries - BodyWeight provider = BodyWeight(auth, []); + BodyWeight provider = BodyWeight(testAuth, []); await provider.fetchAndSetEntries(client: client); // Check that everything is ok @@ -43,7 +36,7 @@ void main() { // Mock the server response when(client.post('https://localhost/api/v2/weightentry/', headers: { - 'Authorization': 'Token ${auth.token}', + 'Authorization': 'Token ${testAuth.token}', 'Content-Type': 'application/json; charset=UTF-8', }, body: '{"id":null,"weight":"80","date":"2021-01-01T00:00:00.000"}')) @@ -52,7 +45,7 @@ void main() { // POST the data to the server final WeightEntry weightEntry = WeightEntry(date: DateTime(2021, 1, 1), weight: 80); - final BodyWeight provider = BodyWeight(auth, []); + final BodyWeight provider = BodyWeight(testAuth, []); final WeightEntry weightEntryNew = await provider.addEntry(weightEntry, client: client); // Check that the server response is what we expect @@ -67,11 +60,11 @@ void main() { // Mock the server response when(client.delete( 'https://localhost/api/v2/weightentry/4/', - headers: {'Authorization': 'Token ${auth.token}'}, + headers: {'Authorization': 'Token ${testAuth.token}'}, )).thenAnswer((_) async => http.Response('', 200)); // DELETE the data from the server - final BodyWeight provider = BodyWeight(auth, [ + final BodyWeight provider = BodyWeight(testAuth, [ WeightEntry(id: 4, weight: 80, date: DateTime(2021, 1, 1)), WeightEntry(id: 2, weight: 100, date: DateTime(2021, 2, 2)), WeightEntry(id: 5, weight: 60, date: DateTime(2021, 2, 2)) From d51007905508b089418be5cce3cc7dbd301e550c Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Sun, 6 Dec 2020 16:20:32 +0100 Subject: [PATCH 07/13] Fix tests --- test/weight_provider_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/weight_provider_test.dart b/test/weight_provider_test.dart index 9ad6f4b0..3fb9b8a6 100644 --- a/test/weight_provider_test.dart +++ b/test/weight_provider_test.dart @@ -13,7 +13,7 @@ void main() { // Mock the server response when(client.get( - 'https://localhost/api/v2/weightentry/', + 'https://localhost/api/v2/weightentry/?ordering=-date', headers: {'Authorization': 'Token ${testAuth.token}'}, )).thenAnswer((_) async => http.Response( '{"results": [{"id": 1, "date": "2021-01-01", "weight": "80.00"}, ' @@ -39,7 +39,7 @@ void main() { 'Authorization': 'Token ${testAuth.token}', 'Content-Type': 'application/json; charset=UTF-8', }, - body: '{"id":null,"weight":"80","date":"2021-01-01T00:00:00.000"}')) + body: '{"id":null,"weight":"80","date":"2021-01-01"}')) .thenAnswer( (_) async => http.Response('{"id": 25, "date": "2021-01-01", "weight": "80"}', 200)); From 4c12607671a28efcfc9a74d4cd0f861e65902533 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Sun, 6 Dec 2020 16:22:26 +0100 Subject: [PATCH 08/13] Add uncommited weight model test --- test/weight_model_test.dart | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 test/weight_model_test.dart diff --git a/test/weight_model_test.dart b/test/weight_model_test.dart new file mode 100644 index 00000000..e73091d6 --- /dev/null +++ b/test/weight_model_test.dart @@ -0,0 +1,26 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:wger/models/body_weight/weight_entry.dart'; + +void main() { + group('fetchPost', () { + test('Test that the weight entries are correctly converted to json', () async { + WeightEntry weightEntry = WeightEntry(id: 1, weight: 80, date: DateTime(2020, 12, 31)); + expect(weightEntry.toJson(), {'id': 1, 'weight': '80', 'date': '2020-12-31'}); + + weightEntry = WeightEntry(id: 2, weight: 70.2, date: DateTime(2020, 12, 01)); + expect(weightEntry.toJson(), {'id': 2, 'weight': '70.2', 'date': '2020-12-01'}); + }); + + test('Test that the weight entries are correctly converted from json', () async { + WeightEntry weightEntryObj = WeightEntry(id: 1, weight: 80, date: DateTime(2020, 12, 31)); + WeightEntry weightEntry = WeightEntry.fromJson({ + 'id': 1, + 'weight': '80', + 'date': '2020-12-31', + }); + expect(weightEntry.id, weightEntryObj.id); + expect(weightEntry.weight, weightEntryObj.weight); + expect(weightEntry.date, weightEntryObj.date); + }); + }); +} From 3dd2197b340fdc49707f5634783824030b2c3b72 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Sun, 6 Dec 2020 16:56:42 +0100 Subject: [PATCH 09/13] Add form to add a description to new nutritional plans --- lib/locale/locales.dart | 8 ++ lib/models/nutrition/nutritional_plan.dart | 8 +- lib/screens/nutrition_screen.dart | 77 +++++++++++++++++-- .../nutrition/nutritional_plans_list.dart | 2 +- 4 files changed, 85 insertions(+), 10 deletions(-) diff --git a/lib/locale/locales.dart b/lib/locale/locales.dart index e38f882d..5a19d999 100644 --- a/lib/locale/locales.dart +++ b/lib/locale/locales.dart @@ -136,6 +136,14 @@ class AppLocalizations { desc: 'Header when adding a new entry such as a weight or log entry', ); } + + String get newNutritionalPlan { + return Intl.message( + 'New nutritional plan', + name: 'newNutritionalPlan', + desc: 'Header when adding a new nutritional plan', + ); + } } class AppLocalizationsDelegate extends LocalizationsDelegate { diff --git a/lib/models/nutrition/nutritional_plan.dart b/lib/models/nutrition/nutritional_plan.dart index 468d939d..f0abcbf1 100644 --- a/lib/models/nutrition/nutritional_plan.dart +++ b/lib/models/nutrition/nutritional_plan.dart @@ -6,16 +6,16 @@ part 'nutritional_plan.g.dart'; @JsonSerializable(explicitToJson: true) class NutritionalPlan { @JsonKey(required: true) - final int id; + int id; @JsonKey(required: true) - final String description; + String description; @JsonKey(required: true, name: 'creation_date') - final DateTime creationDate; + DateTime creationDate; @JsonKey(required: false) - final List meals; + List meals; NutritionalPlan({ this.id, diff --git a/lib/screens/nutrition_screen.dart b/lib/screens/nutrition_screen.dart index 92247a6f..5c0e55f1 100644 --- a/lib/screens/nutrition_screen.dart +++ b/lib/screens/nutrition_screen.dart @@ -1,18 +1,30 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:wger/helpers/ui.dart'; +import 'package:wger/locale/locales.dart'; +import 'package:wger/models/http_exception.dart'; import 'package:wger/models/nutrition/nutritional_plan.dart'; import 'package:wger/providers/nutritional_plans.dart'; import 'package:wger/providers/workout_plans.dart'; import 'package:wger/widgets/app_drawer.dart'; import 'package:wger/widgets/nutrition/nutritional_plans_list.dart'; -class NutritionScreen extends StatelessWidget { +class NutritionScreen extends StatefulWidget { static const routeName = '/nutrition'; + @override + _NutritionScreenState createState() => _NutritionScreenState(); +} + +class _NutritionScreenState extends State { Future _refreshPlans(BuildContext context) async { await Provider.of(context, listen: false).fetchAndSetPlans(); } + final descriptionController = TextEditingController(); + NutritionalPlan nutritionalPlan = NutritionalPlan(); + final _form = GlobalKey(); + Widget getAppBar() { return AppBar( title: Text('Nutrition'), @@ -31,10 +43,8 @@ class NutritionScreen extends StatelessWidget { appBar: getAppBar(), drawer: AppDrawer(), floatingActionButton: FloatingActionButton( - onPressed: () { - Provider.of(context, listen: false).addPlan( - NutritionalPlan(description: 'button'), - ); + onPressed: () async { + await showNutritionalPlanSheet(context); }, child: const Icon(Icons.add), ), @@ -51,4 +61,61 @@ class NutritionScreen extends StatelessWidget { ), ); } + + showNutritionalPlanSheet(BuildContext context) async { + showModalBottomSheet( + context: context, + builder: (BuildContext ctx) { + return Container( + margin: EdgeInsets.all(20), + child: Form( + key: _form, + child: Column( + children: [ + Text( + AppLocalizations.of(ctx).newNutritionalPlan, + style: Theme.of(ctx).textTheme.headline6, + ), + + // Weight + TextFormField( + decoration: InputDecoration(labelText: AppLocalizations.of(ctx).description), + controller: descriptionController, + onFieldSubmitted: (_) {}, + onSaved: (newValue) { + nutritionalPlan.description = newValue; + }, + ), + ElevatedButton( + child: Text(AppLocalizations.of(ctx).save), + onPressed: () async { + // Validate and save the current values to the weightEntry + final isValid = _form.currentState.validate(); + if (!isValid) { + return; + } + _form.currentState.save(); + + // Save the entry on the server + try { + await Provider.of(ctx, listen: false) + .addPlan(nutritionalPlan); + + // Saving was successful, reset the data + descriptionController.clear(); + nutritionalPlan = NutritionalPlan(); + } on HttpException catch (error) { + showHttpExceptionErrorDialog(error, ctx); + } catch (error) { + showErrorDialog(error, context); + } + Navigator.of(ctx).pop(); + }, + ), + ], + ), + ), + ); + }); + } } diff --git a/lib/widgets/nutrition/nutritional_plans_list.dart b/lib/widgets/nutrition/nutritional_plans_list.dart index 3c8fca28..e8262c1b 100644 --- a/lib/widgets/nutrition/nutritional_plans_list.dart +++ b/lib/widgets/nutrition/nutritional_plans_list.dart @@ -22,7 +22,7 @@ class NutritionalPlansList extends StatelessWidget { Scaffold.of(context).showSnackBar( SnackBar( content: Text( - "Workout ${currentPlan.id} deleted", + "Nutritional plan ${currentPlan.id} deleted", textAlign: TextAlign.center, ), ), From c237f4ad77c6a68dddb9d203331caeeb8aff3c88 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Sun, 6 Dec 2020 16:58:55 +0100 Subject: [PATCH 10/13] Remove print statements --- lib/providers/nutritional_plans.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/providers/nutritional_plans.dart b/lib/providers/nutritional_plans.dart index 44d7b9f6..7e7c5d82 100644 --- a/lib/providers/nutritional_plans.dart +++ b/lib/providers/nutritional_plans.dart @@ -60,8 +60,6 @@ class NutritionalPlans with ChangeNotifier { }, body: json.encode(plan.toJson()), ); - print(plan.toJson()); - print(json.decode(response.body)); _entries.insert(0, NutritionalPlan.fromJson(json.decode(response.body))); notifyListeners(); } catch (error) { From cc30b3d9ce4b351d75a05b9e0d25a0067c31032e Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Sun, 6 Dec 2020 17:03:12 +0100 Subject: [PATCH 11/13] Rename exception to avoid name collisions --- lib/helpers/ui.dart | 2 +- lib/models/http_exception.dart | 4 ++-- lib/providers/auth.dart | 2 +- lib/providers/body_weight.dart | 2 +- lib/screens/auth_screen.dart | 2 +- lib/screens/nutrition_screen.dart | 2 +- lib/screens/weight_screen.dart | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/helpers/ui.dart b/lib/helpers/ui.dart index 3d95f756..a1a6b694 100644 --- a/lib/helpers/ui.dart +++ b/lib/helpers/ui.dart @@ -42,7 +42,7 @@ void showErrorDialog(dynamic exception, BuildContext context) { ); } -void showHttpExceptionErrorDialog(HttpException exception, BuildContext context) { +void showHttpExceptionErrorDialog(WgerHttpException exception, BuildContext context) { log('showHttpExceptionErrorDialog: '); log(exception.toString()); log('-------------------'); diff --git a/lib/models/http_exception.dart b/lib/models/http_exception.dart index a72a2395..ae288ffb 100644 --- a/lib/models/http_exception.dart +++ b/lib/models/http_exception.dart @@ -1,7 +1,7 @@ -class HttpException implements Exception { +class WgerHttpException implements Exception { final Map errors; - HttpException(this.errors); + WgerHttpException(this.errors); @override String toString() { diff --git a/lib/providers/auth.dart b/lib/providers/auth.dart index 3fdf35c6..4b838e97 100644 --- a/lib/providers/auth.dart +++ b/lib/providers/auth.dart @@ -53,7 +53,7 @@ class Auth with ChangeNotifier { final responseData = json.decode(response.body); if (response.statusCode >= 400) { - throw HttpException(responseData); + throw WgerHttpException(responseData); } // Log user in diff --git a/lib/providers/body_weight.dart b/lib/providers/body_weight.dart index 76eb80f7..9706c947 100644 --- a/lib/providers/body_weight.dart +++ b/lib/providers/body_weight.dart @@ -66,7 +66,7 @@ class BodyWeight with ChangeNotifier { // Something wrong with our request if (response.statusCode >= 400) { - throw HttpException(json.decode(response.body)); + throw WgerHttpException(json.decode(response.body)); } // Create entry and return diff --git a/lib/screens/auth_screen.dart b/lib/screens/auth_screen.dart index f21c4a7e..cdf4e244 100644 --- a/lib/screens/auth_screen.dart +++ b/lib/screens/auth_screen.dart @@ -124,7 +124,7 @@ class _AuthCardState extends State { // .register(_authData['email'], _authData['password']); } - } on HttpException catch (error) { + } on WgerHttpException catch (error) { showHttpExceptionErrorDialog(error, context); } catch (error) { showErrorDialog(error, context); diff --git a/lib/screens/nutrition_screen.dart b/lib/screens/nutrition_screen.dart index 5c0e55f1..0438809e 100644 --- a/lib/screens/nutrition_screen.dart +++ b/lib/screens/nutrition_screen.dart @@ -104,7 +104,7 @@ class _NutritionScreenState extends State { // Saving was successful, reset the data descriptionController.clear(); nutritionalPlan = NutritionalPlan(); - } on HttpException catch (error) { + } on WgerHttpException catch (error) { showHttpExceptionErrorDialog(error, ctx); } catch (error) { showErrorDialog(error, context); diff --git a/lib/screens/weight_screen.dart b/lib/screens/weight_screen.dart index 935d6b37..e11789aa 100644 --- a/lib/screens/weight_screen.dart +++ b/lib/screens/weight_screen.dart @@ -130,7 +130,7 @@ class _WeightScreenState extends State { weightController.clear(); dateController.clear(); weightEntry = WeightEntry(); - } on HttpException catch (error) { + } on WgerHttpException catch (error) { showHttpExceptionErrorDialog(error, ctx); } catch (error) { showErrorDialog(error, context); From 1c9d0ab7f61ac180c1e94b97a35a29ee92321178 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Sun, 6 Dec 2020 17:14:50 +0100 Subject: [PATCH 12/13] Add copyright notice to all files --- lib/helpers/json.dart | 18 +++++++++++++++ lib/helpers/ui.dart | 4 +++- lib/locale/locales.dart | 18 +++++++++++++++ lib/main.dart | 18 +++++++++++++++ lib/models/body_weight/weight_entry.dart | 18 +++++++++++++++ lib/models/exercises/category.dart | 18 +++++++++++++++ lib/models/exercises/comment.dart | 18 +++++++++++++++ lib/models/exercises/equipment.dart | 18 +++++++++++++++ lib/models/exercises/exercise.dart | 18 +++++++++++++++ lib/models/exercises/image.dart | 18 +++++++++++++++ lib/models/exercises/muscle.dart | 18 +++++++++++++++ lib/models/http_exception.dart | 18 +++++++++++++++ lib/models/nutrition/ingredient.dart | 18 +++++++++++++++ .../nutrition/ingredient_weight_unit.dart | 18 +++++++++++++++ lib/models/nutrition/log.dart | 18 +++++++++++++++ lib/models/nutrition/meal.dart | 18 +++++++++++++++ lib/models/nutrition/meal_item.dart | 18 +++++++++++++++ lib/models/nutrition/nutritional_plan.dart | 18 +++++++++++++++ lib/models/nutrition/weight_unit.dart | 18 +++++++++++++++ lib/providers/auth.dart | 18 +++++++++++++++ lib/providers/body_weight.dart | 18 +++++++++++++++ lib/providers/exercises.dart | 18 +++++++++++++++ lib/providers/nutritional_plans.dart | 18 +++++++++++++++ lib/providers/workout_plans.dart | 18 +++++++++++++++ lib/screens/auth_screen.dart | 18 +++++++++++++++ lib/screens/dashboard.dart | 18 +++++++++++++++ lib/screens/home_tabs_screen.dart | 18 +++++++++++++++ lib/screens/nutrition_screen.dart | 18 +++++++++++++++ lib/screens/splash_screen.dart | 18 +++++++++++++++ lib/screens/weight_screen.dart | 18 +++++++++++++++ lib/screens/workout_plan_screen.dart | 18 +++++++++++++++ lib/screens/workout_plans_screen.dart | 18 +++++++++++++++ lib/theme/theme.dart | 18 +++++++++++++++ lib/widgets/app_drawer.dart | 18 +++++++++++++++ .../nutrition/nutritional_plans_list.dart | 18 +++++++++++++++ lib/widgets/weight/entries_list.dart | 18 +++++++++++++++ lib/widgets/workouts/day.dart | 4 +++- lib/widgets/workouts/workout_plan_detail.dart | 4 +++- lib/widgets/workouts/workout_plans_list.dart | 18 +++++++++++++++ test/auth_screen_test.dart | 23 ++++++++++++++----- test/utils.dart | 4 +++- test/weight_model_test.dart | 18 +++++++++++++++ test/weight_provider_test.dart | 18 +++++++++++++++ 43 files changed, 713 insertions(+), 10 deletions(-) diff --git a/lib/helpers/json.dart b/lib/helpers/json.dart index 140ae58b..b94597e5 100644 --- a/lib/helpers/json.dart +++ b/lib/helpers/json.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:intl/intl.dart'; num toNum(String e) { diff --git a/lib/helpers/ui.dart b/lib/helpers/ui.dart index a1a6b694..3734e55a 100644 --- a/lib/helpers/ui.dart +++ b/lib/helpers/ui.dart @@ -1,5 +1,6 @@ /* - * This file is part of wger Workout Manager. + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team * * wger Workout Manager is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -12,6 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ import 'dart:developer'; diff --git a/lib/locale/locales.dart b/lib/locale/locales.dart index 5a19d999..7dd927a7 100644 --- a/lib/locale/locales.dart +++ b/lib/locale/locales.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:wger/l10n/messages_all.dart'; diff --git a/lib/main.dart b/lib/main.dart index d713c58b..65a6d7b2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:provider/provider.dart'; diff --git a/lib/models/body_weight/weight_entry.dart b/lib/models/body_weight/weight_entry.dart index ab240e7a..b9a0c3a3 100644 --- a/lib/models/body_weight/weight_entry.dart +++ b/lib/models/body_weight/weight_entry.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:json_annotation/json_annotation.dart'; import 'package:wger/helpers/json.dart'; diff --git a/lib/models/exercises/category.dart b/lib/models/exercises/category.dart index b8160668..23f15402 100644 --- a/lib/models/exercises/category.dart +++ b/lib/models/exercises/category.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:json_annotation/json_annotation.dart'; part 'category.g.dart'; diff --git a/lib/models/exercises/comment.dart b/lib/models/exercises/comment.dart index fbd5f72c..e2965f51 100644 --- a/lib/models/exercises/comment.dart +++ b/lib/models/exercises/comment.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:json_annotation/json_annotation.dart'; part 'comment.g.dart'; diff --git a/lib/models/exercises/equipment.dart b/lib/models/exercises/equipment.dart index f63f6491..e826ecfd 100644 --- a/lib/models/exercises/equipment.dart +++ b/lib/models/exercises/equipment.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/foundation.dart'; import 'package:json_annotation/json_annotation.dart'; diff --git a/lib/models/exercises/exercise.dart b/lib/models/exercises/exercise.dart index 60833cf9..d374e5d9 100644 --- a/lib/models/exercises/exercise.dart +++ b/lib/models/exercises/exercise.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:json_annotation/json_annotation.dart'; import 'package:wger/models/exercises/category.dart'; import 'package:wger/models/exercises/comment.dart'; diff --git a/lib/models/exercises/image.dart b/lib/models/exercises/image.dart index a6758768..c13a9c1a 100644 --- a/lib/models/exercises/image.dart +++ b/lib/models/exercises/image.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:json_annotation/json_annotation.dart'; part 'image.g.dart'; diff --git a/lib/models/exercises/muscle.dart b/lib/models/exercises/muscle.dart index e3a62005..298befe1 100644 --- a/lib/models/exercises/muscle.dart +++ b/lib/models/exercises/muscle.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:json_annotation/json_annotation.dart'; part 'muscle.g.dart'; diff --git a/lib/models/http_exception.dart b/lib/models/http_exception.dart index ae288ffb..e06d1ecc 100644 --- a/lib/models/http_exception.dart +++ b/lib/models/http_exception.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + class WgerHttpException implements Exception { final Map errors; diff --git a/lib/models/nutrition/ingredient.dart b/lib/models/nutrition/ingredient.dart index 033e781c..bcf34f03 100644 --- a/lib/models/nutrition/ingredient.dart +++ b/lib/models/nutrition/ingredient.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/foundation.dart'; import 'package:json_annotation/json_annotation.dart'; diff --git a/lib/models/nutrition/ingredient_weight_unit.dart b/lib/models/nutrition/ingredient_weight_unit.dart index 8f3c0560..67d2125a 100644 --- a/lib/models/nutrition/ingredient_weight_unit.dart +++ b/lib/models/nutrition/ingredient_weight_unit.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/foundation.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:wger/models/nutrition/ingredient.dart'; diff --git a/lib/models/nutrition/log.dart b/lib/models/nutrition/log.dart index f4c9518e..9cc71860 100644 --- a/lib/models/nutrition/log.dart +++ b/lib/models/nutrition/log.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/foundation.dart'; import 'package:wger/models/nutrition/ingredient.dart'; import 'package:wger/models/nutrition/ingredient_weight_unit.dart'; diff --git a/lib/models/nutrition/meal.dart b/lib/models/nutrition/meal.dart index 5415fe9c..56187e94 100644 --- a/lib/models/nutrition/meal.dart +++ b/lib/models/nutrition/meal.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:json_annotation/json_annotation.dart'; import 'package:wger/models/nutrition/meal_item.dart'; diff --git a/lib/models/nutrition/meal_item.dart b/lib/models/nutrition/meal_item.dart index 9f8f74c0..fcc631f0 100644 --- a/lib/models/nutrition/meal_item.dart +++ b/lib/models/nutrition/meal_item.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/foundation.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:wger/models/nutrition/ingredient.dart'; diff --git a/lib/models/nutrition/nutritional_plan.dart b/lib/models/nutrition/nutritional_plan.dart index f0abcbf1..133140be 100644 --- a/lib/models/nutrition/nutritional_plan.dart +++ b/lib/models/nutrition/nutritional_plan.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:json_annotation/json_annotation.dart'; import 'package:wger/models/nutrition/meal.dart'; diff --git a/lib/models/nutrition/weight_unit.dart b/lib/models/nutrition/weight_unit.dart index 207aacea..0565cb5a 100644 --- a/lib/models/nutrition/weight_unit.dart +++ b/lib/models/nutrition/weight_unit.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/foundation.dart'; import 'package:json_annotation/json_annotation.dart'; diff --git a/lib/providers/auth.dart b/lib/providers/auth.dart index 4b838e97..fff135be 100644 --- a/lib/providers/auth.dart +++ b/lib/providers/auth.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'dart:async'; import 'dart:convert'; import 'dart:developer'; diff --git a/lib/providers/body_weight.dart b/lib/providers/body_weight.dart index 9706c947..f7814f7c 100644 --- a/lib/providers/body_weight.dart +++ b/lib/providers/body_weight.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'dart:convert'; import 'package:flutter/material.dart'; diff --git a/lib/providers/exercises.dart b/lib/providers/exercises.dart index b00eb48d..fc4d3634 100644 --- a/lib/providers/exercises.dart +++ b/lib/providers/exercises.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'dart:async'; import 'dart:convert'; import 'dart:developer'; diff --git a/lib/providers/nutritional_plans.dart b/lib/providers/nutritional_plans.dart index 7e7c5d82..d99e2b2b 100644 --- a/lib/providers/nutritional_plans.dart +++ b/lib/providers/nutritional_plans.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'dart:convert'; import 'package:flutter/material.dart'; diff --git a/lib/providers/workout_plans.dart b/lib/providers/workout_plans.dart index 4918ab36..db2f5ead 100644 --- a/lib/providers/workout_plans.dart +++ b/lib/providers/workout_plans.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'dart:convert'; import 'dart:developer'; diff --git a/lib/screens/auth_screen.dart b/lib/screens/auth_screen.dart index cdf4e244..4a05eb9f 100644 --- a/lib/screens/auth_screen.dart +++ b/lib/screens/auth_screen.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:wger/helpers/ui.dart'; diff --git a/lib/screens/dashboard.dart b/lib/screens/dashboard.dart index 44cbcf28..5503c67c 100644 --- a/lib/screens/dashboard.dart +++ b/lib/screens/dashboard.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:wger/locale/locales.dart'; diff --git a/lib/screens/home_tabs_screen.dart b/lib/screens/home_tabs_screen.dart index 95bdce18..444c9328 100644 --- a/lib/screens/home_tabs_screen.dart +++ b/lib/screens/home_tabs_screen.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/material.dart'; import 'package:wger/screens/nutrition_screen.dart'; import 'package:wger/screens/weight_screen.dart'; diff --git a/lib/screens/nutrition_screen.dart b/lib/screens/nutrition_screen.dart index 0438809e..8dd8f470 100644 --- a/lib/screens/nutrition_screen.dart +++ b/lib/screens/nutrition_screen.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:wger/helpers/ui.dart'; diff --git a/lib/screens/splash_screen.dart b/lib/screens/splash_screen.dart index e2876568..78dab998 100644 --- a/lib/screens/splash_screen.dart +++ b/lib/screens/splash_screen.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/material.dart'; class SplashScreen extends StatelessWidget { diff --git a/lib/screens/weight_screen.dart b/lib/screens/weight_screen.dart index e11789aa..bcba823c 100644 --- a/lib/screens/weight_screen.dart +++ b/lib/screens/weight_screen.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:wger/helpers/json.dart'; diff --git a/lib/screens/workout_plan_screen.dart b/lib/screens/workout_plan_screen.dart index 6b0b5952..94d0bdc4 100644 --- a/lib/screens/workout_plan_screen.dart +++ b/lib/screens/workout_plan_screen.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:wger/locale/locales.dart'; diff --git a/lib/screens/workout_plans_screen.dart b/lib/screens/workout_plans_screen.dart index f4bad3ad..3bc4a497 100644 --- a/lib/screens/workout_plans_screen.dart +++ b/lib/screens/workout_plans_screen.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; diff --git a/lib/theme/theme.dart b/lib/theme/theme.dart index b57687f0..09f33d67 100644 --- a/lib/theme/theme.dart +++ b/lib/theme/theme.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:charts_flutter/flutter.dart' as charts; import 'package:flutter/material.dart'; diff --git a/lib/widgets/app_drawer.dart b/lib/widgets/app_drawer.dart index 095ac3ed..63218b23 100644 --- a/lib/widgets/app_drawer.dart +++ b/lib/widgets/app_drawer.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; diff --git a/lib/widgets/nutrition/nutritional_plans_list.dart b/lib/widgets/nutrition/nutritional_plans_list.dart index e8262c1b..58175039 100644 --- a/lib/widgets/nutrition/nutritional_plans_list.dart +++ b/lib/widgets/nutrition/nutritional_plans_list.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; diff --git a/lib/widgets/weight/entries_list.dart b/lib/widgets/weight/entries_list.dart index d0d670b2..0922fad5 100644 --- a/lib/widgets/weight/entries_list.dart +++ b/lib/widgets/weight/entries_list.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:charts_flutter/flutter.dart' as charts; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; diff --git a/lib/widgets/workouts/day.dart b/lib/widgets/workouts/day.dart index 889cca91..8b192243 100644 --- a/lib/widgets/workouts/day.dart +++ b/lib/widgets/workouts/day.dart @@ -1,5 +1,6 @@ /* - * This file is part of wger Workout Manager. + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team * * wger Workout Manager is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -12,6 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ import 'package:flutter/material.dart'; diff --git a/lib/widgets/workouts/workout_plan_detail.dart b/lib/widgets/workouts/workout_plan_detail.dart index 8ba3d3b9..9c86fe3a 100644 --- a/lib/widgets/workouts/workout_plan_detail.dart +++ b/lib/widgets/workouts/workout_plan_detail.dart @@ -1,5 +1,6 @@ /* - * This file is part of wger Workout Manager. + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team * * wger Workout Manager is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -12,6 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ import 'package:flutter/material.dart'; diff --git a/lib/widgets/workouts/workout_plans_list.dart b/lib/widgets/workouts/workout_plans_list.dart index bd6a337a..2e5b7bb7 100644 --- a/lib/widgets/workouts/workout_plans_list.dart +++ b/lib/widgets/workouts/workout_plans_list.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; diff --git a/test/auth_screen_test.dart b/test/auth_screen_test.dart index 1cf96cb9..221911ea 100644 --- a/test/auth_screen_test.dart +++ b/test/auth_screen_test.dart @@ -1,9 +1,20 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/test/utils.dart b/test/utils.dart index d0f47905..6122853d 100644 --- a/test/utils.dart +++ b/test/utils.dart @@ -1,5 +1,6 @@ /* - * This file is part of wger Workout Manager. + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team * * wger Workout Manager is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -12,6 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ import 'package:http/http.dart' as http; diff --git a/test/weight_model_test.dart b/test/weight_model_test.dart index e73091d6..381b7efd 100644 --- a/test/weight_model_test.dart +++ b/test/weight_model_test.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter_test/flutter_test.dart'; import 'package:wger/models/body_weight/weight_entry.dart'; diff --git a/test/weight_provider_test.dart b/test/weight_provider_test.dart index 3fb9b8a6..122ee423 100644 --- a/test/weight_provider_test.dart +++ b/test/weight_provider_test.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import 'package:flutter_test/flutter_test.dart'; import 'package:http/http.dart' as http; import 'package:mockito/mockito.dart'; From aed4beb0abe0434650fa648650e0b09d755c4e47 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Sun, 6 Dec 2020 17:15:15 +0100 Subject: [PATCH 13/13] Delete empty dummy test --- test/widget_test.dart | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 test/widget_test.dart diff --git a/test/widget_test.dart b/test/widget_test.dart deleted file mode 100644 index abe6764b..00000000 --- a/test/widget_test.dart +++ /dev/null @@ -1,22 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:wger/main.dart'; - -void main() { - testWidgets('Empty dummy test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that we don't find anything - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsNothing); - }); -}