integrate recipes in HomePage
continuous-integration/drone/push Build is passing Details

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

@ -13,12 +13,12 @@ public partial class App : Application, ConnectionObserver, IApp
public App()
{
InitializeComponent();
ForceLogin(); //start in login state
ForceLogin(); //start in login shell
}
public void OnAccountConnected(Account account)
{
Shell shell = new MainAppShell(account, this);
Shell shell = new MainAppShell(account, Endpoint, this);
shell.GoToAsync("//Home");
MainPage = shell;
}

@ -6,6 +6,8 @@ namespace Endpoint
{
public IAccountManager AccountManager { get; }
public IRecipesService RecipesService { get; }
}
}

@ -0,0 +1,20 @@
using Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Endpoint
{
public interface IRecipesService
{
public List<RecipeInfo> RecommendedRecipes(Account account);
public List<RecipeInfo> PopularRecipes();
public Recipe GetRecipe(RecipeInfo info);
public RecipeState RecipeStateOf(Account account, Recipe recipe);
}
}

@ -14,7 +14,7 @@ namespace LocalEndpoint
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)
@ -24,6 +24,7 @@ namespace LocalEndpoint
return null;
}
public Account? Register(string email, string username, string password)
{
if (email == null || username == null || password == null)

@ -6,5 +6,6 @@ namespace LocalEndpoint
{
public IAccountManager AccountManager => new AccountManager();
public IRecipesService RecipesService => new RecipesService();
}
}

