mirror of
https://github.com/wger-project/flutter.git
synced 2026-02-18 00:17:48 +01:00
Pre-load necessary data
This commit is contained in:
@@ -29,6 +29,10 @@ import 'package:wger/models/http_exception.dart';
|
||||
class Auth with ChangeNotifier {
|
||||
String token;
|
||||
String serverUrl;
|
||||
|
||||
/// flag to indicate that the application has successfully loaded all initial data
|
||||
bool dataInit = false;
|
||||
|
||||
// DateTime _expiryDate;
|
||||
// String _userId;
|
||||
// Timer _authTimer;
|
||||
|
||||
@@ -276,6 +276,13 @@ class Nutrition extends WgerBaseProvider with ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Log meal to nutrition diary
|
||||
Future<void> fetchAndSetAllLogs() async {
|
||||
for (var plan in _plans) {
|
||||
fetchAndSetLogs(plan);
|
||||
}
|
||||
}
|
||||
|
||||
/// Log meal to nutrition diary
|
||||
Future<void> fetchAndSetLogs(NutritionalPlan plan) async {
|
||||
// TODO: update fetch to that it can use the pagination
|
||||
|
||||
@@ -90,7 +90,13 @@ class WorkoutPlans extends WgerBaseProvider with ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<WorkoutPlan> fetchAndSetFullWorkout(int workoutId) async {
|
||||
Future<void> setAllFullWorkouts() async {
|
||||
for (var plan in _workoutPlans) {
|
||||
setFullWorkout(plan.id);
|
||||
}
|
||||
}
|
||||
|
||||
Future<WorkoutPlan> setFullWorkout(int workoutId) async {
|
||||
final data = await fetch(makeUrl(
|
||||
_workoutPlansUrlPath,
|
||||
id: workoutId,
|
||||
|
||||
@@ -20,6 +20,7 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:wger/locale/locales.dart';
|
||||
import 'package:wger/providers/auth.dart';
|
||||
import 'package:wger/providers/body_weight.dart';
|
||||
import 'package:wger/providers/exercises.dart';
|
||||
import 'package:wger/providers/nutrition.dart';
|
||||
@@ -43,13 +44,27 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
/// Load inital data from the server
|
||||
Future _loadCachedEntries(BuildContext context) async {
|
||||
await Provider.of<Exercises>(context, listen: false).fetchAndSetExercises();
|
||||
await Provider.of<Nutrition>(context, listen: false).fetchIngredientsFromCache();
|
||||
await Provider.of<WorkoutPlans>(context, listen: false).fetchAndSetWorkouts();
|
||||
await Provider.of<Nutrition>(context, listen: false).fetchAndSetPlans();
|
||||
await Provider.of<BodyWeight>(context, listen: false).fetchAndSetEntries();
|
||||
/// Load initial data from the server
|
||||
Future<void> _loadEntries(BuildContext context) async {
|
||||
if (!Provider.of<Auth>(context, listen: false).dataInit) {
|
||||
// Exercises
|
||||
await Provider.of<Exercises>(context, listen: false).fetchAndSetExercises();
|
||||
|
||||
// Nutrition
|
||||
Nutrition nutritionProvider = Provider.of<Nutrition>(context, listen: false);
|
||||
await nutritionProvider.fetchIngredientsFromCache();
|
||||
await nutritionProvider.fetchAndSetPlans();
|
||||
await nutritionProvider.fetchAndSetAllLogs();
|
||||
|
||||
// Workouts
|
||||
WorkoutPlans workoutProvider = Provider.of<WorkoutPlans>(context, listen: false);
|
||||
await workoutProvider.fetchAndSetWorkouts();
|
||||
await workoutProvider.setAllFullWorkouts();
|
||||
|
||||
// Weight
|
||||
await Provider.of<BodyWeight>(context, listen: false).fetchAndSetEntries();
|
||||
}
|
||||
Provider.of<Auth>(context, listen: false).dataInit = true;
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -58,7 +73,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
||||
appBar: getAppBar(),
|
||||
drawer: AppDrawer(),
|
||||
body: FutureBuilder(
|
||||
future: _loadCachedEntries(context),
|
||||
future: _loadEntries(context),
|
||||
builder: (ctx, authResultSnapshot) =>
|
||||
authResultSnapshot.connectionState == ConnectionState.waiting
|
||||
? Column(
|
||||
|
||||
@@ -131,8 +131,7 @@ class _WorkoutPlanScreenState extends State<WorkoutPlanScreen> {
|
||||
return Scaffold(
|
||||
appBar: getAppBar(workoutPlan),
|
||||
body: FutureBuilder<WorkoutPlan>(
|
||||
future: Provider.of<WorkoutPlans>(context, listen: false)
|
||||
.fetchAndSetFullWorkout(workoutPlan.id),
|
||||
future: Provider.of<WorkoutPlans>(context, listen: false).setFullWorkout(workoutPlan.id),
|
||||
builder: (context, AsyncSnapshot<WorkoutPlan> snapshot) =>
|
||||
snapshot.connectionState == ConnectionState.waiting
|
||||
? Center(child: CircularProgressIndicator())
|
||||
|
||||
@@ -72,7 +72,7 @@ class _DashboardCalendarWidgetState extends State<DashboardCalendarWidget>
|
||||
_animationController.forward();
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
// Fetch weight entries
|
||||
// Process weight entries
|
||||
BodyWeight weightProvider = Provider.of<BodyWeight>(context, listen: false);
|
||||
for (var entry in weightProvider.items) {
|
||||
final date = DateTime(entry.date.year, entry.date.month, entry.date.day);
|
||||
@@ -83,7 +83,7 @@ class _DashboardCalendarWidgetState extends State<DashboardCalendarWidget>
|
||||
_events[date].add('Body weight: ${entry.weight} kg');
|
||||
}
|
||||
|
||||
// Fetch workout sessions
|
||||
// Process workout sessions
|
||||
WorkoutPlans plans = Provider.of<WorkoutPlans>(context, listen: false);
|
||||
plans.fetchSessionData().then((entries) {
|
||||
for (var entry in entries['results']) {
|
||||
@@ -102,20 +102,17 @@ class _DashboardCalendarWidgetState extends State<DashboardCalendarWidget>
|
||||
}
|
||||
});
|
||||
|
||||
// Fetch nutritional plans
|
||||
// Process nutritional plans
|
||||
Nutrition nutritionProvider = Provider.of<Nutrition>(context, listen: false);
|
||||
for (var plan in nutritionProvider.items) {
|
||||
nutritionProvider.fetchAndSetLogs(plan).then((value) {
|
||||
//print(plan.logEntriesValues);
|
||||
for (var entry in plan.logEntriesValues.entries) {
|
||||
final date = DateTime(entry.key.year, entry.key.month, entry.key.day);
|
||||
if (!_events.containsKey(date)) {
|
||||
_events[date] = [];
|
||||
}
|
||||
|
||||
_events[date].add('Nutrition diary: ${entry.value.energy.toStringAsFixed(0)} kcal');
|
||||
for (var entry in plan.logEntriesValues.entries) {
|
||||
final date = DateTime(entry.key.year, entry.key.month, entry.key.day);
|
||||
if (!_events.containsKey(date)) {
|
||||
_events[date] = [];
|
||||
}
|
||||
});
|
||||
|
||||
_events[date].add('Nutrition diary: ${entry.value.energy.toStringAsFixed(0)} kcal');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -340,7 +337,7 @@ class _DashboardCalendarWidgetState extends State<DashboardCalendarWidget>
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(width: 0.5),
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
|
||||
child: ListTile(
|
||||
|
||||
@@ -47,12 +47,10 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
|
||||
Nutrition nutrition;
|
||||
NutritionalPlan plan;
|
||||
|
||||
Future<void> _refreshPlanEntries(BuildContext context) async {
|
||||
plan = Provider.of<Nutrition>(context, listen: false).currentPlan;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
plan = Provider.of<Nutrition>(context, listen: false).currentPlan;
|
||||
|
||||
return Card(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -61,36 +59,31 @@ class _DashboardNutritionWidgetState extends State<DashboardNutritionWidget> {
|
||||
AppLocalizations.of(context).nutritionalPlan,
|
||||
style: Theme.of(context).textTheme.headline4,
|
||||
),
|
||||
FutureBuilder(
|
||||
future: _refreshPlanEntries(context),
|
||||
builder: (context, snapshot) => snapshot.connectionState == ConnectionState.waiting
|
||||
? Container(height: 180, child: Center(child: CircularProgressIndicator()))
|
||||
: plan != null
|
||||
? Column(
|
||||
children: [
|
||||
Text(
|
||||
DateFormat.yMd().format(plan.creationDate),
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
TextButton(
|
||||
child: Text(
|
||||
plan.description,
|
||||
style: TextStyle(fontSize: 20),
|
||||
),
|
||||
onPressed: () {
|
||||
return Navigator.of(context)
|
||||
.pushNamed(NutritionalPlanScreen.routeName, arguments: plan);
|
||||
},
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.all(15),
|
||||
height: 180,
|
||||
child: NutritionalPlanPieChartWidget(plan.nutritionalValues),
|
||||
)
|
||||
],
|
||||
)
|
||||
: Text('You have no nutritional plans'),
|
||||
),
|
||||
plan != null
|
||||
? Column(
|
||||
children: [
|
||||
Text(
|
||||
DateFormat.yMd().format(plan.creationDate),
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
TextButton(
|
||||
child: Text(
|
||||
plan.description,
|
||||
style: TextStyle(fontSize: 20),
|
||||
),
|
||||
onPressed: () {
|
||||
return Navigator.of(context)
|
||||
.pushNamed(NutritionalPlanScreen.routeName, arguments: plan);
|
||||
},
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.all(15),
|
||||
height: 180,
|
||||
child: NutritionalPlanPieChartWidget(plan.nutritionalValues),
|
||||
)
|
||||
],
|
||||
)
|
||||
: Text('You have no nutritional plans'),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
@@ -127,12 +120,10 @@ class DashboardWeightWidget extends StatefulWidget {
|
||||
class _DashboardWeightWidgetState extends State<DashboardWeightWidget> {
|
||||
BodyWeight weightEntriesData;
|
||||
|
||||
Future<void> _refreshWeightEntries(BuildContext context) async {
|
||||
weightEntriesData = Provider.of<BodyWeight>(context, listen: false);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
weightEntriesData = Provider.of<BodyWeight>(context, listen: false);
|
||||
|
||||
return Card(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -141,39 +132,31 @@ class _DashboardWeightWidgetState extends State<DashboardWeightWidget> {
|
||||
AppLocalizations.of(context).weight,
|
||||
style: Theme.of(context).textTheme.headline4,
|
||||
),
|
||||
FutureBuilder(
|
||||
future: _refreshWeightEntries(context),
|
||||
builder: (context, snapshot) => snapshot.connectionState == ConnectionState.waiting
|
||||
? Container(
|
||||
height: 180,
|
||||
child: Center(child: CircularProgressIndicator()),
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
weightEntriesData.items.length > 0
|
||||
? Container(
|
||||
padding: EdgeInsets.all(15),
|
||||
height: 180,
|
||||
child: WeightChartWidget(weightEntriesData.items),
|
||||
)
|
||||
: Text('You have no weight entries'),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('Action one'),
|
||||
onPressed: () {},
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
TextButton(
|
||||
child: const Text('Action two'),
|
||||
onPressed: () {},
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
],
|
||||
),
|
||||
],
|
||||
Column(
|
||||
children: [
|
||||
weightEntriesData.items.length > 0
|
||||
? Container(
|
||||
padding: EdgeInsets.all(15),
|
||||
height: 180,
|
||||
child: WeightChartWidget(weightEntriesData.items),
|
||||
)
|
||||
: Text('You have no weight entries'),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('Action one'),
|
||||
onPressed: () {},
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
TextButton(
|
||||
child: const Text('Action two'),
|
||||
onPressed: () {},
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -197,14 +180,16 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
|
||||
WorkoutPlan _workoutPlan;
|
||||
var showDetail = false;
|
||||
|
||||
Future<void> _fetchWorkoutEntries(BuildContext context) async {
|
||||
_workoutPlan = Provider.of<WorkoutPlans>(context, listen: false).activePlan;
|
||||
_workoutPlan = await Provider.of<WorkoutPlans>(context, listen: false)
|
||||
.fetchAndSetFullWorkout(_workoutPlan.id);
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_workoutPlan = Provider.of<WorkoutPlans>(context, listen: false).activePlan;
|
||||
|
||||
return Card(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -213,60 +198,52 @@ class _DashboardWorkoutWidgetState extends State<DashboardWorkoutWidget> {
|
||||
AppLocalizations.of(context).labelWorkoutPlan,
|
||||
style: Theme.of(context).textTheme.headline4,
|
||||
),
|
||||
FutureBuilder(
|
||||
future: _fetchWorkoutEntries(context),
|
||||
builder: (context, snapshot) => snapshot.connectionState == ConnectionState.waiting
|
||||
? Center(
|
||||
child:
|
||||
Container(height: 180, child: Center(child: CircularProgressIndicator())),
|
||||
_workoutPlan != null
|
||||
? Column(children: [
|
||||
Text(
|
||||
DateFormat.yMd().format(_workoutPlan.creationDate),
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
TextButton(
|
||||
child: Text(
|
||||
_workoutPlan.description,
|
||||
style: TextStyle(fontSize: 20),
|
||||
),
|
||||
onPressed: () {
|
||||
return Navigator.of(context)
|
||||
.pushNamed(WorkoutPlanScreen.routeName, arguments: _workoutPlan);
|
||||
},
|
||||
),
|
||||
..._workoutPlan.days.map((workoutDay) {
|
||||
return Column(children: [
|
||||
const SizedBox(height: 10),
|
||||
showDetail == true
|
||||
? Text(
|
||||
workoutDay.description,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
)
|
||||
: Text(workoutDay.description),
|
||||
if (showDetail)
|
||||
...workoutDay.sets
|
||||
.map((set) => Text(set.exercises.map((e) => e.name).join(',')))
|
||||
.toList(),
|
||||
]);
|
||||
}).toList(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
TextButton(
|
||||
child: Text(AppLocalizations.of(context).toggleDetails),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
showDetail = !showDetail;
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
: _workoutPlan != null
|
||||
? Column(children: [
|
||||
Text(
|
||||
DateFormat.yMd().format(_workoutPlan.creationDate),
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
TextButton(
|
||||
child: Text(
|
||||
_workoutPlan.description,
|
||||
style: TextStyle(fontSize: 20),
|
||||
),
|
||||
onPressed: () {
|
||||
return Navigator.of(context)
|
||||
.pushNamed(WorkoutPlanScreen.routeName, arguments: _workoutPlan);
|
||||
},
|
||||
),
|
||||
..._workoutPlan.days.map((workoutDay) {
|
||||
return Column(children: [
|
||||
const SizedBox(height: 10),
|
||||
showDetail == true
|
||||
? Text(
|
||||
workoutDay.description,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
)
|
||||
: Text(workoutDay.description),
|
||||
if (showDetail)
|
||||
...workoutDay.sets
|
||||
.map((set) => Text(set.exercises.map((e) => e.name).join(',')))
|
||||
.toList(),
|
||||
]);
|
||||
}).toList(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
TextButton(
|
||||
child: Text(AppLocalizations.of(context).toggleDetails),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
showDetail = !showDetail;
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
])
|
||||
: Text('you have no workouts'),
|
||||
),
|
||||
])
|
||||
: Text('you have no workouts'),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -86,7 +86,6 @@ class WeightEntriesList extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
background: Container(
|
||||
//color: Theme.of(context).accentColor,
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: EdgeInsets.only(right: 20),
|
||||
margin: EdgeInsets.symmetric(
|
||||
@@ -98,13 +97,8 @@ class WeightEntriesList extends StatelessWidget {
|
||||
//color: Colors.white,
|
||||
),
|
||||
),
|
||||
//direction: DismissDirection.endToStart,
|
||||
child: Card(
|
||||
child: ListTile(
|
||||
//onTap: () => Navigator.of(context).pushNamed(
|
||||
// WorkoutPlanScreen.routeName,
|
||||
// arguments: currentPlan,
|
||||
//),
|
||||
onTap: () {},
|
||||
title: Text(DateFormat.yMd().format(currentEntry.date).toString()),
|
||||
subtitle: Text('${currentEntry.weight} kg'),
|
||||
|
||||
Reference in New Issue
Block a user