diff --git a/lib/models/nutrition/nutritional_plan.dart b/lib/models/nutrition/nutritional_plan.dart index 4318f07e7..6857ea5a3 100644 --- a/lib/models/nutrition/nutritional_plan.dart +++ b/lib/models/nutrition/nutritional_plan.dart @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +import 'dart:collection'; import 'package:collection/collection.dart'; import 'package:flutter/widgets.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -226,15 +227,25 @@ class NutritionalPlan { /// returns diary entries /// deduped by the combination of amount and ingredient ID List get dedupDiaryEntries { - final out = []; + //Get unique and sort by frequency + const Duration recentWindow = Duration(days: -90); + var uniqueLogs = {}; for (final log in diaryEntries) { - final found = out.firstWhereOrNull( - (e) => e.amount == log.amount && e.ingredientId == log.ingredientId, - ); - if (found == null) { - out.add(log); - } + final int howMany = diaryEntries + .where((diaryEntries) => + diaryEntries.ingredientId == log.ingredientId && + diaryEntries.amount == log.amount && + diaryEntries.datetime.isAfter(DateTime.now().add(recentWindow))) + .length; + //Padding allows for sorting string as if number + final String howManyPadded = howMany.toString().padLeft(10, '0'); + final uniqueAndCountString = '${howManyPadded}_${log.ingredientId}_${log.amount}'; + uniqueLogs[uniqueAndCountString] = log; } + + final sortedByFrequency = SplayTreeMap.from(uniqueLogs, (b, a) => a.compareTo(b)); + final out = sortedByFrequency.values.toList(); + return out; } diff --git a/lib/widgets/nutrition/forms.dart b/lib/widgets/nutrition/forms.dart index 60d329674..d5e3bfeab 100644 --- a/lib/widgets/nutrition/forms.dart +++ b/lib/widgets/nutrition/forms.dart @@ -141,6 +141,7 @@ Widget MealItemForm( Widget IngredientLogForm(NutritionalPlan plan) { return IngredientForm( + allDiaryEntries: plan.diaryEntries, recent: plan.dedupDiaryEntries, onSave: (BuildContext context, MealItem mealItem, DateTime? dt) { Provider.of(context, listen: false) @@ -166,6 +167,7 @@ class IngredientForm extends StatefulWidget { final bool withDate; final String barcode; final bool test; + final List? allDiaryEntries; const IngredientForm({ required this.recent, @@ -173,6 +175,7 @@ class IngredientForm extends StatefulWidget { required this.withDate, this.barcode = '', this.test = false, + this.allDiaryEntries, }); @override @@ -331,7 +334,6 @@ class IngredientFormState extends State { onTap: () async { // Stop keyboard from appearing FocusScope.of(context).requestFocus(FocusNode()); - // Open time picker final pickedTime = await showTimePicker( context: context, @@ -439,11 +441,13 @@ class IngredientFormState extends State { ); } + const Duration recentWindow = Duration(days: -90); return Card( child: ListTile( onTap: select, title: Text( - '${suggestions[index].ingredient.name} (${suggestions[index].amount.toStringAsFixed(0)}$unit)', + '${widget.allDiaryEntries?.where((diaryEntries) => diaryEntries.ingredientId == suggestions[index].ingredientId && diaryEntries.amount == suggestions[index].amount && diaryEntries.datetime.isAfter(DateTime.now().add(recentWindow))).length} x ' + '${suggestions[index].ingredient.name} (${suggestions[index].amount.toStringAsFixed(0)}$unit) ', ), subtitle: Text(getShortNutritionValues( suggestions[index].ingredient.nutritionalValues,