@ -0,0 +1,48 @@
using Endpoint;
using Models;
namespace LocalEndpoint
{
internal class RecipesService : IRecipesService
{
public List<RecipeInfo> PopularRecipes()
{
return new List<RecipeInfo> {
new RecipeInfo("Chicken Curry", 45, new Uri("https://cdn.chefclub.tools/uploads/recipes/cover-thumbnail/f287b191-dc8e-4c85-bbb6-e26387c354d3.jpg"), 3),
new RecipeInfo("Spaghetti Bolognese", 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", 10, new Uri("https://www.cookwithnabeela.com/wp-content/uploads/2023/02/BeefStroganoff.webp"), 5),
new RecipeInfo("Fish And Ships", 15, new Uri("https://upload.wikimedia.org/wikipedia/commons/f/ff/Fish_and_chips_blackpool.jpg"), 4),
new RecipeInfo("Caesar Salad", 20, new Uri("https://www.galbani.fr/wp-content/uploads/2020/04/AdobeStock_157570276-2.jpeg"), 1)
};
}
public List<RecipeInfo> RecommendedRecipes(Account account)
{
return new List<RecipeInfo> {
new RecipeInfo("Chicken Salad", 20, new Uri("https://healthyfitnessmeals.com/wp-content/uploads/2021/04/Southwest-chicken-salad-7-500x500.jpg"), 4),
new RecipeInfo("Chocolate Cake", 10, new Uri("https://bakewithshivesh.com/wp-content/uploads/2022/08/IMG_0248-scaled.jpg"), 3),
new RecipeInfo("Salmon", 10, new Uri("https://www.wholesomeyum.com/wp-content/uploads/2021/06/wholesomeyum-Pan-Seared-Salmon-Recipe-13.jpg"), 4),
new RecipeInfo("Fish", 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", 5, new Uri("https://static.youmiam.com/images/recipe/1500x1000/space-cake-22706?placeholder=web_recipe&sig=f14a7a86da837c6b8cc678cde424d6d5902f99ec&v3"), 5)
};
}
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<Ingredient> ingredients = new List<Ingredient> { new Ingredient("Banana", 12), new Ingredient("Apple", 2) };
List<PreparationStep> steps = new List<PreparationStep> { new PreparationStep("Step 1", "This step is an hardcoded step from a stub implementation of IRecipesSeervice") };
return new Recipe(info, owner, ingredients, steps);
}
public RecipeState RecipeStateOf(Account account, Recipe recipe)
{
Random random = new Random();
return new RecipeState((uint) random.Next(1, 10), random.Next() % 2 == 0, (uint)random.Next(0, 6), recipe);
}
}
}

@ -3,13 +3,13 @@ using Microsoft.Maui.Controls;
using Models;
using ShoopNCook.Controllers;
using ShoopNCook.Pages;
using Endpoint;
public partial class MainAppShell : Shell
{
public MainAppShell(Account account, IApp app)
public MainAppShell(Account account, IEndpoint endpoint, IApp app)
{
InitializeComponent();
HomeTab.ContentTemplate = new DataTemplate(() => new HomePage(account, app));
HomeTab.ContentTemplate = new DataTemplate(() => new HomePage(account, endpoint));
FavoritesTab.ContentTemplate = new DataTemplate(() => new FavoritesPage(account, app));
MyListTab.ContentTemplate = new DataTemplate(() => new MyListPage(account, app));
MoreTab.ContentTemplate = new DataTemplate(() => new MorePage(account, new MorePageController(app)));

@ -3,15 +3,13 @@
public class Ingredient
{
public Ingredient(string name, float amount, Quantity quantity)
public Ingredient(string name, float amount)
{
Name = name;
Amount = amount;
Quantity = quantity;
}
public string Name { get; init; }
public float Amount { get; init; }
public Quantity Quantity { get; init; }
}
}

@ -1,6 +0,0 @@
namespace Models
{
public class Quantity
{
}
}

@ -3,14 +3,17 @@
public class RecipeInfo
{
public string Name { get; init; }
public string Description { get; init; }
public uint CookTimeMins { get; init; }
public uint Energy { get; init; }
public Uri Image { get; init; }
public float AverageNote { get; init; }
public RecipeInfo(string name, string description, Uri image, float averageNote)
public RecipeInfo(string name, uint cookTimeMins, Uri image, float averageNote)
{
Name = name;
Description = description;
CookTimeMins = cookTimeMins;
Image = image;
AverageNote = averageNote;
}

@ -0,0 +1,22 @@

namespace Models
{
public class RecipeState
{
public uint PersonAmount { get; private init; }
public bool IsAccountFavorite { get; private init; }
public uint AccountNote { get; private init; }
public Recipe Recipe { get; private init; }
public RecipeState(uint personAmount, bool isAccountFavorite, uint accountNote, Recipe recipe)
{
PersonAmount = personAmount;
IsAccountFavorite = isAccountFavorite;
AccountNote = accountNote;
Recipe = recipe;
}
}
}

@ -196,9 +196,7 @@
</ItemGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties XamarinHotReloadDebuggerTimeoutExceptionShoopNCookHideInfoBar="True" XamarinHotReloadUnhandledDeviceExceptionShoopNCookHideInfoBar="True" />
</VisualStudio>
<VisualStudio><UserProperties XamarinHotReloadDebuggerTimeoutExceptionShoopNCookHideInfoBar="True" XamarinHotReloadGenericExceptionInfoBarShoopNCookHideInfoBar="True" XamarinHotReloadUnhandledDeviceExceptionShoopNCookHideInfoBar="True" /></VisualStudio>
</ProjectExtensions>
</Project>

@ -1,3 +1,5 @@
using Models;
namespace ShoopNCook.Views;
public partial class IngredientView : ContentView
@ -30,12 +32,13 @@ public partial class IngredientView : ContentView
set => SetValue(UnitProperty, value);
}
public IngredientView(string name, float quantity, string unit)
public IngredientView(Ingredient ingredient)
{
InitializeComponent();
Name = name;
Quantity = quantity;
Unit = unit;
Name = ingredient.Name;
Quantity = ingredient.Amount;
//TODO Unit implementation in IngredientView.xaml.cs
Unit = "TODO: Unit implementation in IngredientView.xaml.cs";
}
}

@ -5,14 +5,19 @@ namespace ShoopNCook.Views;
public partial class RecipeView : ContentView
{
public RecipeView(RecipeInfo info)
private readonly Action callback;
public RecipeView(RecipeInfo info, Action onClickCallback)
{
InitializeComponent();
Note = info.AverageNote;
Title = info.Name;
Subtitle = info.Description;
Subtitle = info.CookTimeMins + " min";
RecipeImage.Source = ImageSource.FromUri(info.Image);
}
callback = onClickCallback;
}
public float Note
{
@ -43,8 +48,8 @@ public partial class RecipeView : ContentView
else img.Opacity = 1;
}
}
private async void OnRecipeTapped(object sender, EventArgs e)
private void OnRecipeTapped(object sender, EventArgs e)
{
await Shell.Current.Navigation.PushAsync(new RecipePage());
callback();
}
}

