Add nutritional diary data to calendar

This commit is contained in:
Roland Geider
2021-01-16 13:44:19 +01:00
parent ffcf0f5ea4
commit b8c159c841
8 changed files with 81 additions and 49 deletions

View File

@@ -5,11 +5,7 @@ import 'package:wger/helpers/json.dart';
part 'session.g.dart';
class Impression {
static const bad = 1;
static const neutral = 2;
static const good = 3;
}
const impressionMap = {1: 'bad', 2: 'neutral', 3: 'good'};
@JsonSerializable()
class WorkoutSession {
@@ -43,4 +39,8 @@ class WorkoutSession {
// Boilerplate
factory WorkoutSession.fromJson(Map<String, dynamic> json) => _$WorkoutSessionFromJson(json);
Map<String, dynamic> toJson() => _$WorkoutSessionToJson(this);
get impressionAsString {
return impressionMap[impression];
}
}

View File

@@ -48,8 +48,8 @@ class BodyWeight extends WgerBaseProvider with ChangeNotifier {
}
_entries = loadedEntries;
return _entries;
notifyListeners();
return _entries;
}
Future<WeightEntry> addEntry(WeightEntry entry) async {

View File

@@ -69,7 +69,7 @@ class Nutrition extends WgerBaseProvider with ChangeNotifier {
return null;
}
Future<void> fetchAndSetPlans() async {
Future<List<NutritionalPlan>> fetchAndSetPlans() async {
final data = await fetch(makeUrl(_nutritionalPlansInfoPath));
final List<NutritionalPlan> loadedPlans = [];
for (final entry in data['results']) {
@@ -78,6 +78,7 @@ class Nutrition extends WgerBaseProvider with ChangeNotifier {
_plans = loadedPlans;
notifyListeners();
return loadedPlans;
}
Future<NutritionalPlan> fetchAndSetPlan(int planId) async {
@@ -143,9 +144,9 @@ class Nutrition extends WgerBaseProvider with ChangeNotifier {
}
/// Adds a meal item to a meal
Future<MealItem> addMealIteam(MealItem mealItem, int mealId) async {
Future<MealItem> addMealItem(MealItem mealItem, int mealId) async {
var meal = findMealById(mealId);
final data = await add(mealItem.toJson(), _mealItemPath);
final data = await add(mealItem.toJson(), makeUrl(_mealItemPath));
mealItem = MealItem.fromJson(data);
mealItem.ingredientObj = await fetchIngredient(mealItem.ingredientId);

View File

@@ -53,7 +53,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
DashboardWeightWidget(context: context),
Container(
height: 650,
child: DashboardCalendarWidget(title: 'Table Calendar Demo'),
child: DashboardCalendarWidget(title: 'Calendar'),
),
Container(
child: Align(

View File

@@ -15,13 +15,18 @@
* 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 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:wger/helpers/json.dart';
import 'package:wger/models/workouts/session.dart';
import 'package:wger/providers/body_weight.dart';
import 'package:wger/providers/nutrition.dart';
import 'package:wger/providers/workout_plans.dart';
import 'package:wger/theme/theme.dart';
// Example holidays
final Map<DateTime, List> _holidays = {
@@ -76,7 +81,7 @@ class _DashboardCalendarWidgetState extends State<DashboardCalendarWidget>
_events[date] = [];
}
_events[date].add('${entry.weight} kg');
_events[date].add('Body weight: ${entry.weight} kg');
}
});
@@ -90,7 +95,32 @@ class _DashboardCalendarWidgetState extends State<DashboardCalendarWidget>
_events[date] = [];
}
_events[date].add('Workout session ${session.impression}');
var time = '';
if (session.timeStart != null && session.timeEnd != null) {
time = '(${timeToString(session.timeStart)} - ${timeToString(session.timeEnd)})';
}
_events[date].add('Workout session: ${session.impressionAsString} $time');
}
});
// Fetch nutritional plans
//
// TODO: E/flutter ( 1702): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: A Nutrition was used after being disposed.
Nutrition nutrition = Provider.of<Nutrition>(context, listen: false);
nutrition.fetchAndSetPlans().then((nutritionalPlans) {
for (var plan in nutritionalPlans) {
nutrition.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');
}
});
}
});
});
@@ -104,39 +134,36 @@ class _DashboardCalendarWidgetState extends State<DashboardCalendarWidget>
}
void _onDaySelected(DateTime day, List events, List holidays) {
print('CALLBACK: _onDaySelected');
log('CALLBACK: _onDaySelected');
setState(() {
_selectedEvents = events;
});
}
void _onVisibleDaysChanged(DateTime first, DateTime last, CalendarFormat format) {
print('CALLBACK: _onVisibleDaysChanged');
log('CALLBACK: _onVisibleDaysChanged');
}
void _onCalendarCreated(DateTime first, DateTime last, CalendarFormat format) {
print('CALLBACK: _onCalendarCreated');
log('CALLBACK: _onCalendarCreated');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
// Switch out 2 lines below to play with TableCalendar's settings
//-----------------------
_buildTableCalendar(),
//_buildTableCalendarWithBuilders(),
const SizedBox(height: 8.0),
_buildButtons(),
const SizedBox(height: 8.0),
Expanded(child: _buildEventList()),
],
),
return Column(
mainAxisSize: MainAxisSize.max,
children: [
const SizedBox(height: 8.0),
Text(widget.title, style: Theme.of(context).textTheme.headline6),
// Switch out 2 lines below to play with TableCalendar's settings
//-----------------------
_buildTableCalendar(),
//_buildTableCalendarWithBuilders(),
const SizedBox(height: 8.0),
_buildButtons(),
const SizedBox(height: 8.0),
Expanded(child: _buildEventList()),
],
);
}
@@ -150,7 +177,7 @@ class _DashboardCalendarWidgetState extends State<DashboardCalendarWidget>
holidays: _holidays,
startingDayOfWeek: StartingDayOfWeek.monday,
calendarStyle: CalendarStyle(
selectedColor: Colors.deepOrange[400],
selectedColor: wgerSecondaryColor,
todayColor: Colors.deepOrange[200],
markersColor: Colors.brown[700],
outsideDaysVisible: false,
@@ -314,18 +341,20 @@ class _DashboardCalendarWidgetState extends State<DashboardCalendarWidget>
Widget _buildEventList() {
return ListView(
children: _selectedEvents
.map((event) => Container(
width: double.infinity,
decoration: BoxDecoration(
border: Border.all(width: 0.8),
borderRadius: BorderRadius.circular(12.0),
),
margin: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
child: ListTile(
title: Text(event.toString()),
onTap: () => print('$event tapped!'),
),
))
.map(
(event) => Container(
width: double.infinity,
decoration: BoxDecoration(
border: Border.all(width: 0.5),
borderRadius: BorderRadius.circular(12.0),
),
margin: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
child: ListTile(
title: Text(event.toString()),
onTap: () => print('$event tapped!'),
),
),
)
.toList(),
);
/*

View File

@@ -178,7 +178,7 @@ class MealItemForm extends StatelessWidget {
try {
mealItem.meal = meal.id;
Provider.of<Nutrition>(context, listen: false).addMealIteam(mealItem, meal.id);
Provider.of<Nutrition>(context, listen: false).addMealItem(mealItem, meal.id);
} on WgerHttpException catch (error) {
showHttpExceptionErrorDialog(error, context);
} catch (error) {

View File

@@ -134,7 +134,7 @@ class DismissibleMealHeader extends StatelessWidget {
width: double.infinity,
decoration: BoxDecoration(color: Colors.black12),
padding: const EdgeInsets.all(10),
child: Text(_meal.time.format(context)),
child: _meal.time != null ? Text(_meal.time.format(context)) : Text('aaaa'),
),
secondaryBackground: Container(
color: Theme.of(context).accentColor,

View File

@@ -18,6 +18,7 @@
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:wger/locale/locales.dart';
import 'package:wger/models/nutrition/nutritional_plan.dart';
import 'package:wger/models/nutrition/nutritrional_values.dart';
@@ -56,7 +57,8 @@ class NutritionalPlanDetailWidget extends StatelessWidget {
style: Theme.of(context).textTheme.headline5,
),
),
..._nutritionalPlan.meals.map((meal) => MealWidget(meal)).toList(),
if (_nutritionalPlan.meals.length > 0)
..._nutritionalPlan.meals.map((meal) => MealWidget(meal)).toList(),
ElevatedButton(
child: Text(AppLocalizations.of(context).add),
onPressed: () {
@@ -169,7 +171,7 @@ class NutritionDiaryEntry extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 8),
child: Column(
children: [
Text(DefaultMaterialLocalizations().formatMediumDate(date).toString()),
Text(DateFormat.yMd().format(date).toString()),
Text(values.energy.toStringAsFixed(0)),
Text(values.protein.toStringAsFixed(0)),
Text(values.carbohydrates.toStringAsFixed(0)),