diff --git a/FoxTube/Classes/DownloadAgent.cs b/FoxTube/Classes/DownloadAgent.cs index 2e0ca64..6c4748c 100644 --- a/FoxTube/Classes/DownloadAgent.cs +++ b/FoxTube/Classes/DownloadAgent.cs @@ -50,19 +50,19 @@ namespace FoxTube.Controls item.DownloadComplete += Item_DownloadComplete; Items.Add(item); - ListChanged.Invoke(item, new ObjectEventArgs("add")); + ListChanged.Invoke(item, "add"); } - private void Item_DownloadComplete(object sender, ObjectEventArgs e) + private void Item_DownloadComplete(object sender, params object[] e) { - doc["downloads"].InnerXml += e.Parameters[0]; + doc["downloads"].InnerXml += e[0]; settings.Values["downloadHistory"] = doc.InnerXml; } - private void Item_DownloadCanceled(object sender, ObjectEventArgs e) + private void Item_DownloadCanceled(object sender, params object[] e) { Items.Remove(sender as DownloadItem); - ListChanged.Invoke(sender, new ObjectEventArgs("remove")); + ListChanged.Invoke(sender, "remove"); } } } diff --git a/FoxTube/Classes/Methods.cs b/FoxTube/Classes/Methods.cs index 182fbb7..8779977 100644 --- a/FoxTube/Classes/Methods.cs +++ b/FoxTube/Classes/Methods.cs @@ -20,32 +20,33 @@ namespace FoxTube public static string GetAgo(DateTime dateTime) { TimeSpan span = DateTime.Now - dateTime; + if (span.TotalMinutes < 1) return "Just now"; - else if (span.Minutes == 1) + else if (Math.Round(span.TotalMinutes) == 1) return "1 minute ago"; - else if (span.TotalMinutes > 60) - return span.Minutes + " minutes ago"; - else if (span.Hours == 1) + else if (span.TotalMinutes < 60) + return Math.Round(span.TotalMinutes) + " minutes ago"; + else if (Math.Round(span.TotalHours) == 1) return "1 hour ago"; - else if (span.TotalHours > 24) - return span.Hours + " hours ago"; - else if (span.Days == 1) + else if (span.TotalHours < 24) + return Math.Round(span.TotalHours) + " hours ago"; + else if (Math.Round(span.TotalDays) == 1) return "1 day ago"; - else if (span.TotalDays > 7) - return span.Days + " days ago"; - else if (span.Days == 7) + else if (span.TotalDays < 7) + return Math.Round(span.TotalDays) + " days ago"; + else if (Math.Round(span.TotalDays) == 7) return "1 week ago"; - else if (span.Days > 30) - return (int)(span.Days / 7) + " weeks ago"; - else if (span.Days == 30) + else if (span.TotalDays < 30) + return Math.Round(span.TotalDays / 7) + " weeks ago"; + else if (Math.Round(span.TotalDays) == 30) return "1 month ago"; - else if (span.Days > 365) - return (int)(span.Days / 30) + " months ago"; - else if (span.Days == 365) + else if (Math.Round(span.TotalDays) < 365) + return Math.Round(span.TotalDays / 30) + " months ago"; + else if (Math.Round(span.TotalDays / 365) == 365) return "1 year ago"; else - return (int)(span.Days / 365) + " years ago"; + return Math.Round(span.TotalDays / 365) + " years ago"; } public static void FormatText(ref TextBlock block, string text) diff --git a/FoxTube/Classes/SecretsVault.cs b/FoxTube/Classes/SecretsVault.cs index a7478d2..80d3519 100644 --- a/FoxTube/Classes/SecretsVault.cs +++ b/FoxTube/Classes/SecretsVault.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Net; using System.Threading; using System.Threading.Tasks; @@ -12,45 +13,44 @@ using Windows.Storage; namespace FoxTube { - public class SecretsVault + public static class SecretsVault { - #region Static Information public static event EventHandler AuthorizationStateChanged; public static event ObjectEventHandler SubscriptionsChanged; + private static ApplicationDataContainer settings = ApplicationData.Current.LocalSettings; public static NetworkCredential EmailCredential => new NetworkCredential("youwillneverknowthisadress@gmail.com", "thisisthepassword12345"); public static ClientSecrets Secrets => new ClientSecrets() { ClientId = "349735264870-2ekqlm0a4mkg3mmrfcv90s3qp3o15dq0.apps.googleusercontent.com", ClientSecret = "BkVZOAaCU2Zclf0Zlicg6y2_" }; + private static UserCredential Credential; + public static BaseClientService.Initializer Initializer => new BaseClientService.Initializer() + { + HttpClientInitializer = Credential, + ApplicationName = "FoxTube" + }; - public static SecretsVault Vault => Methods.MainPage.Vault; + public static string AccountId { get; private set; } + public static bool IsAuthorized { get; private set; } = false; - public static string AccountId => Methods.MainPage.Vault.userId; - 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 Google.Apis.YouTube.v3.Data.Channel UserChannel { get; private set; } + public static List WatchLater { get; private set; } = new List(); + public static List UserHistory { get; private set; } = new List(); + public static List Subscriptions { get; private set; } = new List(); public static YouTubeService NoAuthService => new YouTubeService(new BaseClientService.Initializer() { ApiKey = "AIzaSyBgHrCnrlzlVmk0cJKL8RqP9Y8x6XSuk_0", ApplicationName = "FoxTube" }); - public static YouTubeService Service { get { if (IsAuthorized) - return new YouTubeService(new BaseClientService.Initializer() - { - HttpClientInitializer = Vault.Credential, - ApplicationName = "FoxTube" - }); + return new YouTubeService(Initializer); else return NoAuthService; } @@ -65,7 +65,11 @@ namespace FoxTube { Snippet = new SubscriptionSnippet() { - ChannelId = id + ResourceId = new ResourceId() + { + ChannelId = id, + Kind = "youtube#channel" + } } }, "snippet"); @@ -82,32 +86,29 @@ namespace FoxTube Subscription s = null; foreach(Subscription i in Subscriptions) - if (i.Snippet.ChannelId == id) + if (i.Snippet.ResourceId.ChannelId == id) { s = i; break; } if (s == null) return false; - SubscriptionsChanged.Invoke(null, "remove", Subscriptions.IndexOf(s)); - await Service.Subscriptions.Delete(s.Id).ExecuteAsync(); //??? + try + { + await Service.Subscriptions.Delete(s.Id).ExecuteAsync(); + } + catch + { + return false; + } + + SubscriptionsChanged.Invoke(null, "remove", Subscriptions.IndexOf(s)); Subscriptions.Remove(s); return true; } - #endregion - - #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 Google.Apis.YouTube.v3.Data.Channel channel; - public UserCredential Credential; - private ApplicationDataContainer settings = ApplicationData.Current.LocalSettings; - - public async void Authorize() + + public static async void Authorize() { try { Credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(Secrets, new[] { Google.Apis.Oauth2.v2.Oauth2Service.Scope.UserinfoProfile, YouTubeService.Scope.YoutubeForceSsl }, "user", CancellationToken.None); } catch { } @@ -116,29 +117,29 @@ namespace FoxTube if (settings.Values["authorized"] == null) settings.Values.Add("authorized", true); else settings.Values["authorized"] = true; - IsLoged = true; + IsAuthorized = true; var request = Service.Channels.List("snippet,contentDetails"); request.Mine = true; - channel = (await request.ExecuteAsync()).Items[0]; - userId = channel.Id; + UserChannel = (await request.ExecuteAsync()).Items[0]; + AccountId = UserChannel.Id; PlaylistItemsResource.ListRequest playlistRequest = Service.PlaylistItems.List("snippet"); - playlistRequest.PlaylistId = channel.ContentDetails.RelatedPlaylists.WatchHistory; + playlistRequest.PlaylistId = UserChannel.ContentDetails.RelatedPlaylists.WatchHistory; playlistRequest.MaxResults = 50; PlaylistItemListResponse playlistResponse = await playlistRequest.ExecuteAsync(); - history.Clear(); + UserHistory.Clear(); foreach (PlaylistItem i in playlistResponse.Items) - history.Add(i); + UserHistory.Add(i); playlistRequest = Service.PlaylistItems.List("snippet"); - playlistRequest.PlaylistId = channel.ContentDetails.RelatedPlaylists.WatchLater; + playlistRequest.PlaylistId = UserChannel.ContentDetails.RelatedPlaylists.WatchLater; playlistRequest.MaxResults = 50; playlistResponse = await playlistRequest.ExecuteAsync(); - later.Clear(); + WatchLater.Clear(); foreach (PlaylistItem i in playlistResponse.Items) - later.Add(i); + WatchLater.Add(i); string nextToken = playlistResponse.NextPageToken; while (nextToken != null) @@ -146,7 +147,7 @@ namespace FoxTube playlistRequest.PageToken = nextToken; playlistResponse = await playlistRequest.ExecuteAsync(); foreach (PlaylistItem i in playlistResponse.Items) - later.Add(i); + WatchLater.Add(i); nextToken = playlistResponse.NextPageToken; } @@ -156,10 +157,10 @@ namespace FoxTube subRequest.MaxResults = 50; subRequest.Order = SubscriptionsResource.ListRequest.OrderEnum.Relevance; SubscriptionListResponse subResponse = await subRequest.ExecuteAsync(); - subs.Clear(); + Subscriptions.Clear(); foreach (Subscription s in subResponse.Items) - subs.Add(s); + Subscriptions.Add(s); nextToken = subResponse.NextPageToken; while(nextToken != null) @@ -167,30 +168,29 @@ namespace FoxTube subRequest.PageToken = nextToken; subResponse = await subRequest.ExecuteAsync(); foreach (Subscription s in subResponse.Items) - subs.Add(s); + Subscriptions.Add(s); } - AuthorizationStateChanged.Invoke(this, null); + AuthorizationStateChanged.Invoke(null, null); } } - public async void Deauthenticate() + public static async void Deauthenticate() { if(await Credential.RevokeTokenAsync(CancellationToken.None)) { Credential = null; - AuthorizationStateChanged.Invoke(this, null); + AuthorizationStateChanged.Invoke(null, null); settings.Values["authorized"] = false; } } - public void CheckAuthorization() + public static void CheckAuthorization() { if (settings.Values["authorized"] == null || !(bool)settings.Values["authorized"]) - IsLoged = false; + IsAuthorized = false; else Authorize(); } - #endregion } } diff --git a/FoxTube/Controls/ChannelCard.xaml b/FoxTube/Controls/ChannelCard.xaml index 4fbab61..e07827b 100644 --- a/FoxTube/Controls/ChannelCard.xaml +++ b/FoxTube/Controls/ChannelCard.xaml @@ -14,10 +14,10 @@ diff --git a/FoxTube/Controls/ChannelCard.xaml.cs b/FoxTube/Controls/ChannelCard.xaml.cs index 369cde2..8b2c746 100644 --- a/FoxTube/Controls/ChannelCard.xaml.cs +++ b/FoxTube/Controls/ChannelCard.xaml.cs @@ -38,7 +38,7 @@ namespace FoxTube.Controls public async void Initialize(string id, string live) { - ChannelsResource.ListRequest request = SecretsVault.NoAuthService.Channels.List("snippet,contentDetails,statistics,liveStreamingDetails"); + ChannelsResource.ListRequest request = SecretsVault.NoAuthService.Channels.List("snippet,statistics,brandingSettings"); request.Id = id; ChannelListResponse response = await request.ExecuteAsync(); @@ -46,10 +46,9 @@ namespace FoxTube.Controls channelId = id; title.Text = item.Snippet.Title; - description.Text = item.Snippet.Description; - subs.Text = $"{item.Statistics.SubscriberCount} subscribers"; - uploads.Text = $"{item.Statistics.VideoCount} videos"; + subs.Text = $"{item.Statistics.SubscriberCount:0,0} subscribers"; + uploads.Text = $"{item.Statistics.VideoCount:0,0} videos"; if (live == "live") liveTag.Visibility = Visibility.Visible; @@ -58,8 +57,11 @@ namespace FoxTube.Controls { foreach(Subscription s in SecretsVault.Subscriptions) { - if(s.Snippet.ChannelId == id) + if(s.Snippet.ResourceId.ChannelId == id) + { subscribe.IsChecked = true; + subscribe.Content = "Subscribed"; + } } subscriptionPane.Visibility = Visibility.Visible; } @@ -67,7 +69,7 @@ namespace FoxTube.Controls try { avatar.ProfilePicture = new BitmapImage(new Uri(item.Snippet.Thumbnails.Medium.Url)); - cover.Source = new BitmapImage(new Uri(item.BrandingSettings.Image.BannerImageUrl)); + cover.Source = new BitmapImage(new Uri(item.BrandingSettings.Image.BannerTvLowImageUrl)); } catch { } } @@ -79,7 +81,7 @@ namespace FoxTube.Controls private void Hyperlink_Click(Windows.UI.Xaml.Documents.Hyperlink sender, Windows.UI.Xaml.Documents.HyperlinkClickEventArgs args) { - SecretsVault.Vault.Authorize(); + SecretsVault.Authorize(); } private async void subscribe_Click(object sender, RoutedEventArgs e) @@ -88,10 +90,16 @@ namespace FoxTube.Controls { if (!await SecretsVault.Subscribe(channelId)) subscribe.IsChecked = false; + else + subscribe.Content = "Subscribed"; } else + { if (!await SecretsVault.Unsubscibe(channelId)) - subscribe.IsChecked = true; + subscribe.IsChecked = true; + else + subscribe.Content = "Subscribe"; + } } } } diff --git a/FoxTube/Controls/DownloadItem.xaml.cs b/FoxTube/Controls/DownloadItem.xaml.cs index c782c96..4a431bd 100644 --- a/FoxTube/Controls/DownloadItem.xaml.cs +++ b/FoxTube/Controls/DownloadItem.xaml.cs @@ -105,7 +105,7 @@ namespace FoxTube.Controls "; - DownloadComplete.Invoke(this, new ObjectEventArgs(node)); + DownloadComplete.Invoke(this, node); } public DownloadItem(string videoId, string videoName, string channelName, string thumbUrl, string length, string videoQuality, string path) diff --git a/FoxTube/Controls/PlaylistCard.xaml b/FoxTube/Controls/PlaylistCard.xaml new file mode 100644 index 0000000..2149058 --- /dev/null +++ b/FoxTube/Controls/PlaylistCard.xaml @@ -0,0 +1,51 @@ + + + + diff --git a/FoxTube/Controls/PlaylistCard.xaml.cs b/FoxTube/Controls/PlaylistCard.xaml.cs new file mode 100644 index 0000000..dd1c4cc --- /dev/null +++ b/FoxTube/Controls/PlaylistCard.xaml.cs @@ -0,0 +1,71 @@ +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. + /// + public sealed partial class PlaylistCard : Page + { + Playlist item; + string playlistId; + + public PlaylistCard(string id) + { + this.InitializeComponent(); + Initialize(id); + } + + public async void Initialize(string id) + { + 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; + channelName.Text = item.Snippet.ChannelTitle; + counter.Text = item.ContentDetails.ItemCount.ToString(); + date.Text = item.Snippet.PublishedAt.ToString(); + + ChannelsResource.ListRequest r = SecretsVault.NoAuthService.Channels.List("snippet"); + r.Id = item.Snippet.ChannelId; + + try + { + thumbnail.Source = new BitmapImage(new Uri(item.Snippet.Thumbnails.Standard.Url)); + avatar.ProfilePicture = new BitmapImage(new Uri((await r.ExecuteAsync()).Items[0].Snippet.Thumbnails.Standard.Url)); + } catch { } + } + + private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e) + { + Height = e.NewSize.Width * 0.75; + } + + private void Button_Click(object sender, RoutedEventArgs e) + { + //Goto playlist + } + } +} diff --git a/FoxTube/Controls/PlaylistCardWide.xaml b/FoxTube/Controls/PlaylistCardWide.xaml index abd519e..473a829 100644 --- a/FoxTube/Controls/PlaylistCardWide.xaml +++ b/FoxTube/Controls/PlaylistCardWide.xaml @@ -12,7 +12,7 @@ - -