addded measurements to dashboard, categories card refactor

This commit is contained in:
Bujdy
2022-10-05 17:09:59 +02:00
parent 718dcfacb3
commit 5cc6413f0d
6 changed files with 234 additions and 86 deletions

View File

@@ -41,6 +41,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
DashboardWorkoutWidget(),
DashboardNutritionWidget(),
DashboardWeightWidget(),
DashboardMeasurementsWidget(),
const DashboardCalendarWidget(),
],
),

View File

@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@@ -35,14 +36,20 @@ import 'package:wger/screens/workout_plan_screen.dart';
import 'package:wger/theme/theme.dart';
import 'package:wger/widgets/core/charts.dart';
import 'package:wger/widgets/core/core.dart';
import 'package:wger/widgets/measurements/categories_card.dart';
import 'package:wger/widgets/nutrition/charts.dart';
import 'package:wger/widgets/nutrition/forms.dart';
import 'package:wger/widgets/weight/forms.dart';
import 'package:wger/widgets/workouts/forms.dart';
import '../../providers/measurement.dart';
import '../../screens/measurement_entries_screen.dart';
import '../measurements/forms.dart';
class DashboardNutritionWidget extends StatefulWidget {
@override
_DashboardNutritionWidgetState createState() => _DashboardNutritionWidgetState();
_DashboardNutritionWidgetState createState() =>
_DashboardNutritionWidgetState();
}
class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
@@ -53,7 +60,8 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
@override
void initState() {
super.initState();
_plan = Provider.of<NutritionPlansProvider>(context, listen: false).currentPlan;
_plan =
Provider.of<NutritionPlansProvider>(context, listen: false).currentPlan;
_hasContent = _plan != null;
}
@@ -96,7 +104,8 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
icon: const Icon(Icons.history_edu),
color: wgerPrimaryButtonColor,
onPressed: () {
Provider.of<NutritionPlansProvider>(context, listen: false).logMealToDiary(meal);
Provider.of<NutritionPlansProvider>(context, listen: false)
.logMealToDiary(meal);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
@@ -127,7 +136,8 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
),
),
const SizedBox(width: 5),
Text('${item.amount.toStringAsFixed(0)} ${AppLocalizations.of(context).g}'),
Text(
'${item.amount.toStringAsFixed(0)} ${AppLocalizations.of(context).g}'),
],
),
],
@@ -147,7 +157,9 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
return const Text('');
}
return _showDetail ? const Icon(Icons.expand_less) : const Icon(Icons.expand_more);
return _showDetail
? const Icon(Icons.expand_less)
: const Icon(Icons.expand_more);
}
@override
@@ -157,7 +169,9 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
children: [
ListTile(
title: Text(
_hasContent ? _plan!.description : AppLocalizations.of(context).nutritionalPlan,
_hasContent
? _plan!.description
: AppLocalizations.of(context).nutritionalPlan,
style: Theme.of(context).textTheme.headline4,
),
subtitle: Text(
@@ -186,7 +200,8 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
Container(
padding: const EdgeInsets.all(15),
height: 180,
child: NutritionalPlanPieChartWidget(_plan!.nutritionalValues),
child:
NutritionalPlanPieChartWidget(_plan!.nutritionalValues),
)
],
),
@@ -218,8 +233,9 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
TextButton(
child: Text(AppLocalizations.of(context).goToDetailPage),
onPressed: () {
Navigator.of(context)
.pushNamed(NutritionalPlanScreen.routeName, arguments: _plan);
Navigator.of(context).pushNamed(
NutritionalPlanScreen.routeName,
arguments: _plan);
},
),
],
@@ -253,7 +269,7 @@ class _DashboardWeightWidgetState extends State<DashboardWeightWidget> {
style: Theme.of(context).textTheme.headline4,
),
leading: const FaIcon(
FontAwesomeIcons.weightScale,
FontAwesomeIcons.weight,
color: Colors.black,
),
trailing: IconButton(
@@ -286,9 +302,11 @@ class _DashboardWeightWidgetState extends State<DashboardWeightWidget> {
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
TextButton(
child: Text(AppLocalizations.of(context).goToDetailPage),
child: Text(
AppLocalizations.of(context).goToDetailPage),
onPressed: () {
Navigator.of(context).pushNamed(WeightScreen.routeName);
Navigator.of(context)
.pushNamed(WeightScreen.routeName);
}),
],
),
@@ -309,6 +327,101 @@ class _DashboardWeightWidgetState extends State<DashboardWeightWidget> {
}
}
class DashboardMeasurementsWidget extends StatefulWidget {
@override
_DashboardMeasurementsWidgetState createState() =>
_DashboardMeasurementsWidgetState();
}
class _DashboardMeasurementsWidgetState
extends State<DashboardMeasurementsWidget> {
int _current = 0;
final CarouselController _controller = CarouselController();
@override
Widget build(BuildContext context) {
final _provider = Provider.of<MeasurementProvider>(context, listen: false);
var items = _provider.categories
.map(
(item) => CategoriesCard(item),
)
.toList();
return Consumer<BodyWeightProvider>(
builder: (context, workoutProvider, child) => Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: Text(
AppLocalizations.of(context).measurements,
style: Theme.of(context).textTheme.headline4,
),
leading: const FaIcon(
FontAwesomeIcons.weight,
color: Colors.black,
),
),
Column(
children: [
if (items.isNotEmpty)
Column(children: [
CarouselSlider(
items: items,
carouselController: _controller,
options: CarouselOptions(
autoPlay: false,
enlargeCenterPage: false,
viewportFraction: 1,
enableInfiniteScroll: false,
aspectRatio: 1.1,
onPageChanged: (index, reason) {
setState(() {
_current = index;
});
}),
),
Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: items.asMap().entries.map((entry) {
return GestureDetector(
onTap: () => _controller.animateToPage(entry.key),
child: Container(
width: 12.0,
height: 12.0,
margin: EdgeInsets.symmetric(
vertical: 8.0, horizontal: 4.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: (Theme.of(context).brightness ==
Brightness.dark
? Colors.white
: wgerPrimaryColor)
.withOpacity(
_current == entry.key ? 0.9 : 0.4)),
),
);
}).toList(),
),
),
])
else
NothingFound(
AppLocalizations.of(context).noWeightEntries,
AppLocalizations.of(context).newEntry,
WeightForm(),
),
],
),
],
),
),
);
}
}
class DashboardWorkoutWidget extends StatefulWidget {
@override
_DashboardWorkoutWidgetState createState() => _DashboardWorkoutWidgetState();
@@ -332,7 +445,9 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
return const Text('');
}
return _showDetail ? const Icon(Icons.expand_less) : const Icon(Icons.expand_more);
return _showDetail
? const Icon(Icons.expand_less)
: const Icon(Icons.expand_more);
}
List<Widget> getContent() {
@@ -364,7 +479,8 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
icon: const Icon(Icons.play_arrow),
color: wgerPrimaryButtonColor,
onPressed: () {
Navigator.of(context).pushNamed(GymModeScreen.routeName, arguments: day);
Navigator.of(context)
.pushNamed(GymModeScreen.routeName, arguments: day);
},
),
],
@@ -386,7 +502,8 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
children: [
Text(s.exerciseObj.name),
const SizedBox(width: 10),
MutedText(set.getSmartRepr(s.exerciseObj).join('\n')),
MutedText(
set.getSmartRepr(s.exerciseObj).join('\n')),
],
),
const SizedBox(height: 10),
@@ -411,7 +528,9 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
children: [
ListTile(
title: Text(
_hasContent ? _workoutPlan!.name : AppLocalizations.of(context).labelWorkoutPlan,
_hasContent
? _workoutPlan!.name
: AppLocalizations.of(context).labelWorkoutPlan,
style: Theme.of(context).textTheme.headline4,
),
subtitle: Text(
@@ -453,8 +572,8 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
TextButton(
child: Text(AppLocalizations.of(context).goToDetailPage),
onPressed: () {
Navigator.of(context)
.pushNamed(WorkoutPlanScreen.routeName, arguments: _workoutPlan);
Navigator.of(context).pushNamed(WorkoutPlanScreen.routeName,
arguments: _workoutPlan);
},
),
],

View File

@@ -24,6 +24,7 @@ import 'package:wger/screens/form_screen.dart';
import 'package:wger/screens/measurement_entries_screen.dart';
import 'package:wger/widgets/core/charts.dart';
import 'categories_card.dart';
import 'forms.dart';
class CategoriesList extends StatelessWidget {
@@ -37,58 +38,7 @@ class CategoriesList extends StatelessWidget {
itemBuilder: (context, index) {
final currentCategory = _provider.categories[index];
return Card(
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 5),
child: Text(
currentCategory.name,
style: Theme.of(context).textTheme.headline6,
),
),
Container(
color: Colors.white,
padding: const EdgeInsets.all(10),
height: 220,
child: MeasurementChartWidget(
currentCategory.entries
.map((e) => MeasurementChartEntry(e.value, e.date))
.toList(),
unit: currentCategory.unit,
),
),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
TextButton(
child: Text(AppLocalizations.of(context).goToDetailPage),
onPressed: () {
Navigator.pushNamed(
context,
MeasurementEntriesScreen.routeName,
arguments: currentCategory.id,
);
}),
IconButton(
onPressed: () async {
await Navigator.pushNamed(
context,
FormScreen.routeName,
arguments: FormScreenArguments(
AppLocalizations.of(context).newEntry,
MeasurementEntryForm(currentCategory.id!),
),
);
},
icon: const Icon(Icons.add),
),
],
),
],
),
);
return CategoriesCard(currentCategory);
},
);
}

