ability to display added ingredients in listview

This commit is contained in:
SomnusVeritas
2023-10-31 19:26:12 +01:00
parent 3e094bf8f0
commit a29f37b0e8
5 changed files with 141 additions and 53 deletions

View File

@@ -7,7 +7,7 @@ class Ingredient {
Ingredient({ Ingredient({
required this.title, required this.title,
required this.possibleUnits, this.possibleUnits = const [],
this.preferredBrands = const [], this.preferredBrands = const [],
}); });

View File

@@ -0,0 +1,11 @@
import 'ingredient.dart';
import 'unit.dart';
class IngredientListEntry {
final Ingredient ingredient;
final int amount;
final Unit unit;
final bool optional;
IngredientListEntry(this.ingredient, this.amount, this.unit, this.optional);
}

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:rezepte/widgets/ingredients_bottomsheet.dart'; import 'package:rezepte/widgets/ingredients_bottomsheet.dart';
import '../models/difficulty.dart'; import '../models/difficulty.dart';
import '../models/ingredient_list_entry.dart';
import '../services/providers/recipe_provider.dart'; import '../services/providers/recipe_provider.dart';
class CreateRecipe extends StatefulWidget { class CreateRecipe extends StatefulWidget {
@@ -14,6 +15,7 @@ class CreateRecipe extends StatefulWidget {
class _CreateRecipeState extends State<CreateRecipe> { class _CreateRecipeState extends State<CreateRecipe> {
late RecipeProvider recipeProvider; late RecipeProvider recipeProvider;
final List<IngredientListEntry> ingredientEntries = [];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -23,6 +25,8 @@ class _CreateRecipeState extends State<CreateRecipe> {
title: const Text('Create Recipe'), title: const Text('Create Recipe'),
), ),
body: Form( body: Form(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column( child: Column(
children: [ children: [
TextFormField( TextFormField(
@@ -40,21 +44,67 @@ class _CreateRecipeState extends State<CreateRecipe> {
DropdownMenu<Difficulty?>( DropdownMenu<Difficulty?>(
dropdownMenuEntries: DifficultyUtil.getDropdownList(), dropdownMenuEntries: DifficultyUtil.getDropdownList(),
onSelected: (value) => recipeProvider.difficulty = value, onSelected: (value) => recipeProvider.difficulty = value,
label: const Text('Difficulty'),
), ),
ElevatedButton( ElevatedButton(
onPressed: _openIngredientBottomSheet, onPressed: _openIngredientBottomSheet,
child: const Text('Add Ingredient'), child: const Text('Add Ingredient'),
), ),
Expanded(
child: ListView.separated(
itemCount: ingredientEntries.length,
itemBuilder: _ingredientListBuilder,
separatorBuilder: (context, index) => const Divider(),
),
)
], ],
), ),
), ),
),
); );
} }
void _openIngredientBottomSheet() { void _openIngredientBottomSheet() {
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
builder: (context) => const IngredientsBottomsheet(), builder: (context) => IngredientsBottomsheet(
onSubmitted: _onIngredientSubmitted,
),
); );
} }
void _onIngredientSubmitted(IngredientListEntry ingredient) => setState(() {
ingredientEntries.add(ingredient);
});
Widget? _ingredientListBuilder(BuildContext context, int index) {
final ingredient = ingredientEntries.elementAt(index);
final textTheme = Theme.of(context).textTheme.titleMedium;
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(ingredient.ingredient.title, style: textTheme),
Row(
children: [
Text(
ingredient.amount.toString(),
style: textTheme,
),
const Padding(padding: EdgeInsets.symmetric(horizontal: 2)),
Text(
ingredient.unit.name,
style: textTheme,
),
],
),
],
),
);
}
Widget _seperatorBuilder(BuildContext context, int index) {
return const Divider(indent: 20, endIndent: 20);
}
} }

View File

