Merge remote-tracking branch 'origin/master'

# Conflicts:
#	lib/models/body_weight/weight_entry.dart
#	test/utils.dart
#	test/weight_provider_test.dart
This commit is contained in:
Roland Geider
2020-12-06 22:05:24 +01:00
49 changed files with 1515 additions and 192 deletions

View File

@@ -1,3 +1,23 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:intl/intl.dart';
num toNum(String e) {
return num.parse(e);
}
@@ -5,3 +25,14 @@ 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) {
if (dateTime == null) {
return null;
}
return DateFormat('yyyy-MM-dd').format(dateTime).toString();
}

84
lib/helpers/ui.dart Normal file
View File

@@ -0,0 +1,84 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:wger/locale/locales.dart';
import 'package:wger/models/http_exception.dart';
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(exception.toString()),
actions: [
TextButton(
child: Text('Dismiss'),
onPressed: () {
Navigator.of(ctx).pop();
},
)
],
),
);
}
void showHttpExceptionErrorDialog(WgerHttpException exception, BuildContext context) {
log('showHttpExceptionErrorDialog: ');
log(exception.toString());
log('-------------------');
//Navigator.of(context).pop();
List<Widget> 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));
}
}
//GlobalKey(debugLabel: 'wgerApp').currentContext
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();
},
)
],
),
);
}

View File

