using LibTVRefCommonPortable.Utils;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace TVApps.ViewModels
{
+ /// <summary>
+ /// A class contains installed, pinned application list.
+ /// The MainPageViewModel changes state of application item by AppsHolder's API
+ /// </summary>
internal class AppsHolder
{
+ /// <summary>
+ /// The interface for interaction with view model
+ /// </summary>
IAppsViewModel ViewModel;
+ /// <summary>
+ /// A flag indicates how to sort InstalledApps
+ /// </summary>
+ /// <see cref="SortingOptions"/>
public SortingOptions SortingOption;
+ /// <summary>
+ /// A list contains AppShortcutInfo about installed applications
+ /// </summary>
+ /// <see cref="AppShortcutInfo"/>
public List<AppShortcutInfo> InstalledApps;
+ /// <summary>
+ /// A dictionary contains ID of pinned applications
+ /// </summary>
public Dictionary<string, string> PinnedApps;
+ /// <summary>
+ /// A name of pinned application
+ /// </summary>
+ public string PinnedAppName;
+ /// <summary>
+ /// A name of unpinned application
+ /// </summary>
+ public string UnpinnedAppName;
+
+ public bool IsSelectedExceeds;
+
+ /// <summary>
+ /// A constructor
+ /// Initializes installed and pinned app list
+ /// </summary>
+ /// <param name="ViewModel">The instance of MainPageViewModel</param>
public AppsHolder(IAppsViewModel ViewModel)
{
this.ViewModel = ViewModel;
App.SetAppUninstalledListener((s, e) =>
{
- // TODO : find apps by package id
- // TODO : remove all apps from pinned app list
-
SetApps();
});
+ SynchronizationContext.Current.Post((o) =>
+ {
+ SetApps();
+ }, "");
- SetApps();
}
+ /// <summary>
+ /// A method gets installed, pinned application information from AppShortcutController.
+ /// And adds state descriptions about pin, delete, long press state
+ /// </summary>
private async void SetApps()
{
var pinnedAppsGettingTask = TVHomeImpl.GetInstance.AppShortcutControllerInstance.GetPinnedAppsAppIDs();
await Task.WhenAll(pinnedAppsGettingTask, installedAppsGettingTask);
PinnedApps = pinnedAppsGettingTask.Result;
+ ViewModel.OnPropertyChanged("SumOfCheckedApp");
+
var installedApps = installedAppsGettingTask.Result;
foreach (AppShortcutInfo item in installedApps)
continue;
}
- item.SetPinned(PinnedApps.ContainsKey(item.AppID));
+ item.IsPinned = PinnedApps.ContainsKey(item.AppID);
+
+ CommandAction pinAction = new CommandAction()
+ {
+ NextStateDescription = AppsStatus.Pin.ToString().ToLower(),
+ CommandParameter = item.AppID
+ };
+ pinAction.Command += new System.EventHandler<string>((s, arg) =>
+ {
+ PinToggle(arg);
+ });
var pinStateDescription = new StateDescription()
{
Label = item.CurrentStateDescription.Label,
IconPath = item.CurrentStateDescription.IconPath,
- Action = new CommandAction()
- {
- NextStateDescription = AppsStatus.Pin.ToString().ToLower(),
- Command = new Command<string>((key) =>
- {
- PinToggle(key);
- }),
- CommandParameter = item.AppID
- }
+ Action = pinAction,
};
item.StateDescriptions.Add(AppsStatus.Pin.ToString().ToLower(), pinStateDescription);
+ CommandAction checkDeleteAction = new CommandAction()
+ {
+ NextStateDescription = AppsStatus.Delete.ToString().ToLower(),
+ CommandParameter = item.AppID
+ };
+ checkDeleteAction.Command += new System.EventHandler<string>((s, arg) =>
+ {
+ CheckDeleteApp(arg);
+ });
+
var deleteStateDescription = new StateDescription()
{
Label = item.CurrentStateDescription.Label,
IconPath = item.CurrentStateDescription.IconPath,
- Action = new CommandAction()
- {
- NextStateDescription = AppsStatus.Delete.ToString().ToLower(),
- Command = new Command<string>((key) =>
- {
- DeleteApp(key);
- }),
- CommandParameter = item.AppID
- }
+ Action = checkDeleteAction,
};
item.StateDescriptions.Add(AppsStatus.Delete.ToString().ToLower(), deleteStateDescription);
+ CommandAction longPressAction = new CommandAction()
+ {
+ NextStateDescription = AppsStatus.LongPress.ToString().ToLower(),
+ CommandParameter = item.AppID
+ };
+ pinAction.Command += new System.EventHandler<string>((s, arg) =>
+ {
+ LongPressApp(arg);
+ });
+
var longPressStateDescription = new StateDescription()
{
Label = item.CurrentStateDescription.Label,
IconPath = item.CurrentStateDescription.IconPath,
- Action = new CommandAction()
- {
- NextStateDescription = AppsStatus.LongPress.ToString().ToLower(),
- Command = new Command<string>((key) =>
- {
- LongPressApp(key);
- }),
- CommandParameter = item.AppID
- }
+ Action = longPressAction,
};
item.StateDescriptions.Add(AppsStatus.LongPress.ToString().ToLower(), longPressStateDescription);
}
UpdateStateDescription(ViewModel.CurrentStatus);
}
- private void PinToggle(string key)
+ /// <summary>
+ /// A method changes pin state of AppShortcutInfo
+ /// And adds or removes application ID in PinnedApps
+ /// </summary>
+ /// <param name="appID">The ID of application for changing pin state</param>
+ private void PinToggle(string appID)
{
- if (PinnedApps.ContainsKey(key))
+ AppShortcutInfo selectedApp = InstalledApps.FirstOrDefault(a => a.AppID == appID);
+ if (selectedApp == null)
{
- DebuggingUtils.Dbg("UnPin!");
- InstalledApps.FirstOrDefault(a => a.AppID == key).SetChecked(false);
- InstalledApps.FirstOrDefault(a => a.AppID == key).SetPinned(false);
- PinnedApps.Remove(key);
+ DebuggingUtils.Err("Failed to Pin!!!, Nothing selected, AppID = " + appID);
+ return;
+ }
+
+ if (PinnedApps.ContainsKey(appID))
+ {
+ DebuggingUtils.Dbg("UnPin! : " + selectedApp);
+ selectedApp.IsChecked = false;
+ selectedApp.IsPinned = false;
+ PinnedApps.Remove(appID);
+ UnpinnedAppName = selectedApp.CurrentStateDescription.Label;
+ ViewModel.OnPropertyChanged("UnpinnedAppName");
}
else
{
- DebuggingUtils.Dbg("Pin!");
- InstalledApps.FirstOrDefault(a => a.AppID == key).SetChecked(true);
- InstalledApps.FirstOrDefault(a => a.AppID == key).SetPinned(true);
- PinnedApps.Add(key, key);
+ if (PinnedApps.Count >= 10)
+ {
+ IsSelectedExceeds = true;
+ ViewModel.OnPropertyChanged("IsSelectedExceeds");
+ return;
+ }
+
+ DebuggingUtils.Dbg("Pin! : " + selectedApp);
+ selectedApp.IsChecked = true;
+ selectedApp.IsPinned = true;
+ PinnedApps.Add(appID, appID);
+ PinnedAppName = selectedApp.CurrentStateDescription.Label;
+ ViewModel.OnPropertyChanged("PinnedAppName");
+ }
+
+ UpdatePinnedApps();
+ ViewModel.OnPropertyChanged("SumOfCheckedApp");
+ }
+
+ /// <summary>
+ /// A method changes pin state of AppShortcutInfo by the Option Menu Pin/Unpin button
+ /// And adds or removes application ID in PinnedApps
+ /// </summary>
+ /// <param name="appID">The ID of application for changing pin state</param>
+ public void OptionMenuPinToggle(string appID)
+ {
+ AppShortcutInfo SelectedApp = InstalledApps.FirstOrDefault(a => a.AppID.Equals(appID));
+ if (SelectedApp == null)
+ {
+ DebuggingUtils.Err("Failed to get selected app : " + appID);
+ return;
+ }
+
+ if (PinnedApps.ContainsKey(appID))
+ {
+ DebuggingUtils.Dbg("Unpin : " + appID);
+ SelectedApp.IsPinned = false;
+ PinnedApps.Remove(appID);
+ }
+ else
+ {
+ DebuggingUtils.Dbg("Pin : " + appID);
+ SelectedApp.IsPinned = true;
+ PinnedApps.Add(appID, appID);
+ }
+
+ ViewModel.OnPropertyChanged("SumOfCheckedApp");
+
+ this.UpdatePinnedApps();
+ ViewModel.ChangeCurrentStatus(AppsStatus.Default);
+ }
+
+ /// <summary>
+ /// A method for changing status of applications to Default
+ /// </summary>
+ public void ChangeToDefaultStatus()
+ {
+ ViewModel.ChangeCurrentStatus(AppsStatus.Default);
+ }
+
+ /// <summary>
+ /// Removes the pinned app by app ID
+ /// </summary>
+ /// <param name="removableAppsList">The apps list to remove at the pinned app list</param>
+ public void RemovePinnedApp(List<string> removableAppsList)
+ {
+ foreach (string app in removableAppsList)
+ {
+ if (PinnedApps.ContainsKey(app))
+ {
+ DebuggingUtils.Dbg("UnPin! : " + app);
+
+ PinnedApps.Remove(app);
+ }
+ }
+
+ UpdatePinnedApps();
+ }
+
+ /// <summary>
+ /// A method for checking the application is removable
+ /// If the application is removable, show Delete Popup
+ /// </summary>
+ /// <param name="appID">The ID of application for checking</param>
+ public void CheckDeleteApp(string appID)
+ {
+ DebuggingUtils.Dbg("check that the app( " + appID + ") can be deleted");
+
+ if (!ApplicationManagerUtils.Instance.GetAppInfoRemovable(appID))
+ {
+ DebuggingUtils.Dbg("This app is not removable : " + appID);
+ return;
+ }
+
+ string appLabel = null;
+ if (ApplicationManagerUtils.Instance.GetInstalledApplication(appID).TryGetValue("Label", out appLabel))
+ {
+ ViewModel.ShowDeletePopup(appLabel);
}
}
- private void DeleteApp(string AppID)
+ /// <summary>
+ /// A method sends application delete request
+ /// If application is pinned, removes in PinnedApps
+ /// </summary>
+ /// <param name="appID">The ID of application for deleting</param>
+ public void DeleteApp(string appID)
{
- DebuggingUtils.Dbg("Delete, " + AppID);
+ // if the app to be deleted is pinned, remove the app in the pinned apps list
+ string pkgID = PackageManagerUtils.GetPackageIDByAppID(appID);
+ if (pkgID == null)
+ {
+ DebuggingUtils.Err("Failed to get the package ID by app ID(" + appID + ")");
+
+ return;
+ }
- // TODO : popup
+ List<string> appsList = PackageManagerUtils.GetApplicationsByPkgID(pkgID);
+ if (appsList == null || appsList.Count == 0)
+ {
+ DebuggingUtils.Err("Failed to get the apps list by package ID(" + pkgID + ")");
- // TODO : remove all app of removed package!!!
- RemovePinnedApp(AppID);
+ return;
+ }
ViewModel.ChangeCurrentStatus(AppsStatus.Default);
- if (PackageManagerUtils.UninstallPackageByAppID(AppID) == false)
+ if (PackageManagerUtils.UninstallPackageByAppID(appID) == false)
{
- DebuggingUtils.Err("App uninstall is failed!!!, " + AppID);
+ DebuggingUtils.Err("App uninstall is failed!!!, " + appID);
}
else
{
var removed = from app in InstalledApps
- where app.AppID == AppID
+ where app.AppID == appID
select app;
InstalledApps.Remove(removed.First());
foreach (var item in InstalledApps)
DebuggingUtils.Dbg("- " + item.AppID);
}
+ RemovePinnedApp(appsList);
RefreshApps();
}
}
+ /// <summary>
+ /// A method changes long press state of AppShortcutInfo
+ /// </summary>
+ /// <param name="AppID">The ID of application for showing option menu</param>
private void LongPressApp(string AppID)
{
- // TODO:
DebuggingUtils.Dbg(" +++++ long press app : " + AppID);
}
+ /// <summary>
+ /// A method updates state description of applications
+ /// </summary>
+ /// <param name="status">The state name for updating state description</param>
public void UpdateStateDescription(AppsStatus status)
{
string tag = status.ToString().ToLower();
+ if (status == AppsStatus.LongPress)
+ {
+ AppShortcutInfo focuesedApp = InstalledApps.Find(a => a.IsFocused);
+ if (focuesedApp == null)
+ {
+ DebuggingUtils.Dbg("FocusedApp is not exist. Change app status to default");
+ ViewModel.ChangeCurrentStatus(AppsStatus.Default);
+ return;
+ }
+ }
+
DebuggingUtils.Dbg("AppsListStateUpdate, status = " + status.ToString() + ", tag = " + tag);
foreach (AppShortcutInfo item in InstalledApps)
{
item.CurrentStateDescription = item.StateDescriptions[tag];
switch (status)
{
+ case AppsStatus.Default:
+ item.IsChecked = false;
+ item.IsDim = false;
+ item.IsShowOptions = false;
+ break;
case AppsStatus.Pin:
- item.SetChecked(item.IsPinned);
+ item.IsChecked = item.IsPinned;
+ break;
+ case AppsStatus.LongPress:
+ if (item.IsFocused)
+ {
+ item.IsShowOptions = true;
+ }
+ else
+ {
+ item.IsDim = true;
+ }
+
break;
+ case AppsStatus.Delete:
+ if (!item.IsRemovable)
+ {
+ item.IsDim = true;
+ }
- default:
- item.SetChecked(false);
+ item.IsChecked = false;
break;
}
- item.SetPinned(PinnedApps.ContainsKey(item.AppID));
+ item.IsPinned = PinnedApps.ContainsKey(item.AppID);
}
ViewModel.OnPropertyChanged("InstalledAppList");
}
- // Just use to update list view which is binding
+ /// <summary>
+ /// A method refresh InstalledApps
+ /// </summary>
private void RefreshApps()
{
+ // Only updating elements of InstalledApps is not update the GUI.
InstalledApps = new List<AppShortcutInfo>(InstalledApps);
ViewModel.OnPropertyChanged("InstalledAppList");
}
+ /// <summary>
+ /// A method sorts InstalledApps according to parameter
+ /// </summary>
+ /// <param name="sortOption">The option for sorting InstalledApps</param>
+ /// <see cref="SortingOptions"></see>
public void SortApps(SortingOptions sortOption)
{
AppsListSorter.GetSortedAppsList(sortOption, ref InstalledApps);
RefreshApps();
}
+ /// <summary>
+ /// A method reloads PinnedApps from AppShortcutController
+ /// </summary>
public async void ResetPinnedApps()
{
PinnedApps = await TVHomeImpl.GetInstance.AppShortcutControllerInstance.GetPinnedAppsAppIDs();
}
+ /// <summary>
+ /// A method updates list about pinned application to AppShortcutController
+ /// </summary>
public void UpdatePinnedApps()
{
List<AppShortcutInfo> pinnedAppList = new List<AppShortcutInfo>();
foreach (var item in PinnedApps)
{
- DebuggingUtils.Dbg("Pinned App : " + item.Key);
pinnedAppList.Add(new AppShortcutInfo()
{
AppID = item.Key,
TVHomeImpl.GetInstance.AppShortcutControllerInstance.UpdatePinnedApps(pinnedAppList);
}
- public void RemovePinnedApp(string AppID)
- {
- if (PinnedApps.ContainsKey(AppID))
- {
- PinnedApps.Remove(AppID);
- UpdatePinnedApps();
- }
- }
-
- public void HideLongPressedApp(string appId)
- {
- InstalledApps = new List<AppShortcutInfo>(InstalledApps);
- AppShortcutInfo longPressedApp = InstalledApps.Find(app => app.AppID.Equals(appId));
- if (longPressedApp != null)
- {
- DebuggingUtils.Dbg("Hide the app icon : " + longPressedApp.AppID);
- longPressedApp.SetVisible(false);
- }
- }
-
- public void ShowLongPressedApp(string appId)
- {
- InstalledApps = new List<AppShortcutInfo>(InstalledApps);
- AppShortcutInfo longPressedApp = InstalledApps.Find(app => app.AppID.Equals(appId));
- if (longPressedApp != null)
- {
- DebuggingUtils.Dbg("Show the app icon : " + longPressedApp.AppID);
- longPressedApp.SetVisible(true);
- }
- }
-
- public void SetAppItemDim(string appId)
- {
- InstalledApps = new List<AppShortcutInfo>(InstalledApps);
- foreach (AppShortcutInfo app in InstalledApps)
- {
- if (!app.AppID.Equals(appId))
- {
- app.SetDim(true);
- }
- }
- }
-
- public void UnsetAppItemDim(string appId)
- {
- InstalledApps = new List<AppShortcutInfo>(InstalledApps);
- foreach (AppShortcutInfo app in InstalledApps)
- {
- if (!app.AppID.Equals(appId))
- {
- app.SetDim(false);
- }
- }
- }
-
+ /// <summary>
+ /// A method changes visible state of option menu to true
+ /// </summary>
+ /// <param name="appId">The ID of application for showing option menu</param>
public void ShowLongPressOption(string appId)
{
- InstalledApps = new List<AppShortcutInfo>(InstalledApps);
AppShortcutInfo longPressedApp = InstalledApps.Find(app => app.AppID.Equals(appId));
if (longPressedApp != null)
{
- longPressedApp.ShowOptions();
+ longPressedApp.IsDim = false;
+ longPressedApp.IsShowOptions = true;
}
}
+ /// <summary>
+ /// A method changes visible state of option menu to false
+ /// </summary>
+ /// <param name="appId">The ID of application for hiding option menu</param>
public void HideLongPressOption(string appId)
{
- InstalledApps = new List<AppShortcutInfo>(InstalledApps);
AppShortcutInfo longPressedApp = InstalledApps.Find(app => app.AppID.Equals(appId));
if (longPressedApp != null)
{
- longPressedApp.HideOptions();
+ longPressedApp.IsShowOptions = false;
}
}
}