import 'package:diameter/utils/dialog_utils.dart'; import 'package:diameter/models/ingredient.dart'; import 'package:diameter/models/recipe.dart'; import 'package:diameter/models/settings.dart'; import 'package:diameter/navigation.dart'; import 'package:diameter/screens/recipe/recipe_detail.dart'; import 'package:flutter/material.dart'; class RecipeListScreen extends StatefulWidget { static const String routeName = '/recipes'; const RecipeListScreen({Key? key}) : super(key: key); @override _RecipeListScreenState createState() => _RecipeListScreenState(); } class _RecipeListScreenState extends State { List _recipes = []; final ScrollController _scrollController = ScrollController(); @override void initState() { super.initState(); reload(); } void reload({String? message}) { setState(() { _recipes = Recipe.getAll(); }); setState(() { if (message != null) { var snackBar = SnackBar( content: Text(message), duration: const Duration(seconds: 2), ); ScaffoldMessenger.of(context) ..removeCurrentSnackBar() ..showSnackBar(snackBar); } }); } void onDelete(Recipe recipe) { Recipe.remove(recipe.id); reload(message: 'Recipe deleted'); } void handleDeleteAction(Recipe recipe) async { if (Settings.get().showConfirmationDialogOnDelete) { DialogUtils.showConfirmationDialog( context: context, onConfirm: () => onDelete(recipe), message: 'Are you sure you want to delete this Recipe?', ); } else { onDelete(recipe); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Recipes'), actions: [ IconButton(onPressed: reload, icon: const Icon(Icons.refresh)) ]), drawer: const Navigation(currentLocation: RecipeListScreen.routeName), body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: _recipes.isNotEmpty ? Scrollbar( controller: _scrollController, child: ListView.builder( controller: _scrollController, padding: const EdgeInsets.all(10.0), itemCount: _recipes.length, itemBuilder: (context, index) { final recipe = _recipes[index]; final carbsRatio = Ingredient.getCarbsRatioForRecipe(recipe.id); final carbsPerPortion = Recipe.getCarbsPerPortion(recipe.id); return Card( child: ListTile( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => RecipeDetailScreen(id: recipe.id), ), ).then((result) => reload(message: result?[0])); }, title: Text( recipe.name.toUpperCase(), style: Theme.of(context).textTheme.subtitle2, ), subtitle: Padding( padding: const EdgeInsets.symmetric(vertical: 10.0), child: Row( children: [ Column( children: [ Text(recipe.notes ?? ''), ], ), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: ((carbsRatio ?? 0) > 0) ? [ Text(carbsRatio!.toString()), const Text('% carbs', textScaleFactor: 0.75), ] : [], ), ), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: (recipe.servings != null) ? [ Text(recipe.servings! .toStringAsPrecision(3)), const Text('servings', textScaleFactor: 0.75), ] : [], ), ), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: ((carbsPerPortion ?? 0) > 0) ? [ Text(carbsPerPortion! .toStringAsPrecision(3)), Text( '${Settings.nutritionMeasurementSuffix} carbs per serving', textScaleFactor: 0.75), ] : [], ), ), ], ), ), trailing: Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.end, children: [ IconButton( onPressed: () => handleDeleteAction(recipe), icon: const Icon(Icons.delete, color: Colors.blue), ) ], ), ), ); }, ), ) : const Center( child: Text('You have not created any Recipes yet!'), ), ), ], ), floatingActionButton: FloatingActionButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const RecipeDetailScreen(), ), ).then((result) => reload(message: result?[0])); }, child: const Icon(Icons.add), ), ); } }