using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; using TINK.Services.CopriApi.ServerUris; using TINK.View; using TINK.View.Account; using TINK.View.Contact; using TINK.View.Info; using TINK.View.Login; using TINK.View.Map; using TINK.View.FindBike; using TINK.View.MyBikes; using TINK.View.Root; using TINK.View.Settings; using Xamarin.Forms; using TINK.ViewModel.MasterDetail; #if USEFLYOUT using TINK.View.MasterDetail; #endif using TINK.Services; using TINK.View.Themes; namespace TINK.ViewModel.Root { /// /// View model for flyout menu entries. Respositility /// - populates entries depending on app state on showing menu /// - updates menu denpending on app state change, i.e. user logs in/ out. /// public class RootPageFlyoutViewModel : INotifyPropertyChanged { /// /// Dictionary to manage collection of menu items. /// private Dictionary m_oEntryDictionary; public event PropertyChangedEventHandler PropertyChanged; /// Updates menu entries depending on state. private void UpdateMenuEntries() { for (int l_iIndex = MenuItems.Count - 1; l_iIndex >= 0; l_iIndex--) { MenuItems.Clear(); m_oEntryDictionary.Clear(); } CheckAddItem(typeof(MapPage)); if (App.ModelRoot.ActiveUser.IsLoggedIn) { CheckAddItem(typeof(MyBikesPage)); CheckAddItem(typeof(FindBikePage)); CheckAddItem(typeof(AccountPage)); } else { CheckAddItem(typeof(LoginPage)); } if (App.ModelRoot.Uris.ActiveUri.Host.GetIsCopri() || App.ModelRoot.ActiveUser.IsLoggedIn) { CheckAddItem(typeof(SettingsPage)); } CheckAddItem(typeof(FeesAndBikesPage)); // Fees and bikes CheckAddItem(typeof(ContactPage)); // Feedback and contact CheckAddItem(typeof(TabbedPageInfo)); // About sharee.bike } /// Adds a menu item to master detail menu. /// Type decribing entry to be added. private void CheckAddItem(Type p_oType) { if (m_oEntryDictionary.ContainsKey(p_oType)) { // Nothing to do because has already been added. return; } m_oEntryDictionary.Add( p_oType, m_oEntryDictionary.Count); MenuItems.Add(new RootPageFlyoutMenuItem { TargetType = p_oType, GlyphCode = Helper.GetGlyphCode(p_oType), Title = Helper.GetCaption(p_oType), Id = m_oEntryDictionary[p_oType] }) ; } /// Removes a page from menu. /// private void RemoveItem(Type p_oType) { if (!m_oEntryDictionary.ContainsKey(p_oType)) { // Nothing to do because item was never added/ already removed. return; } MenuItems.Remove(MenuItems[m_oEntryDictionary[p_oType]]); m_oEntryDictionary.Remove(p_oType); } public RootPageFlyoutViewModel() { MenuItems = new ObservableCollection(); m_oEntryDictionary = new Dictionary(); // Update menu entries on login/ logout actions. App.ModelRoot.ActiveUser.StateChanged += (sender, eventargs) => OnUpdateRequired(); // Update flyout view model whenever theme is switched. App.ModelRoot.Themes.PropertyChanged += (sender, eventargs) => { if (!(sender is ServicesContainerMutable themes)) return; MasterDetailMenuTitlte = GetMasterDetailMenuTitle(themes.Active); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MasterDetailMenuTitlte))); }; MasterDetailMenuTitlte = GetMasterDetailMenuTitle(App.ModelRoot.Themes.Active); UpdateMenuEntries(); } /// /// Gets the flyout title from theme name /// /// Name of theme. /// Flyout title. private string GetMasterDetailMenuTitle(object theme) { if (!(theme is ITheme active)) return "sharee.bike"; return $"sharee.bike{(!string.IsNullOrEmpty(active.OperatorInfo) ? ($"\r\n{active.OperatorInfo}") : string.Empty)}"; } /// /// Holds the title of the fylout page. /// public string MasterDetailMenuTitlte { get; private set; } /// /// Provides collection of menu items for master page. /// public ObservableCollection MenuItems { get; private set; } /// /// Gets or sets the selected item. /// public MainPageMenuItem SelectedMenuItem { get; set; } /// /// Command object which is invoked from view when an item is selected. /// public Command MenuItemSelected { get { return new Command(OnUpdateRequired); } } /// Manges updates required due to selection of a menu or login events. public void OnUpdateRequired() { UpdateMenuEntries(); if (SelectedMenuItem == null) { // Nothing to do if no menu entry is selected. return; } } } }