Move body weight chart to own widget

This commit is contained in:
Roland Geider
2020-12-29 21:28:42 +01:00
parent 373cfb0dfd
commit 005e719c78
4 changed files with 132 additions and 95 deletions

View File

@@ -19,8 +19,10 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:wger/locale/locales.dart';
import 'package:wger/providers/body_weight.dart';
import 'package:wger/providers/exercises.dart';
import 'package:wger/widgets/app_drawer.dart';
import 'package:wger/widgets/weight/charts.dart';
class DashboardScreen extends StatefulWidget {
static const routeName = '/dashboard';
@@ -89,7 +91,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: Icon(Icons.fitness_center),
leading: Icon(Icons.restaurant),
title: Text('Nutrition'),
subtitle: Text('Nutrition overview, graphs, etc'),
),
@@ -114,14 +116,20 @@ class _DashboardScreenState extends State<DashboardScreen> {
}
Widget getWeightCard() {
final weightEntriesData = Provider.of<BodyWeight>(context);
return Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: Icon(Icons.restaurant),
leading: Icon(Icons.bar_chart),
title: Text('Weight'),
subtitle: Text('Weight overview, graphs, etc'),
subtitle: Container(
padding: EdgeInsets.all(15),
height: 180,
child: WeightChartWidget(weightEntriesData.items),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,

View File

@@ -47,12 +47,6 @@ class _WeightScreenState extends State<WeightScreen> {
Widget getAppBar() {
return AppBar(
title: Text('Weight'),
actions: [
IconButton(
icon: Icon(Icons.add),
onPressed: () {},
),
],
);
}
@@ -83,83 +77,84 @@ class _WeightScreenState extends State<WeightScreen> {
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,
),
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());
// 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(),
);
// 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: (_) {},
),
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();
// 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);
// 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();
},
),
],
),
// 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

@@ -0,0 +1,47 @@
/*
* 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/widgets.dart';
import 'package:wger/models/body_weight/weight_entry.dart';
import 'package:wger/theme/theme.dart';
/// Weight chart widget
class WeightChartWidget extends StatelessWidget {
final List<WeightEntry> _entries;
/// [_entries] is a list of [WeightEntry] as returned e.g. by the
/// [BodyWeight] provider.
WeightChartWidget(this._entries);
@override
Widget build(BuildContext context) {
return charts.TimeSeriesChart(
[
charts.Series<WeightEntry, DateTime>(
id: 'Weight',
colorFn: (_, __) => wgerChartSecondaryColor,
domainFn: (WeightEntry weightEntry, _) => weightEntry.date,
measureFn: (WeightEntry weightEntry, _) => weightEntry.weight,
data: _entries,
)
],
defaultRenderer: new charts.LineRendererConfig(includePoints: true),
);
}
}

View File

@@ -16,13 +16,11 @@
* 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';
import 'package:wger/widgets/weight/charts.dart';
class WeightEntriesList extends StatelessWidget {
@override
@@ -33,18 +31,7 @@ class WeightEntriesList extends StatelessWidget {
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),
),
child: WeightChartWidget(weightEntriesData.items),
),
Divider(),
Expanded(