Skip to content

Commit bf9e614

Browse files
committed
make it work for measurements + couple fixes
1 parent 3dc1c4e commit bf9e614

File tree

8 files changed

+128
-81
lines changed

8 files changed

+128
-81
lines changed

lib/screens/measurement_entries_screen.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,10 @@ class MeasurementEntriesScreen extends StatelessWidget {
133133
);
134134
},
135135
),
136-
body: Consumer<MeasurementProvider>(
137-
builder: (context, provider, child) => EntriesList(category),
136+
body: SingleChildScrollView(
137+
child: Consumer<MeasurementProvider>(
138+
builder: (context, provider, child) => EntriesList(category),
139+
),
138140
),
139141
);
140142
}

lib/screens/weight_screen.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ import 'package:provider/provider.dart';
2222
import 'package:wger/providers/body_weight.dart';
2323
import 'package:wger/screens/form_screen.dart';
2424
import 'package:wger/widgets/core/app_bar.dart';
25-
import 'package:wger/widgets/weight/weight_overview.dart';
2625
import 'package:wger/widgets/weight/forms.dart';
26+
import 'package:wger/widgets/weight/weight_overview.dart';
2727

2828
class WeightScreen extends StatelessWidget {
2929
const WeightScreen();

lib/widgets/dashboard/widgets.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,9 @@ class _DashboardMeasurementWidgetState extends State<DashboardMeasurementWidget>
280280
FontAwesomeIcons.chartLine,
281281
color: Theme.of(context).textTheme.headlineSmall!.color,
282282
),
283+
// TODO: this icon feels out of place and inconsistent with all
284+
// other dashboard widgets.
285+
// maybe we should just add a "Go to all" at the bottom of the widget
283286
trailing: IconButton(
284287
icon: const Icon(Icons.arrow_forward),
285288
onPressed: () => Navigator.pushNamed(

lib/widgets/measurements/categories_card.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@ class CategoriesCard extends StatelessWidget {
1515

1616
@override
1717
Widget build(BuildContext context) {
18+
final entriesAll =
19+
currentCategory.entries.map((e) => MeasurementChartEntry(e.value, e.date)).toList();
20+
final entries7dAvg = moving7dAverage(entriesAll);
21+
1822
return Card(
1923
elevation: elevation,
20-
color: Theme.of(context).colorScheme.onInverseSurface,
2124
child: Column(
2225
children: [
2326
Padding(
@@ -31,10 +34,16 @@ class CategoriesCard extends StatelessWidget {
3134
padding: const EdgeInsets.all(10),
3235
height: 220,
3336
child: MeasurementChartWidgetFl(
34-
currentCategory.entries.map((e) => MeasurementChartEntry(e.value, e.date)).toList(),
37+
entriesAll,
3538
currentCategory.unit,
39+
avgs: entries7dAvg,
3640
),
3741
),
42+
MeasurementOverallChangeWidget(
43+
entries7dAvg.first,
44+
entries7dAvg.last,
45+
currentCategory.unit,
46+
),
3847
const Divider(),
3948
Row(
4049
mainAxisAlignment: MainAxisAlignment.spaceBetween,

lib/widgets/measurements/charts.dart

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,14 @@ class MeasurementOverallChangeWidget extends StatelessWidget {
3030

3131
@override
3232
Widget build(BuildContext context) {
33-
return Text(
34-
'overall change ${(_last.value - _first.value).toStringAsFixed(1)} $_unit',
35-
);
33+
final delta = _last.value - _first.value;
34+
final prefix = delta > 0
35+
? '+'
36+
: delta < 0
37+
? '-'
38+
: '';
39+
40+
return Text('overall change $prefix ${delta.abs().toStringAsFixed(1)} $_unit');
3641
}
3742
}
3843

lib/widgets/measurements/entries.dart

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ import 'package:intl/intl.dart';
2222
import 'package:provider/provider.dart';
2323
import 'package:wger/models/measurements/measurement_category.dart';
2424
import 'package:wger/providers/measurement.dart';
25+
import 'package:wger/providers/nutrition.dart';
2526
import 'package:wger/screens/form_screen.dart';
2627
import 'package:wger/widgets/measurements/charts.dart';
28+
import 'package:wger/widgets/measurements/helpers.dart';
2729

2830
import 'forms.dart';
2931

@@ -34,16 +36,23 @@ class EntriesList extends StatelessWidget {
3436

3537
@override
3638
Widget build(BuildContext context) {
39+
final plan = Provider.of<NutritionPlansProvider>(context, listen: false).currentPlan;
40+
41+
final entriesAll =
42+
_category.entries.map((e) => MeasurementChartEntry(e.value, e.date)).toList();
43+
final entries7dAvg = moving7dAverage(entriesAll);
44+
3745
return Column(children: [
38-
Container(
39-
padding: const EdgeInsets.all(10),
40-
height: 220,
41-
child: MeasurementChartWidgetFl(
42-
_category.entries.map((e) => MeasurementChartEntry(e.value, e.date)).toList(),
43-
_category.unit,
44-
),
46+
...getOverviewWidgetsSeries(
47+
_category.name,
48+
entriesAll,
49+
entries7dAvg,
50+
plan,
51+
_category.unit,
52+
context,
4553
),
46-
Expanded(
54+
SizedBox(
55+
height: 300,
4756
child: ListView.builder(
4857
padding: const EdgeInsets.all(10.0),
4958
itemCount: _category.entries.length,
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:wger/models/nutrition/nutritional_plan.dart';
3+
import 'package:wger/widgets/measurements/charts.dart';
4+
5+
List<Widget> getOverviewWidgets(
6+
String title,
7+
List<MeasurementChartEntry> raw,
8+
List<MeasurementChartEntry> avg,
9+
String unit,
10+
BuildContext context,
11+
) {
12+
return [
13+
Text(
14+
title,
15+
textAlign: TextAlign.center,
16+
style: Theme.of(context).textTheme.titleLarge,
17+
),
18+
Container(
19+
padding: const EdgeInsets.all(15),
20+
height: 220,
21+
child: MeasurementChartWidgetFl(raw, unit, avgs: avg),
22+
),
23+
if (avg.isNotEmpty) MeasurementOverallChangeWidget(avg.first, avg.last, unit),
24+
const SizedBox(height: 8),
25+
];
26+
}
27+
28+
List<Widget> getOverviewWidgetsSeries(
29+
String name,
30+
List<MeasurementChartEntry> entriesAll,
31+
List<MeasurementChartEntry> entries7dAvg,
32+
NutritionalPlan? plan,
33+
String unit,
34+
BuildContext context,
35+
) {
36+
final monthAgo = DateTime.now().subtract(const Duration(days: 30));
37+
return [
38+
...getOverviewWidgets(
39+
'$name all-time',
40+
entriesAll,
41+
entries7dAvg,
42+
unit,
43+
context,
44+
),
45+
if (plan != null)
46+
...getOverviewWidgets(
47+
'$name during nutritional plan ${plan.description}',
48+
entriesAll.where((e) => e.date.isAfter(plan.creationDate)).toList(),
49+
entries7dAvg.where((e) => e.date.isAfter(plan.creationDate)).toList(),
50+
unit,
51+
context,
52+
),
53+
// if all time is significantly longer than 30 days (let's say > 75 days)
54+
// and if there is is a plan and it also was > 75 days,
55+
// then let's show a separate chart just focusing on the last 30 days
56+
if (entriesAll.first.date.isBefore(entriesAll.last.date.subtract(const Duration(days: 75))) &&
57+
(plan == null ||
58+
entriesAll
59+
.firstWhere((e) => e.date.isAfter(plan.creationDate))
60+
.date
61+
.isBefore(entriesAll.last.date.subtract(const Duration(days: 30)))))
62+
...getOverviewWidgets(
63+
'$name last 30 days',
64+
entriesAll.where((e) => e.date.isAfter(monthAgo)).toList(),
65+
entries7dAvg.where((e) => e.date.isAfter(monthAgo)).toList(),
66+
unit,
67+
context,
68+
),
69+
// legend
70+
Row(
71+
mainAxisAlignment: MainAxisAlignment.center,
72+
children: [
73+
Indicator(color: Theme.of(context).colorScheme.primary, text: 'raw', isSquare: true),
74+
Indicator(color: Theme.of(context).colorScheme.tertiary, text: 'avg', isSquare: true),
75+
],
76+
),
77+
];
78+
}

lib/widgets/weight/weight_overview.dart

Lines changed: 6 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import 'package:wger/providers/user.dart';
2626
import 'package:wger/screens/form_screen.dart';
2727
import 'package:wger/screens/measurement_categories_screen.dart';
2828
import 'package:wger/widgets/measurements/charts.dart';
29+
import 'package:wger/widgets/measurements/helpers.dart';
2930
import 'package:wger/widgets/weight/forms.dart';
3031

3132
class WeightOverview extends StatelessWidget {
@@ -40,78 +41,18 @@ class WeightOverview extends StatelessWidget {
4041
weightProvider.items.map((e) => MeasurementChartEntry(e.weight, e.date)).toList();
4142
final entries7dAvg = moving7dAverage(entriesAll);
4243

43-
List<Widget> getOverviewWidgets(String title, bool isMetric, List<MeasurementChartEntry> raw,
44-
List<MeasurementChartEntry> avg, BuildContext context) {
45-
return [
46-
Text(
47-
title,
48-
textAlign: TextAlign.center,
49-
style: Theme.of(context).textTheme.titleLarge,
50-
),
51-
Container(
52-
padding: const EdgeInsets.all(15),
53-
height: 220,
54-
child: MeasurementChartWidgetFl(
55-
raw,
56-
weightUnit(isMetric, context),
57-
avgs: avg,
58-
),
59-
),
60-
MeasurementOverallChangeWidget(
61-
avg.first,
62-
avg.last,
63-
weightUnit(isMetric, context),
64-
),
65-
const SizedBox(height: 8),
66-
];
67-
}
44+
final unit = weightUnit(profile!.isMetric, context);
6845

6946
return Column(
7047
children: [
71-
...getOverviewWidgets(
72-
'Weight all-time',
73-
profile!.isMetric,
48+
...getOverviewWidgetsSeries(
49+
'Weight',
7450
entriesAll,
7551
entries7dAvg,
52+
plan,
53+
unit,
7654
context,
7755
),
78-
if (plan != null)
79-
...getOverviewWidgets(
80-
'Weight during nutritional plan ${plan.description}',
81-
profile.isMetric,
82-
entriesAll.where((e) => e.date.isAfter(plan.creationDate)).toList(),
83-
entries7dAvg.where((e) => e.date.isAfter(plan.creationDate)).toList(),
84-
context,
85-
),
86-
// if all time is significantly longer than 30 days (let's say > 75 days)
87-
// and if there is is a plan and it also was > 75 days,
88-
// then let's show a separate chart just focusing on the last 30 days
89-
if (entriesAll.first.date
90-
.isBefore(entriesAll.last.date.subtract(const Duration(days: 75))) &&
91-
(plan == null ||
92-
entriesAll
93-
.firstWhere((e) => e.date.isAfter(plan.creationDate))
94-
.date
95-
.isBefore(entriesAll.last.date.subtract(const Duration(days: 30)))))
96-
...getOverviewWidgets(
97-
'Weight last 30 days',
98-
profile.isMetric,
99-
entriesAll
100-
.where((e) => e.date.isAfter(DateTime.now().subtract(const Duration(days: 30))))
101-
.toList(),
102-
entries7dAvg
103-
.where((e) => e.date.isAfter(DateTime.now().subtract(const Duration(days: 30))))
104-
.toList(),
105-
context,
106-
),
107-
108-
Row(
109-
mainAxisAlignment: MainAxisAlignment.center,
110-
children: [
111-
Indicator(color: Theme.of(context).colorScheme.primary, text: 'raw', isSquare: true),
112-
Indicator(color: Theme.of(context).colorScheme.tertiary, text: 'avg', isSquare: true),
113-
],
114-
),
11556
TextButton(
11657
onPressed: () => Navigator.pushNamed(
11758
context,

0 commit comments

Comments
 (0)