make remove recipe system
continuous-integration/drone/push Build is passing Details

pull/50/head
maxime.BATISTA@etu.uca.fr 2 years ago
parent b213edb4ef
commit c04fec0927

@ -8,7 +8,7 @@ public partial class App : Application, ConnectionObserver, IApp
private IEndpoint Endpoint = new LocalEndpoint(); private IEndpoint Endpoint = new LocalEndpoint();
public UserNotifier Notifier => new ConsoleUserNotifier(); public IUserNotifier Notifier => new ConsoleUserNotifier();
public App() public App()
{ {

@ -7,7 +7,7 @@ using ShoopNCook.Pages;
public partial class ConnectAppShell : Shell 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); ConnectionController controller = new ConnectionController(observer, accounts, notifier);
InitializeComponent(); InitializeComponent();

@ -4,8 +4,15 @@
/// A notice reporter implementation that prints in console the applications's user notices. /// A notice reporter implementation that prints in console the applications's user notices.
/// </summary> /// </summary>
public class ConsoleUserNotifier : public class ConsoleUserNotifier :
UserNotifier IUserNotifier
{ {
public void Success(string message)
{
Console.WriteLine("<User Notice> Success: " + message);
}
public void Error(string message) public void Error(string message)
{ {
Console.WriteLine("<User Notice> Error: " + message); Console.WriteLine("<User Notice> Error: " + message);

@ -7,8 +7,8 @@ namespace ShoopNCook.Controllers
{ {
private readonly ConnectionObserver observer; private readonly ConnectionObserver observer;
private readonly IAccountManager accounts; private readonly IAccountManager accounts;
private readonly UserNotifier notifier; private readonly IUserNotifier notifier;
public ConnectionController(ConnectionObserver observer, IAccountManager accounts, UserNotifier notifier) { public ConnectionController(ConnectionObserver observer, IAccountManager accounts, IUserNotifier notifier) {
this.observer = observer; this.observer = observer;
this.accounts = accounts; this.accounts = accounts;
this.notifier = notifier; this.notifier = notifier;

@ -1,8 +1,6 @@
using System; using Endpoint;
using System.Collections.Generic; using Models;
using System.Linq; using ShoopNCook.Pages;
using System.Text;
using System.Threading.Tasks;
namespace ShoopNCook.Controllers namespace ShoopNCook.Controllers
{ {
@ -10,9 +8,14 @@ namespace ShoopNCook.Controllers
{ {
private readonly IApp app; 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.app = app;
this.endpoint = endpoint;
this.account = account;
} }
public void Logout() public void Logout()
@ -20,5 +23,15 @@ namespace ShoopNCook.Controllers
app.Notifier.Notice("You have been loged out."); app.Notifier.Notice("You have been loged out.");
app.ForceLogin(); 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));
}
} }
} }

@ -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<RecipeInfo> GetAccountRecipes();
public ImmutableList<RecipeInfo> GetRecommendedRecipes();
public ImmutableList<RecipeInfo> GetFavorites();
public ImmutableList<(RecipeInfo, uint)> GetWeeklyList();
}
}

@ -1,4 +1,5 @@
using Models; using LocalEndpoint;
using Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -9,17 +10,12 @@ namespace Endpoint
{ {
public interface IRecipesService public interface IRecipesService
{ {
public List<RecipeInfo> PopularRecipes(); public List<RecipeInfo> PopularRecipes();
public Recipe GetRecipe(RecipeInfo info); public Recipe GetRecipe(RecipeInfo info);
public List<RecipeInfo> RecommendedRecipesOf(Account account); public IAccountRecipes GetRecipesOf(Account account);
public List<RecipeInfo> LookupFavoritesOf(Account account);
public List<(RecipeInfo, uint)> LookupWeeklyListOf(Account account);
public AccountRecipeRate GetRateOf(Account account, Recipe recipe);
} }
} }

@ -9,7 +9,7 @@ namespace ShoopNCook
{ {
public interface IApp public interface IApp
{ {
public UserNotifier Notifier { get; } public IUserNotifier Notifier { get; }
public void ForceLogin(); public void ForceLogin();
} }

@ -6,9 +6,10 @@ using System.Threading.Tasks;
namespace ShoopNCook namespace ShoopNCook
{ {
public interface UserNotifier public interface IUserNotifier
{ {
public void Success(string message);
public void Notice(string message); public void Notice(string message);
public void Error(string message); public void Error(string message);

@ -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<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, 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<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, 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;
}
}
}

@ -4,8 +4,11 @@ namespace LocalEndpoint
{ {
public class LocalEndpoint : IEndpoint 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();
} }
} }

@ -1,66 +1,45 @@
using Endpoint; using Endpoint;
using Models; using Models;
using System.Collections.Immutable;
namespace LocalEndpoint namespace LocalEndpoint
{ {
internal class RecipesService : IRecipesService internal class RecipesService : IRecipesService
{ {
private readonly Dictionary<Account, IAccountRecipes> accountsRecipes = new Dictionary<Account, IAccountRecipes>();
public List<RecipeInfo> PopularRecipes() public List<RecipeInfo> PopularRecipes()
{ {
return new List<RecipeInfo> { 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), 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 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 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 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 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) 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"); 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<Ingredient> ingredients = new List<Ingredient> { new Ingredient("Banana", 12), new Ingredient("Apple", 2) }; var ingredients = new List<Ingredient> { new Ingredient("Banana", 12), new Ingredient("Apple", 2) }.ToImmutableList();
List<PreparationStep> steps = new List<PreparationStep> { new PreparationStep("Step 1", "This step is an hardcoded step from a stub implementation of IRecipesSeervice") }; 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 new Recipe(info, owner, ingredients, steps);
} }
public List<RecipeInfo> RecommendedRecipesOf(Account account) public IAccountRecipes GetRecipesOf(Account account)
{
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),
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<RecipeInfo> LookupFavoritesOf(Account account)
{
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),
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)
{ {
Random random = new Random(); IAccountRecipes? recipes;
return new AccountRecipeRate(random.Next() % 2 == 0, (uint)random.Next(0, 6)); 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<Ingredient> { new Ingredient("Chocolate", 4) }.ToImmutableList(), new List<PreparationStep> { new PreparationStep("Eat Chocolate", "Eat the chocolate") }.ToImmutableList()));
accountsRecipes.Add(account, recipes);
}
return recipes;
} }

@ -12,6 +12,6 @@ public partial class MainAppShell : Shell
HomeTab.ContentTemplate = new DataTemplate(() => new HomePage(account, endpoint)); HomeTab.ContentTemplate = new DataTemplate(() => new HomePage(account, endpoint));
FavoritesTab.ContentTemplate = new DataTemplate(() => new FavoritesPage(account, endpoint.RecipesService)); FavoritesTab.ContentTemplate = new DataTemplate(() => new FavoritesPage(account, endpoint.RecipesService));
MyListTab.ContentTemplate = new DataTemplate(() => new MyListPage(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)));
} }
} }

@ -1,8 +1,10 @@
namespace Models using System.Collections.Immutable;
namespace Models
{ {
public record Recipe( public record Recipe(
RecipeInfo Info, RecipeInfo Info,
User Owner, User Owner,
List<Ingredient> Ingredients, ImmutableList<Ingredient> Ingredients,
List<PreparationStep> Steps); ImmutableList<PreparationStep> Steps);
} }

@ -1,4 +1,10 @@
namespace Models 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);
} }

@ -12,13 +12,20 @@
MinimumHeightRequest="175" MinimumHeightRequest="175"
MinimumWidthRequest="150" MinimumWidthRequest="150"
RowDefinitions="*, Auto"> RowDefinitions="*, Auto">
<Grid.GestureRecognizers>
<TapGestureRecognizer
Tapped="OnViewTapped"
NumberOfTapsRequired="1"/>
</Grid.GestureRecognizers>
<Border <Border
Grid.Row="0" Grid.Row="0"
Stroke="Transparent" Stroke="Transparent"
StrokeShape="RoundRectangle 20" StrokeShape="RoundRectangle 20"
BackgroundColor="{StaticResource ImageBackground}"> BackgroundColor="{StaticResource ImageBackground}">
<Grid> <Grid>
<Image /> <Image x:Name="RecipeImage" />
<HorizontalStackLayout <HorizontalStackLayout
x:Name="Stars" x:Name="Stars"
VerticalOptions="End" VerticalOptions="End"
@ -60,7 +67,7 @@
> >
<Grid.GestureRecognizers> <Grid.GestureRecognizers>
<TapGestureRecognizer <TapGestureRecognizer
Tapped="TapGestureRecognizer_Tapped" Tapped="OnRemoveButtonTapped"
NumberOfTapsRequired="1"/> NumberOfTapsRequired="1"/>
</Grid.GestureRecognizers> </Grid.GestureRecognizers>
<Image <Image

@ -1,18 +1,31 @@
using Models;
namespace ShoopNCook.Views; namespace ShoopNCook.Views;
public partial class OwnedRecipeView : ContentView public partial class OwnedRecipeView : ContentView
{ {
public OwnedRecipeView() : this(5, "Title") private readonly Action clickCallback;
{ } private readonly Action removeCallback;
private readonly RecipeInfo recipeInfo;
public OwnedRecipeView(float note, string title) public OwnedRecipeView(RecipeInfo info, Action onClickCallback, Action onRemoveCallback)
{ {
InitializeComponent(); InitializeComponent();
Note = note;
Title = title; RecipeImage.Source = ImageSource.FromUri(info.Image);
Note = info.AverageNote;
Title = info.Name;
this.recipeInfo = info;
this.clickCallback = onClickCallback;
this.removeCallback = onRemoveCallback;
} }
public bool IsViewing(RecipeInfo info)
{
return recipeInfo == info;
}
public float Note public float Note
{ {
set => SetNote(value); set => 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();
} }
} }

@ -19,6 +19,8 @@ public partial class RecipeView : ContentView
} }
public float Note public float Note
{ {
set => SetNote(value); set => SetNote(value);
@ -34,7 +36,6 @@ public partial class RecipeView : ContentView
set => SubtitleLabel.Text = value; set => SubtitleLabel.Text = value;
} }
private void SetNote(float note) private void SetNote(float note)
{ {
int i = 1; int i = 1;

@ -3,6 +3,7 @@ using Models;
namespace ShoopNCook.Pages; namespace ShoopNCook.Pages;
using Endpoint; using Endpoint;
using LocalEndpoint;
using Models; using Models;
using ShoopNCook.Views; using ShoopNCook.Views;
@ -12,13 +13,13 @@ public partial class FavoritesPage : ContentPage
{ {
InitializeComponent(); InitializeComponent();
//TODO this code can be factorised (see HomePage, MyListPage) IAccountRecipes recipes = service.GetRecipesOf(account);
service.LookupFavoritesOf(account).ForEach(info => recipes.GetFavorites().ForEach(info =>
{ {
RecipeViewLayout.Children.Add(new RecipeView(info, () => RecipeViewLayout.Children.Add(new RecipeView(info, () =>
{ {
Recipe recipe = service.GetRecipe(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)); Shell.Current.Navigation.PushAsync(new RecipePage(recipe, rate, 1));
})); }));
}); });

@ -3,6 +3,7 @@ namespace ShoopNCook.Pages;
using Models; using Models;
using ShoopNCook.Views; using ShoopNCook.Views;
using Endpoint; using Endpoint;
using LocalEndpoint;
public partial class HomePage : ContentPage public partial class HomePage : ContentPage
{ {
@ -11,6 +12,7 @@ public partial class HomePage : ContentPage
InitializeComponent(); InitializeComponent();
IRecipesService service = endpoint.RecipesService; IRecipesService service = endpoint.RecipesService;
IAccountRecipes recipes = service.GetRecipesOf(account);
//TODO this code can be factorised //TODO this code can be factorised
@ -19,14 +21,13 @@ public partial class HomePage : ContentPage
layout.Children.Add(new RecipeView(info, () => layout.Children.Add(new RecipeView(info, () =>
{ {
Recipe recipe = service.GetRecipe(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)); Shell.Current.Navigation.PushAsync(new RecipePage(recipe, rate, 1));
})); }));
} }
service.PopularRecipes().ForEach(recipe => PushRecipe(PopularsList, recipe)); 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); ProfilePictureImage.Source = ImageSource.FromUri(account.User.ProfilePicture);
ProfilePictureName.Text = account.User.Name; ProfilePictureName.Text = account.User.Name;

@ -16,14 +16,14 @@ public partial class MorePage : ContentPage
this.controller = controller; 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) private void OnLogoutButtonTapped(object sender, EventArgs e)

