diff --git a/FoxTube/Controls/VideoPlayer.xaml.cs b/FoxTube/Controls/VideoPlayer.xaml.cs index 90f49de..0c163ce 100644 --- a/FoxTube/Controls/VideoPlayer.xaml.cs +++ b/FoxTube/Controls/VideoPlayer.xaml.cs @@ -53,7 +53,6 @@ namespace FoxTube public event ObjectEventHandler SetFullSize; public event ObjectEventHandler NextClicked; - public Button Next => next; bool isMuxed = false; bool audioReady = false; diff --git a/FoxTube/Package.appxmanifest b/FoxTube/Package.appxmanifest index af79362..3a8f43c 100644 --- a/FoxTube/Package.appxmanifest +++ b/FoxTube/Package.appxmanifest @@ -1,6 +1,6 @@  - + FoxTube diff --git a/FoxTube/Pages/MainPage.xaml.cs b/FoxTube/Pages/MainPage.xaml.cs index 5fdad95..cff7741 100644 --- a/FoxTube/Pages/MainPage.xaml.cs +++ b/FoxTube/Pages/MainPage.xaml.cs @@ -392,13 +392,6 @@ namespace FoxTube nav.IsBackEnabled = true; else nav.IsBackEnabled = false; - - if (content.SourcePageType == typeof(Home) || content.SourcePageType == typeof(Settings) || content.SourcePageType == typeof(Subscriptions)) - { - nav.ExpandedModeThresholdWidth = 1008; - if (nav.DisplayMode == NavigationViewDisplayMode.Expanded) - nav.IsPaneOpen = true; - } } public void MaximizeVideo() @@ -410,9 +403,6 @@ namespace FoxTube videoPlaceholder.Margin = new Thickness(0); nav.IsBackEnabled = true; - - nav.ExpandedModeThresholdWidth = short.MaxValue; - nav.IsPaneOpen = false; } public void Fullscreen(bool on) @@ -451,6 +441,7 @@ namespace FoxTube (videoPlaceholder.Content as VideoPage).player.pointerCaptured = false; videoPlaceholder.Content = null; Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Arrow, 0); + MaximizeVideo(); if (content.CanGoBack) nav.IsBackEnabled = true; @@ -674,7 +665,7 @@ namespace FoxTube nav.IsPaneOpen = true; } else - nav.ExpandedModeThresholdWidth = short.MaxValue; + nav.ExpandedModeThresholdWidth = int.MaxValue; if (videoPlaceholder.Content != null && videoPlaceholder.HorizontalAlignment == HorizontalAlignment.Stretch) MinimizeAsInitializer(); diff --git a/FoxTube/Pages/VideoPage.xaml b/FoxTube/Pages/VideoPage.xaml index 444f60d..3e4c9b9 100644 --- a/FoxTube/Pages/VideoPage.xaml +++ b/FoxTube/Pages/VideoPage.xaml @@ -82,7 +82,26 @@ - + + + + + + + + + + + + + + + + + + + + diff --git a/FoxTube/Pages/VideoPage.xaml.cs b/FoxTube/Pages/VideoPage.xaml.cs index 9e086c4..6d41da4 100644 --- a/FoxTube/Pages/VideoPage.xaml.cs +++ b/FoxTube/Pages/VideoPage.xaml.cs @@ -20,7 +20,7 @@ using FoxTube.Controls; using YoutubeExplode.Models.MediaStreams; using YoutubeExplode; -//TODO: Refactor page sizing algorythm; Cleanup code +// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 namespace FoxTube.Pages { @@ -61,8 +61,6 @@ namespace FoxTube.Pages public CommentsPage comments; public LoadingPage loading; - DispatcherTimer liveTimer; - public VideoPage() { this.InitializeComponent(); @@ -92,10 +90,7 @@ namespace FoxTube.Pages private void Player_NextClicked(object sender, params object[] e) { - if(playlistId != null) - playlistList.SelectedIndex++; - else - (relatedVideos.Children[0] as VideoCard).Button_Click(this, null); + (relatedVideos.Children[0] as VideoCard).Button_Click(this, null); } protected override void OnNavigatedTo(NavigationEventArgs e) @@ -116,20 +111,123 @@ namespace FoxTube.Pages videoId = ids[0]; if (ids[1] != null) - LoadPlaylist(ids[1]); + { + playlistId = ids[1]; + List items = new List(); + VideoPlaylistItem selection = null; + + PlaylistsResource.ListRequest playlistRequest = SecretsVault.Service.Playlists.List("snippet,contentDetails"); + playlistRequest.Id = ids[1]; + Playlist playlistItem = (await playlistRequest.ExecuteAsync()).Items[0]; + + playlistName.Text = playlistItem.Snippet.Title; + playlistChannel.Text = playlistItem.Snippet.ChannelTitle; + + PlaylistItemsResource.ListRequest listRequest = SecretsVault.Service.PlaylistItems.List("snippet"); + listRequest.MaxResults = 50; + listRequest.PlaylistId = ids[1]; + PlaylistItemListResponse listResponse = await listRequest.ExecuteAsync(); + + foreach (PlaylistItem i in listResponse.Items) + { + items.Add(new VideoPlaylistItem(i.Snippet.Thumbnails.Medium.Url, i.Snippet.Title, i.Snippet.ResourceId.VideoId)); + if (items.Last().Id == videoId) + selection = items.Last(); + } + + string token = listResponse.NextPageToken; + while(!string.IsNullOrWhiteSpace(token)) + { + listRequest.PageToken = token; + listResponse = await listRequest.ExecuteAsync(); + + foreach (PlaylistItem i in listResponse.Items) + { + items.Add(new VideoPlaylistItem(i.Snippet.Thumbnails.Medium.Url, i.Snippet.Title, i.Snippet.ResourceId.VideoId)); + if (items.Last().Id == videoId) + selection = items.Last(); + } + + token = listResponse.NextPageToken; + } + + for (int k = 0; k < items.Count; k++) + items[k].Number = k + 1; + + playlistCounter.Text = $"{items.IndexOf(selection) + 1}/{playlistItem.ContentDetails.ItemCount}"; + + playlistList.ItemsSource = items; + playlistList.SelectedItem = selection; + pivot.SelectedItem = playlist; + } else pivot.Items.Remove(playlist); - VideosResource.ListRequest request = SecretsVault.Service.Videos.List("snippet,statistics,status,contentDetails,liveStreamingDetails"); + VideosResource.ListRequest request = SecretsVault.Service.Videos.List("snippet,statistics,status,contentDetails"); request.Id = ids[0]; item = (await request.ExecuteAsync()).Items[0]; - if (item.Snippet.LiveBroadcastContent == "none") - LoadStats(); - else - LoadStream(); + title.Text = item.Snippet.Title; + Methods.FormatText(ref description, item.Snippet.Description); - LoadInfo(); + publishedAt.Text = item.Snippet.PublishedAt.ToString(); + if (item.Status.License == "youtube") + license.Text = "Standard YouTube License"; + else license.Text = "Creative Commons Attribution license (reuse allowed)"; + + VideoCategoriesResource.ListRequest categoryRequest = SecretsVault.NoAuthService.VideoCategories.List("snippet"); + categoryRequest.Id = item.Snippet.CategoryId; + category.Text = (await categoryRequest.ExecuteAsync()).Items[0].Snippet.Title; + + views.Text = $"{item.Statistics.ViewCount:0,0} views"; + dislikes.Text = $"{item.Statistics.DislikeCount:0,0}"; + likes.Text = $"{item.Statistics.LikeCount:0,0}"; + rating.Value = (double)item.Statistics.DislikeCount / (double)(item.Statistics.DislikeCount + item.Statistics.LikeCount) * 100; + + if (SecretsVault.IsAuthorized) + { + VideoGetRatingResponse ratingResponse = await SecretsVault.Service.Videos.GetRating(ids[0]).ExecuteAsync(); + if (ratingResponse.Items[0].Rating == "like") + { + userRating = Rating.Like; + like.Foreground = new SolidColorBrush(Colors.Green); + } + else if (ratingResponse.Items[0].Rating == "dislike") + { + userRating = Rating.Dislike; + dislike.Foreground = new SolidColorBrush(Colors.Red); + } + + foreach (Subscription s in SecretsVault.Subscriptions) + { + if (s.Snippet.ResourceId.ChannelId == item.Snippet.ChannelId) + { + subscribe.Background = new SolidColorBrush(Colors.Transparent); + subscribe.Foreground = new SolidColorBrush(Colors.Gray); + subscribe.Content = "Subscribed"; + } + } + subscribe.Visibility = Visibility.Visible; + } + else + { + download.Visibility = Visibility.Collapsed; + addTo.Visibility = Visibility.Collapsed; + subscribe.Visibility = Visibility.Collapsed; + } + + ChannelsResource.ListRequest channelRequest = SecretsVault.Service.Channels.List("snippet, statistics"); + channelRequest.Id = item.Snippet.ChannelId; + var item1 = (await channelRequest.ExecuteAsync()).Items[0]; + + channelAvatar.ProfilePicture = new BitmapImage(new Uri(item1.Snippet.Thumbnails.Medium.Url)); + channelName.Text = item.Snippet.ChannelTitle; + subscribers.Text = $"{item1.Statistics.SubscriberCount:0,0} subscribers"; + + comments.Initialize(item); + player.Initialize(item, item1.Snippet.Thumbnails.Medium.Url); + LoadRelatedVideos(); + LoadDownloads(); loading.Close(); } @@ -143,155 +241,6 @@ namespace FoxTube.Pages } } - async void LoadPlaylist(string id) - { - playlistId = id; - List items = new List(); - VideoPlaylistItem selection = null; - - //Retrieving data - PlaylistsResource.ListRequest playlistRequest = SecretsVault.Service.Playlists.List("snippet,contentDetails"); - playlistRequest.Id = id; - Playlist playlistItem = (await playlistRequest.ExecuteAsync()).Items[0]; - - PlaylistItemsResource.ListRequest listRequest = SecretsVault.Service.PlaylistItems.List("snippet"); - listRequest.MaxResults = 50; - listRequest.PlaylistId = id; - PlaylistItemListResponse listResponse = await listRequest.ExecuteAsync(); - - foreach (PlaylistItem i in listResponse.Items) - { - items.Add(new VideoPlaylistItem(i.Snippet.Thumbnails.Medium.Url, i.Snippet.Title, i.Snippet.ResourceId.VideoId)); - if (items.Last().Id == videoId) - selection = items.Last(); - } - - string token = listResponse.NextPageToken; - while (!string.IsNullOrWhiteSpace(token)) - { - listRequest.PageToken = token; - listResponse = await listRequest.ExecuteAsync(); - - foreach (PlaylistItem i in listResponse.Items) - { - items.Add(new VideoPlaylistItem(i.Snippet.Thumbnails.Medium.Url, i.Snippet.Title, i.Snippet.ResourceId.VideoId)); - if (items.Last().Id == videoId) - selection = items.Last(); - } - - token = listResponse.NextPageToken; - } - - for (int k = 0; k < items.Count; k++) - items[k].Number = k + 1; - - //Setting data - playlistName.Text = playlistItem.Snippet.Title; - playlistChannel.Text = playlistItem.Snippet.ChannelTitle; - - playlistCounter.Text = $"{items.IndexOf(selection) + 1}/{playlistItem.ContentDetails.ItemCount}"; - - playlistList.ItemsSource = items; - playlistList.SelectedItem = selection; - pivot.SelectedItem = playlist; - - if (playlistList.SelectedIndex == playlistList.Items.Count - 1) - player.Next.Visibility = Visibility.Collapsed; - } - - async void LoadInfo() - { - //Setting meta - title.Text = item.Snippet.Title; - Methods.FormatText(ref description, item.Snippet.Description); - - //Setting channel button - ChannelsResource.ListRequest channelRequest = SecretsVault.Service.Channels.List("snippet, statistics"); - channelRequest.Id = item.Snippet.ChannelId; - var item1 = (await channelRequest.ExecuteAsync()).Items[0]; - - channelAvatar.ProfilePicture = new BitmapImage(new Uri(item1.Snippet.Thumbnails.Medium.Url)); - channelName.Text = item.Snippet.ChannelTitle; - subscribers.Text = $"{item1.Statistics.SubscriberCount:0,0} subscribers"; - - //Setting ratings - dislikes.Text = $"{item.Statistics.DislikeCount:0,0}"; - likes.Text = $"{item.Statistics.LikeCount:0,0}"; - rating.Value = (double)item.Statistics.DislikeCount / (double)(item.Statistics.DislikeCount + item.Statistics.LikeCount) * 100; - - //Setting category - VideoCategoriesResource.ListRequest categoryRequest = SecretsVault.NoAuthService.VideoCategories.List("snippet"); - categoryRequest.Id = item.Snippet.CategoryId; - category.Text = (await categoryRequest.ExecuteAsync()).Items[0].Snippet.Title; - - //Setting User's rate - if (SecretsVault.IsAuthorized) - { - VideoGetRatingResponse ratingResponse = await SecretsVault.Service.Videos.GetRating(videoId).ExecuteAsync(); - if (ratingResponse.Items[0].Rating == "like") - { - userRating = Rating.Like; - like.Foreground = new SolidColorBrush(Colors.Green); - } - else if (ratingResponse.Items[0].Rating == "dislike") - { - userRating = Rating.Dislike; - dislike.Foreground = new SolidColorBrush(Colors.Red); - } - - foreach (Subscription s in SecretsVault.Subscriptions) - { - if (s.Snippet.ResourceId.ChannelId == item.Snippet.ChannelId) - { - subscribe.Background = new SolidColorBrush(Colors.Transparent); - subscribe.Foreground = new SolidColorBrush(Colors.Gray); - subscribe.Content = "Subscribed"; - } - } - subscribe.Visibility = Visibility.Visible; - } - else - { - download.Visibility = Visibility.Collapsed; - addTo.Visibility = Visibility.Collapsed; - subscribe.Visibility = Visibility.Collapsed; - } - - //Initializing player - player.Initialize(item, item1.Snippet.Thumbnails.Medium.Url); - - LoadRelatedVideos(); - } - - void LoadStream() - { - liveTimer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(10) }; - liveTimer.Tick += LiveStatsUpdate; - liveTimer.Start(); - LiveStatsUpdate(); - - commentsPlaceholder.Header = "Chat"; - //TODO: Initialize chat - download.Visibility = Visibility.Collapsed; - } - - private async void LiveStatsUpdate(object sender = null, object e = null) - { - VideosResource.ListRequest request = SecretsVault.Service.Videos.List("liveStreamingDetails"); - request.Id = videoId; - Video video = (await request.ExecuteAsync()).Items[0]; - - views.Text = $"{item.LiveStreamingDetails.ConcurrentViewers} viewers"; - } - - void LoadStats() - { - views.Text = $"{item.Statistics.ViewCount:0,0} views"; - - comments.Initialize(item); - LoadDownloads(); - } - async void LoadDownloads() { try @@ -302,10 +251,9 @@ namespace FoxTube.Pages MenuFlyoutItem menuItem = new MenuFlyoutItem() { Text = i.VideoQualityLabel, - Tag = new { i, i.VideoQualityLabel } + Tag = new object[] { i, i.VideoQualityLabel } }; - menuItem.Click += (sender, e) => - DownloadAgent.Add(((sender as MenuFlyoutItem).Tag as object[])[0] as MediaStreamInfo, item, ((sender as MenuFlyoutItem).Tag as object[])[1] as string); + menuItem.Click += downloadItemSelected; downloadSelector.Items.Add(menuItem); } @@ -314,17 +262,20 @@ namespace FoxTube.Pages Text = "Audio track", Tag = new object[] { infoSet.Audio[0], "Audio only" } }; - audioItem.Click += (sender, e) => - DownloadAgent.Add(((sender as MenuFlyoutItem).Tag as object[])[0] as MediaStreamInfo, item, ((sender as MenuFlyoutItem).Tag as object[])[1] as string); + audioItem.Click += downloadItemSelected; downloadSelector.Items.Add(audioItem); } catch (Exception e) { - Debug.WriteLine($"{e.GetType()}: '{e.Message}'"); - download.Visibility = Visibility.Collapsed; + loading.Error(e.GetType().ToString(), e.Message); } } + private void downloadItemSelected(object sender, RoutedEventArgs e) + { + DownloadAgent.Add(((sender as MenuFlyoutItem).Tag as object[])[0] as MediaStreamInfo, item, ((sender as MenuFlyoutItem).Tag as object[])[1] as string); + } + async void LoadRelatedVideos() { SearchResource.ListRequest request = SecretsVault.Service.Search.List("snippet"); @@ -381,7 +332,8 @@ namespace FoxTube.Pages public void refresh_Click(object sender, RoutedEventArgs e) { - Methods.MainPage.GoToVideo(videoId, playlistId); + player = new VideoPlayer(); + Initialize(new string[2] { videoId, playlistId }); } private void grid_SizeChanged(object sender, SizeChangedEventArgs e) @@ -536,8 +488,12 @@ namespace FoxTube.Pages private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { - if ((e.AddedItems[0] as VideoPlaylistItem).Id != videoId) - Methods.MainPage.GoToVideo((e.AddedItems[0] as VideoPlaylistItem).Id, playlistId); + try + { + if ((e.AddedItems[0] as VideoPlaylistItem).Id != videoId) + Methods.MainPage.GoToVideo((e.AddedItems[0] as VideoPlaylistItem).Id, playlistId); + } + catch { } } private async void subscribe_Click(object sender, RoutedEventArgs e)