add favorite list handlings on app side and LocalEnpoint. Add 'RecipeDatabase' class to simulate a Recipe database
continuous-integration/drone/push Build is passing Details

pull/50/head
maxime.BATISTA@etu.uca.fr 2 years ago
parent ebeed7a28c
commit 4638b3efd6

@ -0,0 +1,23 @@
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 IAccountOwnedRecipes
{
public Account Account { get; }
public bool UploadRecipe(Recipe recipe);
public bool RemoveRecipe(RecipeInfo info);
public ImmutableList<RecipeInfo> GetAccountRecipes();
}
}

@ -6,27 +6,24 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LocalEndpoint
namespace Endpoint
{
public interface IAccountRecipes
public interface IAccountRecipesPreferences
{
public Account Account { get; }
public bool UploadRecipe(Recipe recipe);
public bool RemoveRecipe(RecipeInfo info);
public void SetRate(RecipeInfo info, AccountRecipeRate rate);
public void AddToFavorites(RecipeInfo info);
public void RemoveFromFavorites(RecipeInfo info);
public void SetReviewScore(RecipeInfo info, uint score);
public AccountRecipeRate? FindRate(RecipeInfo info);
public AccountRecipeRate GetRate(RecipeInfo info);
public ImmutableList<RecipeInfo> GetAccountRecipes();
public ImmutableList<RecipeInfo> GetFavorites();
public ImmutableList<RecipeInfo> GetRecommendedRecipes();
public ImmutableList<RecipeInfo> GetFavorites();
public ImmutableList<(RecipeInfo, uint)> GetWeeklyList();
}
}

@ -2,6 +2,7 @@
using Models;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -10,11 +11,12 @@ namespace Endpoint
{
public interface IRecipesService
{
public List<RecipeInfo> PopularRecipes();
public ImmutableList<RecipeInfo> PopularRecipes();
public Recipe GetRecipe(RecipeInfo info);
public IAccountRecipes GetRecipesOf(Account account);
public IAccountOwnedRecipes GetRecipesOf(Account account);
public IAccountRecipesPreferences GetPreferencesOf(Account account);
}

@ -0,0 +1,11 @@
using Endpoint;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LocalEndpoint
{
internal record AccountData(IAccountOwnedRecipes Recipes, IAccountRecipesPreferences Preferences);
}

@ -1,38 +0,0 @@
using Models;
using Endpoint;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LocalEndpoint
{
internal class AccountManager : IAccountManager
{
private static readonly Uri DEFAULT_ACCOUNT_IMAGE = new Uri("https://www.pngkey.com/png/full/115-1150152_default-profile-picture-avatar-png-green.png");
private Account userAccount = new Account(new User(DEFAULT_ACCOUNT_IMAGE, "Stub Account"), "test@example.com");
private string userPassword = "123456";
public Account? Login(string email, string password)
{
if (userAccount.Email == email && userPassword == password)
{
return userAccount;
}
return null;
}
public Account? Register(string email, string username, string password)
{
if (email == null || username == null || password == null)
return null;
userAccount = new Account(new User(DEFAULT_ACCOUNT_IMAGE, username), email);
userPassword = password;
return userAccount;
}
}
}

@ -0,0 +1,52 @@
using LocalEndpoint;
using Models;
using System.Collections.Immutable;
namespace Endpoint
{
internal class AccountOwnedRecipes : IAccountOwnedRecipes
{
public Account Account { get; init; }
private readonly Dictionary<Guid, Recipe> ownedRecipes = new Dictionary<Guid, Recipe>();
private readonly RecipesDatabase db;
public AccountOwnedRecipes(Account account, RecipesDatabase db)
{
Account = account;
this.db = db;
//Retrieve all owned recipes from database.
db.ListAll().ForEach(recipe =>
{
if (recipe.Owner == account.User) ownedRecipes[recipe.Info.Id] = recipe;
});
}
public bool UploadRecipe(Recipe recipe)
{
Guid id = recipe.Info.Id;
if (ownedRecipes.ContainsKey(id))
{
return false;
}
db.Insert(recipe);
ownedRecipes.Add(id, recipe);
return true;
}
public bool RemoveRecipe(RecipeInfo info)
{
db.Remove(info.Id);
return ownedRecipes.Remove(info.Id);
}
public ImmutableList<RecipeInfo> GetAccountRecipes()
{
return ownedRecipes.Values.ToImmutableList().ConvertAll(r => r.Info);
}
}
}

@ -1,84 +0,0 @@
using LocalEndpoint;
using Models;
using System.Collections.Immutable;
namespace Endpoint
{
internal class AccountRecipes : IAccountRecipes
{
public Account Account { get; init; }
private readonly Dictionary<Guid, Recipe> ownedRecipes = new Dictionary<Guid, Recipe>();
private readonly Dictionary<Guid, AccountRecipeRate> ratedRecipes = new Dictionary<Guid, AccountRecipeRate>();
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<RecipeInfo> GetAccountRecipes()
{
return ownedRecipes.Values.ToImmutableList().ConvertAll(r => r.Info);
}
public ImmutableList<RecipeInfo> GetRecommendedRecipes()
{
return new List<RecipeInfo> {
new RecipeInfo("Chicken Salad", 500, 20, new Uri("https://healthyfitnessmeals.com/wp-content/uploads/2021/04/Southwest-chicken-salad-7-500x500.jpg"), 4, Guid.NewGuid()),
new RecipeInfo("Chocolate Cake", 2500, 10, new Uri("https://bakewithshivesh.com/wp-content/uploads/2022/08/IMG_0248-scaled.jpg"), 3, Guid.NewGuid()),
new RecipeInfo("Salmon", 20, 10, new Uri("https://www.wholesomeyum.com/wp-content/uploads/2021/06/wholesomeyum-Pan-Seared-Salmon-Recipe-13.jpg"), 4, Guid.NewGuid()),
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, Guid.NewGuid()),
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, Guid.NewGuid())
}.ToImmutableList();
}
public ImmutableList<RecipeInfo> GetFavorites()
{
return new List<RecipeInfo> {
new RecipeInfo("Chicken Salad", 500, 20, new Uri("https://healthyfitnessmeals.com/wp-content/uploads/2021/04/Southwest-chicken-salad-7-500x500.jpg"), 4, Guid.NewGuid()),
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, Guid.NewGuid()),
new RecipeInfo("Fish And Ships", 450, 15, new Uri("https://upload.wikimedia.org/wikipedia/commons/f/ff/Fish_and_chips_blackpool.jpg"), 4, Guid.NewGuid()),
new RecipeInfo("Caesar Salad", 150, 20, new Uri("https://www.galbani.fr/wp-content/uploads/2020/04/AdobeStock_157570276-2.jpeg"), 1, Guid.NewGuid())
}.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, Guid.NewGuid()), 4),
(new RecipeInfo("Chicken Curry", 500, 45, new Uri("https://cdn.chefclub.tools/uploads/recipes/cover-thumbnail/f287b191-dc8e-4c85-bbb6-e26387c354d3.jpg"), 3, Guid.NewGuid()), 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, Guid.NewGuid()), 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;
}
}
}

@ -0,0 +1,91 @@
using Endpoint;
using Models;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LocalEndpoint
{
internal class AccountRecipesPreferences : IAccountRecipesPreferences
{
//Binds a recipe's id to it's account review ratings.
private readonly Dictionary<Guid, AccountRecipeRate> ratings = new Dictionary<Guid, AccountRecipeRate>();
//Binds a recipe's id to its amount of person stored in the account's weekly list
private readonly Dictionary<Guid, uint> weekly = new Dictionary<Guid, uint>();
private readonly RecipesDatabase db;
public AccountRecipesPreferences(Account account, RecipesDatabase db)
{
Account = account;
this.db = db;
}
public Account Account { get; init; }
public ImmutableList<RecipeInfo> GetRecommendedRecipes()
{
return db.ListAll().ConvertAll(recipe => recipe.Info);
}
public ImmutableList<RecipeInfo> GetFavorites()
{
List<RecipeInfo> favorites = new List<RecipeInfo>();
foreach (Recipe recipe in db.ListAll())
{
if (ratings.TryGetValue(recipe.Info.Id, out AccountRecipeRate? rate))
{
if (rate.IsFavorite)
favorites.Add(recipe.Info);
}
}
return favorites.ToImmutableList();
}
public ImmutableList<(RecipeInfo, uint)> GetWeeklyList()
{
List<(RecipeInfo, uint)> weekly = new List<(RecipeInfo, uint)>();
foreach (Recipe recipe in db.ListAll())
{
if (this.weekly.TryGetValue(recipe.Info.Id, out uint personAmmount))
{
weekly.Add((recipe.Info, personAmmount));
}
}
return weekly.ToImmutableList();
}
public AccountRecipeRate GetRate(RecipeInfo info)
{
AccountRecipeRate rate = null;
if (!ratings.TryGetValue(info.Id, out rate))
{
rate = new AccountRecipeRate();
ratings.Add(info.Id, rate);
}
return rate;
}
public void AddToFavorites(RecipeInfo info)
{
AccountRecipeRate rate = GetRate(info);
ratings[info.Id] = new AccountRecipeRate(true, rate.Rate);
}
public void RemoveFromFavorites(RecipeInfo info)
{
AccountRecipeRate rate = GetRate(info);
ratings[info.Id] = new AccountRecipeRate(false, rate.Rate);
}
public void SetReviewScore(RecipeInfo info, uint score)
{
AccountRecipeRate rate = GetRate(info);
ratings[info.Id] = new AccountRecipeRate(rate.IsFavorite, score);
}
}
}

@ -0,0 +1,33 @@
using Models;
using Endpoint;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LocalEndpoint
{
internal class ConnectionManager : IAccountManager
{
private Account userAccount = Constants.MAIN_USER_ACCOUNT;
private string userPassword = Constants.MAIN_USER_PASSWORD;
public Account? Login(string email, string password)
{
if (Constants.MAIN_USER_ACCOUNT.Email == email && Constants.MAIN_USER_PASSWORD == password)
return Constants.MAIN_USER_ACCOUNT;
return null;
}
public Account? Register(string email, string username, string password)
{
if (email == null || username == null || password == null)
return null;
userAccount = new Account(new User(Constants.DEFAULT_ACCOUNT_IMAGE, username), email);
userPassword = password;
return userAccount;
}
}
}

@ -0,0 +1,20 @@
using Models;
namespace LocalEndpoint
{
internal class Constants
{
public static readonly Uri DEFAULT_ACCOUNT_IMAGE = new Uri("https://www.pngkey.com/png/full/115-1150152_default-profile-picture-avatar-png-green.png");
// User account for tests
public static readonly Account MAIN_USER_ACCOUNT = new Account(new User(DEFAULT_ACCOUNT_IMAGE, "Example Account"), "test@example.com");
public static readonly string MAIN_USER_PASSWORD = "123456";
// other user samples
public static readonly User USER1 = 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");
public static readonly User USER2 = new User(DEFAULT_ACCOUNT_IMAGE, "Yanis");
public static readonly User USER3 = new User(DEFAULT_ACCOUNT_IMAGE, "Leo");
}
}

@ -1,11 +1,34 @@
using Endpoint;
using Models;
using System.Collections.Immutable;
namespace LocalEndpoint
{
/// <summary>
/// The local endpoint is an implementation of the Endpoint API definition.
///
/// </summary>
public class LocalEndpoint : IEndpoint
{
private IAccountManager accountManager = new AccountManager();
private IRecipesService recipesService = new RecipesService();
private readonly IAccountManager accountManager = new ConnectionManager();
private readonly IRecipesService recipesService;
public LocalEndpoint()
{
RecipesDatabase db = new RecipesDatabase();
//miam
db.Insert(new Recipe(new RecipeInfo("Chicken Salad", 500, 20, new Uri("https://healthyfitnessmeals.com/wp-content/uploads/2021/04/Southwest-chicken-salad-7-500x500.jpg"), 4, Guid.NewGuid()), Constants.USER1, new List<Ingredient> { new Ingredient("Ingredient 1", 6) }.ToImmutableList(), new List<PreparationStep> { new PreparationStep("Step 1", "Bake the eggs") }.ToImmutableList()));
db.Insert(new Recipe(new RecipeInfo("Chocolate Cake", 2500, 10, new Uri("https://bakewithshivesh.com/wp-content/uploads/2022/08/IMG_0248-scaled.jpg"), 3, Guid.NewGuid()), Constants.USER2, new List<Ingredient> { new Ingredient("Ingredient 1", 6) }.ToImmutableList(), new List<PreparationStep> { new PreparationStep("Step 1", "Bake the eggs") }.ToImmutableList()));
db.Insert(new Recipe(new RecipeInfo("Salmon", 20, 10, new Uri("https://www.wholesomeyum.com/wp-content/uploads/2021/06/wholesomeyum-Pan-Seared-Salmon-Recipe-13.jpg"), 4, Guid.NewGuid()), Constants.MAIN_USER_ACCOUNT.User, new List<Ingredient> { new Ingredient("Ingredient 1", 6) }.ToImmutableList(), new List<PreparationStep> { new PreparationStep("Step 1", "Bake the eggs") }.ToImmutableList()));
db.Insert(new Recipe(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, Guid.NewGuid()), Constants.MAIN_USER_ACCOUNT.User, new List<Ingredient> { new Ingredient("Ingredient 1", 6) }.ToImmutableList(), new List<PreparationStep> { new PreparationStep("Step 1", "Bake the eggs") }.ToImmutableList()));
db.Insert(new Recipe(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, Guid.NewGuid()), Constants.USER3, new List<Ingredient> { new Ingredient("Ingredient 1", 6) }.ToImmutableList(), new List<PreparationStep> { new PreparationStep("Step 1", "Bake the eggs") }.ToImmutableList()));
recipesService = new RecipesService(db);
}
public IAccountManager AccountManager => accountManager;
public IRecipesService RecipesService => recipesService;

@ -0,0 +1,43 @@
using Models;
using System.Collections.Generic;
using System.Collections.Immutable;
namespace LocalEndpoint
{
//Simple class to simulate a recipe database
internal class RecipesDatabase
{
private Dictionary<Guid, Recipe> recipes = new Dictionary<Guid, Recipe>();
public Recipe? Lookup(Guid id)
{
Recipe? recipe;
recipes.TryGetValue(id, out recipe);
return recipe;
}
public Recipe Get(Guid id)
{
return recipes[id];
}
public void Insert(Recipe recipe)
{
recipes[recipe.Info.Id] = recipe;
}
public void Remove(Guid id)
{
recipes.Remove(id);
}
public ImmutableList<Recipe> ListAll()
{
return recipes.Values.ToImmutableList();
}
}
}

