From c04fec0927eb7d41849e05da07c055698a0a006c Mon Sep 17 00:00:00 2001 From: "maxime.BATISTA@etu.uca.fr" Date: Thu, 11 May 2023 14:51:26 +0200 Subject: [PATCH] make remove recipe system --- App.xaml.cs | 2 +- ConnectAppShell.xaml.cs | 2 +- ConsoleUserNotifier.cs | 9 ++- Controllers/ConnectionController.cs | 4 +- Controllers/MorePageController.cs | 25 +++++-- Endpoint/IAccountRecipes.cs | 32 +++++++++ Endpoint/IRecipesService.cs | 10 +-- IApp.cs | 2 +- UserNotifier.cs => IUserNotifier.cs | 37 ++++++----- LocalEndpoint/AccountRecipes.cs | 84 ++++++++++++++++++++++++ LocalEndpoint/LocalEndpoint.cs | 7 +- LocalEndpoint/RecipesService.cs | 61 ++++++----------- MainAppShell.xaml.cs | 2 +- Models/Recipe.cs | 8 ++- Models/RecipeInfo.cs | 8 ++- Views/Components/OwnedRecipeView.xaml | 11 +++- Views/Components/OwnedRecipeView.xaml.cs | 32 +++++++-- Views/Components/RecipeView.xaml.cs | 3 +- Views/FavoritesPage.xaml.cs | 7 +- Views/HomePage.xaml.cs | 7 +- Views/MorePage.xaml.cs | 8 +-- Views/MyListPage.xaml.cs | 11 ++-- Views/MyRecipesPage.xaml | 13 +--- Views/MyRecipesPage.xaml.cs | 52 ++++++++++++++- Views/ProfilePage.xaml.cs | 4 +- Views/RecipePage.xaml.cs | 6 +- 26 files changed, 320 insertions(+), 127 deletions(-) create mode 100644 Endpoint/IAccountRecipes.cs rename UserNotifier.cs => IUserNotifier.cs (78%) create mode 100644 LocalEndpoint/AccountRecipes.cs diff --git a/App.xaml.cs b/App.xaml.cs index 5e0f01e..9c150df 100644 --- a/App.xaml.cs +++ b/App.xaml.cs @@ -8,7 +8,7 @@ public partial class App : Application, ConnectionObserver, IApp private IEndpoint Endpoint = new LocalEndpoint(); - public UserNotifier Notifier => new ConsoleUserNotifier(); + public IUserNotifier Notifier => new ConsoleUserNotifier(); public App() { diff --git a/ConnectAppShell.xaml.cs b/ConnectAppShell.xaml.cs index 15aad38..29f3275 100644 --- a/ConnectAppShell.xaml.cs +++ b/ConnectAppShell.xaml.cs @@ -7,7 +7,7 @@ using ShoopNCook.Pages; public partial class ConnectAppShell : Shell { - public ConnectAppShell(ConnectionObserver observer, IAccountManager accounts, UserNotifier notifier) + public ConnectAppShell(ConnectionObserver observer, IAccountManager accounts, IUserNotifier notifier) { ConnectionController controller = new ConnectionController(observer, accounts, notifier); InitializeComponent(); diff --git a/ConsoleUserNotifier.cs b/ConsoleUserNotifier.cs index 04b7221..1a06c28 100644 --- a/ConsoleUserNotifier.cs +++ b/ConsoleUserNotifier.cs @@ -4,8 +4,15 @@ /// A notice reporter implementation that prints in console the applications's user notices. /// public class ConsoleUserNotifier : - UserNotifier + IUserNotifier { + + public void Success(string message) + { + Console.WriteLine(" Success: " + message); + } + + public void Error(string message) { Console.WriteLine(" Error: " + message); diff --git a/Controllers/ConnectionController.cs b/Controllers/ConnectionController.cs index 2ed88de..6ecfd51 100644 --- a/Controllers/ConnectionController.cs +++ b/Controllers/ConnectionController.cs @@ -7,8 +7,8 @@ namespace ShoopNCook.Controllers { private readonly ConnectionObserver observer; private readonly IAccountManager accounts; - private readonly UserNotifier notifier; - public ConnectionController(ConnectionObserver observer, IAccountManager accounts, UserNotifier notifier) { + private readonly IUserNotifier notifier; + public ConnectionController(ConnectionObserver observer, IAccountManager accounts, IUserNotifier notifier) { this.observer = observer; this.accounts = accounts; this.notifier = notifier; diff --git a/Controllers/MorePageController.cs b/Controllers/MorePageController.cs index f4698fa..c8ecee8 100644 --- a/Controllers/MorePageController.cs +++ b/Controllers/MorePageController.cs @@ -1,8 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Endpoint; +using Models; +using ShoopNCook.Pages; namespace ShoopNCook.Controllers { @@ -10,9 +8,14 @@ namespace ShoopNCook.Controllers { private readonly IApp app; + private readonly IEndpoint endpoint; + private readonly Account account; - public MorePageController(IApp app) { + public MorePageController(Account account, IEndpoint endpoint, IApp app) + { this.app = app; + this.endpoint = endpoint; + this.account = account; } public void Logout() @@ -20,5 +23,15 @@ namespace ShoopNCook.Controllers app.Notifier.Notice("You have been loged out."); app.ForceLogin(); } + + public void GoToMyRecipesPage() + { + Shell.Current.Navigation.PushAsync(new MyRecipesPage(account, endpoint.RecipesService, app.Notifier)); + } + + public void GoToProfilePage() + { + Shell.Current.Navigation.PushAsync(new ProfilePage(account)); + } } } diff --git a/Endpoint/IAccountRecipes.cs b/Endpoint/IAccountRecipes.cs new file mode 100644 index 0000000..fd61153 --- /dev/null +++ b/Endpoint/IAccountRecipes.cs @@ -0,0 +1,32 @@ +using Models; +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LocalEndpoint +{ + public interface IAccountRecipes + { + + public Account Account { get; } + + public bool UploadRecipe(Recipe recipe); + + public bool RemoveRecipe(RecipeInfo info); + + public void SetRate(RecipeInfo info, AccountRecipeRate rate); + + public AccountRecipeRate? FindRate(RecipeInfo info); + + public ImmutableList GetAccountRecipes(); + + public ImmutableList GetRecommendedRecipes(); + + public ImmutableList GetFavorites(); + + public ImmutableList<(RecipeInfo, uint)> GetWeeklyList(); + } +} diff --git a/Endpoint/IRecipesService.cs b/Endpoint/IRecipesService.cs index 5f78d26..df7d16a 100644 --- a/Endpoint/IRecipesService.cs +++ b/Endpoint/IRecipesService.cs @@ -1,4 +1,5 @@ -using Models; +using LocalEndpoint; +using Models; using System; using System.Collections.Generic; using System.Linq; @@ -9,17 +10,12 @@ namespace Endpoint { public interface IRecipesService { - public List PopularRecipes(); public Recipe GetRecipe(RecipeInfo info); - public List RecommendedRecipesOf(Account account); - - public List LookupFavoritesOf(Account account); + public IAccountRecipes GetRecipesOf(Account account); - public List<(RecipeInfo, uint)> LookupWeeklyListOf(Account account); - public AccountRecipeRate GetRateOf(Account account, Recipe recipe); } } diff --git a/IApp.cs b/IApp.cs index 32a77b0..dad1336 100644 --- a/IApp.cs +++ b/IApp.cs @@ -9,7 +9,7 @@ namespace ShoopNCook { public interface IApp { - public UserNotifier Notifier { get; } + public IUserNotifier Notifier { get; } public void ForceLogin(); } diff --git a/UserNotifier.cs b/IUserNotifier.cs similarity index 78% rename from UserNotifier.cs rename to IUserNotifier.cs index bfd4c07..4576a70 100644 --- a/UserNotifier.cs +++ b/IUserNotifier.cs @@ -1,18 +1,19 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace ShoopNCook -{ - public interface UserNotifier - - { - public void Notice(string message); - - public void Error(string message); - - public void Warn(string message); - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShoopNCook +{ + public interface IUserNotifier + { + public void Success(string message); + + public void Notice(string message); + + public void Error(string message); + + public void Warn(string message); + } +} diff --git a/LocalEndpoint/AccountRecipes.cs b/LocalEndpoint/AccountRecipes.cs new file mode 100644 index 0000000..bd1b3fc --- /dev/null +++ b/LocalEndpoint/AccountRecipes.cs @@ -0,0 +1,84 @@ +using LocalEndpoint; +using Models; +using System.Collections.Immutable; + +namespace Endpoint +{ + internal class AccountRecipes : IAccountRecipes + { + + public Account Account { get; init; } + + private readonly Dictionary ownedRecipes = new Dictionary(); + private readonly Dictionary ratedRecipes = new Dictionary(); + + public AccountRecipes(Account account) + { + Account = account; + } + + public bool UploadRecipe(Recipe recipe) + { + Guid id = recipe.Info.Id; + if (ownedRecipes.ContainsKey(id)) + { + return false; + } + ownedRecipes.Add(id, recipe); + return true; + } + + public bool RemoveRecipe(RecipeInfo info) + { + return ownedRecipes.Remove(info.Id); + } + + public ImmutableList GetAccountRecipes() + { + return ownedRecipes.Values.ToImmutableList().ConvertAll(r => r.Info); + } + + + public ImmutableList GetRecommendedRecipes() + { + return new List { + new RecipeInfo("Chicken Salad", 500, 20, new Uri("https://healthyfitnessmeals.com/wp-content/uploads/2021/04/Southwest-chicken-salad-7-500x500.jpg"), 4, new Guid()), + new RecipeInfo("Chocolate Cake", 2500, 10, new Uri("https://bakewithshivesh.com/wp-content/uploads/2022/08/IMG_0248-scaled.jpg"), 3, new Guid()), + new RecipeInfo("Salmon", 20, 10, new Uri("https://www.wholesomeyum.com/wp-content/uploads/2021/06/wholesomeyum-Pan-Seared-Salmon-Recipe-13.jpg"), 4, new Guid()), + new RecipeInfo("Fish", 50, 30, new Uri("https://www.ciaanet.org/wp-content/uploads/2022/07/Atlantic-and-Pacific-whole-salmon-1024x683.jpg"), 4.5F, new Guid()), + new RecipeInfo("Space Cake", 800, 5, new Uri("https://static.youmiam.com/images/recipe/1500x1000/space-cake-22706?placeholder=web_recipe&sig=f14a7a86da837c6b8cc678cde424d6d5902f99ec&v3"), 5, new Guid()) + }.ToImmutableList(); + } + + public ImmutableList GetFavorites() + { + return new List { + new RecipeInfo("Chicken Salad", 500, 20, new Uri("https://healthyfitnessmeals.com/wp-content/uploads/2021/04/Southwest-chicken-salad-7-500x500.jpg"), 4, new Guid()), + new RecipeInfo("Space Cake", 800, 5, new Uri("https://static.youmiam.com/images/recipe/1500x1000/space-cake-22706?placeholder=web_recipe&sig=f14a7a86da837c6b8cc678cde424d6d5902f99ec&v3"), 5, new Guid()), + new RecipeInfo("Fish And Ships", 450, 15, new Uri("https://upload.wikimedia.org/wikipedia/commons/f/ff/Fish_and_chips_blackpool.jpg"), 4, new Guid()), + new RecipeInfo("Caesar Salad", 150, 20, new Uri("https://www.galbani.fr/wp-content/uploads/2020/04/AdobeStock_157570276-2.jpeg"), 1, new Guid()) + }.ToImmutableList(); + } + + public ImmutableList<(RecipeInfo, uint)> GetWeeklyList() + { + return new List<(RecipeInfo, uint)> { + (new RecipeInfo("Space Cake", 800, 5, new Uri("https://static.youmiam.com/images/recipe/1500x1000/space-cake-22706?placeholder=web_recipe&sig=f14a7a86da837c6b8cc678cde424d6d5902f99ec&v3"), 5, new Guid()), 4), + (new RecipeInfo("Chicken Curry", 500, 45, new Uri("https://cdn.chefclub.tools/uploads/recipes/cover-thumbnail/f287b191-dc8e-4c85-bbb6-e26387c354d3.jpg"), 3, new Guid()), 4), + (new RecipeInfo("Spaghetti Bolognese", 1000, 30, new Uri("https://media.istockphoto.com/id/1144823591/fr/photo/spaghetti-dans-un-plat-sur-un-fond-blanc.jpg?s=612x612&w=0&k=20&c=qFzd8iE185mpsX7hWqYaieOWlzJVCkzFdYsxmwUT3-Q="), 1, new Guid()), 1), + }.ToImmutableList(); + } + + public void SetRate(RecipeInfo info, AccountRecipeRate rate) + { + ratedRecipes.Add(info.Id, rate); + } + + public AccountRecipeRate? FindRate(RecipeInfo info) + { + AccountRecipeRate? rate = null; + ratedRecipes.TryGetValue(info.Id, out rate); + return rate; + } + } +} diff --git a/LocalEndpoint/LocalEndpoint.cs b/LocalEndpoint/LocalEndpoint.cs index 1a8e310..dd5a112 100644 --- a/LocalEndpoint/LocalEndpoint.cs +++ b/LocalEndpoint/LocalEndpoint.cs @@ -4,8 +4,11 @@ namespace LocalEndpoint { public class LocalEndpoint : IEndpoint { - public IAccountManager AccountManager => new AccountManager(); + private IAccountManager accountManager = new AccountManager(); + private IRecipesService recipesService = new RecipesService(); + public IAccountManager AccountManager => accountManager; + + public IRecipesService RecipesService => recipesService; - public IRecipesService RecipesService => new RecipesService(); } } \ No newline at end of file diff --git a/LocalEndpoint/RecipesService.cs b/LocalEndpoint/RecipesService.cs index ad91dd9..4125a05 100644 --- a/LocalEndpoint/RecipesService.cs +++ b/LocalEndpoint/RecipesService.cs @@ -1,66 +1,45 @@ using Endpoint; using Models; +using System.Collections.Immutable; namespace LocalEndpoint { internal class RecipesService : IRecipesService { + private readonly Dictionary accountsRecipes = new Dictionary(); + public List PopularRecipes() { return new List { - new RecipeInfo("Chicken Curry", 500, 45, new Uri("https://cdn.chefclub.tools/uploads/recipes/cover-thumbnail/f287b191-dc8e-4c85-bbb6-e26387c354d3.jpg"), 3), - new RecipeInfo("Spaghetti Bolognese", 1000, 30, new Uri("https://media.istockphoto.com/id/1144823591/fr/photo/spaghetti-dans-un-plat-sur-un-fond-blanc.jpg?s=612x612&w=0&k=20&c=qFzd8iE185mpsX7hWqYaieOWlzJVCkzFdYsxmwUT3-Q="), 1), - new RecipeInfo("Beef Stroganoff", 100, 10, new Uri("https://www.cookwithnabeela.com/wp-content/uploads/2023/02/BeefStroganoff.webp"), 5), - new RecipeInfo("Fish And Ships", 450, 15, new Uri("https://upload.wikimedia.org/wikipedia/commons/f/ff/Fish_and_chips_blackpool.jpg"), 4), - new RecipeInfo("Caesar Salad", 150, 20, new Uri("https://www.galbani.fr/wp-content/uploads/2020/04/AdobeStock_157570276-2.jpeg"), 1) + new RecipeInfo("Chicken Curry", 500, 45, new Uri("https://cdn.chefclub.tools/uploads/recipes/cover-thumbnail/f287b191-dc8e-4c85-bbb6-e26387c354d3.jpg"), 3, new Guid()), + new RecipeInfo("Spaghetti Bolognese", 1000, 30, new Uri("https://media.istockphoto.com/id/1144823591/fr/photo/spaghetti-dans-un-plat-sur-un-fond-blanc.jpg?s=612x612&w=0&k=20&c=qFzd8iE185mpsX7hWqYaieOWlzJVCkzFdYsxmwUT3-Q="), 1, new Guid()), + new RecipeInfo("Beef Stroganoff", 100, 10, new Uri("https://www.cookwithnabeela.com/wp-content/uploads/2023/02/BeefStroganoff.webp"), 5, new Guid()), + new RecipeInfo("Fish And Ships", 450, 15, new Uri("https://upload.wikimedia.org/wikipedia/commons/f/ff/Fish_and_chips_blackpool.jpg"), 4, new Guid()), + new RecipeInfo("Caesar Salad", 150, 20, new Uri("https://www.galbani.fr/wp-content/uploads/2020/04/AdobeStock_157570276-2.jpeg"), 1, new Guid()) }; } public Recipe GetRecipe(RecipeInfo info) { User owner = new User(new Uri("https://i.ibb.co/L6t6bGR/DALL-E-2023-05-10-20-27-31-cook-looking-at-the-camera-with-a-chef-s-hat-laughing-in-an-exaggerated-w.png"), "The Funny Chief"); - List ingredients = new List { new Ingredient("Banana", 12), new Ingredient("Apple", 2) }; - List steps = new List { new PreparationStep("Step 1", "This step is an hardcoded step from a stub implementation of IRecipesSeervice") }; + var ingredients = new List { new Ingredient("Banana", 12), new Ingredient("Apple", 2) }.ToImmutableList(); + var steps = new List { new PreparationStep("Step 1", "This step is an hardcoded step from a stub implementation of IRecipesSeervice") }.ToImmutableList(); return new Recipe(info, owner, ingredients, steps); } - public List RecommendedRecipesOf(Account account) - { - return new List { - new RecipeInfo("Chicken Salad", 500, 20, new Uri("https://healthyfitnessmeals.com/wp-content/uploads/2021/04/Southwest-chicken-salad-7-500x500.jpg"), 4), - new RecipeInfo("Chocolate Cake", 2500, 10, new Uri("https://bakewithshivesh.com/wp-content/uploads/2022/08/IMG_0248-scaled.jpg"), 3), - new RecipeInfo("Salmon", 20, 10, new Uri("https://www.wholesomeyum.com/wp-content/uploads/2021/06/wholesomeyum-Pan-Seared-Salmon-Recipe-13.jpg"), 4), - new RecipeInfo("Fish", 50, 30, new Uri("https://www.ciaanet.org/wp-content/uploads/2022/07/Atlantic-and-Pacific-whole-salmon-1024x683.jpg"), 4.5F), - new RecipeInfo("Space Cake", 800, 5, new Uri("https://static.youmiam.com/images/recipe/1500x1000/space-cake-22706?placeholder=web_recipe&sig=f14a7a86da837c6b8cc678cde424d6d5902f99ec&v3"), 5) - }; - } - - public List LookupFavoritesOf(Account account) - { - return new List { - new RecipeInfo("Chicken Salad", 500, 20, new Uri("https://healthyfitnessmeals.com/wp-content/uploads/2021/04/Southwest-chicken-salad-7-500x500.jpg"), 4), - new RecipeInfo("Space Cake", 800, 5, new Uri("https://static.youmiam.com/images/recipe/1500x1000/space-cake-22706?placeholder=web_recipe&sig=f14a7a86da837c6b8cc678cde424d6d5902f99ec&v3"), 5), - new RecipeInfo("Fish And Ships", 450, 15, new Uri("https://upload.wikimedia.org/wikipedia/commons/f/ff/Fish_and_chips_blackpool.jpg"), 4), - new RecipeInfo("Caesar Salad", 150, 20, new Uri("https://www.galbani.fr/wp-content/uploads/2020/04/AdobeStock_157570276-2.jpeg"), 1) - }; - } - - public List<(RecipeInfo, uint)> LookupWeeklyListOf(Account account) - { - return new List<(RecipeInfo, uint)> { - (new RecipeInfo("Space Cake", 800, 5, new Uri("https://static.youmiam.com/images/recipe/1500x1000/space-cake-22706?placeholder=web_recipe&sig=f14a7a86da837c6b8cc678cde424d6d5902f99ec&v3"), 5), 4), - (new RecipeInfo("Chicken Curry", 500, 45, new Uri("https://cdn.chefclub.tools/uploads/recipes/cover-thumbnail/f287b191-dc8e-4c85-bbb6-e26387c354d3.jpg"), 3), 4), - (new RecipeInfo("Spaghetti Bolognese", 1000, 30, new Uri("https://media.istockphoto.com/id/1144823591/fr/photo/spaghetti-dans-un-plat-sur-un-fond-blanc.jpg?s=612x612&w=0&k=20&c=qFzd8iE185mpsX7hWqYaieOWlzJVCkzFdYsxmwUT3-Q="), 1), 1), - }; - } - - - public AccountRecipeRate GetRateOf(Account account, Recipe recipe) + public IAccountRecipes GetRecipesOf(Account account) { - Random random = new Random(); - return new AccountRecipeRate(random.Next() % 2 == 0, (uint)random.Next(0, 6)); + IAccountRecipes? recipes; + accountsRecipes.TryGetValue(account, out recipes); + + if (recipes == null) { + recipes = new AccountRecipes(account); + recipes.UploadRecipe(new Recipe(new RecipeInfo("Cupcake", 500, 12, new Uri("https://www.mycake.fr/wp-content/uploads/2015/12/rs_cupcake_4x3.jpg"), 4.2F, new Guid()), account.User, new List { new Ingredient("Chocolate", 4) }.ToImmutableList(), new List { new PreparationStep("Eat Chocolate", "Eat the chocolate") }.ToImmutableList())); + accountsRecipes.Add(account, recipes); + } + return recipes; } diff --git a/MainAppShell.xaml.cs b/MainAppShell.xaml.cs index 218e9de..decb72a 100644 --- a/MainAppShell.xaml.cs +++ b/MainAppShell.xaml.cs @@ -12,6 +12,6 @@ public partial class MainAppShell : Shell HomeTab.ContentTemplate = new DataTemplate(() => new HomePage(account, endpoint)); FavoritesTab.ContentTemplate = new DataTemplate(() => new FavoritesPage(account, endpoint.RecipesService)); MyListTab.ContentTemplate = new DataTemplate(() => new MyListPage(account, endpoint.RecipesService)); - MoreTab.ContentTemplate = new DataTemplate(() => new MorePage(account, new MorePageController(app))); + MoreTab.ContentTemplate = new DataTemplate(() => new MorePage(account, new MorePageController(account, endpoint, app))); } } diff --git a/Models/Recipe.cs b/Models/Recipe.cs index 523a221..e077c22 100644 --- a/Models/Recipe.cs +++ b/Models/Recipe.cs @@ -1,8 +1,10 @@ -namespace Models +using System.Collections.Immutable; + +namespace Models { public record Recipe( RecipeInfo Info, User Owner, - List Ingredients, - List Steps); + ImmutableList Ingredients, + ImmutableList Steps); } \ No newline at end of file diff --git a/Models/RecipeInfo.cs b/Models/RecipeInfo.cs index 7846de1..0783744 100644 --- a/Models/RecipeInfo.cs +++ b/Models/RecipeInfo.cs @@ -1,4 +1,10 @@ namespace Models { - public record RecipeInfo(string Name, uint CalPerPers, uint CookTimeMins, Uri Image, float AverageNote); + public record RecipeInfo( + string Name, + uint CalPerPers, + uint CookTimeMins, + Uri Image, + float AverageNote, + Guid Id); } diff --git a/Views/Components/OwnedRecipeView.xaml b/Views/Components/OwnedRecipeView.xaml index 627cc7c..dc14df3 100644 --- a/Views/Components/OwnedRecipeView.xaml +++ b/Views/Components/OwnedRecipeView.xaml @@ -12,13 +12,20 @@ MinimumHeightRequest="175" MinimumWidthRequest="150" RowDefinitions="*, Auto"> + + + + + - + SetNote(value); @@ -37,8 +50,13 @@ public partial class OwnedRecipeView : ContentView } } - private void TapGestureRecognizer_Tapped(object sender, TappedEventArgs e) + private void OnViewTapped(object sender, TappedEventArgs e) + { + clickCallback(); + } + + private void OnRemoveButtonTapped(object sender, TappedEventArgs e) { - Console.WriteLine("This is a test"); + removeCallback(); } } \ No newline at end of file diff --git a/Views/Components/RecipeView.xaml.cs b/Views/Components/RecipeView.xaml.cs index 44d826b..ab44ee4 100644 --- a/Views/Components/RecipeView.xaml.cs +++ b/Views/Components/RecipeView.xaml.cs @@ -19,6 +19,8 @@ public partial class RecipeView : ContentView } + + public float Note { set => SetNote(value); @@ -34,7 +36,6 @@ public partial class RecipeView : ContentView set => SubtitleLabel.Text = value; } - private void SetNote(float note) { int i = 1; diff --git a/Views/FavoritesPage.xaml.cs b/Views/FavoritesPage.xaml.cs index 26f7483..ae667ed 100644 --- a/Views/FavoritesPage.xaml.cs +++ b/Views/FavoritesPage.xaml.cs @@ -3,6 +3,7 @@ using Models; namespace ShoopNCook.Pages; using Endpoint; +using LocalEndpoint; using Models; using ShoopNCook.Views; @@ -12,13 +13,13 @@ public partial class FavoritesPage : ContentPage { InitializeComponent(); - //TODO this code can be factorised (see HomePage, MyListPage) - service.LookupFavoritesOf(account).ForEach(info => + IAccountRecipes recipes = service.GetRecipesOf(account); + recipes.GetFavorites().ForEach(info => { RecipeViewLayout.Children.Add(new RecipeView(info, () => { Recipe recipe = service.GetRecipe(info); - AccountRecipeRate rate = service.GetRateOf(account, recipe); + AccountRecipeRate? rate = recipes.FindRate(info); Shell.Current.Navigation.PushAsync(new RecipePage(recipe, rate, 1)); })); }); diff --git a/Views/HomePage.xaml.cs b/Views/HomePage.xaml.cs index 8c1fe20..2082d1f 100644 --- a/Views/HomePage.xaml.cs +++ b/Views/HomePage.xaml.cs @@ -3,6 +3,7 @@ namespace ShoopNCook.Pages; using Models; using ShoopNCook.Views; using Endpoint; +using LocalEndpoint; public partial class HomePage : ContentPage { @@ -11,6 +12,7 @@ public partial class HomePage : ContentPage InitializeComponent(); IRecipesService service = endpoint.RecipesService; + IAccountRecipes recipes = service.GetRecipesOf(account); //TODO this code can be factorised @@ -19,14 +21,13 @@ public partial class HomePage : ContentPage layout.Children.Add(new RecipeView(info, () => { Recipe recipe = service.GetRecipe(info); - AccountRecipeRate rate = service.GetRateOf(account, recipe); + AccountRecipeRate rate = recipes.FindRate(info); Shell.Current.Navigation.PushAsync(new RecipePage(recipe, rate, 1)); })); } - service.PopularRecipes().ForEach(recipe => PushRecipe(PopularsList, recipe)); - service.RecommendedRecipesOf(account).ForEach(recipe => PushRecipe(RecommendedList, recipe)); + recipes.GetRecommendedRecipes().ForEach(recipe => PushRecipe(RecommendedList, recipe)); ProfilePictureImage.Source = ImageSource.FromUri(account.User.ProfilePicture); ProfilePictureName.Text = account.User.Name; diff --git a/Views/MorePage.xaml.cs b/Views/MorePage.xaml.cs index 3564167..9e20b5e 100644 --- a/Views/MorePage.xaml.cs +++ b/Views/MorePage.xaml.cs @@ -16,14 +16,14 @@ public partial class MorePage : ContentPage this.controller = controller; } - private async void OnMyRecipesButtonTapped(object sender, EventArgs e) + private void OnMyRecipesButtonTapped(object sender, EventArgs e) { - await Shell.Current.Navigation.PushAsync(new MyRecipesPage()); + controller.GoToMyRecipesPage(); } - private async void OnEditProfileButtonTapped(object sender, EventArgs e) + private void OnEditProfileButtonTapped(object sender, EventArgs e) { - await Shell.Current.Navigation.PushAsync(new ProfilePage()); + controller.GoToProfilePage(); } private void OnLogoutButtonTapped(object sender, EventArgs e) diff --git a/Views/MyListPage.xaml.cs b/Views/MyListPage.xaml.cs index 1aa06b7..f09d1c7 100644 --- a/Views/MyListPage.xaml.cs +++ b/Views/MyListPage.xaml.cs @@ -1,4 +1,5 @@ using Endpoint; +using LocalEndpoint; using Models; using ShoopNCook.Views; @@ -10,12 +11,14 @@ public partial class MyListPage : ContentPage { InitializeComponent(); - service.LookupWeeklyListOf(account).ForEach(info => + IAccountRecipes recipes = service.GetRecipesOf(account); + recipes.GetWeeklyList().ForEach(tuple => { - RecipesLayout.Children.Add(new StoredRecipeView(info.Item1, info.Item2, amount => + RecipeInfo info = tuple.Item1; + RecipesLayout.Children.Add(new StoredRecipeView(info, tuple.Item2, amount => { - Recipe recipe = service.GetRecipe(info.Item1); - AccountRecipeRate rate = service.GetRateOf(account, recipe); + Recipe recipe = service.GetRecipe(info); + AccountRecipeRate? rate = recipes.FindRate(info); Shell.Current.Navigation.PushAsync(new RecipePage(recipe, rate, amount)); })); }); diff --git a/Views/MyRecipesPage.xaml b/Views/MyRecipesPage.xaml index 34835d0..f9f2b2a 100644 --- a/Views/MyRecipesPage.xaml +++ b/Views/MyRecipesPage.xaml @@ -38,18 +38,9 @@ AlignItems="Start" AlignContent="Start" Direction="Row" - Wrap="Wrap"> + Wrap="Wrap" + x:Name="RecipesLayout"> - - - - - - - - - - diff --git a/Views/MyRecipesPage.xaml.cs b/Views/MyRecipesPage.xaml.cs index cabf0bf..ebd37ba 100644 --- a/Views/MyRecipesPage.xaml.cs +++ b/Views/MyRecipesPage.xaml.cs @@ -1,12 +1,58 @@ +using Endpoint; +using LocalEndpoint; +using Models; +using ShoopNCook.Controllers; +using ShoopNCook.Views; + namespace ShoopNCook.Pages; public partial class MyRecipesPage : ContentPage { - public MyRecipesPage() - { + + private IUserNotifier notifier; + private IAccountRecipes recipes; + + public MyRecipesPage( + Account account, + IRecipesService service, + IUserNotifier notifier) + { InitializeComponent(); - } + this.notifier = notifier; + this.recipes = service.GetRecipesOf(account); + + recipes.GetAccountRecipes().ForEach(info => + { + RecipesLayout.Children.Add(new OwnedRecipeView(info, () => + { + Recipe recipe = service.GetRecipe(info); + AccountRecipeRate? rate = recipes.FindRate(info); + Shell.Current.Navigation.PushAsync(new RecipePage(recipe, rate, 1)); + }, + () => RemoveRecipe(info) + )); + }); + } + + private void RemoveRecipe(RecipeInfo info) + { + if (!recipes.RemoveRecipe(info)) + { + notifier.Error("Could not remove recipe"); + return; + } + foreach (OwnedRecipeView view in RecipesLayout.Children) + { + if (view.IsViewing(info)) + { + RecipesLayout.Remove(view); + break; + } + } + notifier.Success("Recipe successfully removed"); + } + private async void OnBackButtonClicked(object sender, EventArgs e) { await Navigation.PopAsync(); diff --git a/Views/ProfilePage.xaml.cs b/Views/ProfilePage.xaml.cs index 86b31c0..9b90431 100644 --- a/Views/ProfilePage.xaml.cs +++ b/Views/ProfilePage.xaml.cs @@ -1,8 +1,10 @@ +using Models; + namespace ShoopNCook.Pages; public partial class ProfilePage : ContentPage { - public ProfilePage() + public ProfilePage(Account account) { InitializeComponent(); } diff --git a/Views/RecipePage.xaml.cs b/Views/RecipePage.xaml.cs index 61c4c2b..e0df08b 100644 --- a/Views/RecipePage.xaml.cs +++ b/Views/RecipePage.xaml.cs @@ -12,14 +12,14 @@ public partial class RecipePage : ContentPage public ICommand StarCommand => new Command(count => SetNote(uint.Parse(count))); - public RecipePage(Recipe recipe, AccountRecipeRate rate, uint amount) + public RecipePage(Recipe recipe, AccountRecipeRate? rate, uint amount) { InitializeComponent(); Counter.Count = amount; - note = rate.Rate; - isFavorite = rate.IsFavorite; + note = rate?.Rate ?? 0; + isFavorite = rate?.IsFavorite ?? false; SetFavorite(isFavorite); SetNote(note);