305 lines
11 KiB
C#
305 lines
11 KiB
C#
using Google.Apis.YouTube.v3.Data;
|
|
using Microsoft.AppCenter;
|
|
using Microsoft.AppCenter.Analytics;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Xml;
|
|
using Windows.ApplicationModel;
|
|
using Windows.ApplicationModel.Activation;
|
|
using Windows.ApplicationModel.Background;
|
|
using Windows.Globalization;
|
|
using Windows.Storage;
|
|
using Windows.System.Power;
|
|
using Windows.UI.Notifications;
|
|
using Windows.UI.Xaml;
|
|
using Windows.UI.Xaml.Controls;
|
|
using Windows.UI.Xaml.Navigation;
|
|
|
|
namespace FoxTube
|
|
{
|
|
sealed partial class App : Application
|
|
{
|
|
public static string[] AvailableLanguages => new[] { "en-US", "ru-RU" };
|
|
|
|
Stopwatch sw = new Stopwatch();
|
|
public App()
|
|
{
|
|
SettingsStorage.LoadData();
|
|
|
|
switch (SettingsStorage.Theme)
|
|
{
|
|
case 0:
|
|
RequestedTheme = ApplicationTheme.Light;
|
|
break;
|
|
case 1:
|
|
RequestedTheme = ApplicationTheme.Dark;
|
|
break;
|
|
}
|
|
ApplicationLanguages.PrimaryLanguageOverride = SettingsStorage.Language;
|
|
|
|
CheckVersion();
|
|
|
|
InitializeComponent();
|
|
Suspending += OnSuspending;
|
|
UnhandledException += UnhandledError;
|
|
|
|
AppCenter.Start("45774462-9ea7-438a-96fc-03982666f39e", typeof(Analytics));
|
|
AppCenter.SetCountryCode(SettingsStorage.Region);
|
|
|
|
sw.Start();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Comparing current version with last recorded version. If doesn't match, poping up changelog notification
|
|
/// </summary>
|
|
public async void CheckVersion()
|
|
{
|
|
PackageVersion ver = Package.Current.Id.Version;
|
|
if (SettingsStorage.Version != $"{ver.Major}.{ver.Minor}.{ver.Build}")
|
|
{
|
|
try
|
|
{
|
|
XmlDocument changelog = new XmlDocument();
|
|
StorageFile file = await (await Package.Current.InstalledLocation.GetFolderAsync(@"Assets\Data")).GetFileAsync("Patchnotes.xml");
|
|
changelog.Load(await file.OpenStreamForReadAsync());
|
|
XmlElement e = changelog["items"].ChildNodes[0] as XmlElement;
|
|
|
|
ToastNotificationManager.CreateToastNotifier().Show(Background.Notification.GetChangelogToast(e.GetAttribute("version")));
|
|
|
|
SettingsStorage.Version = $"{ver.Major}.{ver.Minor}.{ver.Build}";
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Analytics.TrackEvent("Unable to retrieve changelog", new Dictionary<string, string>
|
|
{
|
|
{ "Exception", e.GetType().ToString() },
|
|
{ "Message", e.Message },
|
|
{ "App version", $"{ver.Major}.{ver.Minor}.{ver.Revision}.{ver.Build}" },
|
|
{ "StackTrace", e.StackTrace }
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
|
{
|
|
if (!(Window.Current.Content is Frame rootFrame))
|
|
{
|
|
rootFrame = new Frame();
|
|
rootFrame.NavigationFailed += OnNavigationFailed;
|
|
Window.Current.Content = rootFrame;
|
|
}
|
|
|
|
if (e.PrelaunchActivated == false)
|
|
{
|
|
if (rootFrame.Content == null)
|
|
rootFrame.Navigate(typeof(MainPage), e.Arguments);
|
|
|
|
Window.Current.Activate();
|
|
}
|
|
|
|
ActivateToastBackgoundTask();
|
|
ActivateBackgoundTask();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes background task for processing toast notifications' clicks
|
|
/// </summary>
|
|
public async void ActivateToastBackgoundTask()
|
|
{
|
|
const string taskName = "FoxtubeToastBackground";
|
|
if (BackgroundTaskRegistration.AllTasks.Any(i => i.Value.Name.Equals(taskName)))
|
|
return;
|
|
|
|
var backgroundRequest = await BackgroundExecutionManager.RequestAccessAsync();
|
|
if (backgroundRequest == BackgroundAccessStatus.DeniedBySystemPolicy || backgroundRequest == BackgroundAccessStatus.DeniedByUser)
|
|
return;
|
|
|
|
BackgroundTaskBuilder builder = new BackgroundTaskBuilder() { Name = taskName };
|
|
builder.SetTrigger(new ToastNotificationActionTrigger());
|
|
|
|
BackgroundTaskRegistration registration = builder.Register();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes background task for checking user's subscriptions and poping toast notifications when new video is uploaded
|
|
/// </summary>
|
|
public async void ActivateBackgoundTask()
|
|
{
|
|
const string taskName = "FoxtubeBackgound";
|
|
if (BackgroundTaskRegistration.AllTasks.Any(i => i.Value.Name.Equals(taskName)))
|
|
return;
|
|
|
|
var backgroundRequest = await BackgroundExecutionManager.RequestAccessAsync();
|
|
var saverRequest = PowerManager.EnergySaverStatus;
|
|
if (backgroundRequest == BackgroundAccessStatus.DeniedBySystemPolicy || backgroundRequest == BackgroundAccessStatus.DeniedByUser || saverRequest == EnergySaverStatus.On)
|
|
return;
|
|
|
|
BackgroundTaskBuilder builder = new BackgroundTaskBuilder()
|
|
{
|
|
Name = taskName,
|
|
IsNetworkRequested = true,
|
|
TaskEntryPoint = "FoxTube.Background.BackgroundProcessor"
|
|
};
|
|
builder.SetTrigger(new TimeTrigger(15, false));
|
|
|
|
BackgroundTaskRegistration registration = builder.Register();
|
|
}
|
|
|
|
protected override void OnBackgroundActivated(BackgroundActivatedEventArgs args)
|
|
{
|
|
var deferral = args.TaskInstance.GetDeferral();
|
|
base.OnBackgroundActivated(args);
|
|
|
|
if (args.TaskInstance.Task.Name == "FoxtubeToastBackground" && args.TaskInstance.TriggerDetails is ToastNotificationActionTriggerDetail details)
|
|
{
|
|
string[] arguments = details.Argument.Split('|');
|
|
|
|
switch (arguments[0])
|
|
{
|
|
case "later":
|
|
try
|
|
{
|
|
SecretsVault.AuthorizationStateChanged += async (s, e) =>
|
|
{
|
|
if ((bool)e[0])
|
|
{
|
|
PlaylistItem item = new PlaylistItem()
|
|
{
|
|
Snippet = new PlaylistItemSnippet()
|
|
{
|
|
ResourceId = new ResourceId()
|
|
{
|
|
Kind = "youtube#video",
|
|
VideoId = arguments[1]
|
|
},
|
|
PlaylistId = "WL"
|
|
}
|
|
};
|
|
|
|
await SecretsVault.Service.PlaylistItems.Insert(item, "snippet").ExecuteAsync();
|
|
}
|
|
};
|
|
SecretsVault.CheckAuthorization(false);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Analytics.TrackEvent("Failed to add video to WL from toast", new Dictionary<string, string>
|
|
{
|
|
{ "Exception", e.GetType().ToString() },
|
|
{ "Message", e.Message },
|
|
{ "Video ID", arguments[1] },
|
|
{ "StackTrace", e.StackTrace }
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
deferral.Complete();
|
|
}
|
|
|
|
protected override void OnActivated(IActivatedEventArgs e)
|
|
{
|
|
base.OnActivated(e);
|
|
|
|
if (!(Window.Current.Content is Frame rootFrame))
|
|
{
|
|
rootFrame = new Frame();
|
|
rootFrame.NavigationFailed += OnNavigationFailed;
|
|
|
|
Window.Current.Content = rootFrame;
|
|
}
|
|
|
|
if (rootFrame.Content == null)
|
|
rootFrame.Navigate(typeof(MainPage));
|
|
|
|
Window.Current.Activate();
|
|
|
|
switch (e.Kind)
|
|
{
|
|
case ActivationKind.ToastNotification:
|
|
if (SecretsVault.IsAuthorized)
|
|
ProcessToast((e as ToastNotificationActivatedEventArgs).Argument);
|
|
else
|
|
SecretsVault.AuthorizationStateChanged += (s, arg) => ProcessToast((e as ToastNotificationActivatedEventArgs).Argument);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void ProcessToast(string arg)
|
|
{
|
|
string[] args = arg.Split('|');
|
|
switch (args[0])
|
|
{
|
|
case "changelog":
|
|
case "inbox":
|
|
Methods.MainPage.GoToDeveloper(args[1]);
|
|
break;
|
|
|
|
case "video":
|
|
Methods.MainPage.GoToVideo(args[1]);
|
|
break;
|
|
|
|
case "channel":
|
|
Methods.MainPage.GoToChannel(args[1]);
|
|
break;
|
|
|
|
case "download":
|
|
Methods.MainPage.GoToDownloads();
|
|
break;
|
|
case "dcancel":
|
|
DownloadAgent.Cancel(args[1]);
|
|
break;
|
|
case "clipboard":
|
|
switch (args[1])
|
|
{
|
|
case "video":
|
|
Methods.MainPage.GoToVideo(args[2]);
|
|
break;
|
|
case "channel":
|
|
Methods.MainPage.GoToChannel(args[2]);
|
|
break;
|
|
case "playlist":
|
|
Methods.MainPage.GoToPlaylist(args[2]);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
|
|
{
|
|
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
|
|
}
|
|
|
|
private void OnSuspending(object sender, SuspendingEventArgs e)
|
|
{
|
|
var deferral = e.SuspendingOperation.GetDeferral();
|
|
|
|
sw.Stop();
|
|
SettingsStorage.Uptime += sw.Elapsed;
|
|
|
|
HistorySet.Save();
|
|
SettingsStorage.SaveData();
|
|
DownloadAgent.QuitPrompt();
|
|
Controls.Player.ManifestGenerator.ClearRoaming();
|
|
deferral.Complete();
|
|
Analytics.TrackEvent("Session terminated");
|
|
}
|
|
|
|
private void UnhandledError(object sender, Windows.UI.Xaml.UnhandledExceptionEventArgs e)
|
|
{
|
|
Analytics.TrackEvent("The app crashed", new Dictionary<string, string>()
|
|
{
|
|
{ "Exception", e.Exception.GetType().ToString() },
|
|
{ "Details", e.Message },
|
|
{ "StackTrace", e.Exception.StackTrace }
|
|
});
|
|
}
|
|
}
|
|
}
|