From d2e3b158cb60eb2fcb01f76db48894ade6865857 Mon Sep 17 00:00:00 2001 From: marco Date: Mon, 10 Feb 2025 19:55:18 +0100 Subject: [PATCH] added provider for recipe wizard --- lib/models/ingredient.dart | 8 ++ lib/models/ingredient_list_entry.dart | 10 ++ lib/models/recipe.dart | 65 +++++++-- lib/services/providers/recipe_provider.dart | 151 ++++++++++++++++++++ lib/src/enums.dart | 3 + pubspec.yaml | 1 + 6 files changed, 226 insertions(+), 12 deletions(-) create mode 100644 lib/services/providers/recipe_provider.dart diff --git a/lib/models/ingredient.dart b/lib/models/ingredient.dart index 6d60c55..53308be 100644 --- a/lib/models/ingredient.dart +++ b/lib/models/ingredient.dart @@ -13,4 +13,12 @@ class Ingredient { this.possibleUnits = const [], this.preferredBrands = const [], }); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is Ingredient && other.title == title && other.type == type; + + @override + int get hashCode => Object.hash(title, type); } diff --git a/lib/models/ingredient_list_entry.dart b/lib/models/ingredient_list_entry.dart index e1643b9..f70f8a7 100644 --- a/lib/models/ingredient_list_entry.dart +++ b/lib/models/ingredient_list_entry.dart @@ -8,4 +8,14 @@ class IngredientListEntry { final bool optional; IngredientListEntry(this.ingredient, this.amount, this.unit, this.optional); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is IngredientListEntry && + ingredient == other.ingredient && + amount == other.amount; + + @override + int get hashCode => Object.hash(ingredient.hashCode, amount.hashCode); } diff --git a/lib/models/recipe.dart b/lib/models/recipe.dart index 9524624..2ef685d 100644 --- a/lib/models/recipe.dart +++ b/lib/models/recipe.dart @@ -6,26 +6,67 @@ class Recipe { final String title; final String description; final Difficulty difficulty; - final List ingredients = []; - final List steps = []; + final List ingredients; + final List steps; final DateTime datePublished; final Duration prepTime; final Duration cookTime; final Duration totalTime; - final List keywords = []; + final List keywords; final MealCategory mealCategory; final Cuisine cuisine; Recipe({ - required this.id, - required this.title, - required this.description, - required this.difficulty, + this.id = -1, + this.title = '', + this.description = '', + this.difficulty = Difficulty.notSelected, required this.datePublished, - required this.prepTime, - required this.cookTime, - required this.totalTime, - required this.mealCategory, - required this.cuisine, + this.prepTime = const Duration(), + this.cookTime = const Duration(), + this.totalTime = const Duration(), + this.mealCategory = MealCategory.notSelected, + this.cuisine = Cuisine.notSelected, + this.ingredients = const [], + this.keywords = const [], + this.steps = const [], }); + + Recipe copyWith({ + int? id, + String? title, + String? description, + Difficulty? difficulty, + List? ingredients, + List? steps, + DateTime? datePublished, + Duration? prepTime, + Duration? cookTime, + Duration? totalTime, + List? keywords, + MealCategory? mealCategory, + Cuisine? cuisine, + }) { + return Recipe( + id: id ?? this.id, + title: title ?? this.title, + description: description ?? this.description, + difficulty: difficulty ?? this.difficulty, + ingredients: ingredients != null + ? List.from(ingredients) + : List.from(this.ingredients), + steps: steps != null + ? List.from(steps) + : List.from(this.steps), + datePublished: datePublished ?? this.datePublished, + prepTime: prepTime ?? this.prepTime, + cookTime: cookTime ?? this.cookTime, + totalTime: totalTime ?? this.totalTime, + keywords: keywords != null + ? List.from(keywords) + : List.from(this.keywords), + mealCategory: mealCategory ?? this.mealCategory, + cuisine: cuisine ?? this.cuisine, + ); + } } diff --git a/lib/services/providers/recipe_provider.dart b/lib/services/providers/recipe_provider.dart new file mode 100644 index 0000000..9d379cb --- /dev/null +++ b/lib/services/providers/recipe_provider.dart @@ -0,0 +1,151 @@ +import 'package:flutter/material.dart'; + +import '../../models/ingredient_list_entry.dart'; +import '../../models/recipe.dart'; +import '../../src/enums.dart'; + +class RecipeProvider extends ChangeNotifier { + Recipe _recipe = Recipe(datePublished: DateTime.now()); + + Recipe get recipe => _recipe; + + void updateTitle(String title, {bool silent = false}) { + _recipe = _recipe.copyWith(title: title); + if (!silent) { + notifyListeners(); + } + } + + void updateDescription(String description, {bool silent = false}) { + _recipe = _recipe.copyWith(description: description); + if (!silent) { + notifyListeners(); + } + } + + void updateDifficulty(Difficulty difficulty, {bool silent = false}) { + _recipe = _recipe.copyWith(difficulty: difficulty); + if (!silent) { + notifyListeners(); + } + } + + void updateIngredients(List ingredients, + {bool silent = false}) { + _recipe = _recipe.copyWith(ingredients: ingredients); + if (!silent) { + notifyListeners(); + } + } + + void updateSteps(List steps, {bool silent = false}) { + _recipe = _recipe.copyWith(steps: steps); + if (!silent) { + notifyListeners(); + } + } + + void updateDatePublished(DateTime datePublished, {bool silent = false}) { + _recipe = _recipe.copyWith(datePublished: datePublished); + if (!silent) { + notifyListeners(); + } + } + + void updatePrepTime(Duration prepTime, {bool silent = false}) { + _recipe = _recipe.copyWith(prepTime: prepTime); + if (!silent) { + notifyListeners(); + } + } + + void updateCookTime(Duration cookTime, {bool silent = false}) { + _recipe = _recipe.copyWith(cookTime: cookTime); + if (!silent) { + notifyListeners(); + } + } + + void updateTotalTime(Duration totalTime, {bool silent = false}) { + _recipe = _recipe.copyWith(totalTime: totalTime); + if (!silent) { + notifyListeners(); + } + } + + void updateKeywords(List keywords, {bool silent = false}) { + _recipe = _recipe.copyWith(keywords: keywords); + if (!silent) { + notifyListeners(); + } + } + + void updateMealCategory(MealCategory mealCategory, {bool silent = false}) { + _recipe = _recipe.copyWith(mealCategory: mealCategory); + if (!silent) { + notifyListeners(); + } + } + + void updateCuisine(Cuisine cuisine, {bool silent = false}) { + _recipe = _recipe.copyWith(cuisine: cuisine); + if (!silent) { + notifyListeners(); + } + } + +// Helper methods for list operations + void addIngredient(IngredientListEntry ingredient, {bool silent = false}) { + _recipe = _recipe.copyWith( + ingredients: [..._recipe.ingredients, ingredient], + ); + if (!silent) { + notifyListeners(); + } + } + + void removeIngredient(IngredientListEntry ingredient, {bool silent = false}) { + _recipe = _recipe.copyWith( + ingredients: _recipe.ingredients.where((i) => i != ingredient).toList(), + ); + if (!silent) { + notifyListeners(); + } + } + + void addStep(String step, {bool silent = false}) { + _recipe = _recipe.copyWith( + steps: [..._recipe.steps, step], + ); + if (!silent) { + notifyListeners(); + } + } + + void removeStep(String step, {bool silent = false}) { + _recipe = _recipe.copyWith( + steps: _recipe.steps.where((s) => s != step).toList(), + ); + if (!silent) { + notifyListeners(); + } + } + + void addKeyword(String keyword, {bool silent = false}) { + _recipe = _recipe.copyWith( + keywords: [..._recipe.keywords, keyword], + ); + if (!silent) { + notifyListeners(); + } + } + + void removeKeyword(String keyword, {bool silent = false}) { + _recipe = _recipe.copyWith( + keywords: _recipe.keywords.where((k) => k != keyword).toList(), + ); + if (!silent) { + notifyListeners(); + } + } +} diff --git a/lib/src/enums.dart b/lib/src/enums.dart index 922b8ba..5e085b7 100644 --- a/lib/src/enums.dart +++ b/lib/src/enums.dart @@ -16,6 +16,7 @@ enum Difficulty { } enum IngredientType { + notSelected, vegetable, meat, fish, @@ -28,6 +29,7 @@ enum IngredientType { } enum MealCategory { + notSelected, // Main Meals breakfast, brunch, @@ -44,6 +46,7 @@ enum MealCategory { } enum Cuisine { + notSelected, // Asian Cuisines chinese, japanese, diff --git a/pubspec.yaml b/pubspec.yaml index 9634e1c..45b89fa 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,6 +11,7 @@ dependencies: sdk: flutter cupertino_icons: ^1.0.8 + provider: ^6.1.2 dev_dependencies: flutter_test: