From 0b6367967871b9079a904950598023bebd37c7c2 Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Sun, 23 Dec 2018 10:59:26 +0300 Subject: [PATCH] Everything is fucked up --- FoxTube/App.xaml.cs | 127 +++++------- FoxTube/Classes/SearchPaameters.cs | 5 +- FoxTube/Classes/SecretsVault.cs | 129 ++++-------- FoxTube/Classes/SettingsStorage.cs | 14 +- FoxTube/Controls/ChannelCardWide.xaml | 36 ---- FoxTube/Controls/ChannelCardWide.xaml.cs | 50 ----- FoxTube/Controls/DownloadItem.xaml.cs | 15 +- FoxTube/Controls/PlaylistCard.xaml.cs | 23 +-- FoxTube/Controls/PlaylistCardWide.xaml | 50 ----- FoxTube/Controls/PlaylistCardWide.xaml.cs | 74 ------- FoxTube/Controls/VideoCardWide.xaml | 53 ----- FoxTube/Controls/VideoCardWide.xaml.cs | 112 ----------- FoxTube/FoxTube.csproj | 28 --- FoxTube/Pages/MainPage.xaml | 4 - FoxTube/Pages/MainPage.xaml.cs | 183 ++++++++++-------- FoxTube/Pages/SettingsPages/Translate.xaml | 54 ------ FoxTube/Pages/SettingsPages/Translate.xaml.cs | 125 ------------ FoxTube/Pages/VideoPage.xaml.cs | 6 +- 18 files changed, 218 insertions(+), 870 deletions(-) delete mode 100644 FoxTube/Controls/ChannelCardWide.xaml delete mode 100644 FoxTube/Controls/ChannelCardWide.xaml.cs delete mode 100644 FoxTube/Controls/PlaylistCardWide.xaml delete mode 100644 FoxTube/Controls/PlaylistCardWide.xaml.cs delete mode 100644 FoxTube/Controls/VideoCardWide.xaml delete mode 100644 FoxTube/Controls/VideoCardWide.xaml.cs delete mode 100644 FoxTube/Pages/SettingsPages/Translate.xaml delete mode 100644 FoxTube/Pages/SettingsPages/Translate.xaml.cs diff --git a/FoxTube/App.xaml.cs b/FoxTube/App.xaml.cs index c6c14d7..bfc8da6 100644 --- a/FoxTube/App.xaml.cs +++ b/FoxTube/App.xaml.cs @@ -1,8 +1,6 @@ using Google.Apis.YouTube.v3.Data; using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Globalization; using System.Linq; using Windows.ApplicationModel; using Windows.ApplicationModel.Activation; @@ -27,36 +25,23 @@ namespace FoxTube /// Initializes the singleton application object. This is the first line of authored code /// executed, and as such is the logical equivalent of main() or WinMain(). /// - ApplicationDataContainer settings = ApplicationData.Current.LocalSettings; public App() { - try + SettingsStorage.LoadData(); + + switch (SettingsStorage.Theme) { - switch((int)settings.Values["themeMode"]) - { - case 0: - RequestedTheme = ApplicationTheme.Light; - break; - case 1: - RequestedTheme = ApplicationTheme.Dark; - break; - } - } catch { } - try - { - if (settings.Values["language"] == null) - { - List cultures = new List() { "ua", "ru", "by", "kz", "kg", "md", "lv", "ee" }; - if (cultures.Contains(CultureInfo.InstalledUICulture.ThreeLetterISOLanguageName)) - settings.Values.Add("language", "ru-RU"); - else - settings.Values.Add("language", "en-US"); - } - ApplicationLanguages.PrimaryLanguageOverride = (string)settings.Values["language"]; + case 0: + RequestedTheme = ApplicationTheme.Light; + break; + case 1: + RequestedTheme = ApplicationTheme.Dark; + break; } - catch { } - this.InitializeComponent(); - this.Suspending += OnSuspending; + + ApplicationLanguages.PrimaryLanguageOverride = SettingsStorage.Language; + InitializeComponent(); + Suspending += OnSuspending; } /// @@ -98,6 +83,9 @@ namespace FoxTube ActivateBackgoundTask(); } + /// + /// Initializes background task for processing toast notifications' clicks + /// public async void ActivateToastBackgoundTask() { const string taskName = "FoxtubeToastBackground"; @@ -115,10 +103,12 @@ namespace FoxTube BackgroundTaskRegistration registration = builder.Register(); } + /// + /// Initializes background task for checking user's subscriptions and poping toast notifications when new video is uploaded + /// public async void ActivateBackgoundTask() { const string taskName = "FoxtubeBackgound"; - Debug.WriteLine($"Background task active: {BackgroundTaskRegistration.AllTasks.Any(i => i.Value.Name.Equals(taskName))}"); if (BackgroundTaskRegistration.AllTasks.Any(i => i.Value.Name.Equals(taskName))) return; @@ -136,7 +126,6 @@ namespace FoxTube builder.SetTrigger(new TimeTrigger(15, false)); BackgroundTaskRegistration registration = builder.Register(); - Debug.WriteLine($"2. Background task active: {BackgroundTaskRegistration.AllTasks.Any(i => i.Value.Name.Equals(taskName))}"); } protected async override void OnBackgroundActivated(BackgroundActivatedEventArgs args) @@ -144,47 +133,43 @@ namespace FoxTube var deferral = args.TaskInstance.GetDeferral(); base.OnBackgroundActivated(args); - if (args.TaskInstance.Task.Name == "FoxtubeToastBackground") + if (args.TaskInstance.Task.Name == "FoxtubeToastBackground" && args.TaskInstance.TriggerDetails is ToastNotificationActionTriggerDetail details) { - var details = args.TaskInstance.TriggerDetails as ToastNotificationActionTriggerDetail; - if (details != null) + string[] arguments = details.Argument.Split('|'); + + switch (arguments[0]) { - string[] arguments = details.Argument.Split('|'); + case "later": + try + { + if (!SecretsVault.IsAuthorized) + SecretsVault.CheckAuthorization(false); + if (!SecretsVault.IsAuthorized) + throw new Exception("Not authenticated"); - switch(arguments[0]) - { - case "later": - try + PlaylistItem item = new PlaylistItem() { - if(!SecretsVault.IsAuthorized) - SecretsVault.CheckAuthorization(false); - if (!SecretsVault.IsAuthorized) - throw new Exception("Not authenticated"); - - PlaylistItem item = new PlaylistItem() + Snippet = new PlaylistItemSnippet() { - Snippet = new PlaylistItemSnippet() + ResourceId = new ResourceId() { - ResourceId = new ResourceId() - { - Kind = "youtube#video", - VideoId = arguments[1] - }, - PlaylistId = "WL" - } - }; + Kind = "youtube#video", + VideoId = arguments[1] + }, + PlaylistId = "WL" + } + }; - await SecretsVault.Service.PlaylistItems.Insert(item, "snippet").ExecuteAsync(); - } - catch (Exception e) - { - Debug.WriteLine(e.Message); - } - break; - case "download": - await Launcher.LaunchFileAsync(await StorageFile.GetFileFromPathAsync(arguments[1])); - break; - } + await SecretsVault.Service.PlaylistItems.Insert(item, "snippet").ExecuteAsync(); + } + catch (Exception e) + { + Debug.WriteLine(e.Message); + } + break; + case "download": + await Launcher.LaunchFileAsync(await StorageFile.GetFileFromPathAsync(arguments[1])); + break; } } @@ -210,6 +195,8 @@ namespace FoxTube rootFrame.Navigate(typeof(MainPage)); } + Window.Current.Activate(); + if (e is ToastNotificationActivatedEventArgs) { string[] args = (e as ToastNotificationActivatedEventArgs).Argument.Split('|'); @@ -235,8 +222,6 @@ namespace FoxTube break; } } - - Window.Current.Activate(); } /// @@ -259,16 +244,6 @@ namespace FoxTube private void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); - - //Saving history - /*await FileIO.WriteTextAsync( - await ApplicationData.Current.RoamingFolder.CreateFileAsync("history.json", CreationCollisionOption.ReplaceExisting), - JsonConvert.SerializeObject(SecretsVault.UserHistory)); - //Saving WL playlist - await FileIO.WriteTextAsync( - await ApplicationData.Current.RoamingFolder.CreateFileAsync("watchlater.json", CreationCollisionOption.ReplaceExisting), - JsonConvert.SerializeObject(SecretsVault.WatchLater));*/ - //Saving downloads DownloadAgent.QuitPrompt(); deferral.Complete(); } diff --git a/FoxTube/Classes/SearchPaameters.cs b/FoxTube/Classes/SearchPaameters.cs index 78dab5c..8b6e86c 100644 --- a/FoxTube/Classes/SearchPaameters.cs +++ b/FoxTube/Classes/SearchPaameters.cs @@ -1,15 +1,12 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using static Google.Apis.YouTube.v3.SearchResource.ListRequest; namespace FoxTube { public delegate void Event(); - public delegate void ObjectEventHandler(object sender, params object[] args); + public delegate void ObjectEventHandler(object sender = null, params object[] args); public class SearchParameters { diff --git a/FoxTube/Classes/SecretsVault.cs b/FoxTube/Classes/SecretsVault.cs index 4067f5b..295ee2b 100644 --- a/FoxTube/Classes/SecretsVault.cs +++ b/FoxTube/Classes/SecretsVault.cs @@ -1,18 +1,13 @@ using System; using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Net; using System.Threading; using System.Threading.Tasks; using Google.Apis.Auth.OAuth2; -using Google.Apis.Auth.OAuth2.Flows; using Google.Apis.Services; using Google.Apis.YouTube.v3; using Google.Apis.YouTube.v3.Data; using Newtonsoft.Json; using Windows.Storage; -using Windows.UI.Popups; namespace FoxTube { @@ -20,7 +15,7 @@ namespace FoxTube { #region Properties //Events - public static event Event AuthorizationStateChanged; + public static event ObjectEventHandler AuthorizationStateChanged; public static event ObjectEventHandler SubscriptionsChanged; public static event Event NotPurchased; //Rising when app finds out that it's not a PRO version @@ -71,7 +66,7 @@ namespace FoxTube try { await Service.Subscriptions.Delete(s.Id).ExecuteAsync(); } catch { return true; } - SubscriptionsChanged.Invoke(null, "remove", Subscriptions.IndexOf(s)); + SubscriptionsChanged?.Invoke(null, "remove", Subscriptions.IndexOf(s)); Subscriptions.Remove(s); return false; } @@ -93,7 +88,7 @@ namespace FoxTube if (s == null) return false; Subscriptions.Add(s); - SubscriptionsChanged.Invoke(null, "add", s); + SubscriptionsChanged?.Invoke(null, "add", s); return true; } } @@ -101,84 +96,32 @@ namespace FoxTube /// /// Prompts to add an Youtube account and retrieves its info when successful /// - /// + /// Loads user's subscriptions if true public static async void Authorize(bool retrieveSubs = true) { try { + #region Retrieving user's credential Credential = await GoogleWebAuthorizationBroker.AuthorizeAsync( Secrets, new[] { - Google.Apis.Oauth2.v2.Oauth2Service.Scope.UserinfoProfile, - YouTubeService.Scope.YoutubeForceSsl + Google.Apis.Oauth2.v2.Oauth2Service.Scope.UserinfoProfile, + YouTubeService.Scope.YoutubeForceSsl }, "user", CancellationToken.None); if (Credential == null || !retrieveSubs) - return; + goto InvokeEvent; - if (settings.Values["authorized"] == null) - settings.Values.Add("authorized", true); - else settings.Values["authorized"] = true; + SettingsStorage.HasAccount = true; + #endregion + #region Retrieving user's data var request = Service.Channels.List("snippet,contentDetails"); request.Mine = true; UserChannel = (await request.ExecuteAsync()).Items[0]; - - /*try - { - await ApplicationData.Current.RoamingFolder.GetFileAsync("history.json"); - UserHistory = JsonConvert.DeserializeObject>(await FileIO.ReadTextAsync(await ApplicationData.Current.RoamingFolder.GetFileAsync("history.json"))); - } - catch - { - await FileIO.WriteTextAsync( - await ApplicationData.Current.RoamingFolder.CreateFileAsync("history.json", CreationCollisionOption.ReplaceExisting), - JsonConvert.SerializeObject(new List())); - UserHistory = new List(); - } - try - { - await ApplicationData.Current.RoamingFolder.GetFileAsync("watchlater.json"); - WatchLater = JsonConvert.DeserializeObject>(await FileIO.ReadTextAsync(await ApplicationData.Current.RoamingFolder.GetFileAsync("watchlater.json"))); - } - catch - { - await FileIO.WriteTextAsync( - await ApplicationData.Current.RoamingFolder.CreateFileAsync("watchlater.json", CreationCollisionOption.ReplaceExisting), - JsonConvert.SerializeObject(new List())); - WatchLater = new List(); - }*/ - - /*PlaylistItemsResource.ListRequest playlistRequest = Service.PlaylistItems.List("snippet"); - playlistRequest.PlaylistId = UserChannel.ContentDetails.RelatedPlaylists.WatchHistory; - playlistRequest.MaxResults = 50; - PlaylistItemListResponse playlistResponse = await playlistRequest.ExecuteAsync(); - UserHistory.Clear(); - foreach (PlaylistItem i in playlistResponse.Items) - UserHistory.Add(i); - - playlistRequest = Service.PlaylistItems.List("snippet"); - playlistRequest.PlaylistId = UserChannel.ContentDetails.RelatedPlaylists.WatchLater; - playlistRequest.MaxResults = 50; - playlistResponse = await playlistRequest.ExecuteAsync(); - WatchLater.Clear(); - - foreach (PlaylistItem i in playlistResponse.Items) - WatchLater.Add(i); - - string nextToken = playlistResponse.NextPageToken; - while (nextToken != null) - { - playlistRequest.PageToken = nextToken; - playlistResponse = await playlistRequest.ExecuteAsync(); - foreach (PlaylistItem i in playlistResponse.Items) - WatchLater.Add(i); - - nextToken = playlistResponse.NextPageToken; - }*/ SubscriptionsResource.ListRequest subRequest = Service.Subscriptions.List("snippet"); subRequest.Mine = true; @@ -197,31 +140,23 @@ namespace FoxTube nextToken = subResponse.NextPageToken; } while (!string.IsNullOrWhiteSpace(nextToken)); + #endregion + //Saving user's subscriptions for background task SaveSubscriptions(); + + InvokeEvent: + AuthorizationStateChanged?.Invoke(args: IsAuthorized); } catch { - MessageDialog dialog = new MessageDialog("We were unabled to retrieve your account information due to weak internet connection or Google servers' problems. PLease, try again later", "Failed to connect"); - - dialog.Commands.Add(new UICommand("Try again", (command) => - { - Authorize(); - })); - dialog.Commands.Add(new UICommand("Quit", (command) => - { - Methods.CloseApp(); - })); - dialog.Commands.Add(new UICommand("Close")); - - await dialog.ShowAsync(); - - IsAuthorized = false; + AuthorizationStateChanged?.Invoke(args: null); } - - AuthorizationStateChanged.Invoke(null, null); } + /// + /// Saves user's subscriptions keypairs (channel ID: avatar URL) into "background.json" file for concurrent background processing + /// public static async void SaveSubscriptions() { Dictionary subs = new Dictionary(); @@ -231,36 +166,44 @@ namespace FoxTube JsonConvert.SerializeObject(subs)); } + /// + /// Deauthenticates current user + /// public static async void Deauthenticate() { if(await Credential.RevokeTokenAsync(CancellationToken.None)) { Credential = null; - AuthorizationStateChanged.Invoke(); - settings.Values["authorized"] = false; + AuthorizationStateChanged?.Invoke(args: false); + SettingsStorage.HasAccount = false; } } + /// + /// Checks if any user has already been logged in. If has, calls *Authorize()* to retrieve his info + /// + /// Loads user's subscriptions if true public static void CheckAuthorization(bool retrieveSubs = true) { - if (settings.Values["authorized"] != null && (bool)settings.Values["authorized"]) + if (SettingsStorage.HasAccount) Authorize(retrieveSubs); + else AuthorizationStateChanged.Invoke(args: false); } - + /// + /// Connects to MS Store and checks if user has bought ad-free + /// public static void CheckAddons() { - //TO-DO: Check addons list + //TODO: Check addons list bool purchased = true; if(!purchased) { AdsDisabled = false; - if(NotPurchased != null) - NotPurchased.Invoke(); + NotPurchased?.Invoke(); } } - #endregion } } diff --git a/FoxTube/Classes/SettingsStorage.cs b/FoxTube/Classes/SettingsStorage.cs index 0abec86..d2a42ef 100644 --- a/FoxTube/Classes/SettingsStorage.cs +++ b/FoxTube/Classes/SettingsStorage.cs @@ -5,7 +5,7 @@ using System.Linq; using Windows.ApplicationModel; using Windows.Storage; -namespace FoxTube.Classes +namespace FoxTube { public static class SettingsStorage { @@ -129,6 +129,7 @@ namespace FoxTube.Classes if (storage.Values["ver"] == null) { PackageVersion ver = Package.Current.Id.Version; + storage.Values["version"] = $"{ver.Major}.{ver.Minor}"; return $"{ver.Major}.{ver.Minor}"; } else return (string)storage.Values["version"]; @@ -140,7 +141,7 @@ namespace FoxTube.Classes } //Settings storage - private static ApplicationDataContainer storage = ApplicationData.Current.LocalSettings; + private static readonly ApplicationDataContainer storage = ApplicationData.Current.LocalSettings; //Predefined preferences private static object[] settings = new object[] @@ -169,12 +170,17 @@ namespace FoxTube.Classes { settings = JsonConvert.DeserializeObject(storage.Values["settings"] as string); } - catch (NullReferenceException) { } + catch (ArgumentNullException) { } } - public static void SaveData() + public static async void SaveData() { storage.Values["settings"] = JsonConvert.SerializeObject(settings); + + bool[] notificationsSettings = new[] { VideoNotifications, DevNotifications }; + await FileIO.WriteTextAsync( + await ApplicationData.Current.RoamingFolder.CreateFileAsync("notifications.json", CreationCollisionOption.ReplaceExisting), + JsonConvert.SerializeObject(notificationsSettings)); } } } diff --git a/FoxTube/Controls/ChannelCardWide.xaml b/FoxTube/Controls/ChannelCardWide.xaml deleted file mode 100644 index 5327558..0000000 --- a/FoxTube/Controls/ChannelCardWide.xaml +++ /dev/null @@ -1,36 +0,0 @@ - - - - diff --git a/FoxTube/Controls/ChannelCardWide.xaml.cs b/FoxTube/Controls/ChannelCardWide.xaml.cs deleted file mode 100644 index 312a0b6..0000000 --- a/FoxTube/Controls/ChannelCardWide.xaml.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Media.Imaging; -using Google.Apis.Services; -using Google.Apis.YouTube.v3; -using Google.Apis.YouTube.v3.Data; - -namespace FoxTube.Controls -{ - public sealed partial class ChannelCardWide : UserControl - { - string channelId; - public ChannelCardWide(string id, string live) - { - this.InitializeComponent(); - Initialize(id, live); - } - - public async void Initialize(string id, string live) - { - YouTubeService ytService = new YouTubeService(new BaseClientService.Initializer() - { - ApiKey = "AIzaSyBgHrCnrlzlVmk0cJKL8RqP9Y8x6XSuk_0", - ApplicationName = this.GetType().ToString() - }); - - ChannelsResource.ListRequest request = ytService.Channels.List("snippet,contentDetails,statistics"); - request.Id = id; - ChannelListResponse response = await request.ExecuteAsync(); - - var item = response.Items[0]; - - channelId = id; - - channelName.Text = item.Snippet.Title; - subscribers.Text = string.Format("{0} subscribers", item.Statistics.SubscriberCount); - videoCount.Text = string.Format("{0} videos", item.Statistics.VideoCount); - - avatar.ProfilePicture = new BitmapImage(new Uri(item.Snippet.Thumbnails.Medium.Url)); - if (live == "live") - liveTag.Visibility = Visibility.Visible; - } - - private void Button_Click(object sender, RoutedEventArgs e) - { - Methods.MainPage.GoToChannel(channelId); - } - } -} diff --git a/FoxTube/Controls/DownloadItem.xaml.cs b/FoxTube/Controls/DownloadItem.xaml.cs index 30ae650..4a84b5b 100644 --- a/FoxTube/Controls/DownloadItem.xaml.cs +++ b/FoxTube/Controls/DownloadItem.xaml.cs @@ -12,10 +12,8 @@ using Google.Apis.YouTube.v3.Data; using System.Threading; using System.Xml; using Windows.UI.Popups; -using Windows.Storage.Pickers; using Windows.UI.Notifications; using Microsoft.Toolkit.Uwp.Notifications; -using System.Diagnostics; using System.Threading.Tasks; namespace FoxTube.Controls @@ -26,25 +24,24 @@ namespace FoxTube.Controls public StorageFile file; public bool InProgress { get; set; } = false; - YoutubeClient client = new YoutubeClient(); - - CancellationTokenSource cts = new CancellationTokenSource(); + readonly YoutubeClient client = new YoutubeClient(); + readonly CancellationTokenSource cts = new CancellationTokenSource(); CancellationToken token; - Progress progress = new Progress(); - NotificationData data = new NotificationData(); + readonly Progress progress = new Progress(); + private readonly NotificationData data = new NotificationData(); DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(1) }; double percentage; public DownloadItem(MediaStreamInfo info, Video meta, string q) { - this.InitializeComponent(); + InitializeComponent(); Download(info, meta, q); } public DownloadItem(DownloadItemContainer container) { - this.InitializeComponent(); + InitializeComponent(); Container = container; Initialize(); diff --git a/FoxTube/Controls/PlaylistCard.xaml.cs b/FoxTube/Controls/PlaylistCard.xaml.cs index e893c26..a59f08c 100644 --- a/FoxTube/Controls/PlaylistCard.xaml.cs +++ b/FoxTube/Controls/PlaylistCard.xaml.cs @@ -1,42 +1,29 @@ using Google.Apis.YouTube.v3; using Google.Apis.YouTube.v3.Data; using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; -using Windows.Foundation; -using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Controls.Primitives; -using Windows.UI.Xaml.Data; -using Windows.UI.Xaml.Input; -using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media.Imaging; -using Windows.UI.Xaml.Navigation; - -// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 namespace FoxTube.Controls { /// - /// An empty page that can be used on its own or navigated to within a Frame. + /// Playlist card control /// public sealed partial class PlaylistCard : Page { Playlist item; - string playlistId; + public string playlistId; public PlaylistCard(string id) { - this.InitializeComponent(); + InitializeComponent(); Initialize(id); } public async void Initialize(string id) { - PlaylistsResource.ListRequest request = SecretsVault.NoAuthService.Playlists.List("snippet,contentDetails"); + PlaylistsResource.ListRequest request = SecretsVault.Service.Playlists.List("snippet,contentDetails"); request.Id = id; PlaylistListResponse response = await request.ExecuteAsync(); @@ -48,7 +35,7 @@ namespace FoxTube.Controls counter.Text = item.ContentDetails.ItemCount.ToString(); date.Text = Methods.GetAgo(item.Snippet.PublishedAt.Value); - ChannelsResource.ListRequest r = SecretsVault.NoAuthService.Channels.List("snippet"); + ChannelsResource.ListRequest r = SecretsVault.Service.Channels.List("snippet"); r.Id = item.Snippet.ChannelId; try diff --git a/FoxTube/Controls/PlaylistCardWide.xaml b/FoxTube/Controls/PlaylistCardWide.xaml deleted file mode 100644 index 473a829..0000000 --- a/FoxTube/Controls/PlaylistCardWide.xaml +++ /dev/null @@ -1,50 +0,0 @@ - - - - diff --git a/FoxTube/Controls/PlaylistCardWide.xaml.cs b/FoxTube/Controls/PlaylistCardWide.xaml.cs deleted file mode 100644 index e89c450..0000000 --- a/FoxTube/Controls/PlaylistCardWide.xaml.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; -using Windows.Foundation; -using Windows.Foundation.Collections; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Controls.Primitives; -using Windows.UI.Xaml.Data; -using Windows.UI.Xaml.Input; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Media.Imaging; -using Windows.UI.Xaml.Navigation; - -using Google.Apis.Services; -using Google.Apis.YouTube.v3; -using Google.Apis.YouTube.v3.Data; -using System.Threading.Tasks; -using System.Threading; -using Google.Apis.Util.Store; - -// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 - -namespace FoxTube -{ - public sealed partial class PlaylistCardWide : UserControl - { - public string playlistId; - Playlist item; - public PlaylistCardWide(string id, bool hideAuthor = false) - { - this.InitializeComponent(); - Initialize(id, hideAuthor); - } - - public async void Initialize(string id, bool hideAuthor) - { - PlaylistsResource.ListRequest request = SecretsVault.NoAuthService.Playlists.List("snippet,contentDetails"); - request.Id = id; - PlaylistListResponse response = await request.ExecuteAsync(); - - item = response.Items[0]; - - playlistId = id; - - title.Text = item.Snippet.Title; - info.Text = string.Format("{0} | {1} videos", item.Snippet.PublishedAt, item.ContentDetails.ItemCount); - thumbCount.Text = item.ContentDetails.ItemCount.ToString(); - thumbnail.Source = new BitmapImage(new Uri(item.Snippet.Thumbnails.Medium.Url)); - - if (hideAuthor) - authorData.Visibility = Visibility.Collapsed; - else - { - var request1 = SecretsVault.NoAuthService.Channels.List("snippet,contentDetails,statistics"); - request1.Id = item.Snippet.ChannelId; - ChannelListResponse response1 = await request1.ExecuteAsync(); - - var item1 = response1.Items[0]; - - avatar.ProfilePicture = new BitmapImage(new Uri(item1.Snippet.Thumbnails.Medium.Url)); - channelName.Text = item1.Snippet.Title; - channelSubs.Text = string.Format("{0} subscribers", item1.Statistics.SubscriberCount); - } - } - - private void channelLink_Click(object sender, RoutedEventArgs e) - { - Methods.MainPage.GoToChannel(item.Snippet.ChannelId); - } - } -} diff --git a/FoxTube/Controls/VideoCardWide.xaml b/FoxTube/Controls/VideoCardWide.xaml deleted file mode 100644 index 3bcb1ff..0000000 --- a/FoxTube/Controls/VideoCardWide.xaml +++ /dev/null @@ -1,53 +0,0 @@ - - - - diff --git a/FoxTube/Controls/VideoCardWide.xaml.cs b/FoxTube/Controls/VideoCardWide.xaml.cs deleted file mode 100644 index 96c0c7a..0000000 --- a/FoxTube/Controls/VideoCardWide.xaml.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; -using Windows.Foundation; -using Windows.Foundation.Collections; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Controls.Primitives; -using Windows.UI.Xaml.Data; -using Windows.UI.Xaml.Input; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Media.Imaging; -using Windows.UI.Xaml.Navigation; - -using Google.Apis.Services; -using Google.Apis.YouTube.v3; -using Google.Apis.YouTube.v3.Data; -using System.Threading.Tasks; -using System.Threading; -using Google.Apis.Util.Store; -using System.Xml; -using Windows.System; - -// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 - -namespace FoxTube -{ - public sealed partial class VideoCardWide : UserControl - { - public string videoId; - Google.Apis.YouTube.v3.Data.Video item; - - bool embed = false; - public VideoCardWide(string id) - { - this.InitializeComponent(); - Initialize(id); - } - - public async void Initialize(string id) - { - YouTubeService ytService = SecretsVault.NoAuthService; - - VideosResource.ListRequest request = ytService.Videos.List("snippet,contentDetails,statistics,liveStreamingDetails"); - request.Id = id; - VideoListResponse response = await request.ExecuteAsync(); - - item = response.Items[0]; - - videoId = id; - - title.Text = item.Snippet.Title; - - string duration; - if (item.ContentDetails.Duration != null || item.ContentDetails.Duration != "") - { - TimeSpan ts = XmlConvert.ToTimeSpan(item.ContentDetails.Duration); - duration = string.Format("{0}{1:00}:{2:00} | ", ts.Hours == 0 ? "" : ts.Hours + ":", ts.Minutes, ts.Seconds); - } - else duration = string.Empty; - - info.Text = string.Format("{0}{1} | {2}", duration, Methods.GetAgo(item.Snippet.PublishedAt.Value), (item.LiveStreamingDetails != null && item.LiveStreamingDetails.ConcurrentViewers.HasValue) ? item.LiveStreamingDetails.ConcurrentViewers + " viewers" : item.Statistics.ViewCount + " views"); - thumbnail.Source = new BitmapImage(new Uri(item.Snippet.Thumbnails.Medium.Url)); - if (item.Snippet.LiveBroadcastContent == "live") - { - embed = true; - liveTag.Visibility = Visibility.Visible; - } - else if(item.Snippet.LiveBroadcastContent == "upcoming") - { - embed = true; - TimeSpan span; - if (item.LiveStreamingDetails.ScheduledStartTime != null && (item.LiveStreamingDetails.ScheduledStartTime - DateTime.Now).Value.TotalMilliseconds > 0) - { - span = (TimeSpan)(item.LiveStreamingDetails.ScheduledStartTime - DateTime.Now); - liveContent.Text = "Goes live in " + string.Format("{0}{1:00}:{2:00}:{3:00}", span.Days != 0 ? span.Days + ":" : "", span.Hours, span.Minutes, span.Seconds); - } - else - liveContent.Text = "Upcoming"; - liveTag.Visibility = Visibility.Visible; - } - - var request1 = ytService.Channels.List("snippet,contentDetails,statistics"); - request1.Id = item.Snippet.ChannelId; - ChannelListResponse response1 = await request1.ExecuteAsync(); - - var item1 = response1.Items[0]; - - avatar.ProfilePicture = new BitmapImage(new Uri(item1.Snippet.Thumbnails.Medium.Url)); - channelName.Text = item1.Snippet.Title; - channelSubs.Text = string.Format("{0} subscribers", item1.Statistics.SubscriberCount); - - //if (SecretsVault.UserHistory.Contains(item.Id)) - //watched.Visibility = Visibility.Visible; - } - - private void channelLink_Click(object sender, RoutedEventArgs e) - { - Methods.MainPage.GoToChannel(item.Snippet.ChannelId); - } - - private async void Button_Click(object sender, RoutedEventArgs e) - { - if (embed) - await Launcher.LaunchUriAsync(new Uri(string.Format("https://www.youtube.com/watch?v={0}", videoId))); - else - Methods.MainPage.GoToVideo(videoId); - } - } -} diff --git a/FoxTube/FoxTube.csproj b/FoxTube/FoxTube.csproj index 56515db..840c28f 100644 --- a/FoxTube/FoxTube.csproj +++ b/FoxTube/FoxTube.csproj @@ -127,9 +127,6 @@ ChannelPage.xaml - - ChannelCardWide.xaml - CommentsPage.xaml @@ -157,9 +154,6 @@ MainPage.xaml - - PlaylistCardWide.xaml - PlaylistPage.xaml @@ -174,18 +168,12 @@ Settings.xaml - - Translate.xaml - VideoPage.xaml VideoCard.xaml - - VideoCardWide.xaml - VideoGrid.xaml @@ -313,10 +301,6 @@ Designer MSBuild:Compile - - Designer - MSBuild:Compile - Designer MSBuild:Compile @@ -353,10 +337,6 @@ MSBuild:Compile Designer - - Designer - MSBuild:Compile - Designer MSBuild:Compile @@ -369,10 +349,6 @@ Designer MSBuild:Compile - - Designer - MSBuild:Compile - Designer MSBuild:Compile @@ -385,10 +361,6 @@ Designer MSBuild:Compile - - Designer - MSBuild:Compile - Designer MSBuild:Compile diff --git a/FoxTube/Pages/MainPage.xaml b/FoxTube/Pages/MainPage.xaml index 81118d2..f75b267 100644 --- a/FoxTube/Pages/MainPage.xaml +++ b/FoxTube/Pages/MainPage.xaml @@ -2,12 +2,8 @@ x:Class="FoxTube.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:local="using:FoxTube" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:ads="using:Microsoft.Advertising.WinRT.UI" - xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls" - xmlns:pages="using:FoxTube.Pages" xmlns:Windows10version1803="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract, 6)" mc:Ignorable="d" SizeChanged="Page_SizeChanged" diff --git a/FoxTube/Pages/MainPage.xaml.cs b/FoxTube/Pages/MainPage.xaml.cs index 0d260f3..6b0121d 100644 --- a/FoxTube/Pages/MainPage.xaml.cs +++ b/FoxTube/Pages/MainPage.xaml.cs @@ -9,47 +9,36 @@ using Windows.UI.Xaml.Navigation; using System.Diagnostics; using Windows.UI.Notifications; using Windows.UI.Xaml.Media.Imaging; -using Windows.Storage; using System.Xml; using Google.Apis.YouTube.v3.Data; -using System.Globalization; using Windows.ApplicationModel.Core; using Windows.System; using Google.Apis.Oauth2.v2; using Google.Apis.Oauth2.v2.Data; -using FoxTube.Controls; using FoxTube.Pages; using Windows.ApplicationModel; using System.Net; using Windows.UI.Popups; using Windows.Networking.Connectivity; using Windows.UI.Core; -using System.IO; -using Newtonsoft.Json; -using Google.Apis.YouTube.v3; - -// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace FoxTube { - /// - /// An empty page that can be used on its own or navigated to within a Frame. - /// - public enum Sender { Menu, Frame, None } + /// + /// Main app's layout + /// public sealed partial class MainPage : Page { Sender s = Sender.None; public MainPage() { - this.InitializeComponent(); + InitializeComponent(); + //Comparing current version with last recorded version. If doesn't match, poping up changelog notification PackageVersion ver = Package.Current.Id.Version; - if (settings.Values["ver"] == null) - settings.Values.Add("ver", $"{ver.Major}.{ver.Minor}"); - - if((string)settings.Values["ver"] != $"{ver.Major}.{ver.Minor}") + if(SettingsStorage.Version != $"{ver.Major}.{ver.Minor}") { try { @@ -59,9 +48,12 @@ namespace FoxTube ToastNotificationManager.CreateToastNotifier().Show(FoxTube.Background.Notification.GetChangelogToast(e.GetAttribute("version"))); - settings.Values["ver"] = $"{ver.Major}.{ver.Minor}"; + SettingsStorage.Version = $"{ver.Major}.{ver.Minor}"; + } + catch + { + Debug.WriteLine("Unable to retrieve changelog"); } - catch { } } SecretsVault.AuthorizationStateChanged += AuthorizationStateChanged; @@ -73,20 +65,6 @@ namespace FoxTube DownloadAgent.Initialize(); SetTitleBar(); - Initialize(); - } - - public async void Initialize() - { - bool[] notificationsSettings = new bool[] { (bool)settings.Values["newVideoNotification"], (bool)settings.Values["devNews"] }; - await FileIO.WriteTextAsync( - await ApplicationData.Current.RoamingFolder.CreateFileAsync("notifications.json", CreationCollisionOption.ReplaceExisting), - JsonConvert.SerializeObject(notificationsSettings)); - } - - protected override void OnNavigatedTo(NavigationEventArgs e) - { - base.OnNavigatedTo(e); } public Video GetCurrentItem() @@ -109,10 +87,17 @@ namespace FoxTube CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = false; } + /// + /// Invoked when subscriptions are edited to edit menu + /// + /// + /// private void SecretsVault_SubscriptionsChanged(object sender, params object[] args) { if ((string)args[0] == "add" && nav.MenuItems.Count < 19) { + subsHeader.Visibility = Visibility.Visible; + Subscription s = args[1] as Subscription; StackPanel panel = new StackPanel() { @@ -134,12 +119,37 @@ namespace FoxTube }); } else if ((string)args[0] == "remove" && (int)args[1] < 10) + { nav.MenuItems.RemoveAt((int)args[1] + 9); + if(SecretsVault.Subscriptions.Count >= 10) + { + Subscription s = SecretsVault.Subscriptions[9]; + StackPanel panel = new StackPanel() + { + Orientation = Orientation.Horizontal, + Padding = new Thickness(5) + }; + panel.Children.Add(new PersonPicture() + { + Height = 20, + Margin = new Thickness(-5, 0, 15, 0), + ProfilePicture = new BitmapImage(new Uri(s.Snippet.Thumbnails.Medium.Url)) + }); + panel.Children.Add(new TextBlock() { Text = s.Snippet.Title }); + nav.MenuItems.Add(new NavigationViewItem() + { + Content = panel, + Name = (nav.MenuItems.Count - 9).ToString(), + Padding = new Thickness(-5) + }); + } + } } - private async void AuthorizationStateChanged() + + private async void AuthorizationStateChanged(object sender, params object[] e) { - if(SecretsVault.IsAuthorized) + if(e[0] as bool? == true) { account.Visibility = Visibility.Collapsed; try @@ -158,7 +168,6 @@ namespace FoxTube toHistory.Visibility = Visibility.Visible; toLiked.Visibility = Visibility.Visible; toLater.Visibility = Visibility.Visible; - subsHeader.Visibility = Visibility.Visible; if (SecretsVault.Subscriptions.Count > 0) { @@ -189,7 +198,7 @@ namespace FoxTube catch { continue; } } } - else + else if (e[0] as bool? == false) { account.Visibility = Visibility.Visible; avatar.Visibility = Visibility.Collapsed; @@ -206,6 +215,25 @@ namespace FoxTube for(int k = 9; k < nav.MenuItems.Count; k++) nav.MenuItems.RemoveAt(k); } + else + { + MessageDialog dialog = new MessageDialog("We were unabled to retrieve your account information due to weak internet connection or Google servers' problems. PLease, try again later", "Failed to connect"); + + dialog.Commands.Add(new UICommand("Try again", (command) => + { + SecretsVault.Authorize(); + })); + dialog.Commands.Add(new UICommand("Quit", (command) => + { + Methods.CloseApp(); + })); + dialog.Commands.Add(new UICommand("Close")); + + dialog.CancelCommandIndex = 1; + dialog.DefaultCommandIndex = 0; + + await dialog.ShowAsync(); + } content.Navigate(typeof(Home)); @@ -241,14 +269,11 @@ namespace FoxTube public void GoToSearch(SearchParameters args) { nav.IsPaneOpen = false; - MinimizeAsInitializer(); content.Navigate(typeof(Search), args); } public void GoToChannel(string id) { - Debug.WriteLine($"Channel id: {id}"); - MinimizeAsInitializer(); content.Navigate(typeof(ChannelPage), id); } @@ -258,7 +283,7 @@ namespace FoxTube try { var connection = NetworkInformation.GetInternetConnectionProfile().GetConnectionCost(); - if ((bool)settings.Values["moblieWarning"] && (connection.NetworkCostType == NetworkCostType.Fixed || connection.NetworkCostType == NetworkCostType.Variable)) + if (SettingsStorage.CheckConnection && (connection.NetworkCostType == NetworkCostType.Fixed || connection.NetworkCostType == NetworkCostType.Variable)) { MessageDialog dialog = new MessageDialog("You are on metered connection now. Additional charges may apply. Do you want to continue?") { @@ -267,36 +292,33 @@ namespace FoxTube }; dialog.Commands.Add(new UICommand("Yes")); dialog.Commands.Add(new UICommand("No", (command) => cancel = true)); - dialog.Commands.Add(new UICommand("Add to 'Watch later' playlist", (command) => - { - try + if(SecretsVault.IsAuthorized) + dialog.Commands.Add(new UICommand("Add to 'Watch later' playlist", (command) => { - if (!SecretsVault.IsAuthorized) - SecretsVault.CheckAuthorization(false); - if (!SecretsVault.IsAuthorized) - throw new Exception("Not authenticated"); - - PlaylistItem item = new PlaylistItem() + try { - Snippet = new PlaylistItemSnippet() + PlaylistItem item = new PlaylistItem() { - ResourceId = new ResourceId() + Snippet = new PlaylistItemSnippet() { - Kind = "youtube#video", - VideoId = id - }, - PlaylistId = "WL" - } - }; + ResourceId = new ResourceId() + { + Kind = "youtube#video", + VideoId = id + }, + PlaylistId = "WL" + } + }; + + SecretsVault.Service.PlaylistItems.Insert(item, "snippet").Execute(); + } + catch (Exception e) + { + Debug.WriteLine(e.Message); + } + cancel = true; + })); - SecretsVault.Service.PlaylistItems.Insert(item, "snippet").Execute(); - } - catch (Exception e) - { - Debug.WriteLine(e.Message); - } - cancel = true; - })); await dialog.ShowAsync(); } } @@ -309,18 +331,16 @@ namespace FoxTube Fullscreen(false); videoPlaceholder.Navigate(typeof(VideoPage), new string[2] { id, playlistId }); + nav.Header = "Video"; } public void GoToDeveloper(string id) { - MinimizeAsInitializer(); content.Navigate(typeof(Settings), $"inbox&{id}"); } public void GoToPlaylist(string id) { - Debug.WriteLine($"Playlist id: {id}"); - MinimizeAsInitializer(); content.Navigate(typeof(PlaylistPage), id); } @@ -361,6 +381,21 @@ namespace FoxTube nav.IsBackEnabled = true; else nav.IsBackEnabled = false; + + Dictionary switchCase = new Dictionary() + { + { typeof(Settings), () => nav.Header = "Settings" }, + { typeof(ChannelPage), () => nav.Header = "Channel" }, + { typeof(PlaylistPage), () => nav.Header = "Playlist" }, + { typeof(Search), () => nav.Header = "Search" }, + { typeof(Subscriptions), () => nav.Header = "Subscriptions" }, + { typeof(History), () => nav.Header = "History" }, + { typeof(Home), () => nav.Header = "Home" }, + { typeof(Downloads), () => nav.Header = "Downloads" } + }; + + try { switchCase[content.SourcePageType](); } + catch { } } public void MaximizeVideo() @@ -372,6 +407,9 @@ namespace FoxTube videoPlaceholder.Margin = new Thickness(0); nav.IsBackEnabled = true; + + if (videoPlaceholder.Content != null) + nav.Header = "Video"; } public void Fullscreen(bool on) @@ -640,11 +678,6 @@ namespace FoxTube MinimizeAsInitializer(); } - private void toChannel_Click(object sender, RoutedEventArgs e) - { - GoToChannel(SecretsVault.UserChannel.Id); - } - private void nav_BackRequested(NavigationView sender, NavigationViewBackRequestedEventArgs args) { if (videoPlaceholder.Content != null) @@ -653,8 +686,6 @@ namespace FoxTube CloseVideo(); else if (videoPlaceholder.HorizontalAlignment == HorizontalAlignment.Stretch) MinimizeAsInitializer(); - else - content.GoBack(); } else content.GoBack(); diff --git a/FoxTube/Pages/SettingsPages/Translate.xaml b/FoxTube/Pages/SettingsPages/Translate.xaml deleted file mode 100644 index 89796d6..0000000 --- a/FoxTube/Pages/SettingsPages/Translate.xaml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - -