diff --git a/.drone.yml b/.drone.yml index 78af971..05189d6 100644 --- a/.drone.yml +++ b/.drone.yml @@ -3,7 +3,12 @@ type: docker name: CI Workflow steps: - - name: Build + - name: Test image: hub.codefirst.iut.uca.fr/marc.chevaldonne/codefirst-dotnet7-maui:latest commands: - dotnet test --framework net7.0 'Tests\\\\Tests.csproj' + + - name: Deploy doc + image: hub.codefirst.iut.uca.fr/maxime.batista/codefirst-docdeployer:latest + commands: + - /entrypoint.sh -t doxygen -l . -d sourcecode_documentation \ No newline at end of file diff --git a/App.xaml.cs b/App.xaml.cs index b769638..4e4d06b 100644 --- a/App.xaml.cs +++ b/App.xaml.cs @@ -1,29 +1,34 @@ namespace ShoopNCook; using Models; -using Endpoint; -using LocalEndpoint; +using Services; +using LocalServices; + +// Classe principale de l'application qui implémente l'interface ConnectionObserver et IApp public partial class App : Application, ConnectionObserver, IApp { - + // Initialisation de l'interface IEndpoint avec une nouvelle instance de LocalEndpoint private IEndpoint Endpoint = new LocalEndpoint(); public App() { InitializeComponent(); - ForceLogin(); //start in login shell + ForceLogin(); // Commencer l'application avec l'écran de connexion } + + // Méthode appelée lorsque l'utilisateur se connecte avec succès public void OnAccountConnected(Account account) { Shell shell = new MainAppShell(account, Endpoint, this); - shell.GoToAsync("//Home"); + shell.GoToAsync("//Home"); MainPage = shell; } + // Méthode pour forcer l'utilisateur à se connecter public void ForceLogin() { - Shell shell = new ConnectAppShell(this, Endpoint.AuthService); + Shell shell = new ConnectAppShell(this, Endpoint.AuthService); shell.GoToAsync("//Splash"); MainPage = shell; } diff --git a/ConnectAppShell.xaml.cs b/ConnectAppShell.xaml.cs index 8e831eb..bbd3198 100644 --- a/ConnectAppShell.xaml.cs +++ b/ConnectAppShell.xaml.cs @@ -1,17 +1,24 @@ namespace ShoopNCook; using Microsoft.Maui.Controls; using Models; -using Endpoint; +using Services; using ShoopNCook.Controllers; using ShoopNCook.Pages; + +// Shell pour la phase de connexion de l'application public partial class ConnectAppShell : Shell { - public ConnectAppShell(ConnectionObserver observer, IAuthService accounts) + // Constructeur qui prend un observateur de connexion et un service d'authentification en argument + + public ConnectAppShell(ConnectionObserver observer, IAuthService accounts) { - ConnectionController controller = new ConnectionController(observer, accounts); + // Création d'un nouveau contrôleur de connexion + ConnectionController controller = new ConnectionController(observer, accounts); InitializeComponent(); - LoginPage.ContentTemplate = new DataTemplate(() => new LoginPage(controller)); + + // Initialisation des pages de connexion et d'inscription avec le contrôleur de connexion + LoginPage.ContentTemplate = new DataTemplate(() => new LoginPage(controller)); RegisterPage.ContentTemplate = new DataTemplate(() => new RegisterPage(controller)); } } diff --git a/ConnectionObserver.cs b/ConnectionObserver.cs index 6cd2772..ec4edd3 100644 --- a/ConnectionObserver.cs +++ b/ConnectionObserver.cs @@ -2,6 +2,8 @@ namespace ShoopNCook { + // Interface définissant un observateur de connexion. + // Tout objet implémentant cette interface doit définir la méthode OnAccountConnected(). public interface ConnectionObserver { public void OnAccountConnected(Account account); diff --git a/Controllers/ConnectionController.cs b/Controllers/ConnectionController.cs index 8d1ebb8..23903b7 100644 --- a/Controllers/ConnectionController.cs +++ b/Controllers/ConnectionController.cs @@ -1,4 +1,4 @@ -using Endpoint; +using Services; using Models; namespace ShoopNCook.Controllers diff --git a/Controllers/MorePageController.cs b/Controllers/MorePageController.cs index b2ffb52..d92b5d1 100644 --- a/Controllers/MorePageController.cs +++ b/Controllers/MorePageController.cs @@ -1,4 +1,4 @@ -using Endpoint; +using Services; using Models; using ShoopNCook.Pages; diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..6cda83d --- /dev/null +++ b/Doxyfile @@ -0,0 +1,429 @@ +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = "ShopNCook" +PROJECT_NUMBER = 1.0.0 +PROJECT_BRIEF = "A Cook application" +PROJECT_LOGO = Resources/appicon.svg +OUTPUT_DIRECTORY = /docs/doxygen +CREATE_SUBDIRS = NO +ALLOW_UNICODE_NAMES = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +JAVADOC_BANNER = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +PYTHON_DOCSTRING = YES +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 4 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +# Well... the one for Java looks so similar to the one for C#... +OPTIMIZE_OUTPUT_JAVA = YES +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +OPTIMIZE_OUTPUT_SLICE = NO +EXTENSION_MAPPING = +MARKDOWN_SUPPORT = YES +TOC_INCLUDE_HEADINGS = 5 +AUTOLINK_SUPPORT = YES +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +GROUP_NESTED_COMPOUNDS = NO +SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = NO +LOOKUP_CACHE_SIZE = 0 +NUM_PROC_THREADS = 1 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +EXTRACT_ALL = YES +# I do not like other members to see my private members... but you can set it to YES if you prefer. +EXTRACT_PRIVATE = NO +EXTRACT_PRIV_VIRTUAL = NO +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +RESOLVE_UNNAMED_PARAMS = YES +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = NO +HIDE_SCOPE_NAMES = NO +HIDE_COMPOUND_REFERENCE= NO +SHOW_HEADERFILE = YES +SHOW_INCLUDE_FILES = YES +SHOW_GROUPED_MEMB_INC = NO +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +LAYOUT_FILE = +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_IF_INCOMPLETE_DOC = YES +WARN_NO_PARAMDOC = NO +WARN_AS_ERROR = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +INPUT = . +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.l \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f18 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.ice +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = */Tests/* +EXCLUDE_PATTERNS += */bin/* +EXCLUDE_PATTERNS += */obj/* +EXCLUDE_PATTERNS += documentation/* +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +SOURCE_TOOLTIPS = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +CLANG_ASSISTED_PARSING = NO +CLANG_ADD_INC_PATHS = YES +CLANG_OPTIONS = +CLANG_DATABASE_PATH = + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +ALPHABETICAL_INDEX = YES +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_STYLESHEET = +HTML_EXTRA_STYLESHEET = +HTML_EXTRA_FILES = images/CodeFirst.png images/clubinfo.png +HTML_COLORSTYLE_HUE = 215 +HTML_COLORSTYLE_SAT = 45 +HTML_COLORSTYLE_GAMMA = 240 +HTML_TIMESTAMP = NO +HTML_DYNAMIC_MENUS = YES +HTML_DYNAMIC_SECTIONS = NO +HTML_INDEX_NUM_ENTRIES = 100 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_FEEDURL = +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = NO +GENERATE_TREEVIEW = NO +FULL_SIDEBAR = NO +ENUM_VALUES_PER_LINE = 4 +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +OBFUSCATE_EMAILS = YES +HTML_FORMULA_FORMAT = png +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +FORMULA_MACROFILE = +USE_MATHJAX = NO +MATHJAX_VERSION = MathJax_2 +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = +MATHJAX_EXTENSIONS = +MATHJAX_CODEFILE = +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +SEARCHENGINE_URL = +SEARCHDATA_FILE = searchdata.xml +EXTERNAL_SEARCH_ID = +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = +MAKEINDEX_CMD_NAME = makeindex +LATEX_MAKEINDEX_CMD = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4 +EXTRA_PACKAGES = +LATEX_HEADER = +LATEX_FOOTER = +LATEX_EXTRA_STYLESHEET = +LATEX_EXTRA_FILES = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_BIB_STYLE = plain +LATEX_TIMESTAMP = NO +LATEX_EMOJI_DIRECTORY = + +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- + +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- + +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_SUBDIR = +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- + +GENERATE_XML = NO +XML_OUTPUT = xml +XML_PROGRAMLISTING = YES +XML_NS_MEMB_FILE_SCOPE = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook + +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to Sqlite3 output +#--------------------------------------------------------------------------- + +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- + +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +EXTERNAL_PAGES = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +DIA_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_NUM_THREADS = 0 +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 +DOT_UML_DETAILS = NO +DOT_WRAP_THRESHOLD = 17 +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DIR_GRAPH_MAX_DEPTH = 1 +DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DIAFILE_DIRS = +PLANTUML_JAR_PATH = +PLANTUML_CFG_FILE = +PLANTUML_INCLUDE_PATH = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES \ No newline at end of file diff --git a/IApp.cs b/IApp.cs index bfc7b8f..765ec6c 100644 --- a/IApp.cs +++ b/IApp.cs @@ -7,6 +7,8 @@ using System.Threading.Tasks; namespace ShoopNCook { + // Interface définissant une application. + // Tout objet implémentant cette interface doit définir la méthode ForceLogin(). public interface IApp { public void ForceLogin(); diff --git a/LocalServices/AccountOwnedRecipes.cs b/LocalServices/AccountOwnedRecipes.cs index 973f00e..6e6ba77 100644 --- a/LocalServices/AccountOwnedRecipes.cs +++ b/LocalServices/AccountOwnedRecipes.cs @@ -1,11 +1,11 @@ -using LocalServices; +using Services; using LocalServices.Data; using Models; using System.Collections.Immutable; -namespace Endpoint +namespace Services { - internal class AccountOwnedRecipes : IAccountOwnedRecipes + internal class AccountOwnedRecipes : IAccountOwnedRecipesService { public Account Account { get; init; } diff --git a/LocalServices/AccountRecipesPreferences.cs b/LocalServices/AccountRecipesPreferences.cs index fba3762..8697a50 100644 --- a/LocalServices/AccountRecipesPreferences.cs +++ b/LocalServices/AccountRecipesPreferences.cs @@ -1,11 +1,11 @@ -using Endpoint; +using Services; using LocalServices.Data; using Models; using System.Collections.Immutable; namespace LocalServices { - internal class AccountRecipesPreferences : IAccountRecipesPreferences + internal class AccountRecipesPreferences : IAccountRecipesPreferencesService { private readonly IDatabase db; @@ -103,7 +103,7 @@ namespace LocalServices var ratings = db.ListRatesOf(userId); RecipeRate rate = GetRate(info); - db.InsertRate(userId, info.Id, new RecipeRate(rate.IsFavorite, score)); + db.InsertRate(userId, info.Id, new RecipeRate(rate.IsFavorite, Math.Min(score, 5))); } } } diff --git a/LocalServices/AccountServices.cs b/LocalServices/AccountServices.cs index 424406b..656f3b7 100644 --- a/LocalServices/AccountServices.cs +++ b/LocalServices/AccountServices.cs @@ -1,6 +1,6 @@ -using Endpoint; +using Services; namespace LocalServices { - internal record AccountServices(IAccountOwnedRecipes Recipes, IAccountRecipesPreferences Preferences); + internal record AccountServices(IAccountOwnedRecipesService Recipes, IAccountRecipesPreferencesService Preferences); } diff --git a/LocalServices/AuthService.cs b/LocalServices/AuthService.cs index deb6697..a68cf5b 100644 --- a/LocalServices/AuthService.cs +++ b/LocalServices/AuthService.cs @@ -1,5 +1,5 @@ using Models; -using Endpoint; +using Services; using System; using System.Collections.Generic; using System.Linq; diff --git a/LocalServices/Data/AccountData.cs b/LocalServices/Data/AccountData.cs index 6ad81c7..7199fa4 100644 --- a/LocalServices/Data/AccountData.cs +++ b/LocalServices/Data/AccountData.cs @@ -1,10 +1,4 @@ -using Models; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.Text; -using System.Threading.Tasks; +using System.Runtime.Serialization; namespace LocalServices.Data { diff --git a/LocalServices/Data/CatastrophicPerformancesDatabase.cs b/LocalServices/Data/CatastrophicPerformancesDatabase.cs index 16c1a02..462417b 100644 --- a/LocalServices/Data/CatastrophicPerformancesDatabase.cs +++ b/LocalServices/Data/CatastrophicPerformancesDatabase.cs @@ -1,27 +1,17 @@ using Models; -using System; -using System.Collections.Generic; using System.Collections.Immutable; -using System.Linq; -using System.Runtime.Serialization; using System.Text; using System.Text.Json; -using System.Text.Json.Serialization; -using System.Threading.Tasks; namespace LocalServices.Data { /// /// Database implementation with catastrophic performances. - /// This database implementation persists data in xml and will save all the data in their files on each mutable requests. + /// This database implementation persists data in json and will save all the data in their files for each mutable requests. /// internal class CatastrophicPerformancesDatabase : IDatabase { - private static readonly DataContractSerializer RECIPES_SERIALIZER = new DataContractSerializer(typeof(Dictionary)); - private static readonly DataContractSerializer USERS_SERIALIZER = new DataContractSerializer(typeof(Dictionary)); - private static readonly DataContractSerializer ACCOUNTS_SERIALIZER = new DataContractSerializer(typeof(Dictionary)); - private static readonly string RECIPES_FILENAME = "recipes_data.xml"; private static readonly string USERS_FILENAME = "users_data.xml"; private static readonly string ACCOUNTS_FILENAME = "accounts_data.xml"; @@ -39,9 +29,9 @@ namespace LocalServices.Data if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath); - usersData = Load(USERS_FILENAME, USERS_SERIALIZER); - recipesData = Load(RECIPES_FILENAME, RECIPES_SERIALIZER); - accountsData = Load(ACCOUNTS_FILENAME, ACCOUNTS_SERIALIZER); + usersData = Load(USERS_FILENAME); + recipesData = Load(RECIPES_FILENAME); + accountsData = Load(ACCOUNTS_FILENAME); } public bool IsEmpty() @@ -61,7 +51,7 @@ namespace LocalServices.Data public void InsertAccount(Account account, string passwordHash) { accountsData[account.Email] = new AccountData(account.User.Id, account.Email, passwordHash); - Save(ACCOUNTS_FILENAME, ACCOUNTS_SERIALIZER, accountsData); + Save(ACCOUNTS_FILENAME, accountsData); } public Recipe? GetRecipe(Guid id) @@ -79,38 +69,38 @@ namespace LocalServices.Data public void InsertInUserList(Guid userId, Guid recipeId, uint persAmount) { usersData[userId].RecipesList[recipeId] = persAmount; - Save(USERS_FILENAME, USERS_SERIALIZER, usersData); + Save(USERS_FILENAME, usersData); } public void RemoveFromUserList(Guid userId, Guid recipeId) { usersData[userId].RecipesList.Remove(recipeId); - Save(USERS_FILENAME, USERS_SERIALIZER, usersData); + Save(USERS_FILENAME, usersData); } public void InsertRecipe(Recipe recipe) { recipesData[recipe.Info.Id] = new RecipeData(recipe.Info, recipe.Owner.Id, recipe.Ingredients, recipe.Steps); - Save(RECIPES_FILENAME, RECIPES_SERIALIZER, recipesData); + Save(RECIPES_FILENAME, recipesData); } public void InsertUser(User user) { usersData[user.Id] = new UserData(user, new Dictionary(), new Dictionary()); - Save(USERS_FILENAME, USERS_SERIALIZER, usersData); + Save(USERS_FILENAME, usersData); } public void InsertRate(Guid userId, Guid recipeId, RecipeRate rate) { usersData[userId].Rates[recipeId] = rate; - Save(USERS_FILENAME, USERS_SERIALIZER, usersData); + Save(USERS_FILENAME, usersData); } public void RemoveRecipe(Guid id) { recipesData.Remove(id); - Save(RECIPES_FILENAME, RECIPES_SERIALIZER, recipesData); + Save(RECIPES_FILENAME, recipesData); } public ImmutableList ListAllRecipes() @@ -135,7 +125,7 @@ namespace LocalServices.Data return new Recipe(rd.Info, owner, rd.Ingredients, rd.Steps); } - private Dictionary Load(string fileName, DataContractSerializer deserializer) + private Dictionary Load(string fileName) { var file = dbPath + "/" + fileName; var fileInfo = new FileInfo(file); @@ -151,10 +141,10 @@ namespace LocalServices.Data return JsonSerializer.Deserialize>(text); } - private async void Save(string fileName, DataContractSerializer serializer, Dictionary dict) + private async void Save(string fileName, Dictionary dict) { string json = JsonSerializer.Serialize(dict); - using (var stream = WaitForFile(fileName, FileMode.Open, FileAccess.Write, FileShare.Write)) + using (var stream = WaitForFile(dbPath + "/" + fileName, FileMode.Open, FileAccess.Write, FileShare.Write)) { var bytes = Encoding.ASCII.GetBytes(json); await stream.WriteAsync(bytes, 0, bytes.Length); @@ -166,7 +156,7 @@ namespace LocalServices.Data // Simply wait until the file is released and return it. This function will never return until private static FileStream WaitForFile(string fullPath, FileMode mode, FileAccess access, FileShare share) { - for (int attempt = 0 ; attempt < 20; attempt++) //20 attempts equals to 2 seconds of wait + for (int attempt = 0 ; attempt < 40; attempt++) { FileStream? fs = null; try @@ -174,7 +164,11 @@ namespace LocalServices.Data fs = new FileStream(fullPath, mode, access, share); return fs; } - catch (IOException) + catch (FileNotFoundException e) + { + throw e; + } + catch (IOException e) { if (fs != null) fs.Dispose(); diff --git a/LocalServices/Data/IDatabase.cs b/LocalServices/Data/IDatabase.cs index 987c587..4e6c1e3 100644 --- a/LocalServices/Data/IDatabase.cs +++ b/LocalServices/Data/IDatabase.cs @@ -4,33 +4,100 @@ using System.Collections.Immutable; namespace LocalServices.Data { - - // The database interface defines all the different kinds of requests the LocalEndpoint needs to store and retrieve data. + /// + /// The database interface defines all the different kinds of requests the LocalEndpoint needs to store and retrieve data. + /// public interface IDatabase { + /// + /// Get a Recipe from its identifier + /// + /// + /// The recipe if the identifier is registered in the database public Recipe? GetRecipe(Guid id); - + /// + /// Get the rate of a user for a given recipe + /// + /// The user identifier + /// The recipe identifier + /// Returns a rate public RecipeRate GetRecipeRate(Guid user, Guid recipe); + /// + /// Gets an account from an email and a password hash + /// + /// + /// + /// some account if the email and the hash is found in the database public Account? GetAccount(string email, string passwordHash); + /// + /// Insert a recipe in user's weekly list + /// + /// + /// + /// public void InsertInUserList(Guid userId, Guid recipeId, uint persAmount); + + /// + /// Remove a recipe from user's weekly list + /// + /// + /// public void RemoveFromUserList(Guid userId, Guid recipeId); + + /// + /// Inserts an account in the database, with the given passwordhash + /// + /// + /// public void InsertAccount(Account account, string passwordHash); + /// + /// Inserts a recipe + /// + /// public void InsertRecipe(Recipe recipe); + /// + /// Inserts a user + /// + /// public void InsertUser(User user); + /// + /// Inserts a user rate over the given recipe identifier + /// + /// + /// + /// public void InsertRate(Guid userId, Guid recipeId, RecipeRate rate); + /// + /// Removes a recipe + /// + /// public void RemoveRecipe(Guid id); + /// + /// Lists all recipes in the database + /// + /// public ImmutableList ListAllRecipes(); + /// + /// List the ratings of an user + /// + /// + /// public ImmutableDictionary ListRatesOf(Guid user); + /// + /// Get the weekly list of given user + /// + /// + /// public ImmutableDictionary GetRecipeListOf(Guid user); } } diff --git a/LocalServices/Data/StubDatabase.cs b/LocalServices/Data/StubDatabase.cs index 820f646..61b759a 100644 --- a/LocalServices/Data/StubDatabase.cs +++ b/LocalServices/Data/StubDatabase.cs @@ -4,6 +4,9 @@ using System.Collections.Immutable; namespace LocalServices.Data { + /// + /// stub implementation for IDatabase + /// internal class StubDatabase : IDatabase { private readonly User User = new User(new Uri("https://images.pexels.com/photos/37546/woman-portrait-face-studio-37546.jpeg?cs=srgb&dl=beauty-face-headshot-37546.jpg&fm=jpg"), "David", Guid.NewGuid()); diff --git a/LocalServices/LocalEndpoint.cs b/LocalServices/LocalEndpoint.cs index 4b28f78..467aca3 100644 --- a/LocalServices/LocalEndpoint.cs +++ b/LocalServices/LocalEndpoint.cs @@ -1,4 +1,4 @@ -using Endpoint; +using Services; using LocalServices.Data; using Models; using System.Collections.Immutable; @@ -7,8 +7,8 @@ namespace LocalServices { /// - /// The local endpoint is an implementation of the Endpoint API definition. - /// + /// The local endpoint is an implementation of the Services API. + /// This class is the _entry point_ class of the implementation /// public class LocalEndpoint : IEndpoint { @@ -20,6 +20,7 @@ namespace LocalServices { var db = new CatastrophicPerformancesDatabase(Environment.GetFolderPath(Environment.SpecialFolder.Personal)); + if (db.IsEmpty()) PrepareDatabase(db); @@ -31,6 +32,11 @@ namespace LocalServices public IRecipesService RecipesService => recipesService; + + /// + /// Inserts sample data in the local database + /// + /// private static void PrepareDatabase(IDatabase db) { 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", MakeGuid(1)); @@ -53,6 +59,11 @@ namespace LocalServices db.InsertRecipe(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()), USER1, new List { new Ingredient("Chocolate", 4) }.ToImmutableList(), new List { new PreparationStep("Eat Chocolate", "Eat the chocolate") }.ToImmutableList())); } + /// + /// helper function to Create a Guid from a given seed + /// + /// the seed to use for the generation + /// private static Guid MakeGuid(int seed) { var r = new Random(seed); diff --git a/LocalServices/RecipesService.cs b/LocalServices/RecipesService.cs index 4f0a845..2237b04 100644 --- a/LocalServices/RecipesService.cs +++ b/LocalServices/RecipesService.cs @@ -1,4 +1,4 @@ -using Endpoint; +using Services; using LocalServices.Data; using Models; using System.Collections.Immutable; @@ -27,11 +27,11 @@ namespace LocalServices } - public IAccountOwnedRecipes GetRecipesOf(Account account) + public IAccountOwnedRecipesService GetRecipesOf(Account account) { return GetOrInitData(account).Recipes; } - public IAccountRecipesPreferences GetPreferencesOf(Account account) + public IAccountRecipesPreferencesService GetPreferencesOf(Account account) { return GetOrInitData(account).Preferences; } diff --git a/MainAppShell.xaml.cs b/MainAppShell.xaml.cs index decb72a..1b7399c 100644 --- a/MainAppShell.xaml.cs +++ b/MainAppShell.xaml.cs @@ -3,13 +3,18 @@ using Microsoft.Maui.Controls; using Models; using ShoopNCook.Controllers; using ShoopNCook.Pages; -using Endpoint; +using Services; + +// Shell principale de l'application après connexion de l'utilisateur public partial class MainAppShell : Shell { - public MainAppShell(Account account, IEndpoint endpoint, IApp app) + // Constructeur qui prend en argument un compte, un endpoint et une application + public MainAppShell(Account account, IEndpoint endpoint, IApp app) { InitializeComponent(); - HomeTab.ContentTemplate = new DataTemplate(() => new HomePage(account, endpoint)); + + // Initialisation de chaque onglet avec sa page respective + 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(account, endpoint, app))); diff --git a/Models/Account.cs b/Models/Account.cs index 5a9973b..142141e 100644 --- a/Models/Account.cs +++ b/Models/Account.cs @@ -1,4 +1,9 @@ namespace Models { + /// + /// Contains the informations of an account. + /// + /// The account's public information + /// The account's email address public record Account(User User, string Email); } diff --git a/Models/Ingredient.cs b/Models/Ingredient.cs index 10e7655..6cacc4a 100644 --- a/Models/Ingredient.cs +++ b/Models/Ingredient.cs @@ -3,7 +3,11 @@ namespace Models { - + /// + /// An ingredient + /// + /// The ingredient's name + /// The ingredient's amount (in kilograms or liters) [DataContract] public record Ingredient([property: DataMember] string Name, [property: DataMember] float Amount); } diff --git a/Models/PreparationStep.cs b/Models/PreparationStep.cs index 35e4734..d14aea2 100644 --- a/Models/PreparationStep.cs +++ b/Models/PreparationStep.cs @@ -2,6 +2,11 @@ namespace Models { + /// + /// A step of preparation + /// + /// The step's name + /// The step's instructions / description [DataContract] public record PreparationStep([property: DataMember] string Name, [property: DataMember] string Description); } diff --git a/Models/Recipe.cs b/Models/Recipe.cs index 021d99a..71f44e3 100644 --- a/Models/Recipe.cs +++ b/Models/Recipe.cs @@ -3,6 +3,13 @@ using System.Runtime.Serialization; namespace Models { + /// + /// A Recipe + /// + /// The essential information of the recipe + /// The creator of the recipe + /// The needed ingredients of the recipe + /// The preparation steps [DataContract] public record Recipe( [property: DataMember] RecipeInfo Info, @@ -10,5 +17,4 @@ namespace Models [property: DataMember] ImmutableList Ingredients, [property: DataMember] ImmutableList Steps ); - } \ No newline at end of file diff --git a/Models/RecipeBuilder.cs b/Models/RecipeBuilder.cs index 047a4c6..ce49872 100644 --- a/Models/RecipeBuilder.cs +++ b/Models/RecipeBuilder.cs @@ -7,6 +7,9 @@ using System.Threading.Tasks; namespace Models { + /// + /// A Simple builder to create a recipe + /// public class RecipeBuilder { private readonly string name; diff --git a/Models/RecipeInfo.cs b/Models/RecipeInfo.cs index fec0ebb..d29f89d 100644 --- a/Models/RecipeInfo.cs +++ b/Models/RecipeInfo.cs @@ -2,12 +2,21 @@ namespace Models { + /// + /// The essential information about a recipe + /// + /// The recipe's name + /// The energy input + /// Estimated time of preparation in minutes + /// An illustrative image of the recipe + /// The average rate of the recipe + /// An unique identifier [DataContract] public record RecipeInfo( [property: DataMember] string Name, [property: DataMember] uint CalPerPers, [property: DataMember] uint CookTimeMins, - [property: DataMember] Uri? Image, + [property: DataMember] Uri Image, [property: DataMember] float AverageNote, [property: DataMember] Guid Id ); diff --git a/Models/RecipeRate.cs b/Models/RecipeRate.cs index b4dc3a3..a8e82c2 100644 --- a/Models/RecipeRate.cs +++ b/Models/RecipeRate.cs @@ -3,6 +3,11 @@ using System.Runtime.Serialization; namespace Models { + /// + /// The rate of a recipe, usually, the instances are bound with an account. + /// + /// + /// a rate between 0 and 5 [DataContract] public record RecipeRate( [property: DataMember] bool IsFavorite = false, diff --git a/Models/User.cs b/Models/User.cs index b70f7b1..7e18db1 100644 --- a/Models/User.cs +++ b/Models/User.cs @@ -2,13 +2,25 @@ namespace Models { + /// + /// Publics informations of a user + /// [DataContract] public class User { + /// + /// The profile picture + /// [DataMember] public Uri ProfilePicture { get; init; } + /// + /// The username + /// [DataMember] public string Name { get; init; } + /// + /// An unique identifier + /// [DataMember] public Guid Id { get; init; } diff --git a/Services/IAccountOwnedRecipes.cs b/Services/IAccountOwnedRecipes.cs deleted file mode 100644 index 69d6b7b..0000000 --- a/Services/IAccountOwnedRecipes.cs +++ /dev/null @@ -1,23 +0,0 @@ -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 GetAccountRecipes(); - } -} diff --git a/Services/IAccountOwnedRecipesService.cs b/Services/IAccountOwnedRecipesService.cs new file mode 100644 index 0000000..c6b375e --- /dev/null +++ b/Services/IAccountOwnedRecipesService.cs @@ -0,0 +1,38 @@ +using Models; +using System.Collections.Immutable; + +namespace Services +{ + /// + /// This service handles the recipes created by an account + /// + public interface IAccountOwnedRecipesService + { + /// + /// This service's bound account + /// + public Account Account { get; } + + /// + /// Upload a new recipe, ensuring the recipe's owner matches the service's bound account user. + /// + /// The recipe to upload + /// true if the recipe could be uploaded, false instead + public bool UploadRecipe(Recipe recipe); + + /// + /// Removes a recipe + /// + /// The informations about the recipe to remove + /// true if the recipe could be removed, false instead + public bool RemoveRecipe(RecipeInfo info); + + /// + /// The living recipes created by this account. + /// If the user removes a recipe (using ) it'll no longer apear in the + /// next invocations of this recipe + /// + /// the list of all the living recipes of the account + public ImmutableList GetAccountRecipes(); + } +} diff --git a/Services/IAccountRecipesPreferences.cs b/Services/IAccountRecipesPreferences.cs deleted file mode 100644 index 64d4f35..0000000 --- a/Services/IAccountRecipesPreferences.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Models; -using System.Collections.Immutable; - -namespace Endpoint -{ - public interface IAccountRecipesPreferences - { - public Account Account { get; } - - - public void AddToFavorites(RecipeInfo info); - public void RemoveFromFavorites(RecipeInfo info); - public void SetReviewScore(RecipeInfo info, uint score); - public bool AddToWeeklyList(RecipeInfo info, uint persAmount); - - public RecipeRate GetRate(RecipeInfo info); - - public ImmutableList GetFavorites(); - - public ImmutableList GetRecommendedRecipes(); - - public ImmutableList<(RecipeInfo, uint)> GetWeeklyList(); - - } -} diff --git a/Services/IAccountRecipesPreferencesService.cs b/Services/IAccountRecipesPreferencesService.cs new file mode 100644 index 0000000..57d14df --- /dev/null +++ b/Services/IAccountRecipesPreferencesService.cs @@ -0,0 +1,68 @@ +using Models; +using System.Collections.Immutable; + +namespace Services +{ + /// + /// This service handles the preferences of a bound account + /// + public interface IAccountRecipesPreferencesService + { + /// + /// The bound account + /// + public Account Account { get; } + + /// + /// Adds a recipe in the favorites of the bound account + /// + /// The information about the recipe to add in favorites + public void AddToFavorites(RecipeInfo info); + /// + /// Removes a recipe from the favorites of the bound account + /// + /// The information about the recipe to remove from favorites + public void RemoveFromFavorites(RecipeInfo info); + /// + /// Sets a score for the specified recipe + /// + /// The information about the targeted recipe + /// The score to set + public void SetReviewScore(RecipeInfo info, uint score); + /// + /// Adds a recipe to the weekly list, specifying the amount of persons that must be fed for the week + /// + /// The information about the targeted recipe + /// The amount of guests that needs to be fed by the recipe for the week + /// + public bool AddToWeeklyList(RecipeInfo info, uint persAmount); + + /// + /// Retrieves the rate of the targeted recipe + /// The rate contains the user's score and whether if the recipe is in the favorites list. + /// + /// + /// The information about the targeted recipe + /// + public RecipeRate GetRate(RecipeInfo info); + + /// + /// The favorites recipes of the account + /// + /// A list containing all the recipe info that are marked as favorite by the bound account + public ImmutableList GetFavorites(); + + /// + /// The recommended recipes for the user based on his preferences. + /// + /// A list of the recommended recipes based on the preferences of the bound account + public ImmutableList GetRecommendedRecipes(); + + /// + /// The weekly list of the bound account + /// + /// The weekly list of the bound account, containing tuples that binds a recipe to the number of guests to feed for the week + public ImmutableList<(RecipeInfo, uint)> GetWeeklyList(); + + } +} diff --git a/Services/IAuthService.cs b/Services/IAuthService.cs index 0e450e2..ad12946 100644 --- a/Services/IAuthService.cs +++ b/Services/IAuthService.cs @@ -1,11 +1,34 @@ -using Models; -namespace Endpoint -{ - public interface IAuthService - { - public Account? Login(string email, string password); - - public Account? Register(string email, string username, string password); - } -} - +using Models; + +namespace Services +{ + /// + /// Service for account authentification + /// Passwords are being passed in this service clearly as the hash function used for passwords is implementation specific + /// + public interface IAuthService + { + /// + /// Tries to login to an account using its mail address and password. + /// + /// The mail address which acts as an identifier for the targeted account + /// The (clear) password used to login. + /// + /// Returns an instance of Account representing the account that got logged in. + /// If the login credentials are invalid to log in the targeted acccount, this method returns null. + /// + public Account? Login(string email, string password); + /// + /// Tries to register to a new account, defining its mail address, username and password. + /// + /// The mail address which acts as an identifier for the targeted account + /// The username of the account + /// The (clear) password used to login on next connections attempt. + /// + /// Returns an instance of Account representing the account that got newly registered. + /// If the register credentials are invalid, or if the account already exists, this method returns null. + /// + public Account? Register(string email, string username, string password); + } +} + diff --git a/Services/IEndpoint.cs b/Services/IEndpoint.cs index b928557..a8aba6f 100644 --- a/Services/IEndpoint.cs +++ b/Services/IEndpoint.cs @@ -1,13 +1,16 @@ - - -namespace Endpoint -{ - public interface IEndpoint - { - public IAuthService AuthService { get; } - - public IRecipesService RecipesService { get; } - - } -} - + + +namespace Services +{ + /// + /// The endpoint is the central element of the 'Services' assembly. + /// + public interface IEndpoint + { + public IAuthService AuthService { get; } + + public IRecipesService RecipesService { get; } + + } +} + diff --git a/Services/IRecipesService.cs b/Services/IRecipesService.cs index 232da18..7efbe1a 100644 --- a/Services/IRecipesService.cs +++ b/Services/IRecipesService.cs @@ -1,18 +1,42 @@ -using LocalEndpoint; -using Models; -using System.Collections.Immutable; - -namespace Endpoint -{ - public interface IRecipesService - { - public ImmutableList PopularRecipes(); - - public Recipe? GetRecipe(RecipeInfo info); - - public IAccountOwnedRecipes GetRecipesOf(Account account); - public IAccountRecipesPreferences GetPreferencesOf(Account account); - - - } -} +using Models; +using System.Collections.Immutable; + +namespace Services +{ + /// + /// The services that is in charge of handling the application's recipes. + /// + public interface IRecipesService + { + /// + /// + /// + /// A list containg the popular recipes of the week + public ImmutableList PopularRecipes(); + + /// + /// Retrieves a recipe from given RecipeInfo + /// + /// the informations about the recipe that we want to retrieve + /// some recipe if the recipe was found, null else + public Recipe? GetRecipe(RecipeInfo info); + + /// + /// Gets the service that is in charge of handling the account's owned recipes. + /// The account's owned recipes are the recipes that the account created. + /// + /// The account logged in + /// The service that handles the given account's recipes + public IAccountOwnedRecipesService GetRecipesOf(Account account); + /// + /// Gets the service that handles all the preferences of the given account + /// + /// The account logged in + /// + /// The service that handles the given account's preferences + /// + public IAccountRecipesPreferencesService GetPreferencesOf(Account account); + + + } +} diff --git a/ShoopNCook.csproj b/ShoopNCook.csproj index f6b7dbe..704771c 100644 --- a/ShoopNCook.csproj +++ b/ShoopNCook.csproj @@ -6,16 +6,17 @@ Exe + ShoopNCook true true enable - ShoopNCook + ShopNCook - com.companyname.shoopncook + com.companyname.shopncook bf17e1fe-a722-42f6-a24d-3327d351c924 @@ -48,26 +49,31 @@ + + + + + diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 42ff44d..1716292 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -1,25 +1,31 @@ - - - - net7.0 - enable - enable - - false - true - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - + + + + net7.0 + enable + enable + + false + true + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + diff --git a/Tests/UnitTest1.cs b/Tests/UnitTest1.cs index f5782ed..5b298b4 100644 --- a/Tests/UnitTest1.cs +++ b/Tests/UnitTest1.cs @@ -1,3 +1,5 @@ +using Models; + namespace Tests { public class UnitTest1 @@ -5,7 +7,7 @@ namespace Tests [Fact] public void Test1() { - + new RecipeRate(true, 4); } } diff --git a/Views/Components/CounterView.xaml.cs b/Views/Components/CounterView.xaml.cs index 39b1b2f..2ea3812 100644 --- a/Views/Components/CounterView.xaml.cs +++ b/Views/Components/CounterView.xaml.cs @@ -1,34 +1,40 @@ namespace ShoopNCook.Views; +// Classe représentant une vue avec un compteur public partial class CounterView : ContentView { - + // Propriété liée pour le nombre à afficher private readonly BindableProperty CountProperty = BindableProperty.Create(nameof(CountLabel), typeof(uint), typeof(CounterView), default(uint) + 1); + // Propriété liée pour le texte à afficher private readonly BindableProperty CounterLabelProperty = BindableProperty.Create(nameof(CounterLabel), typeof(string), typeof(CounterView), default(string)); public CounterView() - { + { InitializeComponent(); + + // Liaison des propriétés à leurs étiquettes respectives CountLabel.BindingContext = this; CountLabel.SetBinding(Label.TextProperty, nameof(Count)); - CounterLabel.BindingContext = this; CounterLabel.SetBinding(Label.TextProperty, nameof(CounterText)); } + // Accesseurs pour Count public uint Count { get => (uint)GetValue(CountProperty); set { + // Assure que la valeur est toujours au minimum 1 SetValue(CountProperty, value <= 1 ? 1 : uint.Parse(value.ToString())); OnPropertyChanged(nameof(Count)); } } + // Accesseurs pour CounterText public string CounterText { get => (string)GetValue(CounterLabelProperty); @@ -39,6 +45,7 @@ public partial class CounterView : ContentView } } + // Méthodes pour augmenter et diminuer le compteur private void OnPlus(object o, EventArgs e) { Count += 1; @@ -48,4 +55,4 @@ public partial class CounterView : ContentView { Count -= 1; } -} \ No newline at end of file +} diff --git a/Views/Components/HeadedButton.xaml.cs b/Views/Components/HeadedButton.xaml.cs index 1c00ef2..1c22ef6 100644 --- a/Views/Components/HeadedButton.xaml.cs +++ b/Views/Components/HeadedButton.xaml.cs @@ -1,26 +1,29 @@ namespace ShoopNCook.Views; using Microsoft.Maui.Graphics; +// Classe représentant un bouton avec une tête (une image en préfixe) public partial class HeadedButton : ContentView { - + // Texte du bouton public string Text { set => BtnLabel.Text = value; } + // Couleur de l'image en préfixe public string HeadColor { set => PrefixBorder.BackgroundColor = Color.FromArgb(value); } + // Source de l'image en préfixe public string HeadSource { set => PrefixImage.Source = ImageSource.FromFile(value); } public HeadedButton() - { - InitializeComponent(); - } -} \ No newline at end of file + { + InitializeComponent(); + } +} diff --git a/Views/Components/IngredientEntry.xaml.cs b/Views/Components/IngredientEntry.xaml.cs index 72a0bc3..cbc4f59 100644 --- a/Views/Components/IngredientEntry.xaml.cs +++ b/Views/Components/IngredientEntry.xaml.cs @@ -2,17 +2,20 @@ using Models; namespace ShoopNCook.Views; +// Classe représentant une entrée d'ingrédient public partial class IngredientEntry : ContentView { - public IngredientEntry() - { - InitializeComponent(); - } + public IngredientEntry() + { + InitializeComponent(); + } - public Ingredient MakeValue() - { + // Renvoie une nouvelle instance de Ingredient à partir des informations entrées par l'utilisateur + public Ingredient MakeValue() + { float quantity; + // Tente de convertir la quantité en float, sinon, attribue une valeur par défaut de 0 if (!float.TryParse(QuantityEntry.Text, out quantity)) { quantity = 0; @@ -21,4 +24,4 @@ public partial class IngredientEntry : ContentView return new Ingredient(NameEntry.Text, quantity); } -} \ No newline at end of file +} diff --git a/Views/Components/IngredientView.xaml.cs b/Views/Components/IngredientView.xaml.cs index 466d557..28ad699 100644 --- a/Views/Components/IngredientView.xaml.cs +++ b/Views/Components/IngredientView.xaml.cs @@ -2,9 +2,10 @@ using Models; namespace ShoopNCook.Views; +// Classe représentant une vue d'ingrédient public partial class IngredientView : ContentView { - + // Propriétés liées pour le nom, la quantité et l'unité de l'ingrédient private readonly BindableProperty NameProperty = BindableProperty.Create(nameof(Name), typeof(string), typeof(IngredientView), default(string)); @@ -36,9 +37,10 @@ public partial class IngredientView : ContentView { InitializeComponent(); + // Initialisation des valeurs de l'ingrédient Name = ingredient.Name; Quantity = ingredient.Amount; //TODO Unit implementation in IngredientView.xaml.cs Unit = "TODO: Unit implementation in IngredientView.xaml.cs"; } -} \ No newline at end of file +} diff --git a/Views/FavoritesPage.xaml.cs b/Views/FavoritesPage.xaml.cs index 9bf6cae..4969735 100644 --- a/Views/FavoritesPage.xaml.cs +++ b/Views/FavoritesPage.xaml.cs @@ -2,7 +2,7 @@ using Models; namespace ShoopNCook.Pages; -using Endpoint; +using Services; using Models; using ShoopNCook.Views; @@ -23,7 +23,7 @@ public partial class FavoritesPage : ContentPage private void UpdateFavorites() { - IAccountRecipesPreferences preferences = service.GetPreferencesOf(account); + IAccountRecipesPreferencesService preferences = service.GetPreferencesOf(account); RecipeViewLayout.Children.Clear(); preferences.GetFavorites().ForEach(info => { diff --git a/Views/HomePage.xaml.cs b/Views/HomePage.xaml.cs index e4b1233..d69b43a 100644 --- a/Views/HomePage.xaml.cs +++ b/Views/HomePage.xaml.cs @@ -1,8 +1,8 @@ namespace ShoopNCook.Pages; using Models; using ShoopNCook.Views; -using Endpoint; -using LocalEndpoint; +using Services; +using Services; public partial class HomePage : ContentPage { @@ -11,7 +11,7 @@ public partial class HomePage : ContentPage InitializeComponent(); IRecipesService service = endpoint.RecipesService; - IAccountRecipesPreferences preferences = service.GetPreferencesOf(account); + IAccountRecipesPreferencesService preferences = service.GetPreferencesOf(account); //TODO this code can be factorised diff --git a/Views/LoginPage.xaml.cs b/Views/LoginPage.xaml.cs index c3eaeb8..31f87f7 100644 --- a/Views/LoginPage.xaml.cs +++ b/Views/LoginPage.xaml.cs @@ -1,4 +1,4 @@ -using Endpoint; +using Services; using ShoopNCook.Controllers; namespace ShoopNCook.Pages; diff --git a/Views/MyListPage.xaml.cs b/Views/MyListPage.xaml.cs index 7adabd1..7e51831 100644 --- a/Views/MyListPage.xaml.cs +++ b/Views/MyListPage.xaml.cs @@ -1,5 +1,5 @@ -using Endpoint; -using LocalEndpoint; +using Services; +using Services; using Models; using ShoopNCook.Views; @@ -8,7 +8,7 @@ namespace ShoopNCook.Pages; public partial class MyListPage : ContentPage { - private readonly IAccountRecipesPreferences preferences; + private readonly IAccountRecipesPreferencesService preferences; private readonly IRecipesService service; public MyListPage(Account account, IRecipesService service) diff --git a/Views/MyRecipesPage.xaml.cs b/Views/MyRecipesPage.xaml.cs index bdfb844..b4210ba 100644 --- a/Views/MyRecipesPage.xaml.cs +++ b/Views/MyRecipesPage.xaml.cs @@ -1,5 +1,5 @@ -using Endpoint; -using LocalEndpoint; +using Services; +using Services; using Models; using ShoopNCook.Views; @@ -31,7 +31,7 @@ public partial class MyRecipesPage : ContentPage RecipesLayout.Children.Add(new OwnedRecipeView(info, () => { Recipe recipe = service.GetRecipe(info); - IAccountRecipesPreferences preferences = service.GetPreferencesOf(account); + IAccountRecipesPreferencesService preferences = service.GetPreferencesOf(account); Shell.Current.Navigation.PushAsync(new RecipePage(recipe, preferences, 1)); }, () => RemoveRecipe(info) @@ -40,7 +40,7 @@ public partial class MyRecipesPage : ContentPage private void RemoveRecipe(RecipeInfo info) { - IAccountOwnedRecipes recipes = service.GetRecipesOf(account); + IAccountOwnedRecipesService recipes = service.GetRecipesOf(account); if (!recipes.RemoveRecipe(info)) { @@ -64,7 +64,7 @@ public partial class MyRecipesPage : ContentPage } private async void OnAddRecipeButtonClicked(object sender, EventArgs e) { - IAccountOwnedRecipes recipes = service.GetRecipesOf(account); + IAccountOwnedRecipesService recipes = service.GetRecipesOf(account); var page = new CreateRecipePage(account.User, recipe => { diff --git a/Views/RecipePage.xaml.cs b/Views/RecipePage.xaml.cs index d8fbe39..6cd094d 100644 --- a/Views/RecipePage.xaml.cs +++ b/Views/RecipePage.xaml.cs @@ -1,8 +1,8 @@ using ShoopNCook.Views; using System.Windows.Input; using Models; -using LocalEndpoint; -using Endpoint; +using Services; +using Services; namespace ShoopNCook.Pages; @@ -13,12 +13,12 @@ public partial class RecipePage : ContentPage private bool isFavorite; - private IAccountRecipesPreferences preferences; + private IAccountRecipesPreferencesService preferences; private RecipeInfo info; public ICommand StarCommand => new Command(count => SetNote(uint.Parse(count))); - public RecipePage(Recipe recipe, IAccountRecipesPreferences preferences, uint amount) + public RecipePage(Recipe recipe, IAccountRecipesPreferencesService preferences, uint amount) { InitializeComponent(); diff --git a/Views/SearchPage.xaml.cs b/Views/SearchPage.xaml.cs index 1e8e0ed..b6109d3 100644 --- a/Views/SearchPage.xaml.cs +++ b/Views/SearchPage.xaml.cs @@ -1,12 +1,9 @@ namespace ShoopNCook.Pages; -using Models; -using ShoopNCook.Views; public partial class SearchPage : ContentPage { public SearchPage() { InitializeComponent(); - //TODO } private async void OnBackButtonClicked(object sender, EventArgs e) {