From 61f5ef70bafc3e987701df9b1326e40541d3aed0 Mon Sep 17 00:00:00 2001 From: Ketan Choyal Date: Fri, 15 Mar 2024 14:25:30 -0400 Subject: [PATCH] Fixed some bugs for add recipe feature --- .../add_calories/view/add_calories.form.dart | 27 + .../add_recipe/bloc/add_recipe_bloc.dart | 1 + .../add_recipe/view/add_recipe.form.dart | 478 ++++++++++-------- .../add_recipe/view/add_recipe.page.dart | 1 + .../add_recipe/view/add_recipe.view.dart | 1 + lib/ui/views/home/view/home.view.dart | 19 - 6 files changed, 294 insertions(+), 233 deletions(-) diff --git a/lib/ui/views/add_calories/view/add_calories.form.dart b/lib/ui/views/add_calories/view/add_calories.form.dart index f3836e6..5fbdd99 100644 --- a/lib/ui/views/add_calories/view/add_calories.form.dart +++ b/lib/ui/views/add_calories/view/add_calories.form.dart @@ -100,6 +100,33 @@ class _AddCaloriesForm extends StatelessWidget { ? const Text('Unmodify Nutrition Values') : const Text('Modify Nutrition Values'), ), + // ListView.builder( + // shrinkWrap: true, + // itemCount: food.incredients?.length ?? 0, + // itemBuilder: (BuildContext context, int index) { + // return IngredientWidget( + // incredient: food.incredients![index], + // ); + // }, + // ), + if (food.incredients != null && food.incredients!.isNotEmpty) ...[ + const SizedBox(height: 16), + const Text( + 'Incredients', + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 16), + ...food.incredients! + .map((e) => IngredientWidget( + incredient: e, + allowEdit: false, + )) + .toList() + ], if (food.notes != null && food.notes!.isNotEmpty) ...[ const SizedBox(height: 16), Text( diff --git a/lib/ui/views/add_recipe/bloc/add_recipe_bloc.dart b/lib/ui/views/add_recipe/bloc/add_recipe_bloc.dart index 039e343..552c6c9 100644 --- a/lib/ui/views/add_recipe/bloc/add_recipe_bloc.dart +++ b/lib/ui/views/add_recipe/bloc/add_recipe_bloc.dart @@ -97,6 +97,7 @@ class AddRecipeBloc extends Bloc { .where((element) => element.id != event.food.id), ], ))); + _updateNutrient(); } } diff --git a/lib/ui/views/add_recipe/view/add_recipe.form.dart b/lib/ui/views/add_recipe/view/add_recipe.form.dart index ea4f732..596d157 100644 --- a/lib/ui/views/add_recipe/view/add_recipe.form.dart +++ b/lib/ui/views/add_recipe/view/add_recipe.form.dart @@ -119,9 +119,11 @@ class AddRecipeForm extends StatelessWidget { class IngredientWidget extends StatefulWidget { final Food incredient; + final bool allowEdit; const IngredientWidget({ super.key, required this.incredient, + this.allowEdit = true, }); @override State createState() => _IngredientWidgetState(); @@ -132,236 +134,284 @@ class _IngredientWidgetState extends State { bool isExpanded = false; @override Widget build(BuildContext context) { - return Card( - elevation: 0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), + return SwipeableTile.card( + swipeThreshold: 0.2, + borderRadius: 10, + shadow: BoxShadow( + color: Colors.black.withOpacity(0.1), ), - child: InkWell( - onTap: () { - setState(() { - isExpanded = !isExpanded; - }); - }, - borderRadius: BorderRadius.circular(10), - child: AnimatedContainer( - padding: const EdgeInsets.symmetric( - vertical: 15, - horizontal: 15, - ), - duration: const Duration(milliseconds: 300), - // height: isExpanded ? 50 : 60, - width: double.infinity, - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - incredient.name, - style: Theme.of(context).textTheme.titleLarge?.copyWith( - fontWeight: FontWeight.bold, - ), - ), - Row( - children: [ - Text( - '${incredient.nutrition.calories.toStringAsFixed(2)} Cal', - style: - Theme.of(context).textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.w700, - color: Colors.grey, - ), - ), - if (!isExpanded) + horizontalPadding: 0, + verticalPadding: 0, + color: Theme.of(context).canvasColor, + direction: + widget.allowEdit ? SwipeDirection.horizontal : SwipeDirection.none, + onSwiped: (direction) { + if (direction == SwipeDirection.endToStart) { + //Delete Here + context + .read() + ?.add(AddRecipeEvent.removeIngredient(incredient)); + } + }, + backgroundBuilder: (context, direction, progress) { + if (direction == SwipeDirection.endToStart) { + return Row( + children: const [ + Spacer(), + Padding( + padding: EdgeInsets.all(8), + child: Icon( + Icons.delete_forever_rounded, + color: Colors.red, + size: 30, + ), + ), + ], + ); + } else if (direction == SwipeDirection.startToEnd) { + // return your widget + } + return Container(); + }, + key: Key(incredient.id!), + child: Card( + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + child: InkWell( + onTap: () { + setState(() { + isExpanded = !isExpanded; + }); + }, + borderRadius: BorderRadius.circular(10), + child: AnimatedContainer( + padding: const EdgeInsets.symmetric( + vertical: 15, + horizontal: 15, + ), + duration: const Duration(milliseconds: 300), + // height: isExpanded ? 50 : 60, + width: double.infinity, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + incredient.name, + style: Theme.of(context).textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + Row( + children: [ Text( - ' x ${incredient.quantity}', + '${incredient.nutrition.calories.toStringAsFixed(2)} Cal', style: - Theme.of(context).textTheme.titleSmall?.copyWith( + Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w700, color: Colors.grey, ), ), - ], - ), - ], - ), - AnimatedCrossFade( - firstChild: SizedBox(), - secondChild: Padding( - padding: EdgeInsets.only(top: 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (incredient.nutrition.protein != null) - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - 'Protein : ', - style: Theme.of(context) - .textTheme - .bodySmall - ?.copyWith( - fontWeight: FontWeight.bold, - letterSpacing: 0, - ), - ), - Text( - '${incredient.nutrition.protein?.toStringAsFixed(2)}g', - textAlign: TextAlign.center, - style: Theme.of(context) - .textTheme - .bodySmall - ?.copyWith( - fontWeight: FontWeight.bold, - ), - ), - ], - ), - if (incredient.nutrition.carbs != null) - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - 'Carbs : ', - style: Theme.of(context) - .textTheme - .bodySmall - ?.copyWith( - fontWeight: FontWeight.bold, - letterSpacing: 0, - ), - ), - Text( - '${incredient.nutrition.carbs?.toStringAsFixed(2)}g', - textAlign: TextAlign.center, - style: Theme.of(context) - .textTheme - .bodySmall - ?.copyWith( - fontWeight: FontWeight.bold, - ), - ), - ], - ), - if (incredient.nutrition.fat != null) - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - 'Fat : ', - style: Theme.of(context) - .textTheme - .bodySmall - ?.copyWith( - fontWeight: FontWeight.bold, - letterSpacing: 0, - ), - ), - Text( - '${incredient.nutrition.fat?.toStringAsFixed(2)}g', - textAlign: TextAlign.center, - style: Theme.of(context) - .textTheme - .bodySmall - ?.copyWith( - fontWeight: FontWeight.bold, - ), - ), - ], - ), - ], - ), - ), - Column( - children: [ + if (!isExpanded) Text( - "Quantity", + ' x ${incredient.quantity}', style: Theme.of(context) .textTheme - .bodyMedium + .titleSmall ?.copyWith( - fontWeight: FontWeight.bold, - letterSpacing: 0, + fontWeight: FontWeight.w700, + color: Colors.grey, + ), + ), + ], + ), + ], + ), + AnimatedCrossFade( + firstChild: SizedBox(), + secondChild: Padding( + padding: EdgeInsets.only(top: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (incredient.nutrition.protein != null) + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + 'Protein : ', + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith( + fontWeight: FontWeight.bold, + letterSpacing: 0, + ), + ), + Text( + '${incredient.nutrition.protein?.toStringAsFixed(2)}g', + textAlign: TextAlign.center, + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + ], + ), + if (incredient.nutrition.carbs != null) + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + 'Carbs : ', + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith( + fontWeight: FontWeight.bold, + letterSpacing: 0, + ), + ), + Text( + '${incredient.nutrition.carbs?.toStringAsFixed(2)}g', + textAlign: TextAlign.center, + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + ], + ), + if (incredient.nutrition.fat != null) + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + 'Fat : ', + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith( + fontWeight: FontWeight.bold, + letterSpacing: 0, + ), + ), + Text( + '${incredient.nutrition.fat?.toStringAsFixed(2)}g', + textAlign: TextAlign.center, + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + ], ), + ], ), - // This will be replaced by textfield - // Text( - // "1", - // style: Theme.of(context) - // .textTheme - // .titleLarge - // ?.copyWith( - // fontWeight: FontWeight.bold, - // letterSpacing: 0, - // ), - // ), - SizedBox( - width: 50, - height: 40, - child: TextField( - inputFormatters: [ - // Reg Expression allows only numbers with 1 decimal point - FilteringTextInputFormatter.allow( - RegExp(r'^\d+\.?\d{0,1}')), - ], - controller: TextEditingController( - text: incredient.quantity.toString()), - textAlign: TextAlign.center, - onChanged: (value) { - double? valueDouble = double.tryParse(value); - if (valueDouble == null) { - return; - } - context.read().add( - AddRecipeEvent.updateIngredient( - incredient, valueDouble)); - }, + ), + Column( + children: [ + Text( + "Quantity", style: Theme.of(context) .textTheme - .titleLarge + .bodyMedium ?.copyWith( fontWeight: FontWeight.bold, letterSpacing: 0, ), - maxLines: 1, - maxLength: 3, - keyboardType: TextInputType.numberWithOptions( - signed: true, decimal: true), - textInputAction: TextInputAction.done, - decoration: InputDecoration( - isDense: true, - counter: SizedBox.shrink(), - hintText: '1', - hintStyle: Theme.of(context) - .textTheme - .titleLarge - ?.copyWith( - fontWeight: FontWeight.bold, - letterSpacing: 0, - color: Colors.grey, - ), - border: InputBorder.none, - ), ), - ), - ], - ) - ], + // This will be replaced by textfield + // Text( + // "1", + // style: Theme.of(context) + // .textTheme + // .titleLarge + // ?.copyWith( + // fontWeight: FontWeight.bold, + // letterSpacing: 0, + // ), + // ), + SizedBox( + width: 50, + height: 40, + child: HookBuilder(builder: (context) { + final controller = useTextEditingController( + text: incredient.quantity.toString()); + return TextField( + enabled: widget.allowEdit, + inputFormatters: [ + // Reg Expression allows only numbers with 1 decimal point + FilteringTextInputFormatter.allow( + RegExp(r'^\d+\.?\d{0,1}')), + ], + controller: controller, + textAlign: TextAlign.center, + onChanged: (value) { + double? valueDouble = + double.tryParse(value); + if (valueDouble == null) { + return; + } + context.read().add( + AddRecipeEvent.updateIngredient( + incredient, valueDouble)); + }, + style: Theme.of(context) + .textTheme + .titleLarge + ?.copyWith( + fontWeight: FontWeight.bold, + letterSpacing: 0, + ), + maxLines: 1, + maxLength: 3, + keyboardType: TextInputType.numberWithOptions( + signed: true, decimal: true), + textInputAction: TextInputAction.done, + decoration: InputDecoration( + isDense: true, + counter: SizedBox.shrink(), + hintText: '1', + hintStyle: Theme.of(context) + .textTheme + .titleLarge + ?.copyWith( + fontWeight: FontWeight.bold, + letterSpacing: 0, + color: Colors.grey, + ), + border: InputBorder.none, + ), + ); + }), + ), + ], + ) + ], + ), ), + crossFadeState: isExpanded + ? CrossFadeState.showSecond + : CrossFadeState.showFirst, + duration: const Duration(milliseconds: 300), ), - crossFadeState: isExpanded - ? CrossFadeState.showSecond - : CrossFadeState.showFirst, - duration: const Duration(milliseconds: 300), - ), - ], + ], + ), ), ), ), @@ -422,16 +472,16 @@ class MainRecipeNutrient extends StatelessWidget { // height: 40, child: AutoSizeTextField( controller: controller, - onSubmitted: (value) { - context - .read() - .add(AddRecipeEvent.updateName(value)); - }, - // onChanged: (value) { + // onSubmitted: (value) { // context // .read() // .add(AddRecipeEvent.updateName(value)); // }, + onChanged: (value) { + context + .read() + .add(AddRecipeEvent.updateName(value)); + }, style: Theme.of(context).textTheme.headlineMedium?.copyWith( fontWeight: FontWeight.bold, ), diff --git a/lib/ui/views/add_recipe/view/add_recipe.page.dart b/lib/ui/views/add_recipe/view/add_recipe.page.dart index 99eb035..5d83e5a 100644 --- a/lib/ui/views/add_recipe/view/add_recipe.page.dart +++ b/lib/ui/views/add_recipe/view/add_recipe.page.dart @@ -7,6 +7,7 @@ import 'package:calorie_tracker/core/models/food/food.dart'; import 'package:calorie_tracker/core/services/firebase/firebase_service.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:swipeable_tile/swipeable_tile.dart'; import 'package:wolt_modal_sheet/wolt_modal_sheet.dart'; part 'add_recipe.view.dart'; diff --git a/lib/ui/views/add_recipe/view/add_recipe.view.dart b/lib/ui/views/add_recipe/view/add_recipe.view.dart index 509f0fa..f1eb6cc 100644 --- a/lib/ui/views/add_recipe/view/add_recipe.view.dart +++ b/lib/ui/views/add_recipe/view/add_recipe.view.dart @@ -50,6 +50,7 @@ class _AddRecipeView extends StatelessWidget { context .read() .add(const AddRecipeEvent.addRecipe()); + Navigator.of(context).pop(); } : null, height: 50 + MediaQuery.of(context).padding.bottom, diff --git a/lib/ui/views/home/view/home.view.dart b/lib/ui/views/home/view/home.view.dart index 932d09c..52d9404 100644 --- a/lib/ui/views/home/view/home.view.dart +++ b/lib/ui/views/home/view/home.view.dart @@ -117,9 +117,6 @@ class _HomeView extends StatelessWidget { final burnedCalories = state.totalBurnedCalories; final totalCalories = state.totalCalories; - // final caloriesGoal = goals.caloriesGoal; - // final caloriesEatenPercent = totalCalories / caloriesGoal; - // final hadExtraCalories = totalCalories > caloriesGoal; final totalProtein = state.totalProtein; final proteinGoal = goals.proteinGoal; @@ -149,22 +146,6 @@ class _HomeView extends StatelessWidget { subtitle: 'EATEN', ), ), - // Rings( - // calories: state.totalCalories, - // protein: state.totalProtein, - // carbs: state.totalCarbs, - // fat: state.totalFat, - // totalCalories: state.totalCalories, - // totalProtein: state.totalProtein, - // totalCarbs: state.totalCarbs, - // totalFat: state.totalFat, - // goals: ( - // calories: caloriesGoal, - // protein: proteinGoal, - // carbs: carbsGoal, - // fat: fatGoal - // ), - // ), SizedBox( height: 145, width: 145,