From 8d06533fe29f09498474af9680cda72f155e7cab Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Thu, 13 Sep 2018 21:44:14 +0300 Subject: [PATCH 01/62] #152, 179, 177 --- FoxTube/Controls/VideoPlayer.xaml | 3 +-- FoxTube/Controls/VideoPlayer.xaml.cs | 10 +++++++++- FoxTube/Pages/MainPage.xaml | 3 ++- FoxTube/Pages/MainPage.xaml.cs | 9 +++++++++ FoxTube/Pages/VideoPage.xaml.cs | 14 ++++++++------ 5 files changed, 29 insertions(+), 10 deletions(-) diff --git a/FoxTube/Controls/VideoPlayer.xaml b/FoxTube/Controls/VideoPlayer.xaml index 70cb15c..7a15539 100644 --- a/FoxTube/Controls/VideoPlayer.xaml +++ b/FoxTube/Controls/VideoPlayer.xaml @@ -13,8 +13,7 @@ RequestedTheme="Dark" PointerMoved="UserControl_PointerMoved" PointerExited="UserControl_PointerExited" - PointerEntered="UserControl_PointerEntered" - KeyUp="UserControl_KeyUp"> + PointerEntered="UserControl_PointerEntered"> diff --git a/FoxTube/Controls/VideoPlayer.xaml.cs b/FoxTube/Controls/VideoPlayer.xaml.cs index b769eb6..10916d8 100644 --- a/FoxTube/Controls/VideoPlayer.xaml.cs +++ b/FoxTube/Controls/VideoPlayer.xaml.cs @@ -93,6 +93,12 @@ namespace FoxTube volume.Value = Convert.ToDouble(settings.Values["volume"]); videoSource.AutoPlay = (bool)settings.Values["videoAutoplay"]; + videoSource.MediaEnded += (s, arg) => + { + seek.Value = seek.Maximum; + seekIndicator.Value = seekIndicator.Maximum; + seekTimer.Stop(); + }; t.Elapsed += T_Elapsed; seekTimer.Elapsed += SeekTimer_Elapsed; } @@ -445,6 +451,8 @@ namespace FoxTube play.IsEnabled = true; touchPlay.IsEnabled = true; + seekTimer.Start(); + play.Content = "\xE103"; touchPlay.Content = "\xE103"; @@ -671,7 +679,7 @@ namespace FoxTube play_Click(this, null); } - private void UserControl_KeyUp(object sender, KeyRoutedEventArgs e) + public void KeyUpPressed(object sender, KeyRoutedEventArgs e) { switch(e.Key) { diff --git a/FoxTube/Pages/MainPage.xaml b/FoxTube/Pages/MainPage.xaml index 1cec469..fdec779 100644 --- a/FoxTube/Pages/MainPage.xaml +++ b/FoxTube/Pages/MainPage.xaml @@ -9,7 +9,8 @@ xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls" xmlns:pages="using:FoxTube.Pages" mc:Ignorable="d" - SizeChanged="Page_SizeChanged"> + SizeChanged="Page_SizeChanged" + PreviewKeyUp="Page_PreviewKeyUp"> diff --git a/FoxTube/Pages/MainPage.xaml.cs b/FoxTube/Pages/MainPage.xaml.cs index 04d1c81..13d7e07 100644 --- a/FoxTube/Pages/MainPage.xaml.cs +++ b/FoxTube/Pages/MainPage.xaml.cs @@ -655,5 +655,14 @@ namespace FoxTube else content.GoBack(); } + + private void Page_PreviewKeyUp(object sender, KeyRoutedEventArgs e) + { + if(videoPlaceholder.Content != null) + { + e.Handled = true; + (videoPlaceholder.Content as VideoPage).player.KeyUpPressed(sender, e); + } + } } } diff --git a/FoxTube/Pages/VideoPage.xaml.cs b/FoxTube/Pages/VideoPage.xaml.cs index 80971e9..774d735 100644 --- a/FoxTube/Pages/VideoPage.xaml.cs +++ b/FoxTube/Pages/VideoPage.xaml.cs @@ -450,7 +450,7 @@ namespace FoxTube.Pages dislike.Foreground = new SolidColorBrush(Colors.Red); dislikes.Text = (int.Parse(dislikes.Text, System.Globalization.NumberStyles.AllowThousands) + 1).ToString("0,0"); - rating.Value = (int)((item.Statistics.LikeCount - 1) / (item.Statistics.DislikeCount + item.Statistics.LikeCount) * 100); + rating.Value--; await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.Dislike).ExecuteAsync(); userRating = Rating.Dislike; @@ -459,7 +459,7 @@ namespace FoxTube.Pages case Rating.None: dislike.Foreground = new SolidColorBrush(Colors.Red); dislikes.Text = (int.Parse(dislikes.Text, System.Globalization.NumberStyles.AllowThousands) + 1).ToString("0,0"); - rating.Value = (int)((item.Statistics.LikeCount) / (item.Statistics.DislikeCount + item.Statistics.LikeCount + 1) * 100); + rating.Maximum++; await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.Dislike).ExecuteAsync(); userRating = Rating.Dislike; @@ -468,7 +468,7 @@ namespace FoxTube.Pages case Rating.Dislike: dislike.Foreground = new SolidColorBrush(Colors.Gray); dislikes.Text = (int.Parse(dislikes.Text, System.Globalization.NumberStyles.AllowThousands) - 1).ToString("0,0"); - rating.Value = (int)((item.Statistics.LikeCount) / (item.Statistics.DislikeCount + item.Statistics.LikeCount - 1) * 100); + rating.Maximum--; await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.None).ExecuteAsync(); break; } @@ -485,7 +485,7 @@ namespace FoxTube.Pages like.Foreground = new SolidColorBrush(Colors.Green); likes.Text = (int.Parse(likes.Text, System.Globalization.NumberStyles.AllowThousands) + 1).ToString("0,0"); - rating.Value = (int)((item.Statistics.LikeCount + 1) / (item.Statistics.DislikeCount + item.Statistics.LikeCount) * 100); + rating.Value++; await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.Like).ExecuteAsync(); userRating = Rating.Like; @@ -494,7 +494,8 @@ namespace FoxTube.Pages case Rating.None: like.Foreground = new SolidColorBrush(Colors.Green); likes.Text = (int.Parse(likes.Text, System.Globalization.NumberStyles.AllowThousands) + 1).ToString("0,0"); - rating.Value = (int)((item.Statistics.LikeCount + 1) / (item.Statistics.DislikeCount + item.Statistics.LikeCount + 1) * 100); + rating.Maximum++; + rating.Value++; await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.Like).ExecuteAsync(); userRating = Rating.Like; @@ -503,7 +504,8 @@ namespace FoxTube.Pages case Rating.Like: like.Foreground = new SolidColorBrush(Colors.Gray); likes.Text = (int.Parse(likes.Text, System.Globalization.NumberStyles.AllowThousands) - 1).ToString("0,0"); - rating.Value = (int)((item.Statistics.LikeCount - 1) / (item.Statistics.DislikeCount + item.Statistics.LikeCount - 1) * 100); + rating.Maximum--; + rating.Value--; await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.None).ExecuteAsync(); break; } From 02862490b3dbd3c0fe50b321b01996aee9a7043a Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Fri, 14 Sep 2018 17:16:59 +0300 Subject: [PATCH 02/62] #173: Fixed --- FoxTube/Classes/ObjectEventArgs.cs | 1 - FoxTube/Pages/MainPage.xaml.cs | 12 ++++++++++-- FoxTube/Pages/Search.xaml | 1 - FoxTube/Pages/Search.xaml.cs | 10 ++++------ 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/FoxTube/Classes/ObjectEventArgs.cs b/FoxTube/Classes/ObjectEventArgs.cs index db18307..23cd9d0 100644 --- a/FoxTube/Classes/ObjectEventArgs.cs +++ b/FoxTube/Classes/ObjectEventArgs.cs @@ -121,7 +121,6 @@ namespace FoxTube public string Channel { get; private set; } public Filters Filter { get; private set; } = new Filters(); - public SearchParameters(string term) { Term = term; diff --git a/FoxTube/Pages/MainPage.xaml.cs b/FoxTube/Pages/MainPage.xaml.cs index 13d7e07..8b76f43 100644 --- a/FoxTube/Pages/MainPage.xaml.cs +++ b/FoxTube/Pages/MainPage.xaml.cs @@ -370,8 +370,16 @@ namespace FoxTube public void MinimizeAsInitializer() { - try { (videoPlaceholder.Content as VideoPage).player.minimize_Click(this, null); } - catch { } + if(videoPlaceholder.Content != null) + { + if ((videoPlaceholder.Content as VideoPage).loading.State != LoadingState.Loaded) + CloseVideo(); + else + { + try { (videoPlaceholder.Content as VideoPage).player.minimize_Click(this, null); } + catch { } + } + } } public void MinimizeVideo() diff --git a/FoxTube/Pages/Search.xaml b/FoxTube/Pages/Search.xaml index 0ed8d0e..888dd35 100644 --- a/FoxTube/Pages/Search.xaml +++ b/FoxTube/Pages/Search.xaml @@ -1,5 +1,4 @@  Date: Fri, 14 Sep 2018 17:44:15 +0300 Subject: [PATCH 03/62] #172: Fixed --- FoxTube/Controls/VideoPlayer.xaml.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/FoxTube/Controls/VideoPlayer.xaml.cs b/FoxTube/Controls/VideoPlayer.xaml.cs index 10916d8..8d608df 100644 --- a/FoxTube/Controls/VideoPlayer.xaml.cs +++ b/FoxTube/Controls/VideoPlayer.xaml.cs @@ -52,6 +52,7 @@ namespace FoxTube public event ObjectEventHandler NextClicked; CoreCursor cursorBackup = Window.Current.CoreWindow.PointerCursor; + Point cursorPositionBackup; public TimeSpan elapsed; TimeSpan remaining; @@ -246,7 +247,10 @@ namespace FoxTube if (!miniView) touchCentral.Visibility = Visibility.Collapsed; if (pointerCaptured) + { + cursorPositionBackup = Window.Current.CoreWindow.PointerPosition; Window.Current.CoreWindow.PointerCursor = null; + } seekIndicator.Visibility = Visibility.Collapsed; t.Stop(); } @@ -304,6 +308,10 @@ namespace FoxTube private void UserControl_PointerMoved(object sender, PointerRoutedEventArgs e) { + if (cursorPositionBackup == null) + cursorPositionBackup = Window.Current.CoreWindow.PointerPosition; + else if (cursorPositionBackup == Window.Current.CoreWindow.PointerPosition) + return; ShowControls(); } From 35ddf4a0120aeb6a8982098fd14df762e5a4b403 Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Fri, 14 Sep 2018 18:10:54 +0300 Subject: [PATCH 04/62] #176: Done --- FoxTube/Controls/LiveCaptions.xaml.cs | 47 +++++++++++++++++---------- FoxTube/Controls/VideoPlayer.xaml.cs | 38 ++++++++++++++-------- FoxTube/Pages/MainPage.xaml.cs | 2 +- FoxTube/Pages/Search.xaml.cs | 6 ++-- 4 files changed, 59 insertions(+), 34 deletions(-) diff --git a/FoxTube/Controls/LiveCaptions.xaml.cs b/FoxTube/Controls/LiveCaptions.xaml.cs index 7231128..8bbd12b 100644 --- a/FoxTube/Controls/LiveCaptions.xaml.cs +++ b/FoxTube/Controls/LiveCaptions.xaml.cs @@ -23,6 +23,7 @@ namespace FoxTube.Controls public sealed partial class LiveCaptions : UserControl { public MediaElement Player { get; set; } + private bool isClosed = false; DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(10) }; List captions = new List(); Caption currentCaption = null; @@ -38,16 +39,17 @@ namespace FoxTube.Controls TimeSpan currentPosition = Player.Position; bool found = false; - captions.ForEach((x) => - { - if (Player.Position >= x.Start && Player.Position <= x.End) + if(!isClosed) + captions.ForEach((x) => { - currentCaption = x; - text.Text = currentCaption.Text; - Visibility = Visibility.Visible; - found = true; - } - }); + if (Player.Position >= x.Start && Player.Position <= x.End) + { + currentCaption = x; + text.Text = currentCaption.Text; + Visibility = Visibility.Visible; + found = true; + } + }); if (!found) { @@ -64,15 +66,16 @@ namespace FoxTube.Controls foreach (XmlElement i in doc["timedtext"]["body"].ChildNodes) captions.Add(new Caption(int.Parse(i.GetAttribute("t")), int.Parse(i.GetAttribute("d")), i.InnerText)); - captions.ForEach((x) => - { - if(Player.Position > x.Start && Player.Position < x.End) + if(!isClosed) + captions.ForEach((x) => { - currentCaption = x; - text.Text = currentCaption.Text; - Visibility = Visibility.Visible; - } - }); + if(Player.Position > x.Start && Player.Position < x.End) + { + currentCaption = x; + text.Text = currentCaption.Text; + Visibility = Visibility.Visible; + } + }); timer.Start(); } @@ -84,5 +87,15 @@ namespace FoxTube.Controls Visibility = Visibility.Collapsed; timer.Stop(); } + + public void Hide() + { + isClosed = true; + } + + public void Show() + { + isClosed = false; + } } } diff --git a/FoxTube/Controls/VideoPlayer.xaml.cs b/FoxTube/Controls/VideoPlayer.xaml.cs index 8d608df..7d50ab6 100644 --- a/FoxTube/Controls/VideoPlayer.xaml.cs +++ b/FoxTube/Controls/VideoPlayer.xaml.cs @@ -44,7 +44,19 @@ namespace FoxTube { public string videoId; - public bool miniView = false; + private bool miniview = false; + public bool MiniView + { + get { return miniview; } + set + { + miniview = value; + if (value) + captions.Hide(); + else + captions.Show(); + } + } private bool fullScreen = false; public bool pointerCaptured = false; @@ -244,7 +256,7 @@ namespace FoxTube void Elapsed() { controls.Visibility = Visibility.Collapsed; - if (!miniView) + if (!MiniView) touchCentral.Visibility = Visibility.Collapsed; if (pointerCaptured) { @@ -257,7 +269,7 @@ namespace FoxTube public void UpdateSize() { - if(miniView) + if(MiniView) { Height = Window.Current.Bounds.Height; Debug.WriteLine("Video player aspect ratio has been corrected."); @@ -318,7 +330,7 @@ namespace FoxTube void ShowControls() { controls.Visibility = Visibility.Visible; - if (miniView) + if (MiniView) seekIndicator.Visibility = Visibility.Visible; if (pointerCaptured) Window.Current.CoreWindow.PointerCursor = cursorBackup; @@ -477,10 +489,10 @@ namespace FoxTube private async void miniView_Click(object sender, RoutedEventArgs e) { ApplicationViewTitleBar titleBar = ApplicationView.GetForCurrentView().TitleBar; - miniView = !miniView; - SetFullSize(this, miniView); + MiniView = !MiniView; + SetFullSize(this, MiniView); - if (miniView) + if (MiniView) { if (fullScreen) { @@ -606,7 +618,7 @@ namespace FoxTube Width = 432; Height = 243; - miniView = true; + MiniView = true; Methods.MainPage.MinimizeVideo(); mainControls.Visibility = Visibility.Collapsed; @@ -633,7 +645,7 @@ namespace FoxTube Width = double.NaN; Height = double.NaN; - miniView = false; + MiniView = false; Methods.MainPage.MaximizeVideo(); mainControls.Visibility = Visibility.Visible; @@ -671,19 +683,19 @@ namespace FoxTube private void playPauseArea_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e) { - if (miniView && ApplicationView.GetForCurrentView().ViewMode == ApplicationViewMode.CompactOverlay) + if (MiniView && ApplicationView.GetForCurrentView().ViewMode == ApplicationViewMode.CompactOverlay) miniView_Click(this, null); - else if (miniView && ApplicationView.GetForCurrentView().ViewMode == ApplicationViewMode.Default) + else if (MiniView && ApplicationView.GetForCurrentView().ViewMode == ApplicationViewMode.Default) maximize_Click(this, null); else if (fullScreen) fullscreen_Click(this, null); - else if (!miniView && !fullScreen) + else if (!MiniView && !fullScreen) fullscreen_Click(this, null); } private void playPauseArea_Tapped(object sender, TappedRoutedEventArgs e) { - if (e.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse && !miniView) + if (e.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse && !MiniView) play_Click(this, null); } diff --git a/FoxTube/Pages/MainPage.xaml.cs b/FoxTube/Pages/MainPage.xaml.cs index 8b76f43..8a2c539 100644 --- a/FoxTube/Pages/MainPage.xaml.cs +++ b/FoxTube/Pages/MainPage.xaml.cs @@ -413,7 +413,7 @@ namespace FoxTube { nav.OpenPaneLength = 0; nav.CompactPaneLength = 0; - if ((videoPlaceholder.Content as VideoPage).player.miniView) + if ((videoPlaceholder.Content as VideoPage).player.MiniView) nav.Margin = new Thickness(0, -80, 0, 0); else nav.Margin = new Thickness(0, -91, 0, 0); diff --git a/FoxTube/Pages/Search.xaml.cs b/FoxTube/Pages/Search.xaml.cs index 6ec6459..0fe757c 100644 --- a/FoxTube/Pages/Search.xaml.cs +++ b/FoxTube/Pages/Search.xaml.cs @@ -96,7 +96,7 @@ namespace FoxTube { loading.Refresh(); - //try + try { Parameters = arg; request = SecretsVault.Service.Search.List("id,snippet"); @@ -159,14 +159,14 @@ namespace FoxTube loading.Close(); } - /*catch (System.Net.Http.HttpRequestException) + 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); - }*/ + } } private void toggleFilters_Click(object sender, RoutedEventArgs e) From 9e0f2d89e7148c0538797c5b0ed81ed8e96cb7e6 Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Fri, 14 Sep 2018 19:24:46 +0300 Subject: [PATCH 05/62] #181: Fixed --- FoxTube/Classes/Caption.cs | 7 +++++++ FoxTube/Controls/LiveCaptions.xaml.cs | 27 +++++++++++++++------------ FoxTube/Controls/VideoPlayer.xaml.cs | 23 ++++++++++++++--------- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/FoxTube/Classes/Caption.cs b/FoxTube/Classes/Caption.cs index 14567bc..f971aa1 100644 --- a/FoxTube/Classes/Caption.cs +++ b/FoxTube/Classes/Caption.cs @@ -22,5 +22,12 @@ namespace FoxTube.Classes Duration = TimeSpan.FromMilliseconds(duration); Text = text; } + + public Caption(double startTime, double duration, string text) + { + Start = TimeSpan.FromSeconds(startTime); + Duration = TimeSpan.FromSeconds(duration); + Text = text; + } } } diff --git a/FoxTube/Controls/LiveCaptions.xaml.cs b/FoxTube/Controls/LiveCaptions.xaml.cs index 8bbd12b..2d21e8d 100644 --- a/FoxTube/Controls/LiveCaptions.xaml.cs +++ b/FoxTube/Controls/LiveCaptions.xaml.cs @@ -58,24 +58,27 @@ namespace FoxTube.Controls } } - public void Initialize(string source) + public void Initialize(string source, bool isAutoGenerated = false) { XmlDocument doc = new XmlDocument(); doc.Load(source); - foreach (XmlElement i in doc["timedtext"]["body"].ChildNodes) - captions.Add(new Caption(int.Parse(i.GetAttribute("t")), int.Parse(i.GetAttribute("d")), i.InnerText)); + if (!isAutoGenerated) + foreach (XmlElement i in doc["timedtext"]["body"].ChildNodes) + captions.Add(new Caption(int.Parse(i.GetAttribute("t")), int.Parse(i.GetAttribute("d")), i.InnerText)); + else + foreach (XmlElement i in doc["transcript"].ChildNodes) + captions.Add(new Caption(double.Parse(i.GetAttribute("start")), double.Parse(i.GetAttribute("dur")), i.InnerText.Replace("", "").Replace("", "").Replace("", "").Replace("'", "'"))); - if(!isClosed) - captions.ForEach((x) => + captions.ForEach((x) => + { + if (Player.Position > x.Start && Player.Position < x.End) { - if(Player.Position > x.Start && Player.Position < x.End) - { - currentCaption = x; - text.Text = currentCaption.Text; - Visibility = Visibility.Visible; - } - }); + currentCaption = x; + text.Text = currentCaption.Text; + Visibility = Visibility.Visible; + } + }); timer.Start(); } diff --git a/FoxTube/Controls/VideoPlayer.xaml.cs b/FoxTube/Controls/VideoPlayer.xaml.cs index 7d50ab6..f003749 100644 --- a/FoxTube/Controls/VideoPlayer.xaml.cs +++ b/FoxTube/Controls/VideoPlayer.xaml.cs @@ -30,11 +30,13 @@ using Windows.ApplicationModel.Core; using Windows.UI; using Windows.Graphics.Display; using Windows.Media.Casting; +using MyToolkit.Multimedia; using YoutubeExplode.Models.MediaStreams; using YoutubeExplode; using YoutubeExplode.Models.ClosedCaptions; using System.Globalization; using FoxTube.Controls; +using Windows.System; // The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 @@ -152,11 +154,13 @@ namespace FoxTube //Loading captions ccInfo = await client.GetVideoClosedCaptionTrackInfosAsync(item.Id); foreach (ClosedCaptionTrackInfo cc in ccInfo) + { subsLang.Items.Add(new ComboBoxItem() { - Content = string.Format("{1}{0}", CultureInfo.GetCultureInfo(cc.Language.Code).DisplayName, cc.IsAutoGenerated ? " (Auto-generated)" : ""), + Content = string.Format("{0}{1}", CultureInfo.GetCultureInfo(cc.Language.Code).DisplayName, cc.IsAutoGenerated ? " (Auto-generated)" : ""), Tag = cc }); + } if(ccInfo.Count > 0) subsLang.SelectedIndex = 0; else @@ -393,8 +397,10 @@ namespace FoxTube { if (subsSwitch.IsOn) { - - captions.Initialize(ccInfo[subsLang.SelectedIndex].Url); + if (ccInfo[subsLang.SelectedIndex].IsAutoGenerated) + captions.Initialize(ccInfo[subsLang.SelectedIndex].Url.Replace("format=3", "format=0"), true); + else + captions.Initialize(ccInfo[subsLang.SelectedIndex].Url); } else captions.Close(); @@ -703,15 +709,15 @@ namespace FoxTube { switch(e.Key) { - case Windows.System.VirtualKey.Escape: - case Windows.System.VirtualKey.F11: + case VirtualKey.Escape: + case VirtualKey.F11: if (fullScreen) fullscreen_Click(this, null); break; - case Windows.System.VirtualKey.Space: + case VirtualKey.Space: play_Click(this, null); break; - case Windows.System.VirtualKey.Left: + case VirtualKey.Left: back10_Click(this, null); break; case Windows.System.VirtualKey.Right: @@ -722,8 +728,7 @@ namespace FoxTube private void subsLang_SelectionChanged(object sender, SelectionChangedEventArgs e) { - if (subsSwitch.IsOn) - captions.Initialize(ccInfo[subsLang.SelectedIndex].Url); + LoadTrack(); } } } From 10a6f028c02f2aa4212b20d76da6d4bcdd009feb Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Sat, 15 Sep 2018 21:23:30 +0300 Subject: [PATCH 06/62] #157/178: Done --- FoxTube/Controls/VideoPlayer.xaml | 3 +- FoxTube/Controls/VideoPlayer.xaml.cs | 160 +++++++++++++++++++++++---- FoxTube/Pages/MainPage.xaml | 3 +- 3 files changed, 140 insertions(+), 26 deletions(-) diff --git a/FoxTube/Controls/VideoPlayer.xaml b/FoxTube/Controls/VideoPlayer.xaml index 7a15539..9dced1b 100644 --- a/FoxTube/Controls/VideoPlayer.xaml +++ b/FoxTube/Controls/VideoPlayer.xaml @@ -16,7 +16,8 @@ PointerEntered="UserControl_PointerEntered"> - + + diff --git a/FoxTube/Controls/VideoPlayer.xaml.cs b/FoxTube/Controls/VideoPlayer.xaml.cs index f003749..bd98229 100644 --- a/FoxTube/Controls/VideoPlayer.xaml.cs +++ b/FoxTube/Controls/VideoPlayer.xaml.cs @@ -37,14 +37,19 @@ using YoutubeExplode.Models.ClosedCaptions; using System.Globalization; using FoxTube.Controls; using Windows.System; +using Windows.Devices.Sensors; +using Windows.System.Profile; // The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 namespace FoxTube { + public enum DeviceType { Other, Desktop, Mobile } + public sealed partial class VideoPlayer : UserControl { public string videoId; + private DeviceType deviceType = DeviceType.Other; private bool miniview = false; public bool MiniView @@ -80,9 +85,8 @@ namespace FoxTube SystemMediaTransportControls systemControls = SystemMediaTransportControls.GetForCurrentView(); LiveCaptions captions; - YoutubeClient client = new YoutubeClient(); IReadOnlyList ccInfo; - MediaStreamInfoSet streamInfo; + List streamInfo; ApplicationDataContainer settings = ApplicationData.Current.LocalSettings; Timer t = new Timer() @@ -101,9 +105,24 @@ namespace FoxTube this.InitializeComponent(); Visibility = Visibility.Collapsed; if (!ApplicationView.GetForCurrentView().IsViewModeSupported(ApplicationViewMode.CompactOverlay)) - miniViewBtn.Visibility = Visibility.Collapsed;; + miniViewBtn.Visibility = Visibility.Collapsed; - captions = grid.Children[1] as LiveCaptions; + switch(AnalyticsInfo.VersionInfo.DeviceFamily) + { + case "Windows.Mobile": + deviceType = DeviceType.Mobile; + break; + + case "Windows.Desktop": + deviceType = DeviceType.Desktop; + break; + + default: + deviceType = DeviceType.Other; + break; + } + + captions = grid.Children[2] as LiveCaptions; volume.Value = Convert.ToDouble(settings.Values["volume"]); videoSource.AutoPlay = (bool)settings.Values["videoAutoplay"]; @@ -114,8 +133,21 @@ namespace FoxTube seekIndicator.Value = seekIndicator.Maximum; seekTimer.Stop(); }; + audioSource.CurrentStateChanged += AudioSource_CurrentStateChanged; t.Elapsed += T_Elapsed; seekTimer.Elapsed += SeekTimer_Elapsed; + + if(SimpleOrientationSensor.GetDefault() != null && deviceType == DeviceType.Mobile) + { + if (SimpleOrientationSensor.GetDefault().GetCurrentOrientation() == SimpleOrientation.Rotated270DegreesCounterclockwise || SimpleOrientationSensor.GetDefault().GetCurrentOrientation() == SimpleOrientation.Rotated90DegreesCounterclockwise) + fullscreen_Click(this, null); + SimpleOrientationSensor.GetDefault().OrientationChanged += (s, arg) => + { + if (((SimpleOrientationSensor.GetDefault().GetCurrentOrientation() == SimpleOrientation.NotRotated || SimpleOrientationSensor.GetDefault().GetCurrentOrientation() == SimpleOrientation.Rotated180DegreesCounterclockwise) && fullScreen) || + ((SimpleOrientationSensor.GetDefault().GetCurrentOrientation() == SimpleOrientation.Rotated270DegreesCounterclockwise || SimpleOrientationSensor.GetDefault().GetCurrentOrientation() == SimpleOrientation.Rotated90DegreesCounterclockwise) && !fullScreen)) + fullscreen_Click(this, null); + }; + } } public async void Initialize(Video meta, string channelAvatar) @@ -126,22 +158,23 @@ namespace FoxTube #region Retrieving info for CC and Media streams //Loading streams - streamInfo = await client.GetVideoMediaStreamInfosAsync(item.Id); - foreach(MuxedStreamInfo i in streamInfo.Muxed) + streamInfo = (await YouTube.GetUrisAsync(item.Id)).ToList(); + streamInfo.ForEach(x => Debug.WriteLine(x)); + foreach (YouTubeUri i in streamInfo) { - if (i.VideoQuality == VideoQuality.High2160) + if (i.VideoQuality == YouTubeQuality.Quality2160P) (quality.Items[0] as ComboBoxItem).Visibility = Visibility.Visible; - if (i.VideoQuality == VideoQuality.High1080) + if (i.VideoQuality == YouTubeQuality.Quality1080P) (quality.Items[1] as ComboBoxItem).Visibility = Visibility.Visible; - if (i.VideoQuality == VideoQuality.High720) + if (i.VideoQuality == YouTubeQuality.Quality720P) (quality.Items[2] as ComboBoxItem).Visibility = Visibility.Visible; - if (i.VideoQuality == VideoQuality.Medium480) + if (i.VideoQuality == YouTubeQuality.Quality480P) (quality.Items[3] as ComboBoxItem).Visibility = Visibility.Visible; - if (i.VideoQuality == VideoQuality.Medium360) + if (i.VideoQuality == YouTubeQuality.Quality360P) (quality.Items[4] as ComboBoxItem).Visibility = Visibility.Visible; - if (i.VideoQuality == VideoQuality.Low240) + if (i.VideoQuality == YouTubeQuality.Quality240P) (quality.Items[5] as ComboBoxItem).Visibility = Visibility.Visible; - if (i.VideoQuality == VideoQuality.Low144) + if (i.VideoQuality == YouTubeQuality.Quality144P) (quality.Items[6] as ComboBoxItem).Visibility = Visibility.Visible; } @@ -152,7 +185,7 @@ namespace FoxTube quality.SelectedItem = quality.Items.First(x => (x as ComboBoxItem).Visibility == Visibility.Visible); //Loading captions - ccInfo = await client.GetVideoClosedCaptionTrackInfosAsync(item.Id); + ccInfo = await new YoutubeClient().GetVideoClosedCaptionTrackInfosAsync(item.Id); foreach (ClosedCaptionTrackInfo cc in ccInfo) { subsLang.Items.Add(new ComboBoxItem() @@ -255,6 +288,11 @@ namespace FoxTube { seek.Value = videoSource.Position.TotalSeconds; seekIndicator.Value = seek.Value; + if (Math.Round(videoSource.Position.TotalSeconds, 1) != Math.Round(audioSource.Position.TotalSeconds, 1)) + { + Debug.WriteLine($"Correcting tracks synchronization (Video track position: {videoSource.Position}; Audio track position: {audioSource.Position})"); + audioSource.Position = videoSource.Position; + } } void Elapsed() @@ -296,7 +334,7 @@ namespace FoxTube settings.Values["volume"] = volume.Value; - videoSource.Volume = volume.Value * 0.01; + audioSource.Volume = volume.Value * 0.01; } private void muteBtn_Click(object sender, RoutedEventArgs e) @@ -344,7 +382,7 @@ namespace FoxTube private void quality_SelectionChanged(object sender, SelectionChangedEventArgs e) { - try + //try { videoSource.Pause(); timecodeBackup = videoSource.Position.TotalSeconds; @@ -352,32 +390,74 @@ namespace FoxTube switch((quality.SelectedItem as ComboBoxItem).Content) { case "2160p": - videoSource.Source = new Uri(streamInfo.Muxed.First(x => x.VideoQuality == VideoQuality.High2160).Url); + videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality2160P).Uri; + try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityHigh).Uri; } + catch + { + try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityMedium).Uri; } + catch { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityLow).Uri; } + } break; case "1080p": - videoSource.Source = new Uri(streamInfo.Muxed.First(x => x.VideoQuality == VideoQuality.High1080).Url); + videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality1080P).Uri; + try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityHigh).Uri; } + catch + { + try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityMedium).Uri; } + catch { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityLow).Uri; } + } break; case "720p": - videoSource.Source = new Uri(streamInfo.Muxed.First(x => x.VideoQuality == VideoQuality.High720).Url); + videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality720P).Uri; + try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityHigh).Uri; } + catch + { + try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityMedium).Uri; } + catch { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityLow).Uri; } + } break; case "480p": - videoSource.Source = new Uri(streamInfo.Muxed.First(x => x.VideoQuality == VideoQuality.Medium480).Url); + videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality480P).Uri; + try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityMedium).Uri; } + catch + { + try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityHigh).Uri; } + catch { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityLow).Uri; } + } break; case "360p": - videoSource.Source = new Uri(streamInfo.Muxed.First(x => x.VideoQuality == VideoQuality.Medium360).Url); + videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality360P).Uri; + try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityMedium).Uri; } + catch + { + try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityHigh).Uri; } + catch { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityLow).Uri; } + } break; case "240p": - videoSource.Source = new Uri(streamInfo.Muxed.First(x => x.VideoQuality == VideoQuality.Low240).Url); + videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality240P).Uri; + try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityLow).Uri; } + catch + { + try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityMedium).Uri; } + catch { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityHigh).Uri; } + } break; case "144p": - videoSource.Source = new Uri(streamInfo.Muxed.First(x => x.VideoQuality == VideoQuality.Low144).Url); + videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality144P).Uri; + try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityLow).Uri; } + catch + { + try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityMedium).Uri; } + catch { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityHigh).Uri; } + } break; } needUpdateTimecode = true; videoSource.Play(); } - catch + //catch { } @@ -417,12 +497,18 @@ namespace FoxTube ApplicationView.GetForCurrentView().TryEnterFullScreenMode(); fullscreen.Content = "\xE1D8"; Height = Methods.MainPage.Height; + + if (deviceType == DeviceType.Mobile) + DisplayInformation.AutoRotationPreferences = DisplayOrientations.Landscape; } else { ApplicationView.GetForCurrentView().ExitFullScreenMode(); fullscreen.Content = "\xE1D9"; Height = double.NaN; + + if (deviceType == DeviceType.Mobile) + DisplayInformation.AutoRotationPreferences = DisplayOrientations.Portrait; } } @@ -434,6 +520,21 @@ namespace FoxTube videoSource.Play(); } + private void AudioSource_CurrentStateChanged(object sender, RoutedEventArgs e) + { + switch (audioSource.CurrentState) + { + case MediaElementState.Buffering: + videoSource.Pause(); + break; + + case MediaElementState.Playing: + if(videoSource.CurrentState == MediaElementState.Paused) + videoSource.Play(); + break; + } + } + private void videoSource_CurrentStateChanged(object sender, RoutedEventArgs e) { if(videoSource.CurrentState == MediaElementState.Playing && needUpdateTimecode) @@ -445,6 +546,7 @@ namespace FoxTube switch(videoSource.CurrentState) { case MediaElementState.Buffering: + audioSource.Pause(); bufferingBar.Visibility = Visibility.Visible; seek.IsEnabled = false; @@ -458,6 +560,8 @@ namespace FoxTube break; case MediaElementState.Paused: + if(audioSource.CurrentState != MediaElementState.Buffering) + audioSource.Pause(); bufferingBar.Visibility = Visibility.Collapsed; seek.IsEnabled = true; @@ -471,6 +575,7 @@ namespace FoxTube break; case MediaElementState.Playing: + audioSource.Play(); bufferingBar.Visibility = Visibility.Collapsed; seek.IsEnabled = true; @@ -482,10 +587,17 @@ namespace FoxTube play.Content = "\xE103"; touchPlay.Content = "\xE103"; + if (Math.Round(videoSource.Position.TotalSeconds, 1) != Math.Round(audioSource.Position.TotalSeconds, 1)) + { + Debug.WriteLine($"Correcting tracks synchronization (Video track position: {videoSource.Position}; Audio track position: {audioSource.Position})"); + audioSource.Position = videoSource.Position; + } + systemControls.PlaybackStatus = MediaPlaybackStatus.Playing; break; default: + audioSource.Pause(); bufferingBar.Visibility = Visibility.Collapsed; systemControls.PlaybackStatus = MediaPlaybackStatus.Closed; break; diff --git a/FoxTube/Pages/MainPage.xaml b/FoxTube/Pages/MainPage.xaml index fdec779..8a69bb3 100644 --- a/FoxTube/Pages/MainPage.xaml +++ b/FoxTube/Pages/MainPage.xaml @@ -8,6 +8,7 @@ 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" PreviewKeyUp="Page_PreviewKeyUp"> @@ -26,7 +27,7 @@ - + From 8bb0a0e11b4627fb14373e1f085b054c8577b17a Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Sat, 22 Sep 2018 23:07:10 +0300 Subject: [PATCH 07/62] #144: Fixed --- FoxTube/Classes/Methods.cs | 1 + FoxTube/Pages/ChannelPage.xaml.cs | 6 +-- FoxTube/Pages/MainPage.xaml.cs | 70 ++++++++++++++++++------------ FoxTube/Pages/PlaylistPage.xaml.cs | 3 ++ 4 files changed, 50 insertions(+), 30 deletions(-) diff --git a/FoxTube/Classes/Methods.cs b/FoxTube/Classes/Methods.cs index 2913870..f201fb6 100644 --- a/FoxTube/Classes/Methods.cs +++ b/FoxTube/Classes/Methods.cs @@ -14,6 +14,7 @@ namespace FoxTube { public static class Methods { + public static bool NeedToResponse { get; set; } = false; public static MainPage MainPage { get { return (Window.Current.Content as Frame).Content as MainPage; } diff --git a/FoxTube/Pages/ChannelPage.xaml.cs b/FoxTube/Pages/ChannelPage.xaml.cs index a419167..4b6d70a 100644 --- a/FoxTube/Pages/ChannelPage.xaml.cs +++ b/FoxTube/Pages/ChannelPage.xaml.cs @@ -86,6 +86,9 @@ namespace FoxTube.Pages try { channelId = id; + if (Methods.NeedToResponse) + Methods.MainPage.content_Navigated(this, null); + ChannelsResource.ListRequest request = SecretsVault.Service.Channels.List("snippet,statistics,brandingSettings"); request.Id = id; if (content.Items.Count == 4) @@ -133,8 +136,6 @@ namespace FoxTube.Pages if (SecretsVault.IsAuthorized) { - SecretsVault.Subscriptions.ForEach(x => Debug.WriteLine($"{x.Snippet.Title}: {x.Snippet.ResourceId.ChannelId}")); - Debug.WriteLine($"Current channel ID: {item.Id}"); bool b = false; foreach (Subscription s in SecretsVault.Subscriptions) { @@ -148,7 +149,6 @@ namespace FoxTube.Pages break; } } - Debug.WriteLine($"Channel was found: {b}"); subscriptionPane.Visibility = Visibility.Visible; } diff --git a/FoxTube/Pages/MainPage.xaml.cs b/FoxTube/Pages/MainPage.xaml.cs index 8a2c539..541de69 100644 --- a/FoxTube/Pages/MainPage.xaml.cs +++ b/FoxTube/Pages/MainPage.xaml.cs @@ -502,7 +502,7 @@ namespace FoxTube s = Sender.None; } - private void content_Navigated(object sender, NavigationEventArgs e) + public void content_Navigated(object sender, NavigationEventArgs e) { Dictionary switchCase = new Dictionary() { @@ -535,38 +535,54 @@ namespace FoxTube } }, { typeof(ChannelPage), () => { - if(SecretsVault.IsAuthorized) + if(sender.GetType() != typeof(ChannelPage)) { - if((content.Content as ChannelPage).channelId == SecretsVault.AccountId) + Methods.NeedToResponse = true; + s = Sender.None; + return; + } + Methods.NeedToResponse = false; + if(SecretsVault.IsAuthorized) { - if(nav.SelectedItem != toChannel) - nav.SelectedItem = toChannel; + if((content.Content as ChannelPage).channelId == SecretsVault.UserChannel.Id) + { + if(nav.SelectedItem != toChannel) + nav.SelectedItem = toChannel; + else + s = Sender.None; + } else - s = Sender.None; + { + bool found = false; + for(int k = 0; k < SecretsVault.Subscriptions.Count && k < 10; k++) + if(SecretsVault.Subscriptions[k].Snippet.ResourceId.ChannelId == (content.Content as ChannelPage).channelId) + { + if(nav.SelectedItem != nav.MenuItems[k + 9]) + nav.SelectedItem = nav.MenuItems[k + 9]; + else + s = Sender.None; + found = true; + break; + } + + if(!found) + { + nav.SelectedItem = null; + } + } } else - { - bool found = false; - for(int k = 0; k < SecretsVault.Subscriptions.Count && k < 10; k++) - if(SecretsVault.Subscriptions[k].Snippet.ResourceId.ChannelId == (content.Content as ChannelPage).channelId) - { - if(nav.SelectedItem != nav.MenuItems[k + 9]) - nav.SelectedItem = nav.MenuItems[k + 9]; - else - s = Sender.None; - found = true; - break; - } - - if(!found) - nav.SelectedItem = null; - } - } - else - nav.SelectedItem = null; + nav.SelectedItem = null; } }, { typeof(PlaylistPage), () => { + if(sender.GetType() != typeof(PlaylistPage)) + { + Methods.NeedToResponse = true; + s = Sender.None; + return; + } + Methods.NeedToResponse = false; if((content.Content as PlaylistPage).playlistId == SecretsVault.UserChannel.ContentDetails.RelatedPlaylists.Likes) { if(nav.SelectedItem != toLiked) @@ -617,7 +633,7 @@ namespace FoxTube } } }; - try { navCase[e.SourcePageType](); } + try { navCase[content.SourcePageType](); } catch { nav.SelectedItem = null; @@ -631,7 +647,7 @@ namespace FoxTube else nav.IsBackEnabled = false; - if (e.SourcePageType == typeof(Home) || e.SourcePageType == typeof(Settings) || e.SourcePageType == typeof(Subscriptions)) + if (content.SourcePageType == typeof(Home) || content.SourcePageType == typeof(Settings) || content.SourcePageType == typeof(Subscriptions)) { nav.ExpandedModeThresholdWidth = 1008; if (nav.DisplayMode == NavigationViewDisplayMode.Expanded) diff --git a/FoxTube/Pages/PlaylistPage.xaml.cs b/FoxTube/Pages/PlaylistPage.xaml.cs index e9e86f1..3b815e1 100644 --- a/FoxTube/Pages/PlaylistPage.xaml.cs +++ b/FoxTube/Pages/PlaylistPage.xaml.cs @@ -62,6 +62,9 @@ namespace FoxTube.Pages try { playlistId = id; + if (Methods.NeedToResponse) + Methods.MainPage.content_Navigated(this, null); + PlaylistsResource.ListRequest request = SecretsVault.Service.Playlists.List("snippet,contentDetails"); request.Id = id; From 559b776756a22b24cf1c04496af84492d887020a Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Sun, 23 Sep 2018 20:39:25 +0300 Subject: [PATCH 08/62] #142: Fixed --- FoxTube/Controls/CommentCard.xaml | 6 +- FoxTube/Controls/CommentCard.xaml.cs | 83 +++++++++++++--------------- 2 files changed, 40 insertions(+), 49 deletions(-) diff --git a/FoxTube/Controls/CommentCard.xaml b/FoxTube/Controls/CommentCard.xaml index 65d47ae..c1934c1 100644 --- a/FoxTube/Controls/CommentCard.xaml +++ b/FoxTube/Controls/CommentCard.xaml @@ -77,6 +77,7 @@ + @@ -91,9 +92,6 @@ Content="" /> - - - - + diff --git a/FoxTube/Controls/CommentCard.xaml.cs b/FoxTube/Controls/CommentCard.xaml.cs index 8affa9c..c5b15a1 100644 --- a/FoxTube/Controls/CommentCard.xaml.cs +++ b/FoxTube/Controls/CommentCard.xaml.cs @@ -26,21 +26,18 @@ namespace FoxTube.Controls public enum CommentType { TopLevel, Reply } public sealed partial class CommentCard : UserControl { - ShowMore more; - Comment item; CommentThread thread; + bool repliesLoaded = false; CommentType type = CommentType.TopLevel; - string NextPageToken; public CommentCard(CommentThread comment) { this.InitializeComponent(); - more = repliesPlaceholder.Children[1] as ShowMore; Initialize(comment); } - public async void Initialize(CommentThread comment) + public void Initialize(CommentThread comment) { item = comment.Snippet.TopLevelComment; thread = comment; @@ -67,24 +64,6 @@ namespace FoxTube.Controls try { avatar.ProfilePicture = new BitmapImage(new Uri(comment.Snippet.TopLevelComment.Snippet.AuthorProfileImageUrl)); } catch { } - - if(comment.Snippet.TotalReplyCount > 0) - { - var request = SecretsVault.Service.Comments.List("snippet"); - request.ParentId = item.Id; - request.TextFormat = CommentsResource.ListRequest.TextFormatEnum.PlainText; - request.MaxResults = 10; - - var response = await request.ExecuteAsync(); - - if (response.NextPageToken != null) - NextPageToken = response.NextPageToken; - else - more.Visibility = Visibility.Collapsed; - - foreach (Comment c in response.Items.Reverse()) - replies.Children.Add(new CommentCard(c)); - } } public CommentCard(Comment comment) @@ -125,10 +104,45 @@ namespace FoxTube.Controls grid.RowDefinitions[1].Height = new GridLength(0); } - private void showReplies_Click(object sender, RoutedEventArgs e) + private async void showReplies_Click(object sender, RoutedEventArgs e) { if (grid.RowDefinitions[2].Height == new GridLength(0)) + { + if(type == CommentType.TopLevel && !repliesLoaded) + { + commentsLoading.Visibility = Visibility.Visible; + var request = SecretsVault.Service.Comments.List("snippet"); + request.ParentId = item.Id; + request.TextFormat = CommentsResource.ListRequest.TextFormatEnum.PlainText; + request.MaxResults = 50; + + string token; + IList list = new List(); + + var response = await request.ExecuteAsync(); + token = response.NextPageToken; + + foreach (Comment i in response.Items) + list.Add(i); + + while(token != null) + { + request.PageToken = token; + response = await request.ExecuteAsync(); + token = response.NextPageToken; + + foreach (Comment i in response.Items) + list.Add(i); + } + + foreach (Comment c in list.Reverse()) + replies.Children.Add(new CommentCard(c)); + + repliesLoaded = true; + commentsLoading.Visibility = Visibility.Collapsed; + } grid.RowDefinitions[2].Height = GridLength.Auto; + } else grid.RowDefinitions[2].Height = new GridLength(0); } @@ -138,27 +152,6 @@ namespace FoxTube.Controls Methods.MainPage.GoToChannel(item.Snippet.AuthorChannelId.ToString().Split('"')[3]); } - private async void more_Click() - { - var request = SecretsVault.NoAuthService.Comments.List("snippet"); - request.ParentId = item.Id; - request.MaxResults = 10; - request.PageToken = NextPageToken; - request.TextFormat = CommentsResource.ListRequest.TextFormatEnum.PlainText; - var response = await request.ExecuteAsync(); - - foreach (Comment c in response.Items.Reverse()) - replies.Children.Add(new CommentCard(c)); - - if (response.NextPageToken != null) - { - NextPageToken = response.NextPageToken; - more.Complete(); - } - else - more.Complete(true); - } - private void reply_TextChanged(object sender, TextChangedEventArgs e) { if (reply.Text.Length == 0) From 861631d0bd02a989425343693625fc2d0b2b815f Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Thu, 27 Sep 2018 19:30:26 +0300 Subject: [PATCH 09/62] #189: Fixed --- FoxTube/Pages/MainPage.xaml.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FoxTube/Pages/MainPage.xaml.cs b/FoxTube/Pages/MainPage.xaml.cs index 541de69..40f2833 100644 --- a/FoxTube/Pages/MainPage.xaml.cs +++ b/FoxTube/Pages/MainPage.xaml.cs @@ -445,7 +445,8 @@ namespace FoxTube private void search_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args) { - GoToSearch(new SearchParameters(search.Text)); + if(!string.IsNullOrWhiteSpace(search.Text)) + GoToSearch(new SearchParameters(search.Text)); } private void search_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args) From 02327ad55d71034a2df7b35710640d476dfebacf Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Thu, 27 Sep 2018 20:32:06 +0300 Subject: [PATCH 10/62] #195: Done #191: Done --- FoxTube/Controls/CommentCard.xaml | 13 +++++--- FoxTube/Controls/CommentCard.xaml.cs | 33 ++++++++++++++++++-- FoxTube/Pages/MainPage.xaml.cs | 45 +++++++++++++++++----------- FoxTube/Pages/VideoPage.xaml.cs | 2 +- 4 files changed, 69 insertions(+), 24 deletions(-) diff --git a/FoxTube/Controls/CommentCard.xaml b/FoxTube/Controls/CommentCard.xaml index c1934c1..4881343 100644 --- a/FoxTube/Controls/CommentCard.xaml +++ b/FoxTube/Controls/CommentCard.xaml @@ -23,14 +23,19 @@ + - - + + + + + + - + - + diff --git a/FoxTube/Controls/CommentCard.xaml.cs b/FoxTube/Controls/CommentCard.xaml.cs index c55af90..067a108 100644 --- a/FoxTube/Controls/CommentCard.xaml.cs +++ b/FoxTube/Controls/CommentCard.xaml.cs @@ -218,7 +218,7 @@ namespace FoxTube.Controls private void editorClose_Click(object sender, RoutedEventArgs e) { - ((grid.Children[0] as Grid).Children[1] as Grid).RowDefinitions[2].Height = GridLength.Auto; + ((grid.Children[0] as Grid).Children[1] as Grid).RowDefinitions[3].Height = GridLength.Auto; text.Visibility = Visibility.Visible; editor.Visibility = Visibility.Collapsed; } @@ -236,11 +236,15 @@ namespace FoxTube.Controls item.Snippet.UpdatedAt = DateTime.Now; if (type == CommentType.Reply) + { await SecretsVault.Service.Comments.Update(item, "snippet").ExecuteAsync(); + Initialize(item); + } else { thread.Snippet.TopLevelComment = item; await SecretsVault.Service.CommentThreads.Update(thread, "snippet").ExecuteAsync(); + Initialize(thread); } editorClose_Click(this, null); @@ -265,7 +269,7 @@ namespace FoxTube.Controls private void editBtn_Click(object sender, RoutedEventArgs e) { - ((grid.Children[0] as Grid).Children[1] as Grid).RowDefinitions[2].Height = new GridLength(0); + ((grid.Children[0] as Grid).Children[1] as Grid).RowDefinitions[3].Height = new GridLength(0); text.Visibility = Visibility.Collapsed; editorText.Text = text.Text; editor.Visibility = Visibility.Visible; diff --git a/FoxTube/Controls/VideoPlayer.xaml.cs b/FoxTube/Controls/VideoPlayer.xaml.cs index bd98229..b2d6adc 100644 --- a/FoxTube/Controls/VideoPlayer.xaml.cs +++ b/FoxTube/Controls/VideoPlayer.xaml.cs @@ -44,12 +44,9 @@ using Windows.System.Profile; namespace FoxTube { - public enum DeviceType { Other, Desktop, Mobile } - public sealed partial class VideoPlayer : UserControl { public string videoId; - private DeviceType deviceType = DeviceType.Other; private bool miniview = false; public bool MiniView @@ -107,21 +104,6 @@ namespace FoxTube if (!ApplicationView.GetForCurrentView().IsViewModeSupported(ApplicationViewMode.CompactOverlay)) miniViewBtn.Visibility = Visibility.Collapsed; - switch(AnalyticsInfo.VersionInfo.DeviceFamily) - { - case "Windows.Mobile": - deviceType = DeviceType.Mobile; - break; - - case "Windows.Desktop": - deviceType = DeviceType.Desktop; - break; - - default: - deviceType = DeviceType.Other; - break; - } - captions = grid.Children[2] as LiveCaptions; volume.Value = Convert.ToDouble(settings.Values["volume"]); @@ -136,18 +118,6 @@ namespace FoxTube audioSource.CurrentStateChanged += AudioSource_CurrentStateChanged; t.Elapsed += T_Elapsed; seekTimer.Elapsed += SeekTimer_Elapsed; - - if(SimpleOrientationSensor.GetDefault() != null && deviceType == DeviceType.Mobile) - { - if (SimpleOrientationSensor.GetDefault().GetCurrentOrientation() == SimpleOrientation.Rotated270DegreesCounterclockwise || SimpleOrientationSensor.GetDefault().GetCurrentOrientation() == SimpleOrientation.Rotated90DegreesCounterclockwise) - fullscreen_Click(this, null); - SimpleOrientationSensor.GetDefault().OrientationChanged += (s, arg) => - { - if (((SimpleOrientationSensor.GetDefault().GetCurrentOrientation() == SimpleOrientation.NotRotated || SimpleOrientationSensor.GetDefault().GetCurrentOrientation() == SimpleOrientation.Rotated180DegreesCounterclockwise) && fullScreen) || - ((SimpleOrientationSensor.GetDefault().GetCurrentOrientation() == SimpleOrientation.Rotated270DegreesCounterclockwise || SimpleOrientationSensor.GetDefault().GetCurrentOrientation() == SimpleOrientation.Rotated90DegreesCounterclockwise) && !fullScreen)) - fullscreen_Click(this, null); - }; - } } public async void Initialize(Video meta, string channelAvatar) @@ -497,18 +467,12 @@ namespace FoxTube ApplicationView.GetForCurrentView().TryEnterFullScreenMode(); fullscreen.Content = "\xE1D8"; Height = Methods.MainPage.Height; - - if (deviceType == DeviceType.Mobile) - DisplayInformation.AutoRotationPreferences = DisplayOrientations.Landscape; } else { ApplicationView.GetForCurrentView().ExitFullScreenMode(); fullscreen.Content = "\xE1D9"; Height = double.NaN; - - if (deviceType == DeviceType.Mobile) - DisplayInformation.AutoRotationPreferences = DisplayOrientations.Portrait; } } From 8d09fc9a89ab5c4a6cc9dfcd6c0def44ff7bdfea Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Wed, 3 Oct 2018 20:18:16 +0300 Subject: [PATCH 13/62] Video player debug --- FoxTube/Controls/VideoPlayer.xaml | 9 +- FoxTube/Controls/VideoPlayer.xaml.cs | 169 ++++++++++++++++++--------- 2 files changed, 119 insertions(+), 59 deletions(-) diff --git a/FoxTube/Controls/VideoPlayer.xaml b/FoxTube/Controls/VideoPlayer.xaml index 9dced1b..362a4b4 100644 --- a/FoxTube/Controls/VideoPlayer.xaml +++ b/FoxTube/Controls/VideoPlayer.xaml @@ -16,8 +16,8 @@ PointerEntered="UserControl_PointerEntered"> - - + + @@ -98,7 +98,10 @@ - + + + + diff --git a/FoxTube/Controls/VideoPlayer.xaml.cs b/FoxTube/Controls/VideoPlayer.xaml.cs index b2d6adc..747517c 100644 --- a/FoxTube/Controls/VideoPlayer.xaml.cs +++ b/FoxTube/Controls/VideoPlayer.xaml.cs @@ -67,6 +67,10 @@ namespace FoxTube public event ObjectEventHandler SetFullSize; public event ObjectEventHandler NextClicked; + bool isMuxed = false; + bool audioReady = false; + bool videoReady = false; + CoreCursor cursorBackup = Window.Current.CoreWindow.PointerCursor; Point cursorPositionBackup; @@ -129,7 +133,11 @@ namespace FoxTube #region Retrieving info for CC and Media streams //Loading streams streamInfo = (await YouTube.GetUrisAsync(item.Id)).ToList(); - streamInfo.ForEach(x => Debug.WriteLine(x)); + foreach (YouTubeQuality q in Enum.GetValues(typeof(YouTubeQuality))) + if (streamInfo.FindAll(x => x.VideoQuality == q).Count > 1) + streamInfo.RemoveAll(x => x.VideoQuality == q && !x.HasAudio); + + streamInfo.ForEach(x => Debug.WriteLine($"{x.HasAudio}; {x.HasVideo}; {x.VideoQuality}; {x.AudioQuality}")); foreach (YouTubeUri i in streamInfo) { if (i.VideoQuality == YouTubeQuality.Quality2160P) @@ -258,11 +266,11 @@ namespace FoxTube { seek.Value = videoSource.Position.TotalSeconds; seekIndicator.Value = seek.Value; - if (Math.Round(videoSource.Position.TotalSeconds, 1) != Math.Round(audioSource.Position.TotalSeconds, 1)) + /*if (Math.Round(videoSource.Position.TotalSeconds, 1) != Math.Round(audioSource.Position.TotalSeconds, 1)) { Debug.WriteLine($"Correcting tracks synchronization (Video track position: {videoSource.Position}; Audio track position: {audioSource.Position})"); audioSource.Position = videoSource.Position; - } + }*/ } void Elapsed() @@ -292,19 +300,19 @@ namespace FoxTube { double v = volume.Value; if (v == 0) - muteBtn.Content = openVolume.Content = ""; + muteBtn.Content = openVolume.Content = "\xE74F"; else if (v <= 25 && v > 0) - muteBtn.Content = openVolume.Content = ""; + muteBtn.Content = openVolume.Content = "\xE992"; else if (v <= 50 && v > 25) - muteBtn.Content = openVolume.Content = ""; + muteBtn.Content = openVolume.Content = "\xE993"; else if (v <= 75 && v > 50) - muteBtn.Content = openVolume.Content = ""; + muteBtn.Content = openVolume.Content = "\xE994"; else if (v > 75) - muteBtn.Content = openVolume.Content = ""; + muteBtn.Content = openVolume.Content = "\xE995"; settings.Values["volume"] = volume.Value; - audioSource.Volume = volume.Value * 0.01; + audioSource.Volume = videoSource.Volume = volume.Value * 0.01; } private void muteBtn_Click(object sender, RoutedEventArgs e) @@ -352,82 +360,108 @@ namespace FoxTube private void quality_SelectionChanged(object sender, SelectionChangedEventArgs e) { - //try + try { videoSource.Pause(); + audioSource.Source = null; timecodeBackup = videoSource.Position.TotalSeconds; + audioReady = false; + videoReady = false; + switch((quality.SelectedItem as ComboBoxItem).Content) { case "2160p": - videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality2160P).Uri; - try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityHigh).Uri; } - catch + if(streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality2160P).HasAudio) + isMuxed = true; + else { - try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityMedium).Uri; } - catch { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityLow).Uri; } + isMuxed = false; + audioSource.Source = (streamInfo.Find(x => x.AudioQuality == YouTubeQuality.QualityHigh && !x.HasVideo) ?? + streamInfo.Find(x => x.AudioQuality == YouTubeQuality.QualityMedium && !x.HasVideo) ?? + streamInfo.Find(x => x.AudioQuality == YouTubeQuality.QualityLow && !x.HasVideo) ?? + streamInfo.Find(x => x.HasAudio && !x.HasVideo)).Uri; } + videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality2160P).Uri; break; case "1080p": - videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality1080P).Uri; - try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityHigh).Uri; } - catch + if (streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality1080P).HasAudio) + isMuxed = true; + else { - try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityMedium).Uri; } - catch { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityLow).Uri; } + isMuxed = false; + audioSource.Source = (streamInfo.Find(x => x.AudioQuality == YouTubeQuality.QualityHigh && !x.HasVideo) ?? + streamInfo.Find(x => x.AudioQuality == YouTubeQuality.QualityMedium && !x.HasVideo) ?? + streamInfo.Find(x => x.AudioQuality == YouTubeQuality.QualityLow && !x.HasVideo) ?? + streamInfo.Find(x => x.HasAudio && !x.HasVideo)).Uri; } + videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality1080P).Uri; break; case "720p": - videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality720P).Uri; - try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityHigh).Uri; } - catch + if (streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality720P).HasAudio) + isMuxed = true; + else { - try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityMedium).Uri; } - catch { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityLow).Uri; } + isMuxed = false; + audioSource.Source = (streamInfo.Find(x => x.AudioQuality == YouTubeQuality.QualityHigh && !x.HasVideo) ?? + streamInfo.Find(x => x.AudioQuality == YouTubeQuality.QualityMedium && !x.HasVideo) ?? + streamInfo.Find(x => x.AudioQuality == YouTubeQuality.QualityLow && !x.HasVideo) ?? + streamInfo.Find(x => x.HasAudio && !x.HasVideo)).Uri; } + videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality720P).Uri; break; case "480p": - videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality480P).Uri; - try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityMedium).Uri; } - catch + if (streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality480P).HasAudio) + isMuxed = true; + else { - try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityHigh).Uri; } - catch { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityLow).Uri; } + isMuxed = false; + audioSource.Source = (streamInfo.Find(x => x.AudioQuality == YouTubeQuality.QualityMedium && !x.HasVideo) ?? + streamInfo.Find(x => x.AudioQuality == YouTubeQuality.QualityLow && !x.HasVideo) ?? + streamInfo.Find(x => x.HasAudio && !x.HasVideo)).Uri; } + videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality480P).Uri; break; case "360p": - videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality360P).Uri; - try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityMedium).Uri; } - catch + if (streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality360P).HasAudio) + isMuxed = true; + else { - try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityHigh).Uri; } - catch { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityLow).Uri; } + isMuxed = false; + audioSource.Source = (streamInfo.Find(x => x.AudioQuality == YouTubeQuality.QualityMedium && !x.HasVideo) ?? + streamInfo.Find(x => x.AudioQuality == YouTubeQuality.QualityLow && !x.HasVideo) ?? + streamInfo.Find(x => x.HasAudio && !x.HasVideo)).Uri; } + videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality360P).Uri; break; case "240p": - videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality240P).Uri; - try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityLow).Uri; } - catch + if (streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality240P).HasAudio) + isMuxed = true; + else { - try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityMedium).Uri; } - catch { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityHigh).Uri; } + isMuxed = false; + audioSource.Source = (streamInfo.Find(x => x.AudioQuality == YouTubeQuality.QualityLow && !x.HasVideo) ?? + streamInfo.Find(x => x.HasAudio && !x.HasVideo)).Uri; } + videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality240P).Uri; break; case "144p": - videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality144P).Uri; - try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityLow).Uri; } - catch + if (streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality144P).HasAudio) + isMuxed = true; + else { - try { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityMedium).Uri; } - catch { audioSource.Source = streamInfo.First(x => x.AudioQuality == YouTubeQuality.QualityHigh).Uri; } + isMuxed = false; + audioSource.Source = (streamInfo.Find(x => x.AudioQuality == YouTubeQuality.QualityLow && !x.HasVideo) ?? + streamInfo.Find(x => x.HasAudio && !x.HasVideo)).Uri; } + videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality144P).Uri; break; } needUpdateTimecode = true; videoSource.Play(); } - //catch + catch { } @@ -481,7 +515,8 @@ namespace FoxTube if (videoSource.CurrentState == MediaElementState.Playing) videoSource.Pause(); else if (videoSource.CurrentState == MediaElementState.Paused) - videoSource.Play(); + if((audioReady && videoReady) || isMuxed) + videoSource.Play(); } private void AudioSource_CurrentStateChanged(object sender, RoutedEventArgs e) @@ -489,16 +524,38 @@ namespace FoxTube switch (audioSource.CurrentState) { case MediaElementState.Buffering: - videoSource.Pause(); + if(videoSource.CurrentState != MediaElementState.Buffering) + videoSource.Pause(); break; case MediaElementState.Playing: - if(videoSource.CurrentState == MediaElementState.Paused) + if (videoSource.CurrentState == MediaElementState.Paused) videoSource.Play(); + else if (videoSource.CurrentState == MediaElementState.Buffering) + audioSource.Pause(); break; } } + private void videoSource_Opened(object sender, RoutedEventArgs arg) + { + if(!isMuxed) + { + if(sender == videoSource) + { + videoReady = true; + if (audioReady && ((timecodeBackup == 0 && (bool)settings.Values["videoAutoplay"]) || timecodeBackup > 0)) + play_Click(this, null); + } + else if(sender == audioSource) + { + audioReady = true; + if (videoReady && ((timecodeBackup == 0 && (bool)settings.Values["videoAutoplay"]) || timecodeBackup > 0)) + play_Click(this, null); + } + } + } + private void videoSource_CurrentStateChanged(object sender, RoutedEventArgs e) { if(videoSource.CurrentState == MediaElementState.Playing && needUpdateTimecode) @@ -510,6 +567,7 @@ namespace FoxTube switch(videoSource.CurrentState) { case MediaElementState.Buffering: + audioSource.Position = videoSource.Position; audioSource.Pause(); bufferingBar.Visibility = Visibility.Visible; @@ -551,12 +609,6 @@ namespace FoxTube play.Content = "\xE103"; touchPlay.Content = "\xE103"; - if (Math.Round(videoSource.Position.TotalSeconds, 1) != Math.Round(audioSource.Position.TotalSeconds, 1)) - { - Debug.WriteLine($"Correcting tracks synchronization (Video track position: {videoSource.Position}; Audio track position: {audioSource.Position})"); - audioSource.Position = videoSource.Position; - } - systemControls.PlaybackStatus = MediaPlaybackStatus.Playing; break; @@ -796,7 +848,7 @@ namespace FoxTube case VirtualKey.Left: back10_Click(this, null); break; - case Windows.System.VirtualKey.Right: + case VirtualKey.Right: fwd30_Click(this, null); break; } @@ -806,5 +858,10 @@ namespace FoxTube { LoadTrack(); } + + private void videoSource_BufferingProgressChanged(object sender, RoutedEventArgs e) + { + bufferingLevel.Value = (audioSource.Source != null && videoSource.BufferingProgress > audioSource.BufferingProgress ? audioSource.BufferingProgress : videoSource.BufferingProgress) * 100; + } } } From f642bb5653b599a9ee27560ad5ebde14d28fd09e Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Mon, 8 Oct 2018 19:02:49 +0300 Subject: [PATCH 14/62] #200, 203: Fixed --- FoxTube/Pages/MainPage.xaml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/FoxTube/Pages/MainPage.xaml b/FoxTube/Pages/MainPage.xaml index 8a69bb3..a2bfef9 100644 --- a/FoxTube/Pages/MainPage.xaml +++ b/FoxTube/Pages/MainPage.xaml @@ -23,11 +23,18 @@ + + + + + + - + + @@ -67,7 +74,7 @@ - + @@ -76,7 +83,7 @@ - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - + + + - - - - - + + + + + + diff --git a/FoxTube/Pages/VideoPage.xaml.cs b/FoxTube/Pages/VideoPage.xaml.cs index 30272f6..4995721 100644 --- a/FoxTube/Pages/VideoPage.xaml.cs +++ b/FoxTube/Pages/VideoPage.xaml.cs @@ -92,11 +92,7 @@ namespace FoxTube.Pages { Debug.WriteLine("Correcting layout..."); mainContent.Children.Remove(descriptionPanel); - pivot.Items.Insert(0, new PivotItem() - { - Content = descriptionPanel, - Header = "Description" - }); + pivot.Items.Insert(0, descriptionPanel); tabsPlaceholder.Children.Remove(pivot); mainContent.Children.Add(pivot); @@ -360,39 +356,30 @@ namespace FoxTube.Pages else wide = false; - if (e.NewSize.Width > 1000 && e.PreviousSize.Width <= 1000 && !isExtended) + if (e.NewSize.Width > 1000 && mainContent.Children.Contains(pivot) && !isExtended) { - if (mainContent.Children.Contains(pivot)) - { - mainContent.Children.Remove(pivot); - tabsPlaceholder.Children.Add(pivot); + mainContent.Children.Remove(pivot); + tabsPlaceholder.Children.Add(pivot); + + pivot.Items.RemoveAt(0); + mainContent.Children.Add(descriptionPanel); - (pivot.Items[0] as PivotItem).Content = null; - pivot.Items.RemoveAt(0); - mainContent.Children.Add(descriptionPanel); - } - grid.ColumnDefinitions[1].Width = new GridLength(400); + + pivot.SelectedIndex = 0; } - else if (e.NewSize.Width <= 1000 & e.PreviousSize.Width > 1000) + else if (e.NewSize.Width <= 1000 && mainContent.Children.Contains(descriptionPanel)) { - if (mainContent.Children.Contains(descriptionPanel)) - { - mainContent.Children.Remove(descriptionPanel); - pivot.Items.Insert(0, new PivotItem() - { - Content = descriptionPanel, - Header = "Description" - }); + mainContent.Children.Remove(descriptionPanel); + pivot.Items.Insert(0, descriptionPanel); + + tabsPlaceholder.Children.Remove(pivot); + mainContent.Children.Add(pivot); - tabsPlaceholder.Children.Remove(pivot); - mainContent.Children.Add(pivot); - } - grid.ColumnDefinitions[1].Width = new GridLength(0); - } - pivot.SelectedIndex = 0; + pivot.SelectedIndex = 0; + } } private async void Share(DataTransferManager sender, DataRequestedEventArgs args) From 7db118b498a5bd09c634f42727911ac206bd79fe Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Wed, 10 Oct 2018 20:45:53 +0300 Subject: [PATCH 21/62] #201: Fixed Comments editor height freaking out fixed --- FoxTube/Controls/CommentCard.xaml | 4 ++-- FoxTube/Pages/CommentsPage.xaml | 2 +- FoxTube/Pages/MainPage.xaml.cs | 22 +--------------------- 3 files changed, 4 insertions(+), 24 deletions(-) diff --git a/FoxTube/Controls/CommentCard.xaml b/FoxTube/Controls/CommentCard.xaml index effe425..d1d0174 100644 --- a/FoxTube/Controls/CommentCard.xaml +++ b/FoxTube/Controls/CommentCard.xaml @@ -36,7 +36,7 @@ - + diff --git a/FoxTube/Controls/VideoPlayer.xaml.cs b/FoxTube/Controls/VideoPlayer.xaml.cs index c8930eb..e8eeefa 100644 --- a/FoxTube/Controls/VideoPlayer.xaml.cs +++ b/FoxTube/Controls/VideoPlayer.xaml.cs @@ -1,26 +1,17 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; using System.Timers; using Windows.Foundation; -using Windows.Foundation.Collections; using Windows.Storage; using Windows.UI.Core; 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.Navigation; -using Microsoft.Toolkit.Uwp.UI.Animations; - using Google.Apis.YouTube.v3.Data; -using Google.Apis.YouTube.v3; using Windows.UI.Xaml.Media.Imaging; -using Windows.Networking.Connectivity; using System.Diagnostics; using Windows.Media; using Windows.Storage.Streams; @@ -28,17 +19,13 @@ using Windows.UI.ViewManagement; using System.Xml; using Windows.ApplicationModel.Core; using Windows.UI; -using Windows.Graphics.Display; using Windows.Media.Casting; -using MyToolkit.Multimedia; using YoutubeExplode.Models.MediaStreams; using YoutubeExplode; using YoutubeExplode.Models.ClosedCaptions; using System.Globalization; using FoxTube.Controls; using Windows.System; -using Windows.Devices.Sensors; -using Windows.System.Profile; // The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 @@ -87,7 +74,7 @@ namespace FoxTube LiveCaptions captions; IReadOnlyList ccInfo; - List streamInfo; + MediaStreamInfoSet streamInfo; ApplicationDataContainer settings = ApplicationData.Current.LocalSettings; Timer t = new Timer() @@ -132,35 +119,25 @@ namespace FoxTube #region Retrieving info for CC and Media streams //Loading streams - streamInfo = (await YouTube.GetUrisAsync(item.Id)).ToList(); - foreach (YouTubeQuality q in Enum.GetValues(typeof(YouTubeQuality))) - if (streamInfo.FindAll(x => x.VideoQuality == q).Count > 1) - streamInfo.RemoveAll(x => x.VideoQuality == q && !x.HasAudio); + streamInfo = await new YoutubeClient().GetVideoMediaStreamInfosAsync(videoId); + streamInfo.Audio.ToList().ForEach(x => Debug.WriteLine($"{x.AudioEncoding} {x.Bitrate}")); - streamInfo.ForEach(x => Debug.WriteLine($"{x.HasAudio}; {x.HasVideo}; {x.VideoQuality}; {x.AudioQuality}")); - foreach (YouTubeUri i in streamInfo) - { - if (i.VideoQuality == YouTubeQuality.Quality2160P) - (quality.Items[0] as ComboBoxItem).Visibility = Visibility.Visible; - if (i.VideoQuality == YouTubeQuality.Quality1080P) - (quality.Items[1] as ComboBoxItem).Visibility = Visibility.Visible; - if (i.VideoQuality == YouTubeQuality.Quality720P) - (quality.Items[2] as ComboBoxItem).Visibility = Visibility.Visible; - if (i.VideoQuality == YouTubeQuality.Quality480P) - (quality.Items[3] as ComboBoxItem).Visibility = Visibility.Visible; - if (i.VideoQuality == YouTubeQuality.Quality360P) - (quality.Items[4] as ComboBoxItem).Visibility = Visibility.Visible; - if (i.VideoQuality == YouTubeQuality.Quality240P) - (quality.Items[5] as ComboBoxItem).Visibility = Visibility.Visible; - if (i.VideoQuality == YouTubeQuality.Quality144P) - (quality.Items[6] as ComboBoxItem).Visibility = Visibility.Visible; - } + List q = streamInfo.GetAllVideoQualities().ToList(); + q.Sort(); + q.Reverse(); + foreach (VideoQuality i in q) + quality.Items.Add(new ComboBoxItem() { Content = i.GetVideoQualityLabel() }); - int k = (int)settings.Values["quality"]; - if ((quality.Items[k] as ComboBoxItem).Visibility == Visibility.Visible) - quality.SelectedIndex = k; + string s; + if ((string)settings.Values["quality"] == "remember") + s = (string)settings.Values["rememberedQuality"]; else - quality.SelectedItem = quality.Items.First(x => (x as ComboBoxItem).Visibility == Visibility.Visible); + s = (string)settings.Values["quality"]; + + if (quality.Items.ToList().Find(x => (x as ComboBoxItem).Content as string == s) != null) + quality.SelectedItem = quality.Items.First(x => (x as ComboBoxItem).Content as string == s); + else + quality.SelectedItem = quality.Items.First(); //Loading captions ccInfo = await new YoutubeClient().GetVideoClosedCaptionTrackInfosAsync(item.Id); @@ -369,11 +346,28 @@ namespace FoxTube audioReady = false; videoReady = false; - switch((quality.SelectedItem as ComboBoxItem).Content) + settings.Values["rememberedQuality"] = (quality.SelectedItem as ComboBoxItem).Content as string; + + if(streamInfo.Muxed.ToList().Find(x => x.VideoQualityLabel == (quality.SelectedItem as ComboBoxItem).Content as string) != null) + { + isMuxed = true; + videoSource.Source = streamInfo.Muxed.First(x => x.VideoQualityLabel == (quality.SelectedItem as ComboBoxItem).Content as string).Url.ToUri(); + } + else + { + isMuxed = false; + videoSource.Source = streamInfo.Video.First(x => x.VideoQualityLabel == (quality.SelectedItem as ComboBoxItem).Content as string).Url.ToUri(); + audioSource.Source = streamInfo.Audio.First().Url.ToUri(); + } + + /*switch((quality.SelectedItem as ComboBoxItem).Content) { case "2160p": - if(streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality2160P).HasAudio) + if(streamInfo.Muxed.First(x => x.VideoQuality.)) + { isMuxed = true; + + } else { isMuxed = false; @@ -456,7 +450,7 @@ namespace FoxTube } videoSource.Source = streamInfo.First(x => x.VideoQuality == YouTubeQuality.Quality144P).Uri; break; - } + }*/ needUpdateTimecode = true; videoSource.Play(); diff --git a/FoxTube/FoxTube.csproj b/FoxTube/FoxTube.csproj index 3110a13..52e3fc3 100644 --- a/FoxTube/FoxTube.csproj +++ b/FoxTube/FoxTube.csproj @@ -97,6 +97,7 @@ App.xaml + @@ -398,7 +399,7 @@ - 1.0.1 + 1.1.0 1.30.0-beta02 @@ -419,25 +420,25 @@ 10.1805.7001 - 6.1.5 + 6.1.9 - 3.0.0 + 4.0.0 - 3.0.0 - - - 2.5.16 - - - 2.5.16 + 4.0.0 - 4.3.1 + 4.3.2 + + + 1.2.0 - 4.3.1 + 4.4.0 + + + 0.10.11 diff --git a/FoxTube/Pages/Downloads.xaml b/FoxTube/Pages/Downloads.xaml index 9a44d87..d6ca56f 100644 --- a/FoxTube/Pages/Downloads.xaml +++ b/FoxTube/Pages/Downloads.xaml @@ -5,6 +5,7 @@ xmlns:local="using:FoxTube.Pages" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:controls="using:FoxTube.Controls" mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> @@ -27,7 +28,9 @@ - + + + diff --git a/FoxTube/Pages/Downloads.xaml.cs b/FoxTube/Pages/Downloads.xaml.cs index 3282afb..f48c4e6 100644 --- a/FoxTube/Pages/Downloads.xaml.cs +++ b/FoxTube/Pages/Downloads.xaml.cs @@ -11,11 +11,6 @@ using Windows.Storage.Pickers; using Windows.System; 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.Navigation; // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 #pragma warning disable CS0252 // Possible unintended reference comparison; left hand side needs cast @@ -28,33 +23,20 @@ namespace FoxTube.Pages public sealed partial class Downloads : Page { ApplicationDataContainer settings = ApplicationData.Current.LocalSettings; - DownloadAgent agent = Methods.MainPage.Agent; public Downloads() { this.InitializeComponent(); path.Text = settings.Values["defaultDownload"] as string; - - agent.ListChanged += UpdateList; - - foreach (DownloadItem item in agent.Items) - stack.Children.Add(item); - } - - private void UpdateList(object sender, params object[] e) - { - if (e[0] == "remove") - stack.Children.Remove(sender as DownloadItem); - else if (e[0] == "add") - stack.Children.Add(sender as DownloadItem); } private async void changePath_Click(object sender, RoutedEventArgs e) { FolderPicker picker = new FolderPicker() { - SuggestedStartLocation = PickerLocationId.Desktop, + SuggestedStartLocation = PickerLocationId.Downloads, ViewMode = PickerViewMode.Thumbnail }; + picker.FileTypeFilter.Add(".shit"); //Because overwise it trhows an exception StorageFolder p = await picker.PickSingleFolderAsync(); if (p != null) @@ -64,7 +46,7 @@ namespace FoxTube.Pages private async void openFolder_Click(object sender, RoutedEventArgs e) { - await Launcher.LaunchUriAsync(new Uri(settings.Values["defaultDownload"] as string)); + await Launcher.LaunchFolderAsync( await StorageFolder.GetFolderFromPathAsync(settings.Values["defaultDownload"] as string)); } } } diff --git a/FoxTube/Pages/MainPage.xaml.cs b/FoxTube/Pages/MainPage.xaml.cs index 628e56e..1d5961b 100644 --- a/FoxTube/Pages/MainPage.xaml.cs +++ b/FoxTube/Pages/MainPage.xaml.cs @@ -24,6 +24,7 @@ using System.Net; using Windows.UI.Popups; using Windows.Networking.Connectivity; using Windows.UI.Core; +using Syroot.Windows.IO; // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 @@ -48,7 +49,9 @@ namespace FoxTube this.InitializeComponent(); if (settings.Values["quality"] == null) - settings.Values.Add("quality", 1); + settings.Values.Add("quality", "remember"); + if (settings.Values["rememberedQuality"] == null) + settings.Values.Add("rememberedQuality", "1080p"); if (settings.Values["newVideoNotification"] == null) settings.Values.Add("newVideoNotification", true); @@ -70,7 +73,7 @@ namespace FoxTube settings.Values.Add("safeSearch", 0); if (settings.Values["defaultDownload"] == null) - settings.Values.Add("defaultDownload", Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\DownloadedVideos"); + settings.Values.Add("defaultDownload", Syroot.Windows.IO.KnownFolders.Downloads.Path + "\\DownloadedVideos"); if (settings.Values["notificationsHistory"] == null) { diff --git a/FoxTube/Pages/SettingsPages/General.xaml b/FoxTube/Pages/SettingsPages/General.xaml index 431c28b..cbdfac1 100644 --- a/FoxTube/Pages/SettingsPages/General.xaml +++ b/FoxTube/Pages/SettingsPages/General.xaml @@ -28,14 +28,14 @@ - - - - - - - - + + + + + + + + diff --git a/FoxTube/Pages/SettingsPages/General.xaml.cs b/FoxTube/Pages/SettingsPages/General.xaml.cs index de62173..fb0f11f 100644 --- a/FoxTube/Pages/SettingsPages/General.xaml.cs +++ b/FoxTube/Pages/SettingsPages/General.xaml.cs @@ -76,7 +76,7 @@ namespace FoxTube.Pages.SettingsPages private void quality_SelectionChanged(object sender, SelectionChangedEventArgs e) { - settings.Values["quality"] = quality.SelectedIndex; + settings.Values["quality"] = (quality.SelectedItem as ComboBoxItem).Tag as string; } private void mobileWarning_Toggled(object sender, RoutedEventArgs e) diff --git a/FoxTube/Pages/VideoPage.xaml.cs b/FoxTube/Pages/VideoPage.xaml.cs index e2e73ce..8a632f2 100644 --- a/FoxTube/Pages/VideoPage.xaml.cs +++ b/FoxTube/Pages/VideoPage.xaml.cs @@ -1,36 +1,21 @@ 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.Navigation; using Windows.System; - using Google.Apis.YouTube.v3.Data; using Google.Apis.YouTube.v3; using Windows.UI.Xaml.Media.Imaging; using System.Diagnostics; -using System.Timers; -using Windows.UI.Core; -using System.Threading; using Windows.ApplicationModel.DataTransfer; using Windows.Storage; using Windows.ApplicationModel; using Windows.Storage.Streams; -using Windows.UI.Popups; -using Windows.UI.Text; using Windows.UI; -using FoxTube.Pages; - -using MyToolkit.Multimedia; using FoxTube.Controls; // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 @@ -250,7 +235,7 @@ namespace FoxTube.Pages async void LoadDownloads() { - List uris = (await YouTube.GetUrisAsync(item.Id)).ToList(); + /*List uris = (await YouTube.GetUrisAsync(item.Id)).ToList(); if (uris.Count > 0) foreach (YouTubeUri u in uris) { @@ -276,12 +261,12 @@ namespace FoxTube.Pages } } else - download.Visibility = Visibility.Collapsed; + download.Visibility = Visibility.Collapsed;*/ } private void downloadItemSelected(object sender, RoutedEventArgs e) { - Methods.MainPage.Agent.Add(videoId, (sender as MenuFlyoutItem).Tag.ToString()); + Methods.MainPage.Agent.Add((sender as MenuFlyoutItem).Tag.ToString()); } async void LoadRelatedVideos() From fb3b88a0467537c750da1bf1e01fb5e16e7f88b0 Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Sun, 21 Oct 2018 21:59:35 +0300 Subject: [PATCH 24/62] Now can download videos --- FoxTube/Classes/DownloadAgent.cs | 10 +- FoxTube/Classes/DownloadItemContainer.cs | 7 +- FoxTube/Classes/Methods.cs | 14 +++ FoxTube/Controls/DownloadItem.xaml | 7 +- FoxTube/Controls/DownloadItem.xaml.cs | 126 +++++++++++++------- FoxTube/FoxTube.csproj | 3 - FoxTube/Pages/Downloads.xaml | 25 +--- FoxTube/Pages/Downloads.xaml.cs | 12 +- FoxTube/Pages/MainPage.xaml.cs | 4 - FoxTube/Pages/SettingsPages/General.xaml.cs | 2 +- FoxTube/Pages/VideoPage.xaml.cs | 48 ++++---- 11 files changed, 142 insertions(+), 116 deletions(-) diff --git a/FoxTube/Classes/DownloadAgent.cs b/FoxTube/Classes/DownloadAgent.cs index af7a334..9484c8e 100644 --- a/FoxTube/Classes/DownloadAgent.cs +++ b/FoxTube/Classes/DownloadAgent.cs @@ -5,6 +5,8 @@ using Windows.Storage; using FoxTube.Classes; using Newtonsoft.Json; using Windows.UI.Popups; +using YoutubeExplode.Models.MediaStreams; +using Google.Apis.YouTube.v3.Data; namespace FoxTube.Controls { @@ -32,14 +34,14 @@ namespace FoxTube.Controls catch { } } - public void Add(string url) + public void Add(MediaStreamInfo info, Video meta, string qualty) { - items.Add(new DownloadItem(url)); + items.Add(new DownloadItem(info, meta, qualty)); } - private void Item_DownloadCanceled(object sender, params object[] e) + public void Remove(string id) { - items.Remove(sender as DownloadItem); + items.Remove(items.Find(x => x.Container.Id == id)); } public async void QuitPrompt() diff --git a/FoxTube/Classes/DownloadItemContainer.cs b/FoxTube/Classes/DownloadItemContainer.cs index f7e6fe2..05dcdbb 100644 --- a/FoxTube/Classes/DownloadItemContainer.cs +++ b/FoxTube/Classes/DownloadItemContainer.cs @@ -1,5 +1,5 @@ using System; -using YoutubeExplode.Models.MediaStreams; +using Windows.Storage; namespace FoxTube.Classes { @@ -8,9 +8,10 @@ namespace FoxTube.Classes public string Title { get; set; } public string Channel { get; set; } public string Id { get; set; } - public Uri Path { get; set; } + public Uri Path => File.Path.ToUri(); public Uri Thumbnail { get; set; } - public VideoQuality Quality { get; set; } + public string Quality { get; set; } public TimeSpan Duration { get; set; } + public StorageFile File { get; set; } } } diff --git a/FoxTube/Classes/Methods.cs b/FoxTube/Classes/Methods.cs index f7fa11e..b893da2 100644 --- a/FoxTube/Classes/Methods.cs +++ b/FoxTube/Classes/Methods.cs @@ -1,6 +1,8 @@ using Google.Apis.YouTube.v3; using System; +using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Text.RegularExpressions; using System.Web; using Windows.ApplicationModel.Core; @@ -31,6 +33,18 @@ namespace FoxTube return new Uri(url); } + public static string ReplaceInvalidChars(this string str, char newValue) + { + foreach (char i in Path.GetInvalidFileNameChars()) + str = str.Replace(i, newValue); + return str; + } + + public static string Last(this string[] arr) + { + return arr[arr.Length - 1]; + } + public static string GetAgo(DateTime dateTime) { TimeSpan span = DateTime.Now - dateTime; diff --git a/FoxTube/Controls/DownloadItem.xaml b/FoxTube/Controls/DownloadItem.xaml index 212cb5c..720434e 100644 --- a/FoxTube/Controls/DownloadItem.xaml +++ b/FoxTube/Controls/DownloadItem.xaml @@ -10,7 +10,7 @@ d:DesignWidth="1500"> - + @@ -19,10 +19,11 @@ - + + - + diff --git a/FoxTube/Controls/DownloadItem.xaml.cs b/FoxTube/Controls/DownloadItem.xaml.cs index a23e6e5..20a308a 100644 --- a/FoxTube/Controls/DownloadItem.xaml.cs +++ b/FoxTube/Controls/DownloadItem.xaml.cs @@ -7,6 +7,14 @@ using Windows.UI.Xaml.Media.Imaging; using Windows.System; using FoxTube.Classes; using YoutubeExplode.Models.MediaStreams; +using YoutubeExplode; +using Windows.Storage; +using Google.Apis.YouTube.v3.Data; +using System.Threading; +using System.Xml; +using Windows.UI.Popups; +using Windows.Storage.Pickers; +using System.Diagnostics; // The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 @@ -16,11 +24,18 @@ namespace FoxTube.Controls { public DownloadItemContainer Container { get; private set; } public bool InProgress { get; set; } = false; - - public DownloadItem(string url) + + YoutubeClient client = new YoutubeClient(); + ApplicationDataContainer settings = ApplicationData.Current.LocalSettings; + + CancellationTokenSource cts = new CancellationTokenSource(); + CancellationToken token; + Progress progress = new Progress(); + + public DownloadItem(MediaStreamInfo info, Video meta, string q) { this.InitializeComponent(); - Download(url); + Download(info, meta, q); } public DownloadItem(DownloadItemContainer container) @@ -29,11 +44,14 @@ namespace FoxTube.Controls Container = container; if (!File.Exists(container.Path.AbsolutePath)) - throw new FileNotFoundException(); + { + Methods.MainPage.Agent.Remove(Container.Id); + return; + } title.Text = Container.Title; thumbnail.Source = new BitmapImage(Container.Thumbnail); - quality.Text = $"Quality: {Container.Quality.GetVideoQualityLabel()}"; + quality.Text = $"Quality: {Container.Quality}"; duration.Text = $"Duration: {Container.Duration}"; channel.Text = $"Author: {Container.Channel}"; @@ -41,41 +59,71 @@ namespace FoxTube.Controls donePanel.Visibility = Visibility.Visible; } - void Download(string url) + async void Download(MediaStreamInfo info, Video meta, string q) { + InProgress = true; + Container = new DownloadItemContainer(); + + token = new CancellationTokenSource().Token; + progress.ProgressChanged += UpdateInfo; + + FolderPicker picker = new FolderPicker() + { + SuggestedStartLocation = PickerLocationId.Downloads, + ViewMode = PickerViewMode.Thumbnail + }; + picker.FileTypeFilter.Add(".shit"); //Because overwise it trhows an exception + + StorageFolder folder = await picker.PickSingleFolderAsync(); + if (folder == null) + Cancel(); + Container.File = await folder.CreateFileAsync($"{meta.Snippet.Title.ReplaceInvalidChars('_')}.{info.Container.GetFileExtension()}", CreationCollisionOption.GenerateUniqueName); + + //TO-DO: Create toast + + Container.Channel = meta.Snippet.ChannelTitle; + Container.Duration = XmlConvert.ToTimeSpan(meta.ContentDetails.Duration); + Container.Id = meta.Id; + Container.Quality = q; + Container.Thumbnail = meta.Snippet.Thumbnails.Medium.Url.ToUri(); + Container.Title = meta.Snippet.Title; + + thumbnail.Source = new BitmapImage(new Uri(meta.Snippet.Thumbnails.Medium.Url)); + title.Text = meta.Snippet.Title; + ext.Text = $"Extension: {info.Container.GetFileExtension()}"; + quality.Text = $"Quality: {q}"; + duration.Text = $"Duration: {XmlConvert.ToTimeSpan(meta.ContentDetails.Duration)}"; + channel.Text = $"Author: {meta.Snippet.ChannelTitle}"; + path.Text = Container.File.Path; + + progressPanel.Visibility = Visibility.Visible; + donePanel.Visibility = Visibility.Collapsed; + await client.DownloadMediaStreamAsync(info, await Container.File.OpenStreamForWriteAsync(), progress, token); + + progressPanel.Visibility = Visibility.Collapsed; + donePanel.Visibility = Visibility.Visible; + + InProgress = false; } - private void UpdateInfo(object sender, DownloadProgressChangedEventArgs e) + private void UpdateInfo(object sender, double e) { - progressBar.Value = e.ProgressPercentage; - perc.Text = $"{e.ProgressPercentage}%"; + status.Text = "Downloading"; + progressBar.Value = e; + perc.Text = $"{(int)e}%"; + + //TO-DO: Update toast } private void DownloadCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) { - /*progressPanel.Visibility = Visibility.Collapsed; - donePanel.Visibility = Visibility.Visible; - - string node = $@" - - - {quality.Text.Split(' ')[1]} - {duration.Text.Split(' ')[1]} - {channel.Text.Split(' ')[1]} - -
- {uri} - {Id} -
-
"; - - DownloadComplete.Invoke(this, node);*/ + //TO-DO: Update toast } private async void open_Click(object sender, RoutedEventArgs e) { - await Launcher.LaunchUriAsync(Container.Path); + await Launcher.LaunchFileAsync(Container.File); } private void gotoOriginal_Click(object sender, RoutedEventArgs e) @@ -83,30 +131,28 @@ namespace FoxTube.Controls Methods.MainPage.GoToVideo(Container.Id); } - public void Cancel() + public async void Cancel() { - + status.Text = "Cancelling..."; + progressBar.IsIndeterminate = true; + cancel.IsEnabled = false; + cts.Cancel(); + await Container.File.DeleteAsync(); + Methods.MainPage.Agent.Remove(Container.Id); } - private void cancel_Click(object sender, RoutedEventArgs e) + private async void cancel_Click(object sender, RoutedEventArgs e) { - /*if(client.IsBusy) + if(InProgress) { MessageDialog dialog = new MessageDialog("Are you sure?", "Cancelling download"); - dialog.Commands.Add(new UICommand("Yes", (command) => - { - status.Text = "Cancelling..."; - progressBar.IsIndeterminate = true; - cancel.IsEnabled = false; - client.CancelAsync(); - DownloadCanceled.Invoke(this, null); - })); + dialog.Commands.Add(new UICommand("Yes", (command) => Cancel())); dialog.Commands.Add(new UICommand("No")); dialog.DefaultCommandIndex = 1; await dialog.ShowAsync(); - }*/ + } } } } diff --git a/FoxTube/FoxTube.csproj b/FoxTube/FoxTube.csproj index 52e3fc3..9961956 100644 --- a/FoxTube/FoxTube.csproj +++ b/FoxTube/FoxTube.csproj @@ -431,9 +431,6 @@ 4.3.2 - - 1.2.0 - 4.4.0 diff --git a/FoxTube/Pages/Downloads.xaml b/FoxTube/Pages/Downloads.xaml index d6ca56f..aa5ccd0 100644 --- a/FoxTube/Pages/Downloads.xaml +++ b/FoxTube/Pages/Downloads.xaml @@ -9,28 +9,9 @@ mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> - - - - - + - - - - - - - - + + @@ -70,47 +80,6 @@ - - - - - - - - - - - - - - - - - diff --git a/FoxTube/Pages/MainPage.xaml.cs b/FoxTube/Pages/MainPage.xaml.cs index c65796a..1717536 100644 --- a/FoxTube/Pages/MainPage.xaml.cs +++ b/FoxTube/Pages/MainPage.xaml.cs @@ -40,8 +40,7 @@ namespace FoxTube public DownloadAgent Agent = new DownloadAgent(); ApplicationDataContainer settings = ApplicationData.Current.LocalSettings; - - NotificationsCenter notificationsCenter = new NotificationsCenter(); + Sender s = Sender.None; public MainPage() { @@ -111,7 +110,6 @@ namespace FoxTube } catch { } } - notificationsCenter.Initialize(); SecretsVault.AuthorizationStateChanged += Vault_AuthorizationStateChanged; SecretsVault.SubscriptionsChanged += SecretsVault_SubscriptionsChanged; @@ -191,8 +189,8 @@ namespace FoxTube { Userinfoplus info = await new Oauth2Service(SecretsVault.Initializer).Userinfo.Get().ExecuteAsync(); - ToolTipService.SetToolTip(avatar, new ToolTip() { Content = info.Name }); - (avatar.Content as PersonPicture).ProfilePicture = new BitmapImage(new Uri(info.Picture)); + myName.Text = info.Name; + ((avatar.Content as StackPanel).Children[0] as PersonPicture).ProfilePicture = new BitmapImage(new Uri(info.Picture)); } catch { } avatar.Visibility = Visibility.Visible; @@ -256,16 +254,6 @@ namespace FoxTube GoToVideo((videoPlaceholder.Content as VideoPage).videoId); } - public void GotNotification() - { - notificationMenu.Content = "\xED0C"; - } - - public void notificationMenu_Click(object sender, RoutedEventArgs e) - { - notificationMenu.Content = "\xED0D"; - } - private async void feedback_Click(object sender, RoutedEventArgs e) { await Launcher.LaunchUriAsync(new Uri("feedback-hub:")); @@ -502,14 +490,14 @@ namespace FoxTube { Dictionary switchCase = new Dictionary() { - { typeof(Settings), () => header.Text = "Settings" }, - { typeof(ChannelPage), () => header.Text = "Channel" }, - { typeof(PlaylistPage), () => header.Text = "Playlist" }, - { typeof(Search), () => header.Text = "Search" }, - { typeof(Subscriptions), () => header.Text = "Subscriptions" }, - { typeof(History), () => header.Text = "History" }, - { typeof(Home), () => header.Text = "Home" }, - { typeof(Downloads), () => header.Text = "Downloads" } + { 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[e.SourcePageType](); } From dc8afa289150459343789518decd28227a74b468 Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Wed, 24 Oct 2018 16:46:22 +0300 Subject: [PATCH 26/62] Notificaions development 0 --- FoxTube.Background/BackgroundProcessor.cs | 144 ++++------- FoxTube.Background/Notification.cs | 264 ++++---------------- FoxTube/Controls/Advert.xaml | 15 ++ FoxTube/Controls/Advert.xaml.cs | 27 ++ FoxTube/FoxTube.csproj | 7 + FoxTube/Notifications/DownloadComplete.xml | 2 +- FoxTube/Notifications/ServerLogSamlpe.xml | 5 +- FoxTube/Pages/MainPage.xaml.cs | 30 +-- FoxTube/Pages/SettingsPages/General.xaml | 1 + FoxTube/Pages/SettingsPages/General.xaml.cs | 5 + 10 files changed, 165 insertions(+), 335 deletions(-) create mode 100644 FoxTube/Controls/Advert.xaml create mode 100644 FoxTube/Controls/Advert.xaml.cs diff --git a/FoxTube.Background/BackgroundProcessor.cs b/FoxTube.Background/BackgroundProcessor.cs index fa39192..5fa6e5b 100644 --- a/FoxTube.Background/BackgroundProcessor.cs +++ b/FoxTube.Background/BackgroundProcessor.cs @@ -16,13 +16,8 @@ using Windows.UI.Notifications; namespace FoxTube.Background { - public delegate void NotificationHandler(object sender, Notification item); - public sealed class BackgroundProcessor : IBackgroundTask { - public static event NotificationHandler NotificationRecieved; - - List Notifications = new List(); private DateTime lastCheck = DateTime.Now; private ApplicationDataContainer settings = ApplicationData.Current.LocalSettings; @@ -37,8 +32,6 @@ namespace FoxTube.Background ApiKey = "AIzaSyBgHrCnrlzlVmk0cJKL8RqP9Y8x6XSuk_0", ApplicationName = "FoxTube" }); - - XmlDocument doc = new XmlDocument(); BackgroundTaskDeferral def; public void Run(IBackgroundTaskInstance taskInstance) @@ -47,110 +40,81 @@ namespace FoxTube.Background if (settings.Values["lastCheck"] == null) settings.Values.Add("lastCheck", XmlConvert.ToString(DateTime.Now, "YYYY-MM-DDThh:mm:ss")); else lastCheck = XmlConvert.ToDateTime(settings.Values["lastCheck"] as string, XmlDateTimeSerializationMode.Unspecified); + + if((bool)settings.Values["newVideoNotification"]) + CheckAnnouncements(); + if((bool)settings.Values["devNews"]) + CheckAccount(); - try - { - doc.LoadXml(settings.Values["notificationsHistory"] as string); - } - catch - { - return; - } - - CheckAnnouncements(); - CheckAccount(); - - SendNSave(); + settings.Values["lastCheck"] = XmlConvert.ToString(DateTime.Now, "YYYY-MM-DDThh:mm:ss"); def.Complete(); } async void CheckAccount() { - UserCredential credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(Secrets, new[] { Google.Apis.Oauth2.v2.Oauth2Service.Scope.UserinfoProfile, YouTubeService.Scope.YoutubeForceSsl }, "user", CancellationToken.None); - if (credential == null) - return; - - SubscriptionsResource.ListRequest subRequest = new YouTubeService(new BaseClientService.Initializer() + try { - HttpClientInitializer = credential, - ApplicationName = "FoxTube" - }).Subscriptions.List("snippet"); - subRequest.Mine = true; - subRequest.MaxResults = 50; - SubscriptionListResponse subResponse = await subRequest.ExecuteAsync(); - Dictionary subs = new Dictionary(); + UserCredential credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(Secrets, new[] { Google.Apis.Oauth2.v2.Oauth2Service.Scope.UserinfoProfile, YouTubeService.Scope.YoutubeForceSsl }, "user", CancellationToken.None); + if (credential == null) + return; - foreach (Subscription s in subResponse.Items) - subs.Add(s.Snippet.ResourceId.ChannelId, s.Snippet.Thumbnails.Standard.Url); - - string nextToken = subResponse.NextPageToken; - while (nextToken != null) - { - subRequest.PageToken = nextToken; - subResponse = await subRequest.ExecuteAsync(); - nextToken = subResponse.NextPageToken; + SubscriptionsResource.ListRequest subRequest = new YouTubeService(new BaseClientService.Initializer() + { + HttpClientInitializer = credential, + ApplicationName = "FoxTube" + }).Subscriptions.List("snippet"); + subRequest.Mine = true; + subRequest.MaxResults = 50; + SubscriptionListResponse subResponse = await subRequest.ExecuteAsync(); + Dictionary subs = new Dictionary(); foreach (Subscription s in subResponse.Items) subs.Add(s.Snippet.ResourceId.ChannelId, s.Snippet.Thumbnails.Standard.Url); - } - foreach(var s in subs) - { - SearchResource.ListRequest request = Service.Search.List("snippet"); - request.PublishedAfter = lastCheck; - request.ChannelId = s.Key; - request.Type = "video"; - SearchListResponse response = await request.ExecuteAsync(); + string nextToken = subResponse.NextPageToken; + while (nextToken != null) + { + subRequest.PageToken = nextToken; + subResponse = await subRequest.ExecuteAsync(); + nextToken = subResponse.NextPageToken; - foreach (var i in response.Items) - Notifications.Add(new Notification("video", i.Id.VideoId, - i.Snippet.ChannelTitle, - i.Snippet.Title, - i.Snippet.PublishedAt.Value, - i.Snippet.Thumbnails.Standard.Url, - s.Value)); + foreach (Subscription s in subResponse.Items) + subs.Add(s.Snippet.ResourceId.ChannelId, s.Snippet.Thumbnails.Standard.Url); + } + + foreach (var s in subs) + { + SearchResource.ListRequest request = Service.Search.List("snippet"); + request.PublishedAfter = lastCheck; + request.ChannelId = s.Key; + request.Type = "video"; + request.MaxResults = 5; + SearchListResponse response = await request.ExecuteAsync(); + + foreach (var i in response.Items) + ToastNotificationManager.CreateToastNotifier().Show( + Notification.GetVideoToast(i.Id.VideoId, i.Snippet.ChannelId, i.Snippet.Title, i.Snippet.ChannelTitle, i.Snippet.Thumbnails.Medium.Url, s.Value)); + } } + catch { } } void CheckAnnouncements() { - XmlDocument doc = new XmlDocument(); - doc.Load(XmlReader.Create("http://foxgame.hol.es/foxtube-messages.xml")); - if ((XmlConvert.ToDateTimeOffset((doc["posts"].FirstChild as XmlElement).GetAttribute("time"), "YYYY-MM-DDThh:mm:ss") - lastCheck.ToUniversalTime()).TotalSeconds > 0) - Notifications.Add(new Notification("internal", (doc["posts"].FirstChild as XmlElement).GetAttribute("id"), - doc["posts"].FirstChild["header"].InnerText, - doc["posts"].FirstChild["notificationHeader"].InnerText, - XmlConvert.ToDateTimeOffset((doc["posts"].FirstChild as XmlElement).GetAttribute("time"), "YYYY-MM-DDThh:mm:ss"), - (doc["posts"].FirstChild as XmlElement).GetAttribute("image"), (doc["posts"].FirstChild as XmlElement).GetAttribute("avatar"))); - } - - void SendNotification(Notification notification) - { - ToastNotificationManager.CreateToastNotifier().Show(notification.GetToast()); - } - - void SendNSave() - { - foreach (Notification n in Notifications) + try { - NotificationRecieved.Invoke(this, n); - doc["history"].InnerXml += n.GetXml(); + XmlDocument doc = new XmlDocument(); + doc.Load(XmlReader.Create("http://foxgame.hol.es/foxtube-messages.xml")); + if ((XmlConvert.ToDateTimeOffset((doc["posts"].FirstChild as XmlElement).GetAttribute("time"), "YYYY-MM-DDThh:mm:ss") - lastCheck.ToUniversalTime()).TotalSeconds > 0) + ToastNotificationManager.CreateToastNotifier().Show( + Notification.GetInternalToast(doc["posts"].FirstChild["id"].InnerText, + doc["posts"].FirstChild["header"].InnerText, + doc["posts"].FirstChild["content"].InnerText, + doc["posts"].FirstChild["thumbnail"].InnerText, + doc["posts"].FirstChild["avatar"].InnerText)); } - settings.Values.Add("notificationsHistory", doc.InnerXml); - - foreach (Notification n in Notifications) - switch (n.Type) - { - case NotificationType.Video: - if ((bool)settings.Values["newVideoNotification"]) - SendNotification(n); - break; - - case NotificationType.Internal: - SendNotification(n); - break; - } + catch { } } } } diff --git a/FoxTube.Background/Notification.cs b/FoxTube.Background/Notification.cs index a872194..a1f08d0 100644 --- a/FoxTube.Background/Notification.cs +++ b/FoxTube.Background/Notification.cs @@ -1,235 +1,67 @@ -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.Data.Xml.Dom; 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.Background { - public enum NotificationType + public static class Notification { - Video, Comment, Post, Internal, Changelog - } - - public sealed class Notification - { - public string Channel { get; set; } - public string Content { get; set; } - public DateTimeOffset TimeStamp { get; set; } - public NotificationType Type { get; set; } - public string Avatar { get; set; } - public string Thumbnail { get; set; } - public string Id { get; set; } - - public Notification(string type, string id, - string channelName, string content, DateTimeOffset date, - string thumbnailUrl, string avatarUrl) - { - Channel = channelName; - Content = content; - TimeStamp = date; - Id = id; - Type = TypeConversion(type); - Avatar = avatarUrl ?? "ms-appx:///Assets/Icons/Profile.png"; - Thumbnail = thumbnailUrl; - } - - public Notification(string xmlSource) - { - System.Xml.XmlDocument d = new System.Xml.XmlDocument(); - d.InnerXml = xmlSource; - System.Xml.XmlElement xml = d["item"]; - - Channel = xml["channelName"].InnerText; - Content = xml["content"].InnerText; - TimeStamp = DateTimeOffset.Parse(xml.GetAttribute("time")); - Id = xml.GetAttribute("id"); - Type = TypeConversion(xml.GetAttribute("type")); - Avatar = xml["images"].GetAttribute("avatar"); - Thumbnail = xml["images"].GetAttribute("thumbnail"); - } - - public string GetXml() - { - return $@" - - {Channel} - {Content} - "; - } - - public Button GetNotification() - { - StackPanel stackPanel = new StackPanel() { Margin = new Thickness(10, 0, 0, 0) }; - - //Channel - switch (Type) - { - case NotificationType.Internal: - stackPanel.Children.Add(new TextBlock() - { - FontSize = 14, - FontStyle = Windows.UI.Text.FontStyle.Italic, - Foreground = new SolidColorBrush(Colors.Gray), - Text = "Developer's message" - }); - break; - - case NotificationType.Changelog: - stackPanel.Children.Add(new TextBlock() - { - FontSize = 14, - FontStyle = Windows.UI.Text.FontStyle.Italic, - Foreground = new SolidColorBrush(Colors.Gray), - Text = "Changelog" - }); - break; - - case NotificationType.Video: - stackPanel.Children.Add(new TextBlock() - { - FontSize = 14, - FontStyle = Windows.UI.Text.FontStyle.Italic, - Foreground = new SolidColorBrush(Colors.Gray), - Text = $"{Channel} uploaded new video" - }); - 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() + public static ToastNotification GetChangelogToast(string version) { XmlDocument template = new XmlDocument(); - switch (Type) - { - case NotificationType.Video: - template.LoadXml($@" - - - - {Content} - {Channel} uploaded a new video - - - - - - - - "); - break; - - case NotificationType.Changelog: - template.LoadXml($@" - - - - - {Content} - {Channel} - - - "); - break; - - case NotificationType.Internal: - template.LoadXml($@" - - - - - {Content} - {Channel} - - - "); - break; - } + template.LoadXml($@" + + + + + Changelog + See what's new in version {version} + + + "); return new ToastNotification(template); } - private string TypeConversion(NotificationType type) + public static ToastNotification GetVideoToast(string id, string channelId, string title, string channel, string thumbnail, string avatar) { - switch(type) - { - case NotificationType.Comment: - return "comment"; - case NotificationType.Post: - return "post"; - case NotificationType.Video: - return "video"; - case NotificationType.Changelog: - return "changelog"; - default: - return "internal"; - } + XmlDocument template = new XmlDocument(); + + template.LoadXml($@" + + + + + {title} + {channel} uploaded a new video + + + + + + + + "); + + return new ToastNotification(template); } - private NotificationType TypeConversion(string type) + public static ToastNotification GetInternalToast(string id, string header, string content, string thumbnail, string avatar) { - switch (type) - { - case "comment": - return NotificationType.Comment; - case "post": - return NotificationType.Post; - case "video": - return NotificationType.Video; - case "changelog": - return NotificationType.Changelog; - default: - return NotificationType.Internal; - } + XmlDocument template = new XmlDocument(); + + template.LoadXml($@" + + + + + {header} + {content} + + + "); + + return new ToastNotification(template); } } } diff --git a/FoxTube/Controls/Advert.xaml b/FoxTube/Controls/Advert.xaml new file mode 100644 index 0000000..3834488 --- /dev/null +++ b/FoxTube/Controls/Advert.xaml @@ -0,0 +1,15 @@ + + + + + + diff --git a/FoxTube/Controls/Advert.xaml.cs b/FoxTube/Controls/Advert.xaml.cs new file mode 100644 index 0000000..e2872c3 --- /dev/null +++ b/FoxTube/Controls/Advert.xaml.cs @@ -0,0 +1,27 @@ +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.Navigation; + +// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 + +namespace FoxTube.Controls +{ + public sealed partial class Advert : UserControl + { + public Advert() + { + this.InitializeComponent(); + } + } +} diff --git a/FoxTube/FoxTube.csproj b/FoxTube/FoxTube.csproj index 67b00cd..fd5e489 100644 --- a/FoxTube/FoxTube.csproj +++ b/FoxTube/FoxTube.csproj @@ -101,6 +101,9 @@ + + Advert.xaml + ChannelCard.xaml @@ -277,6 +280,10 @@ MSBuild:Compile Designer + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/FoxTube/Notifications/DownloadComplete.xml b/FoxTube/Notifications/DownloadComplete.xml index 0cc68f2..91e9c37 100644 --- a/FoxTube/Notifications/DownloadComplete.xml +++ b/FoxTube/Notifications/DownloadComplete.xml @@ -1 +1 @@ - Download complete Subnautica - SAY GOODBYE TO SUBNAUTICA! We're Back Home! - Subnautica Ending (Full Release Gameplay) \ No newline at end of file + Download complete Subnautica - SAY GOODBYE TO SUBNAUTICA! We're Back Home! - Subnautica Ending (Full Release Gameplay) \ No newline at end of file diff --git a/FoxTube/Notifications/ServerLogSamlpe.xml b/FoxTube/Notifications/ServerLogSamlpe.xml index 1eecfe5..2c9c73f 100644 --- a/FoxTube/Notifications/ServerLogSamlpe.xml +++ b/FoxTube/Notifications/ServerLogSamlpe.xml @@ -1,6 +1,7 @@  - - Short headline for toast notifications + + +
Main headline for full post
Announcement body (beware of special characters)
diff --git a/FoxTube/Pages/MainPage.xaml.cs b/FoxTube/Pages/MainPage.xaml.cs index 1717536..94c642b 100644 --- a/FoxTube/Pages/MainPage.xaml.cs +++ b/FoxTube/Pages/MainPage.xaml.cs @@ -53,8 +53,8 @@ namespace FoxTube if (settings.Values["newVideoNotification"] == null) settings.Values.Add("newVideoNotification", true); - if (settings.Values["newmessagesNotification"] == null) - settings.Values.Add("newmessagesNotification", true); + if (settings.Values["devNews"] == null) + settings.Values.Add("devNews", true); if (settings.Values["moblieWarning"] == null) settings.Values.Add("moblieWarning", false); @@ -70,19 +70,11 @@ namespace FoxTube if (settings.Values["safeSearch"] == null) settings.Values.Add("safeSearch", 0); - if (settings.Values["notificationsHistory"] == null) - { - XmlDocument doc = new XmlDocument(); - doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", null)); - doc.AppendChild(doc.CreateElement("history")); - settings.Values.Add("notificationsHistory", doc.InnerXml); - } - 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((string)settings.Values["ver"] == $"{ver.Major}.{ver.Minor}") //Replace for '!=' !!! { try { @@ -90,21 +82,7 @@ namespace FoxTube changelog.Load("http://foxgame.hol.es/foxtube-changelog.xml"); XmlElement e = changelog["items"].ChildNodes[0] as XmlElement; - XmlDocument doc = new XmlDocument(); - doc.LoadXml(settings.Values["notificationsHistory"] as string); - - Background.Notification n = new Background.Notification("changelog", - $"changelog-{e.GetAttribute("version").Replace('.', '-')}", - "Changelog", - $"What's new in version {e.GetAttribute("version")}", - DateTime.Parse(e.GetAttribute("time")), - "http://foxgame.hol.es/FoxTubeAssets/WhatsNewThumb.png", - "http://foxgame.hol.es/FoxTubeAssets/NewsAvatar.png"); - - doc["history"].InnerXml += n.GetXml(); - settings.Values["notificationsHistory"] = doc.InnerXml; - - ToastNotificationManager.CreateToastNotifier().Show(n.GetToast()); + ToastNotificationManager.CreateToastNotifier().Show(FoxTube.Background.Notification.GetChangelogToast(e.GetAttribute("version"))); settings.Values["ver"] = $"{ver.Major}.{ver.Minor}"; } diff --git a/FoxTube/Pages/SettingsPages/General.xaml b/FoxTube/Pages/SettingsPages/General.xaml index cbdfac1..1f9d57f 100644 --- a/FoxTube/Pages/SettingsPages/General.xaml +++ b/FoxTube/Pages/SettingsPages/General.xaml @@ -42,6 +42,7 @@ + diff --git a/FoxTube/Pages/SettingsPages/General.xaml.cs b/FoxTube/Pages/SettingsPages/General.xaml.cs index f95c6bc..4a448fd 100644 --- a/FoxTube/Pages/SettingsPages/General.xaml.cs +++ b/FoxTube/Pages/SettingsPages/General.xaml.cs @@ -134,5 +134,10 @@ namespace FoxTube.Pages.SettingsPages { CoreApplication.Exit(); } + + private void devNews_Toggled(object sender, RoutedEventArgs e) + { + settings.Values["devnews"] = devNews.IsOn; + } } } From f545edc6c140c8540b824716c84419382f06ff93 Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Wed, 24 Oct 2018 21:07:08 +0300 Subject: [PATCH 27/62] Toast notifications for downloads --- FoxTube.Background/Notification.cs | 6 +-- FoxTube/Controls/DownloadItem.xaml | 2 +- FoxTube/Controls/DownloadItem.xaml.cs | 65 ++++++++++++++++++++++++--- FoxTube/Pages/Downloads.xaml.cs | 15 ++++++- FoxTube/Pages/MainPage.xaml.cs | 2 +- 5 files changed, 78 insertions(+), 12 deletions(-) diff --git a/FoxTube.Background/Notification.cs b/FoxTube.Background/Notification.cs index a1f08d0..8d3bebe 100644 --- a/FoxTube.Background/Notification.cs +++ b/FoxTube.Background/Notification.cs @@ -9,7 +9,7 @@ namespace FoxTube.Background { XmlDocument template = new XmlDocument(); - template.LoadXml($@" + template.LoadXml($@" @@ -27,7 +27,7 @@ namespace FoxTube.Background { XmlDocument template = new XmlDocument(); - template.LoadXml($@" + template.LoadXml($@" @@ -50,7 +50,7 @@ namespace FoxTube.Background { XmlDocument template = new XmlDocument(); - template.LoadXml($@" + template.LoadXml($@" diff --git a/FoxTube/Controls/DownloadItem.xaml b/FoxTube/Controls/DownloadItem.xaml index 720434e..34b5a96 100644 --- a/FoxTube/Controls/DownloadItem.xaml +++ b/FoxTube/Controls/DownloadItem.xaml @@ -45,7 +45,7 @@
- + - - - - + + + diff --git a/FoxTube/Pages/MainPage.xaml.cs b/FoxTube/Pages/MainPage.xaml.cs index 387497b..f11b131 100644 --- a/FoxTube/Pages/MainPage.xaml.cs +++ b/FoxTube/Pages/MainPage.xaml.cs @@ -81,7 +81,7 @@ namespace FoxTube try { XmlDocument changelog = new XmlDocument(); - changelog.Load("http://foxgame.hol.es/foxtube-changelog.xml"); + changelog.Load("http://foxgame-studio.000webhostapp.com/foxtube-changelog.xml"); XmlElement e = changelog["items"].ChildNodes[0] as XmlElement; ToastNotificationManager.CreateToastNotifier().Show(FoxTube.Background.Notification.GetChangelogToast(e.GetAttribute("version"))); @@ -100,6 +100,11 @@ namespace FoxTube Initialize(); } + async void GetVideosFromToday() + { + + } + public async void Initialize() { if (await ApplicationData.Current.RoamingFolder.GetFileAsync("notifications.json") != null) @@ -130,7 +135,7 @@ namespace FoxTube titleBar.ButtonBackgroundColor = Colors.Red; titleBar.ButtonHoverBackgroundColor = Colors.IndianRed; titleBar.ButtonPressedBackgroundColor = Colors.DarkRed; - titleBar.ButtonInactiveBackgroundColor = Colors.DarkRed; + titleBar.ButtonInactiveBackgroundColor = Colors.Black; titleBar.ForegroundColor = Colors.White; CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = false; @@ -141,18 +146,23 @@ namespace FoxTube if ((string)args[0] == "add" && nav.MenuItems.Count < 19) { Subscription s = args[1] as Subscription; - StackPanel panel = new StackPanel() { Orientation = Orientation.Horizontal }; + StackPanel panel = new StackPanel() + { + Orientation = Orientation.Horizontal, + Padding = new Thickness(5) + }; panel.Children.Add(new PersonPicture() { Height = 20, - Margin = new Thickness(0, 0, 13, 0), + 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() + Name = (nav.MenuItems.Count - 9).ToString(), + Padding = new Thickness(-5) }); } else if ((string)args[0] == "remove" && (int)args[1] < 10) @@ -190,18 +200,23 @@ namespace FoxTube try { Subscription s = SecretsVault.Subscriptions[k]; - StackPanel panel = new StackPanel() { Orientation = Orientation.Horizontal }; + StackPanel panel = new StackPanel() + { + Orientation = Orientation.Horizontal, + Padding = new Thickness(5) + }; panel.Children.Add(new PersonPicture() { Height = 20, - Margin = new Thickness(0, 0, 13, 0), + 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 = k.ToString() + Name = k.ToString(), + Padding = new Thickness(-5) }); } catch { continue; } @@ -234,7 +249,7 @@ namespace FoxTube GoToVideo((videoPlaceholder.Content as VideoPage).videoId); } - private async void feedback_Click(object sender, RoutedEventArgs e) + private async void feedback_Click(object sender, TappedRoutedEventArgs e) { await Launcher.LaunchUriAsync(new Uri("feedback-hub:")); } @@ -466,33 +481,37 @@ namespace FoxTube private void nav_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args) { - if (s == Sender.None) + try { - s = Sender.Menu; - if (args.IsSettingsSelected) - content.Navigate(typeof(Settings)); - else + if (s == Sender.None) { - if (args.SelectedItem == toHome) - content.Navigate(typeof(Home)); - else if (args.SelectedItem == toHistory) - content.Navigate(typeof(History)); - 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); - else if (args.SelectedItem == toSubscriptions) - content.Navigate(typeof(Subscriptions)); - else if (args.SelectedItem == toDownloads) - content.Navigate(typeof(Downloads)); - else if (args.SelectedItem == toChannel) - content.Navigate(typeof(ChannelPage), SecretsVault.UserChannel.Id); + s = Sender.Menu; + if (args.IsSettingsSelected) + content.Navigate(typeof(Settings)); else - content.Navigate(typeof(ChannelPage), SecretsVault.Subscriptions[Convert.ToInt32((args.SelectedItem as NavigationViewItem).Name)].Snippet.ResourceId.ChannelId); + { + if (args.SelectedItem == toHome) + content.Navigate(typeof(Home)); + else if (args.SelectedItem == toHistory) + content.Navigate(typeof(History)); + 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); + else if (args.SelectedItem == toSubscriptions) + content.Navigate(typeof(Subscriptions)); + else if (args.SelectedItem == toDownloads) + content.Navigate(typeof(Downloads)); + else if (args.SelectedItem == toChannel) + content.Navigate(typeof(ChannelPage), SecretsVault.UserChannel.Id); + else + content.Navigate(typeof(ChannelPage), SecretsVault.Subscriptions[Convert.ToInt32((args.SelectedItem as NavigationViewItem).Name)].Snippet.ResourceId.ChannelId); + } } + else + s = Sender.None; } - else - s = Sender.None; + catch { } } public void content_Navigated(object sender, NavigationEventArgs e) @@ -681,5 +700,10 @@ namespace FoxTube (videoPlaceholder.Content as VideoPage).player.KeyUpPressed(sender, e); } } + + private void openContext(object sender, TappedRoutedEventArgs e) + { + ((NavigationViewItem)sender).ContextFlyout.ShowAt((NavigationViewItem)sender); + } } } diff --git a/FoxTube/Pages/SettingsPages/Inbox.xaml.cs b/FoxTube/Pages/SettingsPages/Inbox.xaml.cs index 70cfad5..06dce6f 100644 --- a/FoxTube/Pages/SettingsPages/Inbox.xaml.cs +++ b/FoxTube/Pages/SettingsPages/Inbox.xaml.cs @@ -40,14 +40,14 @@ namespace FoxTube.Pages.SettingsPages { XmlDocument doc = new XmlDocument(); - doc.Load("http://foxgame.hol.es/foxtube-changelog.xml"); + doc.Load("http://foxgame-studio.000webhostapp.com/foxtube-changelog.xml"); foreach (XmlElement e in doc["items"].ChildNodes) items.Add(new InboxItem( e.GetAttribute("version"), e["content"].InnerText, e.GetAttribute("time"))); - doc.Load("http://foxgame.hol.es/foxtube-messages.xml"); + doc.Load("http://foxgame-studio.000webhostapp.com/foxtube-messages.xml"); foreach (XmlElement e in doc["posts"].ChildNodes) items.Add(new InboxItem( e["header"].InnerText, diff --git a/FoxTube/Pages/VideoPage.xaml.cs b/FoxTube/Pages/VideoPage.xaml.cs index 9b405a1..ccafc1a 100644 --- a/FoxTube/Pages/VideoPage.xaml.cs +++ b/FoxTube/Pages/VideoPage.xaml.cs @@ -208,8 +208,6 @@ namespace FoxTube.Pages } } subscribe.Visibility = Visibility.Visible; - - SecretsVault.HistoryAdd(videoId); } else { diff --git a/FoxTube/Strings/en-US/Main.resw b/FoxTube/Strings/en-US/Main.resw index d3b5ac1..ba22dcd 100644 --- a/FoxTube/Strings/en-US/Main.resw +++ b/FoxTube/Strings/en-US/Main.resw @@ -117,13 +117,13 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + Remove ads Downloads - + Give a feedback diff --git a/FoxTube/Strings/ru-RU/Main.resw b/FoxTube/Strings/ru-RU/Main.resw index d907b3b..5d461a8 100644 --- a/FoxTube/Strings/ru-RU/Main.resw +++ b/FoxTube/Strings/ru-RU/Main.resw @@ -117,13 +117,13 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + Убрать рекламу Загрузки - + Оставить отзыв From aa3214cc60d885cd909bee6b086304a6d4ae7f0d Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Sun, 9 Dec 2018 17:15:16 +0300 Subject: [PATCH 37/62] #219: Fixed --- FoxTube/App.xaml.cs | 9 +++++---- FoxTube/Classes/DownloadAgent.cs | 30 ++++++++++------------------ FoxTube/Classes/SecretsVault.cs | 16 +++++++-------- FoxTube/Controls/VideoCard.xaml.cs | 10 ++++------ FoxTube/Controls/VideoPlayer.xaml.cs | 4 ++-- FoxTube/Pages/History.xaml | 2 +- FoxTube/Pages/History.xaml.cs | 9 +++------ FoxTube/Pages/Subscriptions.xaml | 2 +- FoxTube/Pages/Subscriptions.xaml.cs | 5 +++++ FoxTube/Pages/VideoPage.xaml | 6 ++++++ 10 files changed, 45 insertions(+), 48 deletions(-) diff --git a/FoxTube/App.xaml.cs b/FoxTube/App.xaml.cs index acc846c..0bfc754 100644 --- a/FoxTube/App.xaml.cs +++ b/FoxTube/App.xaml.cs @@ -260,20 +260,21 @@ namespace FoxTube /// /// The source of the suspend request. /// Details about the suspend request. - private async void OnSuspending(object sender, SuspendingEventArgs e) + private void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); - //await new MessageDialog("suspending").ShowAsync(); + //Saving history - await FileIO.WriteTextAsync( + /*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)); + JsonConvert.SerializeObject(SecretsVault.WatchLater));*/ //Saving downloads Methods.MainPage.Agent.QuitPrompt(); + ToastNotificationManager.CreateToastNotifier().Show(Background.Notification.GetInternalToast(null, "All data saved", "", null, null)); deferral.Complete(); } } diff --git a/FoxTube/Classes/DownloadAgent.cs b/FoxTube/Classes/DownloadAgent.cs index 7469530..6fb413b 100644 --- a/FoxTube/Classes/DownloadAgent.cs +++ b/FoxTube/Classes/DownloadAgent.cs @@ -52,29 +52,19 @@ namespace FoxTube.Controls items.Remove(item); } - public void QuitPrompt() + public async void QuitPrompt() { - if(items.Exists(x => x.InProgress)) - { - MessageDialog dialog = new MessageDialog($"Waiting pending downloads ({items.FindAll(x => x.InProgress).Count})..."); + foreach (DownloadItem i in items.FindAll(x => x.InProgress)) + i.Cancel(); + items.RemoveAll(x => x.InProgress); - dialog.Commands.Add(new UICommand("Force quit", async (command) => - { - foreach (DownloadItem i in items.FindAll(x => x.InProgress)) - i.Cancel(); - items.RemoveAll(x => x.InProgress); + List containers = new List(); + foreach (DownloadItem i in items) + containers.Add(i.Container); - List containers = new List(); - foreach (DownloadItem i in items) - containers.Add(i.Container); - - await FileIO.WriteTextAsync( - await roaming.CreateFileAsync("downloads.json", CreationCollisionOption.ReplaceExisting), - JsonConvert.SerializeObject(containers)); - })); - - prompt = dialog.ShowAsync(); - } + await FileIO.WriteTextAsync( + await roaming.CreateFileAsync("downloads.json", CreationCollisionOption.ReplaceExisting), + JsonConvert.SerializeObject(containers)); } } } diff --git a/FoxTube/Classes/SecretsVault.cs b/FoxTube/Classes/SecretsVault.cs index f8fdb78..53a452a 100644 --- a/FoxTube/Classes/SecretsVault.cs +++ b/FoxTube/Classes/SecretsVault.cs @@ -16,7 +16,7 @@ using Windows.UI.Popups; namespace FoxTube { - public class HistoryItem + /*public class HistoryItem { public string Id { get; set; } public double LeftOn { get; set; } @@ -32,7 +32,7 @@ namespace FoxTube Id = id; LeftOn = 0; } - } + }*/ public static class SecretsVault { @@ -57,8 +57,8 @@ namespace FoxTube public static bool IsAuthorized { get; private set; } = false; public static 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 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() @@ -77,14 +77,14 @@ namespace FoxTube } } - public static void HistoryAdd(string id, TimeSpan elapsed, TimeSpan total) + /*public static void HistoryAdd(string id, TimeSpan elapsed, TimeSpan total) { UserHistory.Remove(UserHistory.Find(x => x.Id == id)); UserHistory.Add(new HistoryItem(id, elapsed, total)); if (UserHistory.Count > 100) UserHistory.RemoveAt(UserHistory.Count - 1); - } + }*/ public static async Task ChangeSubscriptionState(string id) { @@ -208,7 +208,7 @@ namespace FoxTube UserChannel = (await request.ExecuteAsync()).Items[0]; AccountId = UserChannel.Id; - try + /*try { await ApplicationData.Current.RoamingFolder.GetFileAsync("history.json"); UserHistory = JsonConvert.DeserializeObject>(await FileIO.ReadTextAsync(await ApplicationData.Current.RoamingFolder.GetFileAsync("history.json"))); @@ -231,7 +231,7 @@ namespace FoxTube 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; diff --git a/FoxTube/Controls/VideoCard.xaml.cs b/FoxTube/Controls/VideoCard.xaml.cs index 23a4cae..4ad9977 100644 --- a/FoxTube/Controls/VideoCard.xaml.cs +++ b/FoxTube/Controls/VideoCard.xaml.cs @@ -30,9 +30,7 @@ namespace FoxTube.Controls public async void Initialize(string id, string playlist = null) { - YouTubeService ytService = SecretsVault.NoAuthService; - - VideosResource.ListRequest request = ytService.Videos.List("snippet,contentDetails,statistics,liveStreamingDetails"); + VideosResource.ListRequest request = SecretsVault.Service.Videos.List("snippet,contentDetails,statistics,liveStreamingDetails"); request.Id = id; VideoListResponse response = await request.ExecuteAsync(); @@ -71,7 +69,7 @@ namespace FoxTube.Controls embed = false; } - var request1 = ytService.Channels.List("snippet"); + var request1 = SecretsVault.Service.Channels.List("snippet"); request1.Id = item.Snippet.ChannelId; ChannelListResponse response1 = await request1.ExecuteAsync(); @@ -82,11 +80,11 @@ namespace FoxTube.Controls } catch { } - if(SecretsVault.UserHistory.Exists(x => x.Id == videoId)) + /*if(SecretsVault.UserHistory.Exists(x => x.Id == videoId)) { watched.Visibility = Visibility.Visible; leftOn.Value = SecretsVault.UserHistory.Find(x => x.Id == videoId).LeftOn; - } + }*/ } public async void Button_Click(object sender, RoutedEventArgs e) diff --git a/FoxTube/Controls/VideoPlayer.xaml.cs b/FoxTube/Controls/VideoPlayer.xaml.cs index 64052d2..72bc6d3 100644 --- a/FoxTube/Controls/VideoPlayer.xaml.cs +++ b/FoxTube/Controls/VideoPlayer.xaml.cs @@ -203,7 +203,7 @@ namespace FoxTube systemControls.ButtonPressed += SystemControls_Engaged; systemControls.IsEnabled = true; - SecretsVault.HistoryAdd(videoId, elapsed, total); + //SecretsVault.HistoryAdd(videoId, elapsed, total); t.Start(); @@ -615,7 +615,7 @@ namespace FoxTube break; } - SecretsVault.HistoryAdd(videoId, elapsed, total); + //SecretsVault.HistoryAdd(videoId, elapsed, total); } private async void miniView_Click(object sender, RoutedEventArgs e) diff --git a/FoxTube/Pages/History.xaml b/FoxTube/Pages/History.xaml index e618e2f..5f274ca 100644 --- a/FoxTube/Pages/History.xaml +++ b/FoxTube/Pages/History.xaml @@ -20,7 +20,7 @@ - + diff --git a/FoxTube/Pages/History.xaml.cs b/FoxTube/Pages/History.xaml.cs index 7565c21..6211a17 100644 --- a/FoxTube/Pages/History.xaml.cs +++ b/FoxTube/Pages/History.xaml.cs @@ -34,10 +34,7 @@ namespace FoxTube.Pages public void Initialize() { loading.Refresh(); - - list.Clear(); - SecretsVault.UserHistory.ForEach(i => list.Add(new VideoCard(i.Id))); - + loading.Close(); } @@ -46,9 +43,9 @@ namespace FoxTube.Pages await Launcher.LaunchUriAsync(new Uri("youtube.com/feed/history")); } - private void help_Click(object sender, RoutedEventArgs e) + private void Refresh_Click(object sender, RoutedEventArgs e) { - Methods.MainPage.GoToDeveloper("local-history"); + } } } diff --git a/FoxTube/Pages/Subscriptions.xaml b/FoxTube/Pages/Subscriptions.xaml index 2a9729b..984d428 100644 --- a/FoxTube/Pages/Subscriptions.xaml +++ b/FoxTube/Pages/Subscriptions.xaml @@ -15,7 +15,7 @@ - From 1105460cae496657722a4c681a94af8677ceaf38 Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Wed, 12 Dec 2018 21:15:38 +0300 Subject: [PATCH 38/62] #166: Done --- FoxTube/App.xaml.cs | 18 +++--- FoxTube/Classes/DownloadAgent.cs | 72 +++++++++++++----------- FoxTube/Classes/DownloadItemContainer.cs | 4 +- FoxTube/Controls/DownloadItem.xaml | 4 +- FoxTube/Controls/DownloadItem.xaml.cs | 70 ++++++++++++++--------- FoxTube/Controls/VideoCard.xaml | 11 ++++ FoxTube/Package.appxmanifest | 4 +- FoxTube/Pages/Downloads.xaml | 30 ++++++++-- FoxTube/Pages/Downloads.xaml.cs | 42 +++++++++++--- FoxTube/Pages/MainPage.xaml.cs | 10 +++- FoxTube/Pages/VideoPage.xaml.cs | 2 +- 11 files changed, 179 insertions(+), 88 deletions(-) diff --git a/FoxTube/App.xaml.cs b/FoxTube/App.xaml.cs index 0bfc754..8290dd6 100644 --- a/FoxTube/App.xaml.cs +++ b/FoxTube/App.xaml.cs @@ -12,6 +12,7 @@ using Windows.ApplicationModel.Background; using Windows.ApplicationModel.Core; using Windows.Globalization; using Windows.Storage; +using Windows.System; using Windows.System.Power; using Windows.UI.Notifications; using Windows.UI.Popups; @@ -161,11 +162,6 @@ namespace FoxTube switch(arguments[0]) { - case "dcancel": - Debug.WriteLine("Cancel has been required"); - try { Methods.MainPage.Agent.Remove(arguments[1]); } - catch { } - break; case "later": try { @@ -194,6 +190,9 @@ namespace FoxTube Debug.WriteLine(e.Message); } break; + case "download": + await Launcher.LaunchFileAsync(await StorageFile.GetFileFromPathAsync(arguments[1])); + break; } } } @@ -237,6 +236,12 @@ namespace FoxTube case "channel": Methods.MainPage.GoToChannel(args[1]); break; + case "download": + Methods.MainPage.GoToDownloads(); + break; + case "dcancel": + DownloadAgent.Remove(args[1]); + break; } } @@ -273,8 +278,7 @@ namespace FoxTube await ApplicationData.Current.RoamingFolder.CreateFileAsync("watchlater.json", CreationCollisionOption.ReplaceExisting), JsonConvert.SerializeObject(SecretsVault.WatchLater));*/ //Saving downloads - Methods.MainPage.Agent.QuitPrompt(); - ToastNotificationManager.CreateToastNotifier().Show(Background.Notification.GetInternalToast(null, "All data saved", "", null, null)); + DownloadAgent.QuitPrompt(); deferral.Complete(); } } diff --git a/FoxTube/Classes/DownloadAgent.cs b/FoxTube/Classes/DownloadAgent.cs index 6fb413b..cd60ce3 100644 --- a/FoxTube/Classes/DownloadAgent.cs +++ b/FoxTube/Classes/DownloadAgent.cs @@ -1,70 +1,76 @@ using System; using System.Collections.Generic; -using System.IO; using Windows.Storage; using FoxTube.Classes; using Newtonsoft.Json; -using Windows.UI.Popups; using YoutubeExplode.Models.MediaStreams; using Google.Apis.YouTube.v3.Data; -using Windows.Foundation; +using System.Diagnostics; +using FoxTube.Controls; -namespace FoxTube.Controls +namespace FoxTube { - public class DownloadAgent + public static class DownloadAgent { - public List items = new List(); - StorageFolder roaming = ApplicationData.Current.RoamingFolder; - public IAsyncOperation prompt; - - public DownloadAgent() - { - Initialize(); - Windows.UI.Core.Preview.SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += (s, a) => QuitPrompt(); - } + public static List items = new List(); + private static ApplicationDataContainer settings = ApplicationData.Current.LocalSettings; + public static StorageFolder Downloads { get; set; } - public async void Initialize() + public static async void Initialize() { + Downloads = await KnownFolders.VideosLibrary.CreateFolderAsync("FoxTube", CreationCollisionOption.OpenIfExists); try { - List containers = JsonConvert.DeserializeObject>(await FileIO.ReadTextAsync(await roaming.GetFileAsync("downloads.json"))); - - foreach (DownloadItemContainer i in containers) - try { items.Add(new DownloadItem(i)); } - catch (FileNotFoundException) { } + List containers = JsonConvert.DeserializeObject>((string)settings.Values["downloads"]); + containers.ForEach(i => items.Add(new DownloadItem(i))); } catch { } } - public void Add(MediaStreamInfo info, Video meta, string qualty) + public static void Add(MediaStreamInfo info, Video meta, string qualty) { - items.Add(new DownloadItem(info, meta, qualty)); + items.Insert(0, new DownloadItem(info, meta, qualty)); } - public void Remove(string id) + public static void CancelItem(string id) + { + DownloadItem item = items.Find(x => x.Container.Id == id); + if (item == null || !item.InProgress) + return; + + item.CancelPrompt(); + } + + public static void Remove(string id) { DownloadItem item = items.Find(x => x.Container.Id == id); if (item == null) return; + if (item.InProgress) - item.cancel_Click(this, null); - else + item.Cancel(); + else items.Remove(item); } - public async void QuitPrompt() + public static void QuitPrompt() { - foreach (DownloadItem i in items.FindAll(x => x.InProgress)) + foreach (DownloadItem i in items.FindAll(i => i.InProgress)) i.Cancel(); - items.RemoveAll(x => x.InProgress); List containers = new List(); - foreach (DownloadItem i in items) - containers.Add(i.Container); + items.ForEach(i => containers.Add(i.Container)); - await FileIO.WriteTextAsync( - await roaming.CreateFileAsync("downloads.json", CreationCollisionOption.ReplaceExisting), - JsonConvert.SerializeObject(containers)); + string data = JsonConvert.SerializeObject(containers); + + try + { + settings.Values["downloads"] = data; + } + catch + { + settings.Values.Add("downloads", data); + } } } } diff --git a/FoxTube/Classes/DownloadItemContainer.cs b/FoxTube/Classes/DownloadItemContainer.cs index 05dcdbb..b857c75 100644 --- a/FoxTube/Classes/DownloadItemContainer.cs +++ b/FoxTube/Classes/DownloadItemContainer.cs @@ -8,10 +8,10 @@ namespace FoxTube.Classes public string Title { get; set; } public string Channel { get; set; } public string Id { get; set; } - public Uri Path => File.Path.ToUri(); + public string Name { get; set; } + public string Extension { get; set; } public Uri Thumbnail { get; set; } public string Quality { get; set; } public TimeSpan Duration { get; set; } - public StorageFile File { get; set; } } } diff --git a/FoxTube/Controls/DownloadItem.xaml b/FoxTube/Controls/DownloadItem.xaml index 34b5a96..23eff25 100644 --- a/FoxTube/Controls/DownloadItem.xaml +++ b/FoxTube/Controls/DownloadItem.xaml @@ -20,7 +20,7 @@ - + @@ -47,7 +47,7 @@ - + + + + + + + + + + + diff --git a/FoxTube/Package.appxmanifest b/FoxTube/Package.appxmanifest index a403af9..3a8f43c 100644 --- a/FoxTube/Package.appxmanifest +++ b/FoxTube/Package.appxmanifest @@ -1,5 +1,5 @@  - + @@ -41,5 +41,7 @@ + + \ No newline at end of file diff --git a/FoxTube/Pages/Downloads.xaml b/FoxTube/Pages/Downloads.xaml index aa5ccd0..0a97c37 100644 --- a/FoxTube/Pages/Downloads.xaml +++ b/FoxTube/Pages/Downloads.xaml @@ -9,9 +9,29 @@ mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> - - - - - + + + + + + + + + + + + + - + - 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 @@ - - - - - - - - - - - - - - - -