@@ -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": {}
}
}

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:wger/l10n/messages_all.dart';
@@ -96,6 +114,54 @@ 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',
);
}
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',
);
}
String get newNutritionalPlan {
return Intl.message(
'New nutritional plan',
name: 'newNutritionalPlan',
desc: 'Header when adding a new nutritional plan',
);
}
}
class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:provider/provider.dart';

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/foundation.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:wger/helpers/json.dart';
@@ -10,15 +28,15 @@ class WeightEntry {
final int id;
@JsonKey(required: true, fromJson: toNum, toJson: toString)
final num weight;
num weight;
@JsonKey(required: true)
final DateTime date;
@JsonKey(required: true, toJson: toDate)
DateTime date;
WeightEntry({
this.id,
@required this.weight,
@required this.date,
this.weight,
this.date,
});
// Boilerplate

View File

@@ -19,5 +19,5 @@ Map<String, dynamic> _$WeightEntryToJson(WeightEntry instance) =>
<String, dynamic>{
'id': instance.id,
'weight': toString(instance.weight),
'date': instance.date?.toIso8601String(),
'date': toDate(instance.date),
};

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:json_annotation/json_annotation.dart';
part 'category.g.dart';

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:json_annotation/json_annotation.dart';
part 'comment.g.dart';

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/foundation.dart';
import 'package:json_annotation/json_annotation.dart';

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:json_annotation/json_annotation.dart';
import 'package:wger/models/exercises/category.dart';
import 'package:wger/models/exercises/comment.dart';

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:json_annotation/json_annotation.dart';
part 'image.g.dart';

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:json_annotation/json_annotation.dart';
part 'muscle.g.dart';

View File

@@ -1,7 +1,25 @@
class HttpException implements Exception {
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
class WgerHttpException implements Exception {
final Map<String, dynamic> errors;
HttpException(this.errors);
WgerHttpException(this.errors);
@override
String toString() {

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/foundation.dart';
import 'package:json_annotation/json_annotation.dart';

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/foundation.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:wger/models/nutrition/ingredient.dart';

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/foundation.dart';
import 'package:wger/models/nutrition/ingredient.dart';
import 'package:wger/models/nutrition/ingredient_weight_unit.dart';

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:json_annotation/json_annotation.dart';
import 'package:wger/models/nutrition/meal_item.dart';

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/foundation.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:wger/models/nutrition/ingredient.dart';

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:json_annotation/json_annotation.dart';
import 'package:wger/models/nutrition/meal.dart';
@@ -6,16 +24,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<Meal> meals;
List<Meal> meals;
NutritionalPlan({
this.id,

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/foundation.dart';
import 'package:json_annotation/json_annotation.dart';

View File

@@ -28,9 +28,7 @@ Setting _$SettingFromJson(Map<String, dynamic> json) {
json['repetition_unit'] as Map<String, dynamic>),
reps: json['reps'] as int,
weight: (json['weight'] as num)?.toDouble(),
weightUnit: json['weight_unit'] == null
? null
: WeightUnit.fromJson(json['weight_unit'] as Map<String, dynamic>),
weightUnit: json['weight_unit'],
comment: json['comment'] as String,
repsText: json['repsText'] as String,
);

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
@@ -53,7 +71,7 @@ class Auth with ChangeNotifier {
final responseData = json.decode(response.body);
if (response.statusCode >= 400) {
throw HttpException(responseData);
throw WgerHttpException(responseData);
}
// Log user in

View File

@@ -1,9 +1,27 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
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 {
@@ -34,7 +52,7 @@ class BodyWeight with ChangeNotifier {
// Send the request
final response = await client.get(
_url,
_url + '?ordering=-date',
headers: <String, String>{'Authorization': 'Token ${_auth.token}'},
);
@@ -63,12 +81,19 @@ class BodyWeight with ChangeNotifier {
},
body: json.encode(entry.toJson()),
);
// Something wrong with our request
if (response.statusCode >= 400) {
throw WgerHttpException(json.decode(response.body));
}
// 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) {
log(error.toString());
throw error;
}
}

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'dart:async';
import 'dart:convert';
import 'dart:developer';

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'dart:convert';
import 'package:flutter/material.dart';
@@ -60,8 +78,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) {

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'dart:convert';
import 'dart:developer';

View File

@@ -1,5 +1,24 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
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';
@@ -62,7 +81,7 @@ class AuthScreen extends StatelessWidget {
),
),
Flexible(
flex: deviceSize.width > 600 ? 2 : 1,
//flex: deviceSize.width > 600 ? 2 : 1,
child: AuthCard(),
),
],
@@ -100,24 +119,6 @@ class _AuthCardState extends State<AuthCard> {
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!
@@ -141,20 +142,10 @@ class _AuthCardState extends State<AuthCard> {
// .register(_authData['email'], _authData['password']);
}
} 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);
} on WgerHttpException catch (error) {
showHttpExceptionErrorDialog(error, context);
} catch (error) {
String errorMessage = error.toString();
_showErrorDialog(errorMessage);
showErrorDialog(error, context);
}
setState(() {
@@ -195,6 +186,7 @@ class _AuthCardState extends State<AuthCard> {
child: Column(
children: <Widget>[
TextFormField(
key: Key('inputUsername'),
decoration: InputDecoration(labelText: 'Username'),
controller: _usernameController,
textInputAction: TextInputAction.next,
@@ -211,6 +203,7 @@ class _AuthCardState extends State<AuthCard> {
),
if (_authMode == AuthMode.Signup)
TextFormField(
key: Key('inputEmail'),
decoration: InputDecoration(labelText: 'E-Mail'),
controller: _emailController,
keyboardType: TextInputType.emailAddress,
@@ -226,6 +219,7 @@ class _AuthCardState extends State<AuthCard> {
},
),
TextFormField(
key: Key('inputPassword'),
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
controller: _passwordController,
@@ -244,6 +238,7 @@ class _AuthCardState extends State<AuthCard> {
),
if (_authMode == AuthMode.Signup)
TextFormField(
key: Key('inputPassword2'),
decoration: InputDecoration(labelText: 'Confirm Password'),
controller: _password2Controller,
enabled: _authMode == AuthMode.Signup,
@@ -258,6 +253,7 @@ class _AuthCardState extends State<AuthCard> {
: null,
),
TextFormField(
key: Key('inputServer'),
decoration: InputDecoration(labelText: 'Server URL'),
controller: _serverUrlController,
validator: (value) {
@@ -277,11 +273,13 @@ class _AuthCardState extends State<AuthCard> {
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,
),
],

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:wger/locale/locales.dart';

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/material.dart';
import 'package:wger/screens/nutrition_screen.dart';
import 'package:wger/screens/weight_screen.dart';

View File

@@ -1,18 +1,48 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
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<NutritionScreen> {
Future<void> _refreshPlans(BuildContext context) async {
await Provider.of<NutritionalPlans>(context, listen: false).fetchAndSetPlans();
}
final descriptionController = TextEditingController();
NutritionalPlan nutritionalPlan = NutritionalPlan();
final _form = GlobalKey<FormState>();
Widget getAppBar() {
return AppBar(
title: Text('Nutrition'),
@@ -31,10 +61,8 @@ class NutritionScreen extends StatelessWidget {
appBar: getAppBar(),
drawer: AppDrawer(),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<NutritionalPlans>(context, listen: false).addPlan(
NutritionalPlan(description: 'button'),
);
onPressed: () async {
await showNutritionalPlanSheet(context);
},
child: const Icon(Icons.add),
),
@@ -51,4 +79,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<NutritionalPlans>(ctx, listen: false)
.addPlan(nutritionalPlan);
// Saving was successful, reset the data
descriptionController.clear();
nutritionalPlan = NutritionalPlan();
} on WgerHttpException catch (error) {
showHttpExceptionErrorDialog(error, ctx);
} catch (error) {
showErrorDialog(error, context);
}
Navigator.of(ctx).pop();
},
),
],
),
),
);
});
}
}

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/material.dart';
class SplashScreen extends StatelessWidget {

View File

@@ -1,17 +1,49 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
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<WeightScreen> {
Future<void> _refreshWeightEntries(BuildContext context) async {
await Provider.of<BodyWeight>(context, listen: false).fetchAndSetEntries();
}
final dateController = TextEditingController(text: toDate(DateTime.now()).toString());
final weightController = TextEditingController();
WeightEntry weightEntry = WeightEntry();
final _form = GlobalKey<FormState>();
Widget getAppBar() {
return AppBar(
title: Text('Weight'),
@@ -30,15 +62,10 @@ class WeightScreen extends StatelessWidget {
appBar: getAppBar(),
drawer: AppDrawer(),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<BodyWeight>(context, listen: false).addEntry(
WeightEntry(
date: DateTime.now(),
weight: 80,
),
);
},
child: const Icon(Icons.add),
onPressed: () async {
await showWeightEntrySheet(context);
},
),
body: FutureBuilder(
future: _refreshWeightEntries(context),
@@ -53,4 +80,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<BodyWeight>(ctx, listen: false).addEntry(weightEntry);
// Saving was successful, reset the data
weightController.clear();
dateController.clear();
weightEntry = WeightEntry();
} on WgerHttpException catch (error) {
showHttpExceptionErrorDialog(error, ctx);
} catch (error) {
showErrorDialog(error, context);
}
Navigator.of(ctx).pop();
},
),
],
),
),
);
});
}
}

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:wger/locale/locales.dart';
@@ -24,12 +42,12 @@ class _WorkoutPlanScreenState extends State<WorkoutPlanScreen> {
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 +71,6 @@ class _WorkoutPlanScreenState extends State<WorkoutPlanScreen> {
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<WorkoutPlan>(
future: _loadWorkoutPlanDetail(context, workoutPlan.id),
builder: (context, AsyncSnapshot<WorkoutPlan> snapshot) =>

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

View File

@@ -1,9 +1,32 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
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

View File

@@ -1,5 +1,25 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
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 +78,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 +104,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');
},
)
],
),
),
],
),
],
),
);

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
@@ -22,7 +40,7 @@ class NutritionalPlansList extends StatelessWidget {
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text(
"Workout ${currentPlan.id} deleted",
"Nutritional plan ${currentPlan.id} deleted",
textAlign: TextAlign.center,
),
),