@@ -3,6 +3,8 @@ import 'package:flutter/material.dart';
final _baseTheme = ThemeData( final _baseTheme = ThemeData(
fontFamily: "Ubuntu", fontFamily: "Ubuntu",
useMaterial3: true, useMaterial3: true,
).copyWith(
dividerTheme: const DividerThemeData(indent: 20, endIndent: 20),
); );
final lightTheme = _baseTheme.copyWith( final lightTheme = _baseTheme.copyWith(
@@ -10,7 +12,9 @@ final lightTheme = _baseTheme.copyWith(
seedColor: Colors.deepPurple, seedColor: Colors.deepPurple,
brightness: Brightness.light, brightness: Brightness.light,
), ),
); dividerTheme: DividerThemeData(
color: Colors.grey[600],
));
final darkTheme = _baseTheme.copyWith( final darkTheme = _baseTheme.copyWith(
colorScheme: ColorScheme.fromSeed( colorScheme: ColorScheme.fromSeed(

View File

@@ -2,12 +2,17 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../constants.dart' as constants; import '../constants.dart' as constants;
import '../models/ingredient.dart'; import '../models/ingredient.dart';
import '../models/ingredient_list_entry.dart';
import '../models/unit.dart'; import '../models/unit.dart';
import '../example_data.dart' as ea; import '../example_data.dart' as ea;
import '../services/providers/recipe_provider.dart'; import '../services/providers/recipe_provider.dart';
typedef IngredientCallback = void Function(IngredientListEntry);
class IngredientsBottomsheet extends StatefulWidget { class IngredientsBottomsheet extends StatefulWidget {
const IngredientsBottomsheet({super.key}); const IngredientsBottomsheet({required this.onSubmitted, super.key});
final IngredientCallback onSubmitted;
@override @override
State<IngredientsBottomsheet> createState() => _IngredientsBottomsheetState(); State<IngredientsBottomsheet> createState() => _IngredientsBottomsheetState();
@@ -15,13 +20,13 @@ class IngredientsBottomsheet extends StatefulWidget {
class _IngredientsBottomsheetState extends State<IngredientsBottomsheet> { class _IngredientsBottomsheetState extends State<IngredientsBottomsheet> {
final List<DropdownMenuEntry<Ingredient>> ingredientEntries = []; final List<DropdownMenuEntry<Ingredient>> ingredientEntries = [];
final List<DropdownMenuEntry<Unit>> unitEntries = [];
Unit? selectedUnit;
late RecipeProvider recipeProvider; late RecipeProvider recipeProvider;
Unit? selectedUnit;
final List<DropdownMenuEntry<Unit>> unitEntries = [];
bool _isOptional = false;
TextEditingController _ingredientController = TextEditingController();
TextEditingController _amountController = TextEditingController(); TextEditingController _amountController = TextEditingController();
TextEditingController _ingredientController = TextEditingController();
bool _isOptional = false;
TextEditingController _unitController = TextEditingController(); TextEditingController _unitController = TextEditingController();
@override @override
@@ -137,6 +142,44 @@ class _IngredientsBottomsheetState extends State<IngredientsBottomsheet> {
); );
} }
void _nextTapped() {
final success = _submit();
if (success) {
setState(() {
_ingredientController.value = TextEditingValue.empty;
_unitController.value = TextEditingValue.empty;
_amountController.value = TextEditingValue.empty;
_isOptional = false;
selectedUnit = null;
});
}
}
void _finishTapped() {
final success = _submit();
if (success) {
Navigator.of(context).pop();
}
}
void _cancelTapped() {
Navigator.of(context).pop();
}
bool _submit() {
final ingredient = Ingredient(title: _ingredientController.text);
final unit = selectedUnit;
final amount = int.tryParse(_amountController.text);
if (ingredient.title.isEmpty || unit == null || amount == null) {
return false;
}
final newEntry = IngredientListEntry(ingredient, amount, unit, _isOptional);
widget.onSubmitted(newEntry);
return true;
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
recipeProvider = Provider.of<RecipeProvider>(context); recipeProvider = Provider.of<RecipeProvider>(context);
@@ -145,24 +188,4 @@ class _IngredientsBottomsheetState extends State<IngredientsBottomsheet> {
builder: _bottomSheetContent, builder: _bottomSheetContent,
); );
} }
void _nextTapped() {
_submit();
setState(() {
_ingredientController.value = TextEditingValue.empty;
_unitController.value = TextEditingValue.empty;
_amountController.value = TextEditingValue.empty;
_isOptional = false;
});
}
void _finishTapped() {
// TODO implement}
}
void _cancelTapped() {
// TODO implement}
}
void _submit() {
// TODO implement
}
} }