@ -1,20 +1,16 @@
using Models;
namespace ShoopNCook.Pages;
using Models;
using ShoopNCook.Views;
public partial class FavoritesPage : ContentPage
{
public FavoritesPage(Account account, IApp app)
{
InitializeComponent();
RecipeViewLayout.Children.Add(new RecipeView(new RecipeInfo("Chicken Curry", "45 min", new Uri("https://cdn.chefclub.tools/uploads/recipes/cover-thumbnail/f287b191-dc8e-4c85-bbb6-e26387c354d3.jpg"), 3)));
RecipeViewLayout.Children.Add(new RecipeView(new RecipeInfo("Spaghetti Bolognese", "30 min", 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)));
RecipeViewLayout.Children.Add(new RecipeView(new RecipeInfo("Beef Stroganoff", "10 min", new Uri("https://www.cookwithnabeela.com/wp-content/uploads/2023/02/BeefStroganoff.webp"), 5)));
RecipeViewLayout.Children.Add(new RecipeView(new RecipeInfo("Fish And Ships", "15 min", new Uri("https://upload.wikimedia.org/wikipedia/commons/f/ff/Fish_and_chips_blackpool.jpg"), 4)));
RecipeViewLayout.Children.Add(new RecipeView(new RecipeInfo("Caesar Salad", "20 min", new Uri("https://www.galbani.fr/wp-content/uploads/2020/04/AdobeStock_157570276-2.jpeg"), 1)));
}
namespace ShoopNCook.Pages;
using Models;
using ShoopNCook.Views;
public partial class FavoritesPage : ContentPage
{
public FavoritesPage(Account account, IApp app)
{
InitializeComponent();
//TODO
}
}

@ -62,7 +62,7 @@
Margin="20"
HeightRequest="30">
<Label
Text="Popular recipe"
Text="Popular recipes"
Style="{StaticResource h2}"/>
<Label
@ -76,7 +76,7 @@
<HorizontalStackLayout
Spacing="10"
Padding="0,0,0,40"
x:Name="FavoritesList">
x:Name="PopularsList">
</HorizontalStackLayout>
</ScrollView>
@ -107,7 +107,7 @@
AlignContent="Start"
Direction="Row"
Wrap="Wrap"
x:Name="BasicRecipeView">
x:Name="RecommendedList">
</FlexLayout>
</ScrollView>

@ -2,29 +2,39 @@
namespace ShoopNCook.Pages;
using Models;
using ShoopNCook.Views;
using Endpoint;
public partial class HomePage : ContentPage
{
public HomePage(Account account, IApp app)
public HomePage(Account account, IEndpoint endpoint)
{
InitializeComponent();
FavoritesList.Children.Add(new RecipeView(new RecipeInfo("Chicken Curry", "45 min", new Uri("https://cdn.chefclub.tools/uploads/recipes/cover-thumbnail/f287b191-dc8e-4c85-bbb6-e26387c354d3.jpg"), 3)));
FavoritesList.Children.Add(new RecipeView(new RecipeInfo("Spaghetti Bolognese", "30 min", 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)));
FavoritesList.Children.Add(new RecipeView(new RecipeInfo("Beef Stroganoff", "10 min", new Uri("https://www.cookwithnabeela.com/wp-content/uploads/2023/02/BeefStroganoff.webp"), 5)));
FavoritesList.Children.Add(new RecipeView(new RecipeInfo("Fish And Ships", "15 min", new Uri("https://upload.wikimedia.org/wikipedia/commons/f/ff/Fish_and_chips_blackpool.jpg"), 4)));
FavoritesList.Children.Add(new RecipeView(new RecipeInfo("Caesar Salad", "20 min", new Uri("https://www.galbani.fr/wp-content/uploads/2020/04/AdobeStock_157570276-2.jpeg"), 1)));
BasicRecipeView.Children.Add(new RecipeView(new RecipeInfo("Chicken Curry", "45 min", new Uri("https://cdn.chefclub.tools/uploads/recipes/cover-thumbnail/f287b191-dc8e-4c85-bbb6-e26387c354d3.jpg"), 3)));
BasicRecipeView.Children.Add(new RecipeView(new RecipeInfo("Spaghetti Bolognese", "30 min", 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)));
BasicRecipeView.Children.Add(new RecipeView(new RecipeInfo("Beef Stroganoff", "10 min", new Uri("https://www.cookwithnabeela.com/wp-content/uploads/2023/02/BeefStroganoff.webp"), 5)));
BasicRecipeView.Children.Add(new RecipeView(new RecipeInfo("Fish And Ships", "15 min", new Uri("https://upload.wikimedia.org/wikipedia/commons/f/ff/Fish_and_chips_blackpool.jpg"), 4)));
BasicRecipeView.Children.Add(new RecipeView(new RecipeInfo("Caesar Salad", "20 min", new Uri("https://www.galbani.fr/wp-content/uploads/2020/04/AdobeStock_157570276-2.jpeg"), 1)));
IRecipesService service = endpoint.RecipesService;
void PushRecipe(Layout layout, RecipeInfo info)
{
layout.Children.Add(new RecipeView(info, () =>
{
Recipe recipe = service.GetRecipe(info);
RecipeState state = service.RecipeStateOf(account, recipe);
Shell.Current.Navigation.PushAsync(new RecipePage(state));
}));
}
service.PopularRecipes().ForEach(recipe => PushRecipe(PopularsList, recipe));
service.RecommendedRecipes(account).ForEach(recipe => PushRecipe(RecommendedList, recipe));
ProfilePictureImage.Source = ImageSource.FromUri(account.User.ProfilePicture);
ProfilePictureName.Text = account.User.Name;
}
private async void OnSyncButtonClicked(object sender, EventArgs e)
private void OnSyncButtonClicked(object sender, EventArgs e)
{
await Shell.Current.Navigation.PushAsync(new SearchPage());
Shell.Current.Navigation.PushAsync(new SearchPage());
}
}

@ -1,6 +1,6 @@
using ShoopNCook.Views;
using System.Windows.Input;
using Models;
namespace ShoopNCook.Pages;
public partial class RecipePage : ContentPage
@ -9,53 +9,39 @@ public partial class RecipePage : ContentPage
private uint note;
private bool isFavorite;
public ICommand StarCommand => new Command<string>(count =>
{
SetNote(uint.Parse(count));
});
public RecipePage() :
this("Recipe Sample", 32, 250,
true, 2, 0,
new List<IngredientView> {
new IngredientView("Chocolate", 25, "g"),
new IngredientView("Flour", 250, "g"),
new IngredientView("Sugar", 0.5F, "kg")
},
new List<string> { "This is the first preparation step", "add to furnace and wait", "Enjoy !" }
)
{}
public RecipePage(
string name,
uint cookTime,
uint energy,
bool isFavorite,
uint nbPers,
uint note,
List<IngredientView> ingredients,
List<string> steps
)
public ICommand StarCommand => new Command<string>(count => SetNote(uint.Parse(count)));
public RecipePage(RecipeState state)
{
InitializeComponent();
Counter.Count = nbPers;
Recipe recipe = state.Recipe;
RecipeInfo info = recipe.Info;
note = state.AccountNote;
isFavorite = state.IsAccountFavorite;
Counter.Count = state.PersonAmount;
SetFavorite(isFavorite);
SetNote(note);
CookTime.Text = cookTime.ToString();
Energy.Text = energy.ToString();
RecipeName.Text = name;
CookTime.Text = info.CookTimeMins.ToString();
Energy.Text = info.Energy.ToString();
RecipeName.Text = info.Name;
foreach (IngredientView iv in ingredients)
IngredientList.Add(iv);
foreach (Ingredient ingredient in recipe.Ingredients)
IngredientList.Add(new IngredientView(ingredient));
//retrieves the app's styles
var styles = Application.Current.Resources.MergedDictionaries.ElementAt(1);
int count = 0;
foreach (string step in steps) {
foreach (PreparationStep step in recipe.Steps) {
//TODO display name of PreparationSteps.
Label label = new Label();
label.Style = (Style)styles["Small"];
label.Text = "Step " + ++count + ": " + step;
label.Text = "Step " + ++count + ": " + step.Description;
StepList.Add(label);
}
}

@ -6,11 +6,7 @@ public partial class SearchPage : ContentPage
public SearchPage()
{
InitializeComponent();
ResultSearchView.Children.Add(new RecipeView(new RecipeInfo("Chicken Curry", "45 min", new Uri("https://cdn.chefclub.tools/uploads/recipes/cover-thumbnail/f287b191-dc8e-4c85-bbb6-e26387c354d3.jpg"), 3)));
ResultSearchView.Children.Add(new RecipeView(new RecipeInfo("Spaghetti Bolognese", "30 min", 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)));
ResultSearchView.Children.Add(new RecipeView(new RecipeInfo("Beef Stroganoff", "10 min", new Uri("https://www.cookwithnabeela.com/wp-content/uploads/2023/02/BeefStroganoff.webp"), 5)));
ResultSearchView.Children.Add(new RecipeView(new RecipeInfo("Fish And Ships", "15 min", new Uri("https://upload.wikimedia.org/wikipedia/commons/f/ff/Fish_and_chips_blackpool.jpg"), 4)));
ResultSearchView.Children.Add(new RecipeView(new RecipeInfo("Caesar Salad", "20 min", new Uri("https://www.galbani.fr/wp-content/uploads/2020/04/AdobeStock_157570276-2.jpeg"), 1)));
//TODO
}
private async void OnBackButtonClicked(object sender, EventArgs e)
{

Loading…
Cancel
Save