View File

@@ -1,62 +1,106 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
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<BodyWeight>(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<BodyWeight>(context, listen: false).deleteEntry(currentEntry.id);
return Column(
children: [
Container(
padding: EdgeInsets.all(15),
height: 220,
child: charts.TimeSeriesChart(
[
charts.Series<WeightEntry, DateTime>(
id: 'Weight',
colorFn: (_, __) => wgerChartSecondaryColor,
domainFn: (WeightEntry weightEntry, _) => weightEntry.date,
measureFn: (WeightEntry weightEntry, _) => weightEntry.weight,
data: weightEntriesData.items,
)
],
defaultRenderer: new charts.LineRendererConfig(includePoints: true),
),
),
Divider(),
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<BodyWeight>(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(
"Deleted weight entry for the ${DateFormat('dd.MM.yyyy').format(currentEntry.date).toString()}",
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'),
),
),
);
},
),
],
);
}
}

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/material.dart';
import 'package:wger/locale/locales.dart';
import 'package:wger/models/workouts/day.dart';
@@ -64,20 +82,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 +92,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 +108,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,

View File

@@ -1,5 +1,6 @@
/*
* This file is part of wger Workout Manager.
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/material.dart';

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';

View File

@@ -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:
@@ -628,6 +642,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:
@@ -679,4 +735,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"

View File

@@ -33,6 +33,8 @@ dependencies:
flutter_calendar_carousel: ^1.5.1
cupertino_icons: ^1.0.0
json_serializable: ^3.5.0
url_launcher: ^5.7.10
charts_flutter: ^0.9.0
dev_dependencies:
flutter_test:

View File

@@ -0,0 +1,62 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
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);
});
}

View File

@@ -1,11 +1,28 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
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';
// Mocked HTTP client
class MockClient extends Mock implements http.Client {}

View File

@@ -0,0 +1,44 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
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);
});
});
}

View File

@@ -1,3 +1,21 @@
/*
* This file is part of wger Workout Manager <https://github.com/wger-project>.
* 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 <http://www.gnu.org/licenses/>.
*/
import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:mockito/mockito.dart';
@@ -13,7 +31,7 @@ void main() {
// Mock the server response
when(client.get(
'https://localhost/api/v2/weightentry/',
'https://localhost/api/v2/weightentry/?ordering=-date',
headers: <String, String>{'Authorization': 'Token ${testAuth.token}'},
)).thenAnswer((_) async => http.Response(
'{"results": [{"id": 1, "date": "2021-01-01", "weight": "80.00"}, '
@@ -39,7 +57,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));

View File

@@ -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);
});
}