From 9548be15f3127d9c2a737e0217875c1dba26bd4e Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Sun, 3 Feb 2019 19:57:39 +0300 Subject: [PATCH] History and watch later pages --- FoxTube/Assets/Data/RevEn.xml | 55 ++++++++++++++++++++++++++++++ FoxTube/Classes/Methods.cs | 33 ++++++++++++++++++ FoxTube/Classes/SecretsVault.cs | 6 +++- FoxTube/FoxTube.csproj | 1 + FoxTube/Package.appxmanifest | 2 +- FoxTube/Pages/Browser.xaml.cs | 19 +++-------- FoxTube/Pages/History.xaml | 9 +++-- FoxTube/Pages/History.xaml.cs | 59 +++++++++++++++++++++++++++++---- FoxTube/Pages/Home.xaml.cs | 2 +- FoxTube/Pages/MainPage.xaml.cs | 48 +++++++++++++++------------ FoxTube/Pages/VideoGrid.xaml.cs | 2 ++ 11 files changed, 188 insertions(+), 48 deletions(-) create mode 100644 FoxTube/Assets/Data/RevEn.xml diff --git a/FoxTube/Assets/Data/RevEn.xml b/FoxTube/Assets/Data/RevEn.xml new file mode 100644 index 0000000..5d5cf2f --- /dev/null +++ b/FoxTube/Assets/Data/RevEn.xml @@ -0,0 +1,55 @@ + + + + + ### What's new: + +- Small fixes +- First public pre-release version +- Some content was cut out due to its incompleteness + + ### Что нового: + +- Мелкие исправления багов +- Эта версия является первой пред-релизной публичной версией +- Некотроые функции были вырезаны из-за их незавершенности + + + + + + ### What's new: + +- 'Live' button fixed in the player +- Long channel names on crads fixed +- Fixed video description disappearing on window resizing +- Player seek is fixed +- Added video buffering progress indicatior +- Small fixes + +### Known issues: + +- Recommended and subscriptions pages aren't implemented +- History isn't implemented +- Playlists management isn't implemented +- Ads aren't implemented + + ### Что нового: + +- Кнопка перехода к прямому эфиру на стримах теперь работает +- Исправлен баг с длинными именами каналов на карточках +- Исправлено исчезание описания видео при изменении размеров окна +- Исправлен ползунок перемотки видео +- Добавлен индикатор буферизации видео +- Мелкие исправления + +### Что по-прежнему не работает: + +- Страница рекомендованных видео и страница видео с подписок +- История +- Работа с плейлистами +- Нет карточек рекламы + + + + diff --git a/FoxTube/Classes/Methods.cs b/FoxTube/Classes/Methods.cs index be01184..a107347 100644 --- a/FoxTube/Classes/Methods.cs +++ b/FoxTube/Classes/Methods.cs @@ -1,11 +1,14 @@ using FoxTube.Pages; using Google.Apis.YouTube.v3; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Net.Http; using System.Text.RegularExpressions; +using System.Threading.Tasks; using System.Web; using System.Xml; using Windows.ApplicationModel.Core; @@ -308,5 +311,35 @@ namespace FoxTube deferral.Complete(); } } + + public static async Task> GetHistory() + { + List list = new List(); + + HttpClient client = new HttpClient(); + client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", SecretsVault.Credential.Token.AccessToken); + string output = await client.GetStringAsync($"https://www.youtube.com/list_ajax?style=json&action_get_list=1&list=HL&hl={SettingsStorage.RelevanceLanguage}"); + + dynamic raw = JsonConvert.DeserializeObject(output); + foreach (dynamic i in raw.video) + list.Add(i.encrypted_id.ToString()); + + return list; + } + + public static async Task> GetLater() + { + List list = new List(); + + HttpClient client = new HttpClient(); + client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", SecretsVault.Credential.Token.AccessToken); + string output = await client.GetStringAsync($"https://www.youtube.com/list_ajax?style=json&action_get_list=1&list=WL&hl={SettingsStorage.RelevanceLanguage}"); + + dynamic raw = JsonConvert.DeserializeObject(output); + foreach (dynamic i in raw.video) + list.Add(i.encrypted_id.ToString()); + + return list; + } } } diff --git a/FoxTube/Classes/SecretsVault.cs b/FoxTube/Classes/SecretsVault.cs index 7c7024d..3bcd4b2 100644 --- a/FoxTube/Classes/SecretsVault.cs +++ b/FoxTube/Classes/SecretsVault.cs @@ -110,7 +110,11 @@ namespace FoxTube new[] { Google.Apis.Oauth2.v2.Oauth2Service.Scope.UserinfoProfile, - YouTubeService.Scope.YoutubeForceSsl + YouTubeService.Scope.YoutubeForceSsl, + YouTubeService.Scope.Youtube, + YouTubeService.Scope.YoutubeUpload, + YouTubeService.Scope.YoutubeReadonly, + YouTubeService.Scope.Youtubepartner }, "user", CancellationToken.None); diff --git a/FoxTube/FoxTube.csproj b/FoxTube/FoxTube.csproj index f6e2692..1b0d44f 100644 --- a/FoxTube/FoxTube.csproj +++ b/FoxTube/FoxTube.csproj @@ -209,6 +209,7 @@ + diff --git a/FoxTube/Package.appxmanifest b/FoxTube/Package.appxmanifest index 08dfab0..bf4455f 100644 --- a/FoxTube/Package.appxmanifest +++ b/FoxTube/Package.appxmanifest @@ -1,6 +1,6 @@  - + FoxTube diff --git a/FoxTube/Pages/Browser.xaml.cs b/FoxTube/Pages/Browser.xaml.cs index bee5906..e30c1b4 100644 --- a/FoxTube/Pages/Browser.xaml.cs +++ b/FoxTube/Pages/Browser.xaml.cs @@ -29,27 +29,16 @@ namespace FoxTube.Pages public Browser() { InitializeComponent(); - Initialize(); } public async void Initialize() { - /*Debug.WriteLine(SecretsVault.Credential.Token.AccessToken); - WebClient client = new WebClient(); - client.Headers.Add(HttpRequestHeader.Cookie, "SID=9wYUCqAm2D7AmC_Vi8uNGjYZAf6Js2hasI1gCEhznMjJbYqnt0J6m1sthArcXG_pMMadnQ.; HSID=AhyajPo6nPBx7VB-0; SSID=AaaOvEW6jZVcc4Asp; APISID=tXeMRBKErzlt6KOo/Aapw7Rv4U_HG1A0CQ; SAPISID=FGp4Ff7MMF8Yq0X4/AOdNjGueWyCkkK7C5; LOGIN_INFO=AFmmF2swRAIgZln6SD5aFUlABb9pBEq9uAwLBISe7sYR1NWVXyaDTY4CIBLo_KAFcoo4wtlW0ZPmJnHaa-xVhsA7MzdGm7-vvgX-:QUQ3MjNmekJTZ3M2dXJNaFh3M3NfTFVDS0RIaUM3WlJNWlRJbk5sZUE1eHR3bHkwckhQeEppazkyekhDb0ljcXpacDdwQXlIanhSbnpSWkUyZVFpdWtiT243Rzhad0N4aGZwUXJDZ1Mxd0tFTS0wVDdudk9xaFJDdTNYUWtnQlE3VXhQdVl5MjB2MGdEdl9keElDaS1yX0tmQWowS041ZWF1VU9tV0c3bTRVbWNGSHFjWHRDVTIw;");*/ HttpClient client = new HttpClient(); - client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "BQcUCusfz2zKN_ejHc3Xu15ahz8eEEaKouKJydqBAVKxWxcqfhht1zVux-G9bRf0KSTFBw"); - /*SecretsVault.Credential.ToString(); - string url = $"https://www.youtube.com/list_ajax?style=json&action_get_list=1&list=HL&hl=en"; - string response = client.DownloadString(url.ToUri()); - HttpClient c = new HttpClient();*/ - string response = await SecretsVault.Service.HttpClient.GetStringAsync("https://www.youtube.com/list_ajax?style=xml&action_get_list=1&list=HL"); - //HttpResponseMessage res = await c.GetAsync(""); - Debug.WriteLine(response); - - /*new Google.Apis.Oauth2.v2.Oauth2Service.Initializer(); - code.Text = response;*/ + client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", SecretsVault.Credential.Token.AccessToken); + string response = await SecretsVault.Service.HttpClient.GetStringAsync(adress.Text); + code.Text = response; + view.NavigateToString(response); } private void Adress_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args) diff --git a/FoxTube/Pages/History.xaml b/FoxTube/Pages/History.xaml index b100b65..95e50e7 100644 --- a/FoxTube/Pages/History.xaml +++ b/FoxTube/Pages/History.xaml @@ -1,5 +1,4 @@  @@ -15,8 +15,11 @@ - - + + + + + diff --git a/FoxTube/Pages/History.xaml.cs b/FoxTube/Pages/History.xaml.cs index 0ffb030..717daad 100644 --- a/FoxTube/Pages/History.xaml.cs +++ b/FoxTube/Pages/History.xaml.cs @@ -1,4 +1,7 @@ -using System; +using FoxTube.Controls; +using Microsoft.AppCenter.Analytics; +using System; +using System.Collections.Generic; using Windows.System; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; @@ -11,8 +14,12 @@ namespace FoxTube.Pages /// public sealed partial class History : Page { + List entries; + int page = 1; + public string id = "HL"; LoadingPage loading; VideoGrid list; + ShowMore more; public History() { @@ -24,25 +31,65 @@ namespace FoxTube.Pages base.OnNavigatedTo(e); loading = grid.Children[2] as LoadingPage; - list = scroll.Content as VideoGrid; + list = stack.Children[0] as VideoGrid; + more = stack.Children[1] as ShowMore; + + if (!string.IsNullOrWhiteSpace(e.Parameter.ToString())) + id = e.Parameter.ToString(); + Initialize(); } - public void Initialize() + public async void Initialize() { - loading.Refresh(); + try + { + loading.Refresh(); - loading.Close(); + entries = id == "HL" ? await Methods.GetHistory() : await Methods.GetLater(); + + for (int k = 0; k < 50 && k < entries.Count; k++) + list.Add(new VideoCard(entries[k])); + + if (list.Count >= entries.Count) + more.Complete(true); + + loading.Close(); + } + catch (System.Net.Http.HttpRequestException) + { + loading.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true); + } + catch (Exception e) + { + loading.Error(e.GetType().ToString(), e.Message); + Analytics.TrackEvent("History loading error", new Dictionary() + { + { "Exception", e.GetType().ToString() }, + { "Message", e.Message }, + { "ID", id } + }); + } } private async void toBrowser_Click(object sender, RoutedEventArgs e) { - await Launcher.LaunchUriAsync(new Uri("youtube.com/feed/history")); + await Launcher.LaunchUriAsync(new Uri(id == "HL" ? "https://www.youtube.com/feed/history" : "https://www.youtube.com/playlist?list=WL")); } private void Refresh_Click(object sender, RoutedEventArgs e) { + list.Clear(); + Initialize(); + } + private void ShowMore_Clicked() + { + for (int k = 50 * page++; k < 50 * page; k++) + list.Add(new VideoCard(entries[k])); + + if (list.Count >= entries.Count) + more.Complete(true); } } } diff --git a/FoxTube/Pages/Home.xaml.cs b/FoxTube/Pages/Home.xaml.cs index df1fc2b..b47c3cc 100644 --- a/FoxTube/Pages/Home.xaml.cs +++ b/FoxTube/Pages/Home.xaml.cs @@ -46,7 +46,7 @@ namespace FoxTube try { VideosResource.ListRequest request = SecretsVault.Service.Videos.List("id"); - request.MaxResults = 48; + request.MaxResults = 25; request.PageToken = trendToken; request.Chart = VideosResource.ListRequest.ChartEnum.MostPopular; diff --git a/FoxTube/Pages/MainPage.xaml.cs b/FoxTube/Pages/MainPage.xaml.cs index a2492f7..3279847 100644 --- a/FoxTube/Pages/MainPage.xaml.cs +++ b/FoxTube/Pages/MainPage.xaml.cs @@ -186,9 +186,9 @@ namespace FoxTube toChannel.Visibility = Visibility.Visible; toSubscriptions.Visibility = Visibility.Visible; libHeader.Visibility = Visibility.Visible; - //toHistory.Visibility = Visibility.Visible; + toHistory.Visibility = Visibility.Visible; toLiked.Visibility = Visibility.Visible; - //toLater.Visibility = Visibility.Visible; + toLater.Visibility = Visibility.Visible; if (SecretsVault.Subscriptions.Count > 0) { @@ -230,9 +230,9 @@ namespace FoxTube toChannel.Visibility = Visibility.Collapsed; toSubscriptions.Visibility = Visibility.Collapsed; libHeader.Visibility = Visibility.Collapsed; - //toHistory.Visibility = Visibility.Collapsed; + toHistory.Visibility = Visibility.Collapsed; toLiked.Visibility = Visibility.Collapsed; - //toLater.Visibility = Visibility.Collapsed; + toLater.Visibility = Visibility.Collapsed; subsHeader.Visibility = Visibility.Collapsed; subsHeader.Visibility = Visibility.Collapsed; @@ -557,11 +557,11 @@ namespace FoxTube if (args.SelectedItem == toHome) content.Navigate(typeof(Home)); else if (args.SelectedItem == toHistory) - content.Navigate(typeof(History)); + content.Navigate(typeof(History), "HL"); else if (args.SelectedItem == toLiked) content.Navigate(typeof(PlaylistPage), SecretsVault.UserChannel.ContentDetails.RelatedPlaylists.Likes); else if (args.SelectedItem == toLater) - content.Navigate(typeof(PlaylistPage), SecretsVault.UserChannel.ContentDetails.RelatedPlaylists.WatchLater); + content.Navigate(typeof(History), "WL"); else if (args.SelectedItem == toSubscriptions) content.Navigate(typeof(Subscriptions)); else if (args.SelectedItem == toDownloads) @@ -587,7 +587,14 @@ namespace FoxTube { typeof(PlaylistPage), () => nav.Header = resources.GetString("/Main/playlist") }, { typeof(Search), () => nav.Header = resources.GetString("/Main/searchPlaceholder/PlaceholderText") }, { typeof(Subscriptions), () => nav.Header = resources.GetString("/Main/subscriptions/Content") }, - { typeof(History), () => nav.Header = resources.GetString("/Main/history/Content") }, + { typeof(History), () => + { + if((content.Content as History).id == "HL") + nav.Header = resources.GetString("/Main/history/Content"); + else + nav.Header = resources.GetString("/Main/later/Content"); + + } }, { typeof(Home), () => nav.Header = resources.GetString("/Main/home/Content") }, { typeof(Downloads), () => nav.Header = resources.GetString("/Main/downloads/Content") } }; @@ -642,9 +649,7 @@ namespace FoxTube } if(!found) - { nav.SelectedItem = null; - } } } else @@ -666,17 +671,8 @@ namespace FoxTube else s = Sender.None; } - else if ((content.Content as PlaylistPage).playlistId == SecretsVault.UserChannel.ContentDetails.RelatedPlaylists.WatchLater) - { - if(nav.SelectedItem != toLater) - nav.SelectedItem = toLater; - else - s = Sender.None; - } else - { nav.SelectedItem = null; - } } }, { typeof(Search), () => nav.SelectedItem = null }, {typeof(Subscriptions), () => @@ -688,10 +684,20 @@ namespace FoxTube } }, { typeof(History), () => { - if(nav.SelectedItem != toHistory) - nav.SelectedItem = toHistory; + if((content.Content as History).id == "HL") + { + if(nav.SelectedItem != toHistory) + nav.SelectedItem = toHistory; + else + s = Sender.None; + } else - s = Sender.None; + { + if(nav.SelectedItem != toLater) + nav.SelectedItem = toLater; + else + s = Sender.None; + } } }, { typeof(Home), () => { diff --git a/FoxTube/Pages/VideoGrid.xaml.cs b/FoxTube/Pages/VideoGrid.xaml.cs index 52b1ee5..a5fbc90 100644 --- a/FoxTube/Pages/VideoGrid.xaml.cs +++ b/FoxTube/Pages/VideoGrid.xaml.cs @@ -8,6 +8,8 @@ namespace FoxTube.Pages /// public sealed partial class VideoGrid : Page { + public int Count => list.Items.Count; + public VideoGrid() { InitializeComponent();