From 57c90f40370d7465acf70d320886d0cc8b992ca1 Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Thu, 19 Jul 2018 17:36:49 +0300 Subject: [PATCH] Development 6 --- FoxTube.Background/BackgroundProcessor.cs | 79 +++-- FoxTube.Background/Notification.cs | 44 ++- FoxTube/App.xaml | 46 +-- FoxTube/Classes/Notification.cs | 171 --------- FoxTube/Classes/SecretsVault.cs | 100 +++--- FoxTube/Controls/NotificationsCenter.xaml.cs | 161 ++++----- FoxTube/FoxTube.csproj | 2 +- .../NotificationsHistorySample.xml | 8 + FoxTube/Notifications/ServerLogSamlpe.xml | 2 +- FoxTube/Pages/MainPage.xaml | 218 ++++++------ FoxTube/Pages/MainPage.xaml.cs | 324 ++++++++++-------- FoxTube/Pages/Search.xaml.cs | 1 + 12 files changed, 520 insertions(+), 636 deletions(-) delete mode 100644 FoxTube/Classes/Notification.cs create mode 100644 FoxTube/Notifications/NotificationsHistorySample.xml diff --git a/FoxTube.Background/BackgroundProcessor.cs b/FoxTube.Background/BackgroundProcessor.cs index 2552676..f014e58 100644 --- a/FoxTube.Background/BackgroundProcessor.cs +++ b/FoxTube.Background/BackgroundProcessor.cs @@ -16,11 +16,15 @@ using Windows.UI.Notifications; namespace FoxTube.Background { + public delegate void NotificationHandler(object sender, string xml); + public sealed class BackgroundProcessor : IBackgroundTask { - public List Notifications = new List(); + public static event NotificationHandler NotificationRecieved; + public List Notifications = new List(); private DateTime lastCheck = DateTime.Now; + private ApplicationDataContainer settings = ApplicationData.Current.LocalSettings; private ClientSecrets Secrets => new ClientSecrets() @@ -29,11 +33,17 @@ namespace FoxTube.Background ClientSecret = "BkVZOAaCU2Zclf0Zlicg6y2_" }; + private YouTubeService Service => new YouTubeService(new BaseClientService.Initializer() + { + ApiKey = "AIzaSyBgHrCnrlzlVmk0cJKL8RqP9Y8x6XSuk_0", + ApplicationName = "FoxTube" + }); + + XmlDocument doc = new XmlDocument(); BackgroundTaskDeferral def; - public async void Run(IBackgroundTaskInstance taskInstance) + public void Run(IBackgroundTaskInstance taskInstance) { def = taskInstance.GetDeferral(); - XmlDocument doc = new XmlDocument(); if (settings.Values["lastCheck"] == null) settings.Values.Add("lastCheck", XmlConvert.ToString(DateTime.Now)); else lastCheck = XmlConvert.ToDateTime(settings.Values["lastCheck"] as string, XmlDateTimeSerializationMode.Unspecified); @@ -43,14 +53,17 @@ namespace FoxTube.Background else { doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", null)); - doc.AppendChild(doc.CreateElement("notifications")); + doc.AppendChild(doc.CreateElement("history")); settings.Values.Add("notificationsHistory", doc.InnerXml); } - CheckAccount(); + if((bool)settings.Values["authorized"] == true) + CheckAccount(); CheckAnnouncements(); + SendNSave(); + def.Complete(); } @@ -68,10 +81,10 @@ namespace FoxTube.Background subRequest.Mine = true; subRequest.MaxResults = 50; SubscriptionListResponse subResponse = await subRequest.ExecuteAsync(); - List subs = new List(); + List> subs = new List>(); foreach (Subscription s in subResponse.Items) - subs.Add(s.Snippet.ResourceId.ChannelId); + subs.Add(new KeyValuePair(s.Snippet.ResourceId.ChannelId, s.Snippet.Thumbnails.Standard.Url)); string nextToken = subResponse.NextPageToken; while (nextToken != null) @@ -79,26 +92,25 @@ namespace FoxTube.Background subRequest.PageToken = nextToken; subResponse = await subRequest.ExecuteAsync(); foreach (Subscription s in subResponse.Items) - subs.Add(s.Snippet.ResourceId.ChannelId); + subs.Add(new KeyValuePair(s.Snippet.ResourceId.ChannelId, s.Snippet.Thumbnails.Standard.Url)); } - foreach(string s in subs) + foreach(var s in subs) { - var request = new YouTubeService(new BaseClientService.Initializer() - { - ApiKey = "AIzaSyBgHrCnrlzlVmk0cJKL8RqP9Y8x6XSuk_0", - ApplicationName = "FoxTube" - }).Activities.List("snippet"); + var request = Service.Search.List("snippet"); request.PublishedAfter = lastCheck; - request.ChannelId = s; - request.MaxResults = 10; + request.ChannelId = s.Key; + request.Type = "video"; var response = await request.ExecuteAsync(); if(response.Items.Count > 0) - foreach (Activity a in response.Items) - { - if(a.Snippet.Type == "upload") - } + foreach (var a in response.Items) + Notifications.Add(new Notification("video", a.Id.VideoId, + a.Snippet.ChannelTitle, + a.Snippet.Title, + a.Snippet.PublishedAt.Value, + a.Snippet.Thumbnails.Standard.Url, + s.Value)); } } @@ -107,11 +119,12 @@ namespace FoxTube.Background XmlDocument doc = new XmlDocument(); doc.Load(XmlReader.Create("http://foxgame.hol.es/ftp.xml")); if ((XmlConvert.ToDateTime((doc["posts"].FirstChild as XmlElement).GetAttribute("time"), XmlDateTimeSerializationMode.Utc) - lastCheck.ToUniversalTime()).TotalSeconds > 0) - Add(new Notification(NotificationType.Internal, + Notifications.Add(new Notification("internal", (doc["posts"].FirstChild as XmlElement).GetAttribute("id"), doc["posts"].FirstChild["notificationHeader"].InnerText, doc["posts"].FirstChild["content"].InnerText, XmlConvert.ToDateTime((doc["posts"].FirstChild as XmlElement).GetAttribute("time"), - XmlDateTimeSerializationMode.Local), (doc["posts"].FirstChild as XmlElement).GetAttribute("image"))); + XmlDateTimeSerializationMode.Unspecified), + (doc["posts"].FirstChild as XmlElement).GetAttribute("image"))); return doc.InnerXml; } @@ -121,9 +134,29 @@ namespace FoxTube.Background ToastNotificationManager.CreateToastNotifier().Show(notification.GetToast(0)); } - void Add(Notification notification) + void SendNSave() { + foreach (Notification n in Notifications) + { + NotificationRecieved.Invoke(this, n.GetXml()); + doc["history"].InnerXml += n.GetXml(); + } + settings.Values.Add("notificationsHistory", doc.InnerXml); + if ((bool)settings.Values["notifications"]) + foreach (Notification n in Notifications) + switch (n.Type) + { + case NotificationType.Video: + if ((bool)settings.Values["newVideoNotification"]) + SendNotification(n); + break; + + case NotificationType.Internal: + if ((bool)settings.Values["newmessagesNotification"]) + SendNotification(n); + break; + } } } } diff --git a/FoxTube.Background/Notification.cs b/FoxTube.Background/Notification.cs index 2e2ac0d..b78e9e7 100644 --- a/FoxTube.Background/Notification.cs +++ b/FoxTube.Background/Notification.cs @@ -26,26 +26,30 @@ namespace FoxTube.Background public NotificationType Type { get; set; } public string Avatar { get; set; } public string Thumbnail { get; set; } + public string Id { get; set; } - public Notification(NotificationType type, + public Notification(string type, string id, string channelName, string content, DateTime date, string thumbnailUrl, string avatarUrl = "ms-appx:///Assets/Icons/Profile.png") { Channel = channelName; Content = content; TimeStamp = date; - Type = type; + Type = TypeConversion(type); Avatar = avatarUrl; Thumbnail = thumbnailUrl; } public string GetXml() { - - return string.Empty; + return $@" + + {Channel} + {Content} + "; } - public UIElement GetNotification() + public Button GetNotification() { StackPanel stackPanel = new StackPanel() { Margin = new Thickness(10, 0, 0, 0) }; @@ -231,5 +235,35 @@ namespace FoxTube.Background return new ToastNotification(template); } + + private string TypeConversion(NotificationType type) + { + switch(type) + { + case NotificationType.Comment: + return "comment"; + case NotificationType.Post: + return "post"; + case NotificationType.Video: + return "video"; + default: + return "internal"; + } + } + + private NotificationType TypeConversion(string type) + { + switch (type) + { + case "comment": + return NotificationType.Comment; + case "post": + return NotificationType.Post; + case "video": + return NotificationType.Video; + default: + return NotificationType.Internal; + } + } } } diff --git a/FoxTube/App.xaml b/FoxTube/App.xaml index 6115628..b0d3345 100644 --- a/FoxTube/App.xaml +++ b/FoxTube/App.xaml @@ -11,48 +11,24 @@ - - - - + + + diff --git a/FoxTube/Classes/Notification.cs b/FoxTube/Classes/Notification.cs deleted file mode 100644 index cdb02bb..0000000 --- a/FoxTube/Classes/Notification.cs +++ /dev/null @@ -1,171 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Windows.Data.Xml.Dom; -using Windows.UI; -using Windows.UI.Notifications; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Media.Imaging; - -namespace FoxTube -{ - public enum NotificationType - { - Video, Comment, Post, Internal - } - - public class Notification - { - public string Channel { get; set; } - public string Content { get; set; } - public DateTime TimeStamp { get; set; } - public NotificationType Type { get; set; } - public string Avatar { get; set; } - public string Thumbnail { get; set; } - - public Notification(NotificationType type, - string channelName, string content, DateTime date, - string thumbnailUrl, string avatarUrl = "ms-appx:///Assets/Icons/Profile.png") - { - Channel = channelName; - Content = content; - TimeStamp = date; - Type = type; - Avatar = avatarUrl; - Thumbnail = thumbnailUrl; - } - - public UIElement GetNotification() - { - StackPanel stackPanel = new StackPanel() { Margin = new Thickness(10, 0, 0, 0) }; - - //Channel - switch (Type) - { - case NotificationType.Comment: - stackPanel.Children.Add(new TextBlock() - { - FontSize = 14, - FontStyle = Windows.UI.Text.FontStyle.Italic, - Foreground = new SolidColorBrush(Colors.Gray), - Text = string.Format("{0} replied to your comment", Channel) - }); - break; - - case NotificationType.Internal: - stackPanel.Children.Add(new TextBlock() - { - FontSize = 14, - FontStyle = Windows.UI.Text.FontStyle.Italic, - Foreground = new SolidColorBrush(Colors.Gray), - Text = Channel - }); - break; - - case NotificationType.Post: - stackPanel.Children.Add(new TextBlock() - { - FontSize = 14, - FontStyle = Windows.UI.Text.FontStyle.Italic, - Foreground = new SolidColorBrush(Colors.Gray), - Text = string.Format("{0} published new post", Channel) - }); - break; - - case NotificationType.Video: - stackPanel.Children.Add(new TextBlock() - { - FontSize = 14, - FontStyle = Windows.UI.Text.FontStyle.Italic, - Foreground = new SolidColorBrush(Colors.Gray), - Text = string.Format("{0} uploaded new video", Channel) - }); - break; - } - - //Content - stackPanel.Children.Add(new TextBlock() - { - TextWrapping = TextWrapping.WrapWholeWords, - Text = Content, - }); - //Time - stackPanel.Children.Add(new TextBlock() - { - FontSize = 13, - Foreground = new SolidColorBrush(Colors.Gray), - Text = TimeStamp.ToString() - }); - PersonPicture avatar = new PersonPicture() - { - Height = 50, - VerticalAlignment = VerticalAlignment.Top, - ProfilePicture = string.IsNullOrWhiteSpace(Avatar) ? null : new BitmapImage(new Uri(Avatar)) - }; - - Grid grid = new Grid(); - grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(50) }); - grid.ColumnDefinitions.Add(new ColumnDefinition()); - - grid.Children.Add(avatar); - Grid.SetColumn(stackPanel, 1); - grid.Children.Add(stackPanel); - - Button item = new Button() - { - HorizontalAlignment = HorizontalAlignment.Stretch, - HorizontalContentAlignment = HorizontalAlignment.Left, - Background = new SolidColorBrush(Colors.Transparent), - Content = grid - }; - - return item; - } - - public ToastNotification GetToast(int assignedId) - { - System.Xml.XmlDocument template = new System.Xml.XmlDocument(); - switch(Type) - { - case NotificationType.Comment: - template.Load("ms-appx:///Assets/Notifications/Comment.xml"); - template["toast"]["visual"]["binding"]["image"].SetAttribute("src", Avatar); - template["toast"]["visual"]["binding"].ChildNodes[1].InnerText = string.Format("{0} posted a new comment", Channel); - template["toast"]["visual"]["binding"].LastChild.InnerText = Content; - break; - - case NotificationType.Video: - template.Load("ms-appx:///Assets/Notifications/Video.xml"); - (template["toast"]["visual"]["binding"].FirstChild as System.Xml.XmlElement).SetAttribute("src", Avatar); - template["toast"]["visual"]["binding"].ChildNodes[1].InnerText = string.Format("{0} uploaded a new video", Channel); - template["toast"]["visual"]["binding"].ChildNodes[2].InnerText = Content; - (template["toast"]["visual"]["binding"].LastChild as System.Xml.XmlElement).SetAttribute("src", Thumbnail); - break; - - case NotificationType.Internal: - template.Load("ms-appx:///Assets/Notifications/Internal.xml"); - if(!string.IsNullOrWhiteSpace(Thumbnail)) - (template["toast"]["visual"]["binding"].FirstChild as System.Xml.XmlElement).SetAttribute("src", Avatar); - template["toast"]["visual"]["binding"].LastChild.InnerText = Channel; - break; - - case NotificationType.Post: - template.Load("ms-appx:///Assets/Notifications/Video.xml"); - (template["toast"]["visual"]["binding"].FirstChild as System.Xml.XmlElement).SetAttribute("src", Thumbnail); - (template["toast"]["visual"]["binding"].ChildNodes[1] as System.Xml.XmlElement).SetAttribute("src", Avatar); - template["toast"]["visual"]["binding"].ChildNodes[2].InnerText = string.Format("{0} published a new post", Channel); - template["toast"]["visual"]["binding"].ChildNodes[3].InnerText = Content; - break; - } - - XmlDocument toastXml = new XmlDocument(); - toastXml.LoadXml(template.InnerXml); - - return new ToastNotification(toastXml); - } - } -} diff --git a/FoxTube/Classes/SecretsVault.cs b/FoxTube/Classes/SecretsVault.cs index 14cbb6b..0c87d88 100644 --- a/FoxTube/Classes/SecretsVault.cs +++ b/FoxTube/Classes/SecretsVault.cs @@ -28,9 +28,9 @@ namespace FoxTube public static bool IsAuthorized => Vault.IsLoged; public static Google.Apis.YouTube.v3.Data.Channel UserChannel => Methods.MainPage.Vault.channel; - public static List> WatchLater => Methods.MainPage.Vault.later; - public static List UserHistory => Methods.MainPage.Vault.history; - public static List Subscriptions => Methods.MainPage.Vault.subs; + public static List WatchLater => Methods.MainPage.Vault.later; + public static List UserHistory => Methods.MainPage.Vault.history; + public static List Subscriptions => Methods.MainPage.Vault.subs; public static YouTubeService NoAuthService => new YouTubeService(new BaseClientService.Initializer() { @@ -48,9 +48,9 @@ namespace FoxTube #region Object containers public bool IsLoged = false; public string userId; - public List history = new List(); - public List subs = new List(); - public List> later = new List>(); + public List history = new List(); + public List subs = new List(); + public List later = new List(); public Google.Apis.YouTube.v3.Data.Channel channel; public UserCredential Credential; public event EventHandler AuthorizationStateChanged; @@ -66,58 +66,60 @@ namespace FoxTube settings.Values.Add("authorized", true); else settings.Values["authorized"] = true; IsLoged = true; - AuthorizationStateChanged.Invoke(this, null); - } - var request = Service.Channels.List("snippet,contentDetails"); - request.Mine = true; - channel = (await request.ExecuteAsync()).Items[0]; - userId = channel.Id; + var request = Service.Channels.List("snippet,contentDetails"); + request.Mine = true; + channel = (await request.ExecuteAsync()).Items[0]; + userId = channel.Id; - var historyRequest = Service.PlaylistItems.List("snippet"); - historyRequest.PlaylistId = channel.ContentDetails.RelatedPlaylists.WatchHistory; - historyRequest.MaxResults = 50; - var response = await historyRequest.ExecuteAsync(); - history.Clear(); - foreach (PlaylistItem i in response.Items) - history.Add(i.Snippet.ResourceId.VideoId); + PlaylistItemsResource.ListRequest playlistRequest = Service.PlaylistItems.List("snippet"); + playlistRequest.PlaylistId = channel.ContentDetails.RelatedPlaylists.WatchHistory; + playlistRequest.MaxResults = 50; + PlaylistItemListResponse playlistResponse = await playlistRequest.ExecuteAsync(); + history.Clear(); + foreach (PlaylistItem i in playlistResponse.Items) + history.Add(i); - var laterRequest = Service.PlaylistItems.List("snippet"); - laterRequest.PlaylistId = channel.ContentDetails.RelatedPlaylists.WatchLater; - laterRequest.MaxResults = 50; - var laterResponse = await laterRequest.ExecuteAsync(); - later.Clear(); + playlistRequest = Service.PlaylistItems.List("snippet"); + playlistRequest.PlaylistId = channel.ContentDetails.RelatedPlaylists.WatchLater; + playlistRequest.MaxResults = 50; + playlistResponse = await playlistRequest.ExecuteAsync(); + later.Clear(); - foreach (PlaylistItem i in laterResponse.Items) - later.Add(new KeyValuePair(i.Id, i.Snippet.ResourceId.VideoId)); + foreach (PlaylistItem i in playlistResponse.Items) + later.Add(i); - string nextToken = laterResponse.NextPageToken; - while (nextToken != null) - { - laterRequest.PageToken = nextToken; - laterResponse = await laterRequest.ExecuteAsync(); - foreach (PlaylistItem i in laterResponse.Items) - later.Add(new KeyValuePair(i.Id, i.Snippet.ResourceId.VideoId)); + string nextToken = playlistResponse.NextPageToken; + while (nextToken != null) + { + playlistRequest.PageToken = nextToken; + playlistResponse = await playlistRequest.ExecuteAsync(); + foreach (PlaylistItem i in playlistResponse.Items) + later.Add(i); - nextToken = laterResponse.NextPageToken; - } + nextToken = playlistResponse.NextPageToken; + } - SubscriptionsResource.ListRequest subRequest = SecretsVault.Service.Subscriptions.List("snippet"); - subRequest.Mine = true; - subRequest.MaxResults = 50; - SubscriptionListResponse subResponse = await subRequest.ExecuteAsync(); - subs.Clear(); + SubscriptionsResource.ListRequest subRequest = Service.Subscriptions.List("snippet"); + subRequest.Mine = true; + subRequest.MaxResults = 50; + subRequest.Order = SubscriptionsResource.ListRequest.OrderEnum.Relevance; + SubscriptionListResponse subResponse = await subRequest.ExecuteAsync(); + subs.Clear(); - foreach (Subscription s in subResponse.Items) - subs.Add(s.Snippet.ResourceId.ChannelId); - - nextToken = subResponse.NextPageToken; - while(nextToken != null) - { - subRequest.PageToken = nextToken; - subResponse = await subRequest.ExecuteAsync(); foreach (Subscription s in subResponse.Items) - subs.Add(s.Snippet.ResourceId.ChannelId); + subs.Add(s); + + nextToken = subResponse.NextPageToken; + while(nextToken != null) + { + subRequest.PageToken = nextToken; + subResponse = await subRequest.ExecuteAsync(); + foreach (Subscription s in subResponse.Items) + subs.Add(s); + } + + AuthorizationStateChanged.Invoke(this, null); } } diff --git a/FoxTube/Controls/NotificationsCenter.xaml.cs b/FoxTube/Controls/NotificationsCenter.xaml.cs index caeb692..60a2f8c 100644 --- a/FoxTube/Controls/NotificationsCenter.xaml.cs +++ b/FoxTube/Controls/NotificationsCenter.xaml.cs @@ -1,14 +1,16 @@ -using Microsoft.Toolkit.Uwp.Notifications; +using FoxTube.Background; +using Microsoft.Toolkit.Uwp.Notifications; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; +using System.Xml; using Windows.Foundation; using Windows.Foundation.Collections; +using Windows.Storage; using Windows.UI; -using Windows.UI.Notifications; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; @@ -25,9 +27,50 @@ namespace FoxTube { List notifications = new List(); + private ApplicationDataContainer settings = ApplicationData.Current.LocalSettings; + XmlDocument doc = new XmlDocument(); public NotificationsCenter() { this.InitializeComponent(); + + if (settings.Values["notificationsHistory"] != null) + { + doc.LoadXml(settings.Values["notificationsHistory"] as string); + foreach(XmlElement n in doc["history"].ChildNodes) + { + AddNotification(new Notification( + n.GetAttribute("type"), + n.GetAttribute("id"), + n["channelName"].InnerText, + n["content"].InnerText, + XmlConvert.ToDateTime(n.GetAttribute("time"), "YYYY-MM-DDThh:mm:ss"), + n["images"].GetAttribute("thumbnail"), + n["images"].GetAttribute("avatar") + )); + } + } + else + { + doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", null)); + doc.AppendChild(doc.CreateElement("history")); + settings.Values.Add("notificationsHistory", doc.InnerXml); + } + + BackgroundProcessor.NotificationRecieved += NewNotification; + } + + private void NewNotification(object sender, string xml) + { + XmlElement n = new XmlDocument().CreateElement("item"); + AddNotification(new Notification( + n.GetAttribute("type"), + n.GetAttribute("id"), + n["channelName"].InnerText, + n["content"].InnerText, + XmlConvert.ToDateTime(n.GetAttribute("time"), "YYYY-MM-DDThh:mm:ss"), + n["images"].GetAttribute("thumbnail"), + n["images"].GetAttribute("avatar") + )); } private void clear_Click(object sender, RoutedEventArgs e) @@ -40,122 +83,34 @@ namespace FoxTube private void close_Click(object sender, RoutedEventArgs e) { - Methods.MainPage.ClosePopups(); + Methods.MainPage.notificationMenu_Click(this, null); } - - public void AddNotification(Notification notification, bool needNotify = true) + public void AddNotification(Notification notification) { notifications.Add(notification); Methods.MainPage.GotNotification(); noNotifications.Visibility = Visibility.Collapsed; clear.Visibility = Visibility.Visible; - StackPanel stackPanel = new StackPanel() { Margin = new Thickness(10, 0, 0, 0) }; - //Channel - stackPanel.Children.Add(new TextBlock() - { - FontSize = 14, - FontStyle = Windows.UI.Text.FontStyle.Italic, - Foreground = new SolidColorBrush(Colors.Gray), - Text = notification.Header - }); - //Content - stackPanel.Children.Add(new TextBlock() - { - TextWrapping = TextWrapping.WrapWholeWords, - Text = notification.message, - }); - //Time - stackPanel.Children.Add(new TextBlock() - { - FontSize = 13, - Foreground = new SolidColorBrush(Colors.Gray), - Text = notification.returnTimecode() - }); - PersonPicture avatar = new PersonPicture() - { - Height = 50, - VerticalAlignment = VerticalAlignment.Top - }; - - Grid grid = new Grid(); - grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(50) }); - grid.ColumnDefinitions.Add(new ColumnDefinition()); - - grid.Children.Add(avatar); - Grid.SetColumn(stackPanel, 1); - grid.Children.Add(stackPanel); - - Button item = new Button() - { - HorizontalAlignment = HorizontalAlignment.Stretch, - HorizontalContentAlignment = HorizontalAlignment.Left, - Background = new SolidColorBrush(Colors.Transparent), - Content = grid - }; + Button item = notification.GetNotification(); item.Click += Notification_Click; array.Children.Add(item); - - //Sending notification - if (needNotify) - { - if (notification.Type == NotificationType.Update) - { - ToastContent toast = new ToastContent() - { - Visual = new ToastVisual() - { - BindingGeneric = new ToastBindingGeneric() - { - Children = - { - new AdaptiveText() - { - Text = notification.Header, - HintMaxLines = 2 - }, - new AdaptiveText() - { - Text = notification.message - } - }, - HeroImage = new ToastGenericHeroImage() - { - Source = notification.Thumbnail - }, - AppLogoOverride = new ToastGenericAppLogo() - { - Source = notification.Avatar, - HintCrop = ToastGenericAppLogoCrop.Circle - } - } - }, - Actions = new ToastActionsCustom() - { - Buttons = - { - new ToastButton("View full post", "action=viewupdatenotification") - { - ActivationType = ToastActivationType.Foreground - }, - new ToastButton("Manage notifications", "action=notificationsettings") - { - ActivationType = ToastActivationType.Foreground - } - } - }, - Launch = "action=viewupdatenotification" - }; - ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification(toast.GetXml())); - } - } } private void Notification_Click(object sender, RoutedEventArgs e) { - Debug.WriteLine("Cliked notification index" + ((sender as Button).Parent as StackPanel).Children.IndexOf(sender as Button)); + Notification n = notifications[((sender as Button).Parent as StackPanel).Children.IndexOf(sender as Button)]; + switch(n.Type) + { + case NotificationType.Internal: + Methods.MainPage.GoToDeveloper(n.Id); + break; + case NotificationType.Video: + Methods.MainPage.GoToVideo(n.Id); + break; + } } } } diff --git a/FoxTube/FoxTube.csproj b/FoxTube/FoxTube.csproj index 53fc06e..5ea3b47 100644 --- a/FoxTube/FoxTube.csproj +++ b/FoxTube/FoxTube.csproj @@ -135,7 +135,6 @@ MainPage.xaml - NotificationsCenter.xaml @@ -238,6 +237,7 @@ Designer + Designer diff --git a/FoxTube/Notifications/NotificationsHistorySample.xml b/FoxTube/Notifications/NotificationsHistorySample.xml new file mode 100644 index 0000000..9e37576 --- /dev/null +++ b/FoxTube/Notifications/NotificationsHistorySample.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/FoxTube/Notifications/ServerLogSamlpe.xml b/FoxTube/Notifications/ServerLogSamlpe.xml index 7c849ad..1eecfe5 100644 --- a/FoxTube/Notifications/ServerLogSamlpe.xml +++ b/FoxTube/Notifications/ServerLogSamlpe.xml @@ -1,5 +1,5 @@  - + Short headline for toast notifications
Main headline for full post
Announcement body (beware of special characters) diff --git a/FoxTube/Pages/MainPage.xaml b/FoxTube/Pages/MainPage.xaml index fc7db58..d4c69d3 100644 --- a/FoxTube/Pages/MainPage.xaml +++ b/FoxTube/Pages/MainPage.xaml @@ -52,9 +52,9 @@ - + - + @@ -107,136 +107,140 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + diff --git a/FoxTube/Pages/MainPage.xaml.cs b/FoxTube/Pages/MainPage.xaml.cs index 9a62887..bfe06a3 100644 --- a/FoxTube/Pages/MainPage.xaml.cs +++ b/FoxTube/Pages/MainPage.xaml.cs @@ -37,6 +37,7 @@ using Windows.UI.Xaml.Documents; using Google.Apis.Oauth2.v2; using Google.Apis.Oauth2.v2.Data; using FoxTube.Controls; +using FoxTube.Pages; // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 @@ -56,8 +57,6 @@ namespace FoxTube RightPaneState paneState = RightPaneState.Full; bool isForcedCollapsed = false; - List subscriptions = new List(); - ApplicationDataContainer settings = ApplicationData.Current.LocalSettings; NotificationsCenter notificationsCenter = new NotificationsCenter(); @@ -94,48 +93,40 @@ namespace FoxTube settings.Values.Add("defaultDownload", Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\DownloadedVideos"); content.Navigate(typeof(Home)); + notificationPane.Child = notificationsCenter; Vault.AuthorizationStateChanged += Vault_AuthorizationStateChanged; + Vault.CheckAuthorization(); } - private async void Vault_AuthorizationStateChanged(object sender, EventArgs e) + private void Vault_AuthorizationStateChanged(object sender, EventArgs e) { if(Vault.IsLoged) { account.Visibility = Visibility.Collapsed; try { - Userinfoplus info = await new Oauth2Service(new BaseClientService.Initializer() - { - HttpClientInitializer = Vault.Credential, - ApplicationName = "FoxTube", - }).Userinfo.Get().ExecuteAsync(); - - (avatar.Content as PersonPicture).ProfilePicture = new BitmapImage(new Uri(info.Picture)); - ToolTipService.SetToolTip(avatar, new ToolTip() { Content = string.Format("{0} ({1})", info.Name, info.Email) }); + ToolTipService.SetToolTip(avatar, new ToolTip() { Content = SecretsVault.UserChannel.Snippet.Title }); + (avatar.Content as PersonPicture).ProfilePicture = new BitmapImage(new Uri(SecretsVault.UserChannel.Snippet.Thumbnails.Standard.Url)); } catch { } avatar.Visibility = Visibility.Visible; - historyMenu.Visibility = Visibility.Visible; - likedMenu.Visibility = Visibility.Visible; - watchLaterMenu.Visibility = Visibility.Visible; - subscriptionsMenu.Visibility = Visibility.Visible; - subsLogErr.Visibility = Visibility.Collapsed; - channelMenu.Visibility = Visibility.Visible; + toHistory.Visibility = Visibility.Visible; + toLiked.Visibility = Visibility.Visible; + toLater.Visibility = Visibility.Visible; + toSubscriptions.Visibility = Visibility.Visible; + toChannel.Visibility = Visibility.Visible; - SubscriptionsResource.ListRequest request = SecretsVault.Service.Subscriptions.List("snippet,contentDetails"); - request.Mine = true; - request.MaxResults = 10; - SubscriptionListResponse response = await request.ExecuteAsync(); - - if (response.Items.Count == 0) - subsNull.Visibility = Visibility.Visible; - else - foreach (Subscription s in response.Items) + if (SecretsVault.Subscriptions.Count > 0) + { + subscriptionsList.Visibility = Visibility.Visible; + int l = SecretsVault.Subscriptions.Count; + int n = 10; + for(int k = 0; k < l && k < n; k++) try { - subscriptions.Add(s); + Subscription s = SecretsVault.Subscriptions[k]; StackPanel panel = new StackPanel() { Orientation = Orientation.Horizontal }; panel.Children.Add(new PersonPicture() { @@ -148,19 +139,35 @@ namespace FoxTube VerticalAlignment = VerticalAlignment.Center, Text = s.Snippet.Title }); - subscriptionsHamburger.Items.Add(new ListBoxItem() { Content = panel }); + subscriptionsList.Items.Add(new ListBoxItem() { Content = panel }); } - catch { } + catch { n++; } + } } - Debug.WriteLine("----"); + else + { + account.Visibility = Visibility.Visible; + avatar.Visibility = Visibility.Collapsed; + + toHistory.Visibility = Visibility.Collapsed; + toLiked.Visibility = Visibility.Collapsed; + toLater.Visibility = Visibility.Collapsed; + toSubscriptions.Visibility = Visibility.Collapsed; + toChannel.Visibility = Visibility.Collapsed; + + subscriptionsList.Visibility = Visibility.Collapsed; + for(int k = 1; k < subscriptionsList.Items.Count; k++) + subscriptionsList.Items.RemoveAt(k); + } + + content.CacheSize = 0; + content.Navigate(typeof(Home)); } protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); SetTitleBar(); - - Vault.CheckAuthorization(); } private void SetTitleBar() @@ -186,33 +193,117 @@ namespace FoxTube notificationMenu.Content = ""; } - public void ClosePopups() + private void HamburgerSelectionChanged(object sender, SelectionChangedEventArgs e) { - popupPlaceholder.Content = null; - notificationPane.Child = null; - } - - private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) - { - try + if(sender == mainList) { - if(topHamburger.SelectedItem != null) - bottomHaburger.SelectedItem = null; - MenuSelectionChanged(); - } catch { } - } - - private void bottomHaburgerSelectionChanged(object sender, SelectionChangedEventArgs e) - { - try + subscriptionsList.SelectedItem = null; + categoriesList.SelectedItem = null; + serviceList.SelectedItem = null; + MainListSelected(); + } + else if (sender == subscriptionsList) { - if(bottomHaburger.SelectedItem != null) - topHamburger.SelectedItem = null; - MenuSelectionChanged(); - } catch { } + mainList.SelectedItem = null; + categoriesList.SelectedItem = null; + serviceList.SelectedItem = null; + SubscriptionSelected(); + } + else if(sender == categoriesList) + { + subscriptionsList.SelectedItem = null; + mainList.SelectedItem = null; + serviceList.SelectedItem = null; + FeaturedSelected(); + } + else if(sender == serviceList) + { + subscriptionsList.SelectedItem = null; + mainList.SelectedItem = null; + categoriesList.SelectedItem = null; + ServiceListSelected(); + } + else + { + mainList.SelectedItem = null; + subscriptionsList.SelectedItem = null; + categoriesList.SelectedItem = null; + serviceList.SelectedItem = null; + } } - private void MenuSelectionChanged() + void MainListSelected() + { + if (mainList.SelectedItem == null) + return; + object s = mainList.SelectedItem; + + if (s == toHistory) + content.Navigate(typeof(Settings)); + else if (s == toLiked) + content.Navigate(typeof(Settings)); + else if (s == toLater) + content.Navigate(typeof(Settings)); + else if (s == toSubscriptions) + content.Navigate(typeof(Settings)); + else if (s == toDownloads) + content.Navigate(typeof(Downloads)); + else + content.Navigate(typeof(Home)); + } + + void ServiceListSelected() + { + if (serviceList.SelectedItem == null) + return; + object s = serviceList.SelectedItem; + + if (s == toChannel) + content.Navigate(typeof(Channel), SecretsVault.AccountId); + else if (s == toRemoveAds) + content.Navigate(typeof(Settings), "adblock"); + else + content.Navigate(typeof(Settings)); + } + + void SubscriptionSelected() + { + if (subscriptionsList.SelectedItem == null) + return; + content.Navigate(typeof(Channel), SecretsVault.Subscriptions[subscriptionsList.SelectedIndex - 1].Snippet.ChannelId); + } + + void FeaturedSelected() + { + if (serviceList.SelectedItem == null) + return; + switch(serviceList.SelectedIndex) + { + case 0: + content.Navigate(typeof(Channel), "UC-9-kyTW8ZkZNDHQJ6FgpwQ"); + break; + case 1: + content.Navigate(typeof(Channel), "UCEgdi0XIXXZ-qJOFPf4JSKw"); + break; + case 2: + content.Navigate(typeof(Channel), "UCOpNcN46UbXVtpKMrmU4Abg"); + break; + case 3: + content.Navigate(typeof(Channel), "UCYfdidRxbB8Qhf0Nx7ioOYw"); + break; + case 4: + content.Navigate(typeof(Channel), "UC4R8DWoMoI7CAwX8_LjQHig"); + break; + case 5: + content.Navigate(typeof(Channel), "UC8iNz9uwDGfomRnnKKbOhOQ"); + break; + case 6: + content.Navigate(typeof(Channel), "UCzuqhhs6NWbgTzMuM09WKDQ"); + break; + } + } + + /*private void MenuSelectionChanged() { if(topHamburger.SelectedIndex == 0) { @@ -224,11 +315,11 @@ namespace FoxTube } else if (topHamburger.SelectedIndex == 1) { - /*content.Navigate(typeof(Video)); - headerText.Text = "Video"; - menu.DisplayMode = SplitViewDisplayMode.CompactOverlay; - menu.IsPaneOpen = false; - isForcedCollapsed = true;*/ + //content.Navigate(typeof(Video)); + //headerText.Text = "Video"; + //menu.DisplayMode = SplitViewDisplayMode.CompactOverlay; + //menu.IsPaneOpen = false; + //isForcedCollapsed = true; } else if (bottomHaburger.SelectedIndex == 4) { @@ -255,90 +346,34 @@ namespace FoxTube else if (content.SourcePageType == typeof(Channel)) bottomHaburger.SelectedIndex = 1; } - } + }*/ - private void notificationMenu_Click(object sender, RoutedEventArgs e) + public void notificationMenu_Click(object sender, RoutedEventArgs e) { notificationMenu.Content = ""; - if (Window.Current.Bounds.Width >= 500) - { - notificationPane.Child = notificationsCenter; - notificationPane.IsOpen = !notificationPane.IsOpen; - } - else - popupPlaceholder.Content = notificationsCenter; + notificationPane.IsOpen = !notificationPane.IsOpen; } private void feedback_Click(object sender, RoutedEventArgs e) { - bottomHaburger.SelectedIndex = 4; - (content.Content as Settings).pivot.SelectedIndex = 3; + content.Navigate(typeof(Settings), "feedback"); } public void PreDefineFeedback(bool isProblem, string meta) { - bottomHaburger.SelectedIndex = 4; - Settings s = content.Content as Settings; - s.pivot.SelectedIndex = 3; - s.fb.PreDefine(isProblem, meta); + content.Navigate(typeof(Settings), $"feedback&isProblem={isProblem}&meta={meta}"); } private void menu_PaneClosed(SplitView sender, object args) { - try - { - subsMenuTitle.Visibility = Visibility.Collapsed; - subsMenuStroke.Y1 = subsMenuStroke.Y2 = 0; - subsMenuStroke.X2 = 40; - subscriptionsTitle.Height = 2; - - catMenuTitle.Visibility = Visibility.Collapsed; - catMenuStroke.Y1 = catMenuStroke.Y2 = 0; - catMenuStroke.X2 = 40; - categoriesTitle.Height = 2; - if (Vault.IsLoged) - { - if (subscriptions.Count == 0) - { - subsNull.Visibility = Visibility.Collapsed; - subsMenuStroke.Visibility = Visibility.Collapsed; - } - } - else - { - subsLogErr.Visibility = Visibility.Collapsed; - subsMenuStroke.Visibility = Visibility.Collapsed; - } - } catch { } + subsTitle.Visibility = Visibility.Collapsed; + catTitle.Visibility = Visibility.Collapsed; } private void menu_PaneOpened(SplitView sender, object args) { - try - { - subsMenuTitle.Visibility = Visibility.Visible; - subsMenuStroke.Y1 = catMenuStroke.Y2 = 10; - subsMenuStroke.X2 = 300; - subscriptionsTitle.Height = 17; - - catMenuTitle.Visibility = Visibility.Visible; - catMenuStroke.Y1 = subsMenuStroke.Y2 = 10; - catMenuStroke.X2 = 300; - categoriesTitle.Height = 17; - if (Vault.IsLoged) - { - if (subscriptions.Count == 0) - { - subsNull.Visibility = Visibility.Visible; - subsMenuStroke.Visibility = Visibility.Visible; - } - } - else - { - subsLogErr.Visibility = Visibility.Visible; - subsMenuStroke.Visibility = Visibility.Visible; - } - } catch { } + subsTitle.Visibility = Visibility.Visible; + catTitle.Visibility = Visibility.Visible; } private async void createAccount_Click(object sender, RoutedEventArgs e) @@ -351,6 +386,16 @@ namespace FoxTube Vault.Authorize(); } + private void myChannel_Click(object sender, RoutedEventArgs e) + { + content.Navigate(typeof(Channel), SecretsVault.UserChannel.Id); + } + + private void logout_Click(object sender, RoutedEventArgs e) + { + Vault.Deauthenticate(); + } + private void searchField_TextChanged(object sender, TextChangedEventArgs e) { if (searchField.Text.Length > 2) @@ -373,21 +418,20 @@ namespace FoxTube private void searchButton_Click(object sender, RoutedEventArgs e) { - if(searchField.Text != "") - StartSearch(searchField.Text); + if (searchField.Text != "" || (!(content.Content is Search) && (content.Content as Search).Term != searchField.Text)) + content.Navigate(typeof(Search), searchField.Text); } public void GoToSearch(string keyword) { searchField.Text = keyword; - StartSearch(keyword); + searchButton_Click(this, null); } private async void StartSearch(string keyword) { content.Navigate(typeof(Search)); - topHamburger.SelectedItem = null; - bottomHaburger.SelectedItem = null; + HamburgerSelectionChanged(null, null); YouTubeService ytService = SecretsVault.IsAuthorized ? SecretsVault.Service : SecretsVault.NoAuthService; @@ -418,11 +462,11 @@ namespace FoxTube private void searchField_KeyUp(object sender, KeyRoutedEventArgs e) { - if (e.Key == Windows.System.VirtualKey.Enter) + if (e.Key == VirtualKey.Enter) { searchButton_Click(this, null); content.Focus(FocusState.Pointer); - searchSuggestions.Visibility = Visibility.Collapsed; + searchSuggestions.IsOpen = false; } } @@ -438,10 +482,9 @@ namespace FoxTube public void GoToChannel(string id) { + MinimizeVideo(); headerText.Text = "Channel overview"; - content.Navigate(typeof(Channel)); - Channel page = content.Content as Channel; - page.Initialize(id); + content.Navigate(typeof(Channel), id); } public void GoToVideo(string id) @@ -458,8 +501,12 @@ namespace FoxTube videoPlaceholder.HorizontalAlignment = HorizontalAlignment.Stretch; videoPlaceholder.Margin = new Thickness(0); - videoPlaceholder.Navigate(typeof(Video)); - (videoPlaceholder.Content as Video).Initialize(id); + videoPlaceholder.Navigate(typeof(Video), id); + } + + public void GoToDeveloper(string id) + { + } private void Page_SizeChanged(object sender, SizeChangedEventArgs e) @@ -505,11 +552,6 @@ namespace FoxTube } } - private void closeNotification_Click(object sender, RoutedEventArgs e) - { - notificationPane.IsOpen = false; - } - public void MinimizeVideo() { videoPlaceholder.Width = 432; diff --git a/FoxTube/Pages/Search.xaml.cs b/FoxTube/Pages/Search.xaml.cs index 8f45166..240302d 100644 --- a/FoxTube/Pages/Search.xaml.cs +++ b/FoxTube/Pages/Search.xaml.cs @@ -24,6 +24,7 @@ namespace FoxTube /// public sealed partial class Search : Page { + public string Term; public ProgressRing ring; public StackPanel content; public Search()