diff --git a/lib/models/nutrition/ingredient.dart b/lib/models/nutrition/ingredient.dart index 59a3460f..87684c46 100644 --- a/lib/models/nutrition/ingredient.dart +++ b/lib/models/nutrition/ingredient.dart @@ -18,6 +18,7 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:wger/helpers/json.dart'; import 'package:wger/models/nutrition/image.dart'; +import 'package:wger/models/nutrition/nutritional_values.dart'; part 'ingredient.g.dart'; @@ -91,4 +92,17 @@ class Ingredient { factory Ingredient.fromJson(Map json) => _$IngredientFromJson(json); Map toJson() => _$IngredientToJson(this); + + NutritionalValues get nutritionalValues { + return NutritionalValues.values( + energy * 1, + protein * 1, + carbohydrates * 1, + carbohydratesSugar * 1, + fat * 1, + fatSaturated * 1, + fibres * 1, + sodium * 1, + ); + } } diff --git a/lib/models/nutrition/log.dart b/lib/models/nutrition/log.dart index 730763cc..ac4aa845 100644 --- a/lib/models/nutrition/log.dart +++ b/lib/models/nutrition/log.dart @@ -83,21 +83,10 @@ class Log { /// Calculations NutritionalValues get nutritionalValues { // This is already done on the server. It might be better to read it from there. - final out = NutritionalValues(); - //final weight = amount; final weight = weightUnitObj == null ? amount : amount * weightUnitObj!.amount * weightUnitObj!.grams; - out.energy = ingredient.energy * weight / 100; - out.protein = ingredient.protein * weight / 100; - out.carbohydrates = ingredient.carbohydrates * weight / 100; - out.carbohydratesSugar = ingredient.carbohydratesSugar * weight / 100; - out.fat = ingredient.fat * weight / 100; - out.fatSaturated = ingredient.fatSaturated * weight / 100; - out.fibres = ingredient.fibres * weight / 100; - out.sodium = ingredient.sodium * weight / 100; - - return out; + return ingredient.nutritionalValues / (100 / weight); } } diff --git a/lib/models/nutrition/meal_item.dart b/lib/models/nutrition/meal_item.dart index d484283f..4bf10e94 100644 --- a/lib/models/nutrition/meal_item.dart +++ b/lib/models/nutrition/meal_item.dart @@ -72,6 +72,7 @@ class MealItem { Map toJson() => _$MealItemToJson(this); /// Calculations + /// TODO why does this not consider weightUnitObj ? should we do the same as Log.nutritionalValues here? NutritionalValues get nutritionalValues { // This is already done on the server. It might be better to read it from there. final out = NutritionalValues(); diff --git a/lib/widgets/dashboard/widgets.dart b/lib/widgets/dashboard/widgets.dart index 93297d4a..4d37b167 100644 --- a/lib/widgets/dashboard/widgets.dart +++ b/lib/widgets/dashboard/widgets.dart @@ -42,6 +42,7 @@ import 'package:wger/widgets/measurements/charts.dart'; import 'package:wger/widgets/measurements/forms.dart'; import 'package:wger/widgets/nutrition/charts.dart'; import 'package:wger/widgets/nutrition/forms.dart'; +import 'package:wger/widgets/nutrition/helpers.dart'; import 'package:wger/widgets/weight/forms.dart'; import 'package:wger/widgets/workouts/forms.dart'; @@ -83,23 +84,7 @@ class _DashboardNutritionWidgetState extends State { //textAlign: TextAlign.left, ), ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - mainAxisSize: MainAxisSize.min, - children: [ - MutedText( - '${AppLocalizations.of(context).energyShort} ${meal.plannedNutritionalValues.energy.toStringAsFixed(0)}${AppLocalizations.of(context).kcal}'), - const MutedText(' / '), - MutedText( - '${AppLocalizations.of(context).proteinShort} ${meal.plannedNutritionalValues.protein.toStringAsFixed(0)}${AppLocalizations.of(context).g}'), - const MutedText(' / '), - MutedText( - '${AppLocalizations.of(context).carbohydratesShort} ${meal.plannedNutritionalValues.carbohydrates.toStringAsFixed(0)}${AppLocalizations.of(context).g}'), - const MutedText(' / '), - MutedText( - '${AppLocalizations.of(context).fatShort} ${meal.plannedNutritionalValues.fat.toStringAsFixed(0)}${AppLocalizations.of(context).g} '), - ], - ), + MutedText(getShortNutritionValues(meal.plannedNutritionalValues, context)), IconButton( icon: const Icon(Icons.history_edu), color: wgerPrimaryButtonColor, diff --git a/lib/widgets/nutrition/forms.dart b/lib/widgets/nutrition/forms.dart index 6bf3fcb0..f5b2e7c1 100644 --- a/lib/widgets/nutrition/forms.dart +++ b/lib/widgets/nutrition/forms.dart @@ -23,11 +23,14 @@ import 'package:wger/exceptions/http_exception.dart'; import 'package:wger/helpers/consts.dart'; import 'package:wger/helpers/json.dart'; import 'package:wger/helpers/ui.dart'; +import 'package:wger/models/nutrition/ingredient.dart'; +import 'package:wger/models/nutrition/log.dart'; import 'package:wger/models/nutrition/meal.dart'; import 'package:wger/models/nutrition/meal_item.dart'; import 'package:wger/models/nutrition/nutritional_plan.dart'; import 'package:wger/providers/nutrition.dart'; import 'package:wger/screens/nutritional_plan_screen.dart'; +import 'package:wger/widgets/nutrition/helpers.dart'; import 'package:wger/widgets/nutrition/widgets.dart'; class MealForm extends StatelessWidget { @@ -113,23 +116,66 @@ class MealForm extends StatelessWidget { } } -class MealItemForm extends StatelessWidget { - final Meal _meal; - late final MealItem _mealItem; - final List _listMealItems; - late String _barcode; - late bool _test; +Widget MealItemForm(Meal meal, List recent, [String? barcode, bool? test]) { + return IngredientForm( + // TODO we use planId 0 here cause we don't have one and we don't need it I think? + recent: recent.map((e) => Log.fromMealItem(e, 0, e.mealId)).toList(), + onSave: (BuildContext context, MealItem mealItem, DateTime? dt) { + mealItem.mealId = meal.id!; + Provider.of(context, listen: false).addMealItem(mealItem, meal); + }, + barcode: barcode ?? '', + test: test ?? false, + withDate: false); +} +Widget IngredientLogForm(NutritionalPlan plan) { + return IngredientForm( + recent: plan.diaryEntries, + onSave: (BuildContext context, MealItem mealItem, DateTime? dt) { + Provider.of(context, listen: false) + .logIngredientToDiary(mealItem, plan.id!, dt); + }, + withDate: true); +} + +/// IngredientForm is a form that lets the user pick an ingredient (and amount) to +/// log to the diary or to add to a meal. +class IngredientForm extends StatefulWidget { + final Function(BuildContext context, MealItem mealItem, DateTime? dt) onSave; + final List recent; + final bool withDate; + final String barcode; + final bool test; + + const IngredientForm({ + required this.recent, + required this.onSave, + required this.withDate, + this.barcode = '', + this.test = false, + }); + + @override + State createState() => IngredientFormState(); +} + +class IngredientFormState extends State { final _form = GlobalKey(); - final _ingredientIdController = TextEditingController(); final _ingredientController = TextEditingController(); + final _ingredientIdController = TextEditingController(); final _amountController = TextEditingController(); + final _dateController = TextEditingController(); // optional + final _timeController = TextEditingController(); // optional + final _mealItem = MealItem.empty(); - MealItemForm(this._meal, this._listMealItems, [mealItem, code, test]) { - _mealItem = mealItem ?? MealItem.empty(); - _test = test ?? false; - _barcode = code ?? ''; - _mealItem.mealId = _meal.id!; + bool validIngredientId = false; + @override + void initState() { + super.initState(); + final now = DateTime.now(); + _dateController.text = toDate(now)!; + _timeController.text = timeToString(TimeOfDay.fromDateTime(now))!; } TextEditingController get ingredientIdController => _ingredientIdController; @@ -139,114 +185,6 @@ class MealItemForm extends StatelessWidget { @override Widget build(BuildContext context) { final String unit = AppLocalizations.of(context).g; - return Container( - margin: const EdgeInsets.all(20), - child: Form( - key: _form, - child: Column( - children: [ - IngredientTypeahead( - _ingredientIdController, - _ingredientController, - barcode: _barcode, - test: _test, - ), - TextFormField( - key: const Key('field-weight'), - decoration: InputDecoration(labelText: AppLocalizations.of(context).weight), - controller: _amountController, - keyboardType: TextInputType.number, - onFieldSubmitted: (_) {}, - onSaved: (newValue) { - _mealItem.amount = double.parse(newValue!); - }, - validator: (value) { - try { - double.parse(value!); - } catch (error) { - return AppLocalizations.of(context).enterValidNumber; - } - return null; - }, - ), - ElevatedButton( - key: const Key(SUBMIT_BUTTON_KEY_NAME), - child: Text(AppLocalizations.of(context).save), - onPressed: () async { - if (!_form.currentState!.validate()) { - return; - } - _form.currentState!.save(); - _mealItem.ingredientId = int.parse(_ingredientIdController.text); - - try { - Provider.of(context, listen: false) - .addMealItem(_mealItem, _meal); - } on WgerHttpException catch (error) { - showHttpExceptionErrorDialog(error, context); - } catch (error) { - showErrorDialog(error, context); - } - Navigator.of(context).pop(); - }, - ), - if (_listMealItems.isNotEmpty) const SizedBox(height: 10.0), - Container( - padding: const EdgeInsets.all(10.0), - child: Text(AppLocalizations.of(context).recentlyUsedIngredients), - ), - Expanded( - child: ListView.builder( - itemCount: _listMealItems.length, - shrinkWrap: true, - itemBuilder: (context, index) { - return Card( - child: ListTile( - onTap: () { - _ingredientController.text = _listMealItems[index].ingredient.name; - _ingredientIdController.text = - _listMealItems[index].ingredient.id.toString(); - _amountController.text = _listMealItems[index].amount.toStringAsFixed(0); - _mealItem.ingredientId = _listMealItems[index].ingredientId; - _mealItem.amount = _listMealItems[index].amount; - }, - title: Text(_listMealItems[index].ingredient.name), - subtitle: Text('${_listMealItems[index].amount.toStringAsFixed(0)}$unit'), - trailing: const Icon(Icons.copy), - ), - ); - }, - ), - ) - ], - ), - ), - ); - } -} - -class IngredientLogForm extends StatelessWidget { - late MealItem _mealItem; - final NutritionalPlan _plan; - - final _form = GlobalKey(); - final _ingredientController = TextEditingController(); - final _ingredientIdController = TextEditingController(); - final _amountController = TextEditingController(); - final _dateController = TextEditingController(); - final _timeController = TextEditingController(); - - IngredientLogForm(this._plan) { - _mealItem = MealItem.empty(); - final now = DateTime.now(); - _dateController.text = toDate(now)!; - _timeController.text = timeToString(TimeOfDay.fromDateTime(now))!; - } - - @override - Widget build(BuildContext context) { - final diaryEntries = _plan.diaryEntries; - final String unit = AppLocalizations.of(context).g; return Container( margin: const EdgeInsets.all(20), @@ -257,84 +195,142 @@ class IngredientLogForm extends StatelessWidget { IngredientTypeahead( _ingredientIdController, _ingredientController, - ), - TextFormField( - decoration: InputDecoration(labelText: AppLocalizations.of(context).weight), - controller: _amountController, - keyboardType: TextInputType.number, - onFieldSubmitted: (_) {}, - onSaved: (newValue) { - _mealItem.amount = double.parse(newValue!); - }, - validator: (value) { - try { - double.parse(value!); - } catch (error) { - return AppLocalizations.of(context).enterValidNumber; - } - return null; - }, + barcode: widget.barcode, + test: widget.test, ), Row( children: [ Expanded( child: TextFormField( - readOnly: true, - // Stop keyboard from appearing - decoration: InputDecoration( - labelText: AppLocalizations.of(context).date, - // suffixIcon: const Icon(Icons.calendar_today), - ), - enableInteractiveSelection: false, - controller: _dateController, - onTap: () async { - // Show Date Picker Here - final pickedDate = await showDatePicker( - context: context, - initialDate: DateTime.now(), - firstDate: DateTime(DateTime.now().year - 10), - lastDate: DateTime.now(), - ); - - if (pickedDate != null) { - _dateController.text = toDate(pickedDate)!; - } - }, - onSaved: (newValue) { - _dateController.text = newValue!; - }, - ), - ), - Expanded( - child: TextFormField( - key: const Key('field-time'), - decoration: InputDecoration( - labelText: AppLocalizations.of(context).time, - //suffixIcon: const Icon(Icons.punch_clock) - ), - controller: _timeController, - onTap: () async { - // Stop keyboard from appearing - FocusScope.of(context).requestFocus(FocusNode()); - - // Open time picker - final pickedTime = await showTimePicker( - context: context, - initialTime: stringToTime(_timeController.text), - ); - if (pickedTime != null) { - _timeController.text = timeToString(pickedTime)!; - } - }, - onSaved: (newValue) { - _timeController.text = newValue!; - }, + key: const Key('field-weight'), // needed ? + decoration: InputDecoration(labelText: AppLocalizations.of(context).weight), + controller: _amountController, + keyboardType: TextInputType.number, onFieldSubmitted: (_) {}, + onChanged: (value) { + setState(() { + final v = double.tryParse(value); + if (v != null) { + _mealItem.amount = v; + } + }); + }, + onSaved: (value) { + _mealItem.amount = double.parse(value!); + }, + validator: (value) { + try { + double.parse(value!); + } catch (error) { + return AppLocalizations.of(context).enterValidNumber; + } + return null; + }, ), ), + if (widget.withDate) + Expanded( + child: TextFormField( + readOnly: true, + // Stop keyboard from appearing + decoration: InputDecoration( + labelText: AppLocalizations.of(context).date, + // suffixIcon: const Icon(Icons.calendar_today), + ), + enableInteractiveSelection: false, + controller: _dateController, + onTap: () async { + // Show Date Picker Here + final pickedDate = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime(DateTime.now().year - 10), + lastDate: DateTime.now(), + ); + + if (pickedDate != null) { + _dateController.text = toDate(pickedDate)!; + } + }, + onSaved: (newValue) { + _dateController.text = newValue!; + }, + ), + ), + if (widget.withDate) + Expanded( + child: TextFormField( + key: const Key('field-time'), + decoration: InputDecoration( + labelText: AppLocalizations.of(context).time, + //suffixIcon: const Icon(Icons.punch_clock) + ), + controller: _timeController, + onTap: () async { + // Stop keyboard from appearing + FocusScope.of(context).requestFocus(FocusNode()); + + // Open time picker + final pickedTime = await showTimePicker( + context: context, + initialTime: stringToTime(_timeController.text), + ); + if (pickedTime != null) { + _timeController.text = timeToString(pickedTime)!; + } + }, + onSaved: (newValue) { + _timeController.text = newValue!; + }, + onFieldSubmitted: (_) {}, + ), + ), ], ), + if (validIngredientId) + Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Text( + 'Macros preview', + style: Theme.of(context).textTheme.titleMedium, + ), + FutureBuilder( + future: Provider.of(context, listen: false) + .fetchIngredient(_mealItem.ingredientId), + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.hasData) { + _mealItem.ingredient = snapshot.data!; + return ListTile( + leading: IngredientAvatar(ingredient: _mealItem.ingredient), + title: + Text(getShortNutritionValues(_mealItem.nutritionalValues, context)), + ); + } else if (snapshot.hasError) { + return Padding( + padding: const EdgeInsets.only(top: 16), + child: Text( + 'Ingredient lookup error: ${snapshot.error}', + style: const TextStyle(color: Colors.red), + ), + ); + } else { + return const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator(), + ); + } + }, + ), + ], + ), + ), ElevatedButton( + key: const Key( + SUBMIT_BUTTON_KEY_NAME), // needed? mealItemForm had it, but not ingredientlogform + child: Text(AppLocalizations.of(context).save), onPressed: () async { if (!_form.currentState!.validate()) { @@ -347,8 +343,7 @@ class IngredientLogForm extends StatelessWidget { var date = DateTime.parse(_dateController.text); final tod = stringToTime(_timeController.text); date = DateTime(date.year, date.month, date.day, tod.hour, tod.minute); - Provider.of(context, listen: false) - .logIngredientToDiary(_mealItem, _plan.id!, date); + widget.onSave(context, _mealItem, date); } on WgerHttpException catch (error) { showHttpExceptionErrorDialog(error, context); } catch (error) { @@ -357,27 +352,33 @@ class IngredientLogForm extends StatelessWidget { Navigator.of(context).pop(); }, ), - if (diaryEntries.isNotEmpty) const SizedBox(height: 10.0), + if (widget.recent.isNotEmpty) const SizedBox(height: 10.0), Container( padding: const EdgeInsets.all(10.0), child: Text(AppLocalizations.of(context).recentlyUsedIngredients), ), Expanded( child: ListView.builder( - itemCount: diaryEntries.length, + itemCount: widget.recent.length, shrinkWrap: true, itemBuilder: (context, index) { return Card( child: ListTile( onTap: () { - _ingredientController.text = diaryEntries[index].ingredient.name; - _ingredientIdController.text = diaryEntries[index].ingredient.id.toString(); - _amountController.text = diaryEntries[index].amount.toStringAsFixed(0); - _mealItem.ingredientId = diaryEntries[index].ingredientId; - _mealItem.amount = diaryEntries[index].amount; + _ingredientController.text = widget.recent[index].ingredient.name; + _ingredientIdController.text = + widget.recent[index].ingredient.id.toString(); + _amountController.text = widget.recent[index].amount.toStringAsFixed(0); + setState(() { + _mealItem.ingredientId = widget.recent[index].ingredientId; + _mealItem.amount = widget.recent[index].amount; + validIngredientId = true; + }); }, - title: Text(_plan.diaryEntries[index].ingredient.name), - subtitle: Text('${diaryEntries[index].amount.toStringAsFixed(0)}$unit'), + title: Text( + '${widget.recent[index].ingredient.name} (${widget.recent[index].amount.toStringAsFixed(0)}$unit)'), + subtitle: Text(getShortNutritionValues( + widget.recent[index].ingredient.nutritionalValues, context)), trailing: const Icon(Icons.copy), ), ); diff --git a/lib/widgets/nutrition/helpers.dart b/lib/widgets/nutrition/helpers.dart index 222e8765..766386b1 100644 --- a/lib/widgets/nutrition/helpers.dart +++ b/lib/widgets/nutrition/helpers.dart @@ -40,3 +40,12 @@ List getMutedNutritionalValues(NutritionalValues values, BuildContext co textAlign: TextAlign.right, ), ]; + +String getShortNutritionValues(NutritionalValues values, BuildContext context) { + final loc = AppLocalizations.of(context); + final e = '${loc.energyShort} ${loc.kcalValue(values.energy.toStringAsFixed(0))}'; + final p = '${loc.proteinShort} ${loc.gValue(values.protein.toStringAsFixed(0))}'; + final c = '${loc.carbohydratesShort} ${loc.gValue(values.carbohydrates.toStringAsFixed(0))}'; + final f = '${loc.fatShort} ${loc.gValue(values.fat.toStringAsFixed(0))}'; + return '$e / $p / $c / $f'; +} diff --git a/lib/widgets/nutrition/meal.dart b/lib/widgets/nutrition/meal.dart index 3048bed0..253fde07 100644 --- a/lib/widgets/nutrition/meal.dart +++ b/lib/widgets/nutrition/meal.dart @@ -20,13 +20,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import 'package:wger/helpers/consts.dart'; -import 'package:wger/helpers/misc.dart'; import 'package:wger/models/nutrition/log.dart'; import 'package:wger/models/nutrition/meal.dart'; import 'package:wger/models/nutrition/meal_item.dart'; import 'package:wger/providers/nutrition.dart'; import 'package:wger/screens/form_screen.dart'; -import 'package:wger/widgets/core/core.dart'; import 'package:wger/widgets/nutrition/charts.dart'; import 'package:wger/widgets/nutrition/forms.dart'; import 'package:wger/widgets/nutrition/helpers.dart'; @@ -208,18 +206,7 @@ class MealItemWidget extends StatelessWidget { final values = _item.nutritionalValues; return ListTile( - leading: _item.ingredient.image != null - ? GestureDetector( - child: CircleAvatar(backgroundImage: NetworkImage(_item.ingredient.image!.image)), - onTap: () async { - if (_item.ingredient.image!.objectUrl != '') { - return launchURL(_item.ingredient.image!.objectUrl, context); - } else { - return; - } - }, - ) - : const CircleIconAvatar(Icon(Icons.image, color: Colors.grey)), + leading: IngredientAvatar(ingredient: _item.ingredient), title: Text( '${_item.amount.toStringAsFixed(0)}$unit ${_item.ingredient.name}', overflow: TextOverflow.ellipsis, @@ -273,18 +260,7 @@ class LogDiaryItemWidget extends StatelessWidget { final values = _item.nutritionalValues; return ListTile( - leading: _item.ingredient.image != null - ? GestureDetector( - child: CircleAvatar(backgroundImage: NetworkImage(_item.ingredient.image!.image)), - onTap: () async { - if (_item.ingredient.image!.objectUrl != '') { - return launchURL(_item.ingredient.image!.objectUrl, context); - } else { - return; - } - }, - ) - : const CircleIconAvatar(Icon(Icons.image, color: Colors.grey)), + leading: IngredientAvatar(ingredient: _item.ingredient), title: Text( '${_item.amount.toStringAsFixed(0)}$unit ${_item.ingredient.name}', overflow: TextOverflow.ellipsis, diff --git a/lib/widgets/nutrition/widgets.dart b/lib/widgets/nutrition/widgets.dart index c307bb0e..0cc2d24c 100644 --- a/lib/widgets/nutrition/widgets.dart +++ b/lib/widgets/nutrition/widgets.dart @@ -25,9 +25,11 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:wger/helpers/consts.dart'; +import 'package:wger/helpers/misc.dart'; import 'package:wger/helpers/platform.dart'; import 'package:wger/helpers/ui.dart'; import 'package:wger/models/exercises/ingredient_api.dart'; +import 'package:wger/models/nutrition/ingredient.dart'; import 'package:wger/models/nutrition/log.dart'; import 'package:wger/models/nutrition/nutritional_plan.dart'; import 'package:wger/providers/nutrition.dart'; @@ -335,3 +337,23 @@ class NutritionDiaryEntry extends StatelessWidget { ); } } + +class IngredientAvatar extends StatelessWidget { + final Ingredient ingredient; + + const IngredientAvatar({super.key, required this.ingredient}); + + @override + Widget build(BuildContext context) { + return ingredient.image != null + ? GestureDetector( + child: CircleAvatar(backgroundImage: NetworkImage(ingredient.image!.image)), + onTap: () async { + if (ingredient.image!.objectUrl != '') { + return launchURL(ingredient.image!.objectUrl, context); + } + }, + ) + : const CircleIconAvatar(Icon(Icons.image, color: Colors.grey)); + } +} diff --git a/test/nutrition/nutritional_meal_item_form_test.dart b/test/nutrition/nutritional_meal_item_form_test.dart index 50561722..aa739ba1 100644 --- a/test/nutrition/nutritional_meal_item_form_test.dart +++ b/test/nutrition/nutritional_meal_item_form_test.dart @@ -101,7 +101,7 @@ void main() { home: Scaffold( body: Scrollable( viewportBuilder: (BuildContext context, ViewportOffset position) => - MealItemForm(meal, const [], null, code, test), + MealItemForm(meal, const [], code, test), ), ), routes: { @@ -213,7 +213,7 @@ void main() { testWidgets('confirm found ingredient dialog', (WidgetTester tester) async { await tester.pumpWidget(createMealItemFormScreen(meal1, '123', true)); - final MealItemForm formScreen = tester.widget(find.byType(MealItemForm)); + final IngredientFormState formState = tester.state(find.byType(IngredientForm)); await tester.tap(find.byKey(const Key('scan-button'))); await tester.pumpAndSettle(); @@ -223,7 +223,7 @@ void main() { await tester.tap(find.byKey(const Key('found-dialog-confirm-button'))); await tester.pumpAndSettle(); - expect(formScreen.ingredientIdController.text, '1'); + expect(formState.ingredientIdController.text, '1'); }); testWidgets('close found ingredient dialog', (WidgetTester tester) async { @@ -293,7 +293,7 @@ void main() { (WidgetTester tester) async { await tester.pumpWidget(createMealItemFormScreen(meal1, '123', true)); - final MealItemForm formScreen = tester.widget(find.byType(MealItemForm)); + final IngredientFormState formState = tester.state(find.byType(IngredientForm)); await tester.tap(find.byKey(const Key('scan-button'))); await tester.pumpAndSettle(); @@ -303,7 +303,7 @@ void main() { await tester.tap(find.byKey(const Key('found-dialog-confirm-button'))); await tester.pumpAndSettle(); - expect(formScreen.ingredientIdController.text, '1'); + expect(formState.ingredientIdController.text, '1'); await tester.enterText(find.byKey(const Key('field-weight')), '2'); await tester.pumpAndSettle(); @@ -313,7 +313,7 @@ void main() { await tester.tap(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME))); await tester.pumpAndSettle(); - expect(formScreen.mealItem.amount, 2); + expect(formState.mealItem.amount, 2); verify(mockNutrition.addMealItem(any, meal1)); });