View File

@@ -0,0 +1,70 @@
import 'package:flutter/material.dart';
import '../../models/measurements/measurement_category.dart';
import '../../screens/form_screen.dart';
import '../../screens/measurement_entries_screen.dart';
import '../core/charts.dart';
import 'forms.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class CategoriesCard extends StatelessWidget {
MeasurementCategory currentCategory;
CategoriesCard(this.currentCategory);
@override
Widget build(BuildContext context) {
return Card(
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 5),
child: Text(
currentCategory.name,
style: Theme.of(context).textTheme.headline6,
),
),
Container(
color: Colors.white,
padding: const EdgeInsets.all(10),
height: 220,
child: MeasurementChartWidget(
currentCategory.entries
.map((e) => MeasurementChartEntry(e.value, e.date))
.toList(),
unit: currentCategory.unit,
),
),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
TextButton(
child: Text(AppLocalizations.of(context).goToDetailPage),
onPressed: () {
Navigator.pushNamed(
context,
MeasurementEntriesScreen.routeName,
arguments: currentCategory.id,
);
}),
IconButton(
onPressed: () async {
await Navigator.pushNamed(
context,
FormScreen.routeName,
arguments: FormScreenArguments(
AppLocalizations.of(context).newEntry,
MeasurementEntryForm(currentCategory.id!),
),
);
},
icon: const Icon(Icons.add),
),
],
),
],
),
);
}
}