@ -7,41 +7,49 @@ namespace LocalEndpoint
internal class RecipesService : IRecipesService
{
private readonly Dictionary<Account, IAccountRecipes> accountsRecipes = new Dictionary<Account, IAccountRecipes>();
private readonly RecipesDatabase db;
private readonly Dictionary<Account, AccountData> accountsData = new Dictionary<Account, AccountData>();
public List<RecipeInfo> PopularRecipes()
public RecipesService(RecipesDatabase db)
{
return new List<RecipeInfo> {
new RecipeInfo("Chicken Curry", 500, 45, new Uri("https://cdn.chefclub.tools/uploads/recipes/cover-thumbnail/f287b191-dc8e-4c85-bbb6-e26387c354d3.jpg"), 3, Guid.NewGuid()),
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, Guid.NewGuid()),
new RecipeInfo("Beef Stroganoff", 100, 10, new Uri("https://www.cookwithnabeela.com/wp-content/uploads/2023/02/BeefStroganoff.webp"), 5, Guid.NewGuid()),
new RecipeInfo("Fish And Ships", 450, 15, new Uri("https://upload.wikimedia.org/wikipedia/commons/f/ff/Fish_and_chips_blackpool.jpg"), 4, Guid.NewGuid()),
new RecipeInfo("Caesar Salad", 150, 20, new Uri("https://www.galbani.fr/wp-content/uploads/2020/04/AdobeStock_157570276-2.jpeg"), 1, Guid.NewGuid())
};
this.db = db;
}
public ImmutableList<RecipeInfo> PopularRecipes()
{
return db.ListAll().Take(4).ToImmutableList().ConvertAll(v => v.Info);
}
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");
var ingredients = new List<Ingredient> { new Ingredient("Banana", 12), new Ingredient("Apple", 2) }.ToImmutableList();
var steps = new List<PreparationStep> { new PreparationStep("Step 1", "This step is an hardcoded step from a stub implementation of IRecipesSeervice") }.ToImmutableList();
return new Recipe(info, owner, ingredients, steps);
return db.Get(info.Id);
}
public IAccountRecipes GetRecipesOf(Account account)
public IAccountOwnedRecipes GetRecipesOf(Account account)
{
return GetOrInitData(account).Recipes;
}
public IAccountRecipesPreferences GetPreferencesOf(Account account)
{
return GetOrInitData(account).Preferences;
}
private AccountData GetOrInitData(Account account)
{
IAccountRecipes? recipes;
accountsRecipes.TryGetValue(account, out recipes);
AccountData? data;
accountsData.TryGetValue(account, out data);
if (recipes == null) {
recipes = new AccountRecipes(account);
if (data == null)
{
AccountOwnedRecipes recipes = new AccountOwnedRecipes(account, db);
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, Guid.NewGuid()), account.User, new List<Ingredient> { new Ingredient("Chocolate", 4) }.ToImmutableList(), new List<PreparationStep> { new PreparationStep("Eat Chocolate", "Eat the chocolate") }.ToImmutableList()));
accountsRecipes.Add(account, recipes);
AccountRecipesPreferences preferences = new AccountRecipesPreferences(account, db);
data = new AccountData(recipes, preferences);
accountsData.Add(account, data);
}
return recipes;
return data;
}
}
}

@ -9,9 +9,9 @@ public partial class MainAppShell : Shell
public MainAppShell(Account account, IEndpoint endpoint, IApp app)
{
InitializeComponent();
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));
HomeTab.ContentTemplate = new DataTemplate(() => new HomePage(account, app.Notifier, endpoint));
FavoritesTab.ContentTemplate = new DataTemplate(() => new FavoritesPage(account, app.Notifier, endpoint.RecipesService));
MyListTab.ContentTemplate = new DataTemplate(() => new MyListPage(account, app.Notifier, endpoint.RecipesService));
MoreTab.ContentTemplate = new DataTemplate(() => new MorePage(account, new MorePageController(account, endpoint, app)));
}
}

@ -1,5 +1,5 @@

namespace Models
{
public record AccountRecipeRate(bool IsFavorite, uint Rate);
public record AccountRecipeRate(bool IsFavorite = false, uint Rate = 0);
}

@ -4,7 +4,8 @@
x:Class="ShoopNCook.Pages.FavoritesPage"
Title="FavoritesPage"
xmlns:views="clr-namespace:ShoopNCook.Views"
BackgroundColor="{StaticResource BackgroundPrimary}">
BackgroundColor="{StaticResource BackgroundPrimary}"
NavigatedTo="ContentPage_NavigatedTo">
<Grid
RowDefinitions="Auto, *">

