sharee.bike-App/TINK/TINK/ViewModel/RootFlyout/RootPageViewModel.cs
2021-08-28 10:04:10 +02:00

197 lines
6 KiB
C#

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
{
/// <summary>
/// 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.
/// </summary>
public class RootPageFlyoutViewModel : INotifyPropertyChanged
{
/// <summary>
/// Dictionary to manage collection of menu items.
/// </summary>
private Dictionary<Type, int> m_oEntryDictionary;
public event PropertyChangedEventHandler PropertyChanged;
/// <summary> Updates menu entries depending on state. </summary>
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
}
/// <summary>Adds a menu item to master detail menu.</summary>
/// <param name="p_oType">Type decribing entry to be added.</param>
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] }) ;
}
/// <summary> Removes a page from menu.</summary>
/// <param name="p_oType"></param>
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<RootPageFlyoutMenuItem>();
m_oEntryDictionary = new Dictionary<Type, int>();
// 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<object> themes))
return;
MasterDetailMenuTitlte = GetMasterDetailMenuTitle(themes.Active);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MasterDetailMenuTitlte)));
};
MasterDetailMenuTitlte = GetMasterDetailMenuTitle(App.ModelRoot.Themes.Active);
UpdateMenuEntries();
}
/// <summary>
/// Gets the flyout title from theme name
/// </summary>
/// <param name="theme">Name of theme.</param>
/// <returns>Flyout title.</returns>
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)}";
}
/// <summary>
/// Holds the title of the fylout page.
/// </summary>
public string MasterDetailMenuTitlte { get; private set; }
/// <summary>
/// Provides collection of menu items for master page.
/// </summary>
public ObservableCollection<RootPageFlyoutMenuItem> MenuItems
{
get; private set;
}
/// <summary>
/// Gets or sets the selected item.
/// </summary>
public MainPageMenuItem SelectedMenuItem
{
get;
set;
}
/// <summary>
/// Command object which is invoked from view when an item is selected.
/// </summary>
public Command MenuItemSelected
{
get
{
return new Command(OnUpdateRequired);
}
}
/// <summary> Manges updates required due to selection of a menu or login events.</summary>
public void OnUpdateRequired()
{
UpdateMenuEntries();
if (SelectedMenuItem == null)
{
// Nothing to do if no menu entry is selected.
return;
}
}
}
}