View File

@@ -42,7 +42,7 @@ packages:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.8.2"
version: "2.9.0"
boolean_selector:
dependency: transitive
description:
@@ -141,6 +141,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.0"
carousel_slider:
dependency: "direct main"
description:
name: carousel_slider
url: "https://pub.dartlang.org"
source: hosted
version: "4.1.1"
change:
dependency: transitive
description:
@@ -154,7 +161,7 @@ packages:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.2.1"
charcode:
dependency: transitive
description:
@@ -217,7 +224,7 @@ packages:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.1.1"
code_builder:
dependency: transitive
description:
@@ -287,7 +294,7 @@ packages:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
version: "1.3.1"
ffi:
dependency: transitive
description:
@@ -552,7 +559,7 @@ packages:
name: json_serializable
url: "https://pub.dartlang.org"
source: hosted
version: "6.4.1"
version: "6.4.0"
klizma:
dependency: transitive
description:
@@ -594,21 +601,21 @@ packages:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.11"
version: "0.12.12"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
version: "0.1.5"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
version: "1.8.0"
mime:
dependency: transitive
description:
@@ -664,7 +671,7 @@ packages:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.1"
version: "1.8.2"
path_drawing:
dependency: transitive
description:
@@ -879,7 +886,7 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.2"
version: "1.9.0"
stack_trace:
dependency: transitive
description:
@@ -907,7 +914,7 @@ packages:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.1.1"
table_calendar:
dependency: "direct main"
description:
@@ -921,14 +928,14 @@ packages:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.9"
version: "0.4.12"
timing:
dependency: transitive
description:
@@ -956,7 +963,7 @@ packages:
name: url_launcher
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.6"
version: "6.1.5"
url_launcher_android:
dependency: transitive
description:

View File

@@ -51,9 +51,10 @@ dependencies:
rive: ^0.9.1
shared_preferences: ^2.0.15
table_calendar: ^3.0.7
url_launcher: ^6.1.6
url_launcher: ^6.1.5
flutter_barcode_scanner: ^2.0.0
video_player: ^2.4.7
carousel_slider: ^4.1.1
dev_dependencies:
flutter_test:
@@ -62,7 +63,7 @@ dev_dependencies:
# sdk: flutter
build_runner: ^2.2.1
flutter_launcher_icons: ^0.10.0
json_serializable: ^6.4.1
json_serializable: ^6.3.2
mockito: ^5.3.2
network_image_mock: ^2.1.1
flutter_lints: ^2.0.1