@ -6,24 +6,41 @@ using Endpoint;
using LocalEndpoint;
using Models;
using ShoopNCook.Views;
using System.Security.Principal;
public partial class FavoritesPage : ContentPage
{
public FavoritesPage(Account account, IRecipesService service)
private readonly Account account;
private readonly IUserNotifier notifier;
private IRecipesService service;
public FavoritesPage(Account account, IUserNotifier notifier, IRecipesService service)
{
InitializeComponent();
this.account = account;
this.notifier = notifier;
this.service = service;
UpdateFavorites();
}
IAccountRecipes recipes = service.GetRecipesOf(account);
recipes.GetFavorites().ForEach(info =>
private void UpdateFavorites()
{
IAccountRecipesPreferences preferences = service.GetPreferencesOf(account);
RecipeViewLayout.Children.Clear();
preferences.GetFavorites().ForEach(info =>
{
RecipeViewLayout.Children.Add(new RecipeView(info, () =>
{
Recipe recipe = service.GetRecipe(info);
AccountRecipeRate? rate = recipes.FindRate(info);
Shell.Current.Navigation.PushAsync(new RecipePage(recipe, rate, 1));
Shell.Current.Navigation.PushAsync(new RecipePage(recipe, notifier, preferences, 1));
}));
});
}
private void ContentPage_NavigatedTo(object sender, NavigatedToEventArgs e)
{
UpdateFavorites();
}
}

@ -7,12 +7,12 @@ using LocalEndpoint;
public partial class HomePage : ContentPage
{
public HomePage(Account account, IEndpoint endpoint)
public HomePage(Account account, IUserNotifier notifier, IEndpoint endpoint)
{
InitializeComponent();
IRecipesService service = endpoint.RecipesService;
IAccountRecipes recipes = service.GetRecipesOf(account);
IAccountRecipesPreferences preferences = service.GetPreferencesOf(account);
//TODO this code can be factorised
@ -21,13 +21,12 @@ public partial class HomePage : ContentPage
layout.Children.Add(new RecipeView(info, () =>
{
Recipe recipe = service.GetRecipe(info);
AccountRecipeRate rate = recipes.FindRate(info);
Shell.Current.Navigation.PushAsync(new RecipePage(recipe, rate, 1));
Shell.Current.Navigation.PushAsync(new RecipePage(recipe, notifier, preferences, 1));
}));
}
service.PopularRecipes().ForEach(recipe => PushRecipe(PopularsList, recipe));
recipes.GetRecommendedRecipes().ForEach(recipe => PushRecipe(RecommendedList, recipe));
preferences.GetRecommendedRecipes().ForEach(recipe => PushRecipe(RecommendedList, recipe));
ProfilePictureImage.Source = ImageSource.FromUri(account.User.ProfilePicture);
ProfilePictureName.Text = account.User.Name;

@ -7,19 +7,18 @@ namespace ShoopNCook.Pages;
public partial class MyListPage : ContentPage
{
public MyListPage(Account account, IRecipesService service)
public MyListPage(Account account, IUserNotifier notifier, IRecipesService service)
{
InitializeComponent();
IAccountRecipes recipes = service.GetRecipesOf(account);
recipes.GetWeeklyList().ForEach(tuple =>
IAccountRecipesPreferences preferences = service.GetPreferencesOf(account);
preferences.GetWeeklyList().ForEach(tuple =>
{
RecipeInfo info = tuple.Item1;
RecipesLayout.Children.Add(new StoredRecipeView(info, tuple.Item2, amount =>
{
Recipe recipe = service.GetRecipe(info);
AccountRecipeRate? rate = recipes.FindRate(info);
Shell.Current.Navigation.PushAsync(new RecipePage(recipe, rate, amount));
Shell.Current.Navigation.PushAsync(new RecipePage(recipe, notifier, preferences, amount));
}));
});

@ -10,7 +10,7 @@ public partial class MyRecipesPage : ContentPage
private IUserNotifier notifier;
private IRecipesService service;
private IAccountRecipes recipes;
private Account account;
public MyRecipesPage(
Account account,
@ -21,9 +21,12 @@ public partial class MyRecipesPage : ContentPage
this.notifier = notifier;
this.service = service;
this.recipes = service.GetRecipesOf(account);
this.account = account;
recipes.GetAccountRecipes().ForEach(AddRecipeView);
service
.GetRecipesOf(account)
.GetAccountRecipes()
.ForEach(AddRecipeView);
}
private void AddRecipeView(RecipeInfo info)
@ -31,8 +34,8 @@ public partial class MyRecipesPage : ContentPage
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));
IAccountRecipesPreferences preferences = service.GetPreferencesOf(account);
Shell.Current.Navigation.PushAsync(new RecipePage(recipe, notifier, preferences, 1));
},
() => RemoveRecipe(info)
));
@ -40,6 +43,8 @@ public partial class MyRecipesPage : ContentPage
private void RemoveRecipe(RecipeInfo info)
{
IAccountOwnedRecipes recipes = service.GetRecipesOf(account);
if (!recipes.RemoveRecipe(info))
{
notifier.Error("Could not remove recipe");
@ -62,7 +67,9 @@ public partial class MyRecipesPage : ContentPage
}
private void OnAddRecipeButtonClicked(object sender, EventArgs e)
{
var page = new CreateRecipePage(recipes.Account.User, notifier, recipe =>
IAccountOwnedRecipes recipes = service.GetRecipesOf(account);
var page = new CreateRecipePage(account.User, notifier, recipe =>
{
if (!recipes.UploadRecipe(recipe))
{

@ -8,7 +8,6 @@
BackgroundColor="{StaticResource BackgroundPrimary}">
<Grid
RowDefinitions="90*, 10*"
Padding="10">
@ -51,7 +50,8 @@
StrokeShape="RoundRectangle 20"
BackgroundColor="{StaticResource ImageBackground}">
<Image
HeightRequest="250"/>
HeightRequest="250"
x:Name="RecipeImage"/>
</Border>
<!--Steps-->
@ -146,7 +146,8 @@
BackgroundColor="{StaticResource Selected}"
VerticalOptions="Center"
HorizontalOptions="Center"
Text="Submit"/>
Text="Submit"
Clicked="OnSubmitReviewClicked"/>
</Border>
</HorizontalStackLayout>
</Grid>

@ -1,6 +1,9 @@
using ShoopNCook.Views;
using System.Windows.Input;
using Models;
using LocalEndpoint;
using Endpoint;
namespace ShoopNCook.Pages;
public partial class RecipePage : ContentPage
@ -9,27 +12,39 @@ public partial class RecipePage : ContentPage
private uint note;
private bool isFavorite;
public ICommand StarCommand => new Command<string>(count => SetNote(uint.Parse(count)));
private IAccountRecipesPreferences preferences;
private IUserNotifier notifier;
private RecipeInfo info;
public ICommand StarCommand => new Command<string>(count => SetNote(uint.Parse(count)));
public RecipePage(Recipe recipe, AccountRecipeRate? rate, uint amount)
public RecipePage(Recipe recipe, IUserNotifier notifier, IAccountRecipesPreferences preferences, uint amount)
{
InitializeComponent();
Counter.Count = amount;
this.preferences = preferences;
this.notifier = notifier;
this.info = recipe.Info;
AccountRecipeRate rate = preferences.GetRate(recipe.Info);
note = rate?.Rate ?? 0;
isFavorite = rate?.IsFavorite ?? false;
note = rate.Rate;
isFavorite = rate.IsFavorite;
SetFavorite(isFavorite);
SetNote(note);
RecipeInfo info = recipe.Info;
Counter.Count = amount;
CookTime.Text = info.CookTimeMins.ToString();
Energy.Text = info.CalPerPers.ToString() + " cal/pers";
RecipeName.Text = info.Name;
if (info.Image != null)
RecipeImage.Source = ImageSource.FromUri(info.Image);
foreach (Ingredient ingredient in recipe.Ingredients)
IngredientList.Add(new IngredientView(ingredient));
@ -58,32 +73,39 @@ public partial class RecipePage : ContentPage
i++;
}
else
{
img.Source = ImageSource.FromFile("star_empty.svg");
}
}
}
private void OnFavorite(object o, EventArgs e)
{
SetFavorite(!isFavorite);
}
private void OnSubmitReviewClicked(object o, EventArgs e)
{
preferences.SetReviewScore(info, note);
notifier.Success("Your review has been successfuly submited");
}
private void SetFavorite(bool isFavorite)
{
this.isFavorite = isFavorite;
if (isFavorite)
{
Favorite.Source = ImageSource.FromFile("hearth_on.svg");
preferences.AddToFavorites(info);
}
else
{
Favorite.Source = ImageSource.FromFile("hearth_off.svg");
preferences.RemoveFromFavorites(info);
}
}
private async void OnBackButtonClicked(object sender, EventArgs e)
private void OnBackButtonClicked(object sender, EventArgs e)
{
await Navigation.PopAsync();
Navigation.PopAsync();
}
}
Loading…
Cancel
Save