@ -1,4 +1,5 @@
using Endpoint; using Endpoint;
using LocalEndpoint;
using Models; using Models;
using ShoopNCook.Views; using ShoopNCook.Views;
@ -10,12 +11,14 @@ public partial class MyListPage : ContentPage
{ {
InitializeComponent(); 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); Recipe recipe = service.GetRecipe(info);
AccountRecipeRate rate = service.GetRateOf(account, recipe); AccountRecipeRate? rate = recipes.FindRate(info);
Shell.Current.Navigation.PushAsync(new RecipePage(recipe, rate, amount)); Shell.Current.Navigation.PushAsync(new RecipePage(recipe, rate, amount));
})); }));
}); });

@ -38,18 +38,9 @@
AlignItems="Start" AlignItems="Start"
AlignContent="Start" AlignContent="Start"
Direction="Row" Direction="Row"
Wrap="Wrap"> Wrap="Wrap"
x:Name="RecipesLayout">
<views:OwnedRecipeView Margin="5" Note="4.5" Title="Spaghetti Bolognese"/>
<views:OwnedRecipeView Margin="5" Note="3" Title="Chickend Curry"/>
<views:OwnedRecipeView Margin="5" Note="0.2" Title="Beef Stroganoff"/>
<views:OwnedRecipeView Margin="5" Note="1.6" Title="Fish And Ships"/>
<views:OwnedRecipeView Margin="5" Note="5" Title="Caesar Salad"/>
<views:OwnedRecipeView Margin="5" Note="3.5" Title="Vegetables"/>
<views:OwnedRecipeView Margin="5" Note="4.6" Title="Guacamole"/>
<views:OwnedRecipeView Margin="5" Note="4" Title="Pad Thai"/>
<views:OwnedRecipeView Margin="5" Note="3" Title="French Toast"/>
<views:OwnedRecipeView Margin="5" Note="2" Title="Margherita Pizza"/>
</FlexLayout> </FlexLayout>
</ScrollView> </ScrollView>

@ -1,12 +1,58 @@
using Endpoint;
using LocalEndpoint;
using Models;
using ShoopNCook.Controllers;
using ShoopNCook.Views;
namespace ShoopNCook.Pages; namespace ShoopNCook.Pages;
public partial class MyRecipesPage : ContentPage public partial class MyRecipesPage : ContentPage
{ {
public MyRecipesPage()
{ private IUserNotifier notifier;
private IAccountRecipes recipes;
public MyRecipesPage(
Account account,
IRecipesService service,
IUserNotifier notifier)
{
InitializeComponent(); 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) private async void OnBackButtonClicked(object sender, EventArgs e)
{ {
await Navigation.PopAsync(); await Navigation.PopAsync();

@ -1,8 +1,10 @@
using Models;
namespace ShoopNCook.Pages; namespace ShoopNCook.Pages;
public partial class ProfilePage : ContentPage public partial class ProfilePage : ContentPage
{ {
public ProfilePage() public ProfilePage(Account account)
{ {
InitializeComponent(); InitializeComponent();
} }

@ -12,14 +12,14 @@ public partial class RecipePage : ContentPage
public ICommand StarCommand => new Command<string>(count => SetNote(uint.Parse(count))); public ICommand StarCommand => new Command<string>(count => SetNote(uint.Parse(count)));
public RecipePage(Recipe recipe, AccountRecipeRate rate, uint amount) public RecipePage(Recipe recipe, AccountRecipeRate? rate, uint amount)
{ {
InitializeComponent(); InitializeComponent();
Counter.Count = amount; Counter.Count = amount;
note = rate.Rate; note = rate?.Rate ?? 0;
isFavorite = rate.IsFavorite; isFavorite = rate?.IsFavorite ?? false;
SetFavorite(isFavorite); SetFavorite(isFavorite);
SetNote(note); SetNote(note);

Loading…
Cancel
Save