diff --git a/lib/helpers/json.dart b/lib/helpers/json.dart
index c04bbda4..0eaa9281 100644
--- a/lib/helpers/json.dart
+++ b/lib/helpers/json.dart
@@ -16,6 +16,7 @@
* along with this program. If not, see .
*/
+import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
num toNum(String e) {
@@ -48,20 +49,21 @@ String toDate(DateTime dateTime) {
* Converts a time to a date object.
* Needed e.g. when the wger api only sends a time but no date information.
*/
-DateTime fromTime(String time) {
+TimeOfDay stringToTime(String time) {
if (time == null) {
return null;
}
- return DateTime.parse(DateFormat('yyyy-MM-dd').format(DateTime.now()).toString() + ' ' + time);
+ return TimeOfDay.fromDateTime(
+ DateTime.parse('2020-01-01 $time'),
+ );
}
/*
* Converts a datetime to time.
- * Needed e.g. when the wger api only expects a time and no date information.
*/
-String toTime(DateTime dateTime) {
- if (dateTime == null) {
+String timeToString(TimeOfDay time) {
+ if (time == null) {
return null;
}
- return DateFormat.Hms().format(dateTime).toString();
+ return DefaultMaterialLocalizations().formatTimeOfDay(time, alwaysUse24HourFormat: true);
}
diff --git a/lib/locale/locales.dart b/lib/locale/locales.dart
index 782320d7..8685599d 100644
--- a/lib/locale/locales.dart
+++ b/lib/locale/locales.dart
@@ -155,6 +155,14 @@ class AppLocalizations {
);
}
+ String get time {
+ return Intl.message(
+ 'Time',
+ name: 'time',
+ desc: 'The time of a meal or workout',
+ );
+ }
+
String get newEntry {
return Intl.message(
'New entry',
diff --git a/lib/models/nutrition/meal.dart b/lib/models/nutrition/meal.dart
index ae9c58da..4e0bcf2f 100644
--- a/lib/models/nutrition/meal.dart
+++ b/lib/models/nutrition/meal.dart
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import 'package:intl/intl.dart';
+import 'package:flutter/material.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:wger/helpers/json.dart';
import 'package:wger/models/nutrition/meal_item.dart';
@@ -28,16 +28,11 @@ class Meal {
@JsonKey(required: true)
final int id;
- @JsonKey(required: true, toJson: toTime, fromJson: fromTime)
- final DateTime time;
-
- /// returns the time component of the DateTime time as a string
- String get getTime {
- return DateFormat.jm().format(time).toString();
- }
+ @JsonKey(required: true, toJson: timeToString, fromJson: stringToTime)
+ TimeOfDay time;
@JsonKey(required: true, name: 'meal_items')
- final List mealItems;
+ List mealItems;
Meal({
this.id,
diff --git a/lib/models/nutrition/meal.g.dart b/lib/models/nutrition/meal.g.dart
index 1edcf5df..48b77fda 100644
--- a/lib/models/nutrition/meal.g.dart
+++ b/lib/models/nutrition/meal.g.dart
@@ -10,16 +10,15 @@ Meal _$MealFromJson(Map json) {
$checkKeys(json, requiredKeys: const ['id', 'time', 'meal_items']);
return Meal(
id: json['id'] as int,
- time: fromTime(json['time'] as String),
+ time: stringToTime(json['time'] as String),
mealItems: (json['meal_items'] as List)
- ?.map((e) =>
- e == null ? null : MealItem.fromJson(e as Map))
+ ?.map((e) => e == null ? null : MealItem.fromJson(e as Map))
?.toList(),
);
}
Map _$MealToJson(Meal instance) => {
'id': instance.id,
- 'time': toTime(instance.time),
+ 'time': timeToString(instance.time),
'meal_items': instance.mealItems,
};
diff --git a/lib/providers/exercises.dart b/lib/providers/exercises.dart
index fc4d3634..1da608b4 100644
--- a/lib/providers/exercises.dart
+++ b/lib/providers/exercises.dart
@@ -114,7 +114,7 @@ class Exercises with ChangeNotifier {
//if (false) {
final exerciseData = json.decode(prefs.getString('exerciseData'));
if (DateTime.parse(exerciseData['expiresIn']).isAfter(DateTime.now())) {
- exerciseData['results'].forEach((e) => _entries.add(Exercise.fromJson(e)));
+ exerciseData['exercises'].forEach((e) => _entries.add(Exercise.fromJson(e)));
log("Read exercise data from cache. Valid till ${exerciseData['expiresIn']}");
return;
}
diff --git a/lib/widgets/nutrition/forms.dart b/lib/widgets/nutrition/forms.dart
new file mode 100644
index 00000000..6306733b
--- /dev/null
+++ b/lib/widgets/nutrition/forms.dart
@@ -0,0 +1,106 @@
+/*
+ * 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/helpers/json.dart';
+import 'package:wger/locale/locales.dart';
+import 'package:wger/models/nutrition/meal.dart';
+import 'package:wger/models/nutrition/nutritional_plan.dart';
+
+class MealForm extends StatelessWidget {
+ Meal meal;
+ NutritionalPlan _plan;
+
+ MealForm(plan, [meal]) {
+ this._plan = plan;
+ this.meal = meal ?? Meal();
+ }
+
+ //MealForm(this._plan, {this.meal});
+
+ final _form = GlobalKey();
+ final _timeController = TextEditingController(
+ text: timeToString(TimeOfDay.fromDateTime(DateTime.now())),
+ );
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ margin: EdgeInsets.all(20),
+ child: Form(
+ key: _form,
+ child: Column(
+ children: [
+ Text('tttttt'),
+ TextFormField(
+ decoration: InputDecoration(labelText: AppLocalizations.of(context).time),
+ controller: _timeController,
+ onTap: () async {
+ // Stop keyboard from appearing
+ FocusScope.of(context).requestFocus(new FocusNode());
+
+ // Open time picker
+ var pickedTime = await showTimePicker(
+ context: context,
+ initialTime: TimeOfDay.now(),
+ );
+
+ _timeController.text = timeToString(pickedTime);
+ },
+ onSaved: (newValue) {
+ meal.time = stringToTime(newValue);
+ },
+ onFieldSubmitted: (_) {},
+ ),
+ ElevatedButton(
+ child: Text(AppLocalizations.of(context).save),
+ onPressed: () async {
+ if (!_form.currentState.validate()) {
+ return;
+ }
+ _form.currentState.save();
+
+ try {
+ //Provider.of(context, listen: false)
+ //.addMe(_plan)
+ // .addDay(Day(description: dayController.text, daysOfWeek: [1]), workout);
+ } catch (error) {
+ await showDialog(
+ context: context,
+ builder: (ctx) => AlertDialog(
+ title: Text('An error occurred!'),
+ content: Text('Something went wrong.'),
+ actions: [
+ TextButton(
+ child: Text('Okay'),
+ onPressed: () {
+ Navigator.of(ctx).pop();
+ },
+ )
+ ],
+ ),
+ );
+ }
+ },
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/nutrition/meal.dart b/lib/widgets/nutrition/meal.dart
index 6b1a0d08..edd78dd2 100644
--- a/lib/widgets/nutrition/meal.dart
+++ b/lib/widgets/nutrition/meal.dart
@@ -58,17 +58,14 @@ class MealWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
- //color: Colors.amber,
- //width: double.infinity,
child: Card(
child: Column(
- //mainAxisSize: MainAxisSize.max,
children: [
Container(
width: double.infinity,
decoration: BoxDecoration(color: Colors.black12),
padding: const EdgeInsets.symmetric(vertical: 10),
- child: Text(_meal.getTime),
+ child: Text(_meal.time.format(context)),
),
..._meal.mealItems.map((item) => MealItemWidget(item)).toList(),
],
diff --git a/lib/widgets/nutrition/nutritional_plan_detail.dart b/lib/widgets/nutrition/nutritional_plan_detail.dart
index 73675cf2..8ac3cd64 100644
--- a/lib/widgets/nutrition/nutritional_plan_detail.dart
+++ b/lib/widgets/nutrition/nutritional_plan_detail.dart
@@ -21,6 +21,7 @@ import 'package:intl/intl.dart';
import 'package:wger/locale/locales.dart';
import 'package:wger/models/nutrition/nutritional_plan.dart';
import 'package:wger/widgets/core/bottom_sheet.dart';
+import 'package:wger/widgets/nutrition/forms.dart';
import 'package:wger/widgets/nutrition/meal.dart';
class NutritionalPlanDetailWidget extends StatefulWidget {
@@ -32,10 +33,6 @@ class NutritionalPlanDetailWidget extends StatefulWidget {
}
class _NutritionalPlanDetailWidgetState extends State {
- Widget planForm = Form(
- child: Text('forms come here...'),
- );
-
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
@@ -61,7 +58,7 @@ class _NutritionalPlanDetailWidgetState extends State