2140ec0d5f
- Fixed some cases when the app crashes - Fixed app crashes on trying to navigate to not existing channel/playlist/video
791 lines
30 KiB
C#
791 lines
30 KiB
C#
using FoxTube.Controls;
|
|
using Google.Apis.YouTube.v3;
|
|
using Google.Apis.YouTube.v3.Data;
|
|
using Microsoft.AppCenter.Analytics;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.Threading.Tasks;
|
|
using Windows.ApplicationModel.DataTransfer;
|
|
using Windows.ApplicationModel.Resources;
|
|
using Windows.Foundation;
|
|
using Windows.System;
|
|
using Windows.UI;
|
|
using Windows.UI.Xaml;
|
|
using Windows.UI.Xaml.Controls;
|
|
using Windows.UI.Xaml.Media;
|
|
using Windows.UI.Xaml.Media.Imaging;
|
|
using Windows.UI.Xaml.Navigation;
|
|
using YoutubeExplode;
|
|
using YoutubeExplode.Models.MediaStreams;
|
|
|
|
namespace FoxTube.Pages
|
|
{
|
|
public enum Rating { None, Like, Dislike }
|
|
|
|
public class VideoPlaylistItem
|
|
{
|
|
public int Number { get; set; }
|
|
public string Thumbnail { get; private set; } = "/Assets/videoThumbSample.png";
|
|
public string Id { get; private set; }
|
|
public string Title { get; private set; }
|
|
|
|
public VideoPlaylistItem(string image, string title, string id)
|
|
{
|
|
Thumbnail = image;
|
|
Title = title;
|
|
Id = id;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Video page
|
|
/// </summary>
|
|
public sealed partial class VideoPage : Page, INavigationPage
|
|
{
|
|
ResourceLoader resources = ResourceLoader.GetForCurrentView("VideoPage");
|
|
|
|
public object Parameter { get; set; } = null;
|
|
|
|
public string playlistId = null;
|
|
public Video item;
|
|
public HistoryItem history;
|
|
public bool incognito = false;
|
|
|
|
bool isExtended = false;
|
|
|
|
Rating userRating = Rating.None;
|
|
|
|
DispatcherTimer liveTimer;
|
|
DispatcherTimer countdownTimer;
|
|
|
|
public VideoPlayer Player => player;
|
|
|
|
public VideoPage()
|
|
{
|
|
InitializeComponent();
|
|
|
|
if (Window.Current.Bounds.Width <= 1000)
|
|
{
|
|
Debug.WriteLine("Correcting layout...");
|
|
mainContent.Children.Remove(descriptionPanel);
|
|
pivot.Items.Insert(0, descriptionPanel);
|
|
|
|
tabsPlaceholder.Children.Remove(pivot);
|
|
mainContent.Children.Add(pivot);
|
|
|
|
grid.ColumnDefinitions[1].Width = new GridLength(0);
|
|
}
|
|
}
|
|
|
|
private void Player_NextClicked()
|
|
{
|
|
if (playlistId != null && playlistList.SelectedIndex + 1 < playlistList.Items.Count)
|
|
playlistList.SelectedIndex++;
|
|
else
|
|
(relatedVideos.Children[0] as VideoCard).Button_Click(this, null);
|
|
}
|
|
|
|
protected override void OnNavigatedTo(NavigationEventArgs e)
|
|
{
|
|
base.OnNavigatedTo(e);
|
|
Parameter = e.Parameter;
|
|
|
|
Initialize(e.Parameter as object[]);
|
|
}
|
|
|
|
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
|
{
|
|
base.OnNavigatedFrom(e);
|
|
Player.Player.Stop();
|
|
}
|
|
|
|
public async void Initialize(object[] ids)
|
|
{
|
|
try
|
|
{
|
|
incognito = (bool)ids[2];
|
|
|
|
if (ids[1] != null)
|
|
LoadPlaylist(ids[1] as string);
|
|
else
|
|
pivot.Items.Remove(playlist);
|
|
|
|
VideosResource.ListRequest request = SecretsVault.Service.Videos.List("snippet,statistics,status,contentDetails,liveStreamingDetails");
|
|
request.Id = ids[0] as string;
|
|
request.Hl = SettingsStorage.RelevanceLanguage;
|
|
item = (await request.ExecuteAsync()).Items[0];
|
|
|
|
if (item.Snippet.LiveBroadcastContent == "none")
|
|
LoadStats();
|
|
else
|
|
LoadStream();
|
|
|
|
if (item.Snippet.LiveBroadcastContent == "upcoming")
|
|
SetSchedule();
|
|
|
|
LoadInfo();
|
|
LoadAddTo();
|
|
|
|
Methods.MainPage.VideoContent.LoadingPage.Close();
|
|
}
|
|
catch (System.Net.Http.HttpRequestException)
|
|
{
|
|
Methods.MainPage.VideoContent.LoadingPage.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (item == null)
|
|
{
|
|
Methods.MainPage.PageContent.LoadingPage.Error("VideoNotFound", "Such video doesn't exist");
|
|
return;
|
|
}
|
|
|
|
Methods.MainPage.VideoContent.LoadingPage.Error(e.GetType().ToString(), e.Message);
|
|
Analytics.TrackEvent("Video loading error", new Dictionary<string, string>()
|
|
{
|
|
{ "Exception", e.GetType().ToString() },
|
|
{ "Message", e.Message },
|
|
{ "Video ID", item.Id },
|
|
{ "StackTrace", e.StackTrace }
|
|
});
|
|
}
|
|
}
|
|
|
|
void SetSchedule()
|
|
{
|
|
upcoming.Visibility = Visibility.Visible;
|
|
if (item.LiveStreamingDetails.ScheduledEndTime.HasValue || item.LiveStreamingDetails.ScheduledStartTime.HasValue)
|
|
schedule.Visibility = Visibility.Visible;
|
|
|
|
if (item.LiveStreamingDetails.ScheduledEndTime.HasValue)
|
|
{
|
|
end.Text = $"{resources.GetString("/VideoPage/end")} {item.LiveStreamingDetails.ScheduledEndTime.Value}";
|
|
end.Visibility = Visibility.Visible;
|
|
}
|
|
if (item.LiveStreamingDetails.ScheduledStartTime.HasValue)
|
|
{
|
|
start.Text = $"{resources.GetString("/VideoPage/start")} {item.LiveStreamingDetails.ScheduledStartTime.Value}";
|
|
start.Visibility = Visibility.Visible;
|
|
|
|
countdownPanel.Visibility = Visibility.Visible;
|
|
|
|
countdownTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
|
|
countdownTimer.Tick += (s, e) =>
|
|
{
|
|
countdown.Text = item.LiveStreamingDetails.ScheduledStartTime.Value > DateTime.Now ? "" : "-" + (item.LiveStreamingDetails.ScheduledStartTime.Value - DateTime.Now).ToString(@"hh\:mm\:ss");
|
|
if (countdown.Text == "00:00:00")
|
|
refresh_Click(this, null);
|
|
};
|
|
countdownTimer.Start();
|
|
}
|
|
}
|
|
|
|
async void LoadPlaylist(string id)
|
|
{
|
|
playlistId = id;
|
|
List<VideoPlaylistItem> items = new List<VideoPlaylistItem>();
|
|
VideoPlaylistItem selection = null;
|
|
|
|
if (id == "WL")
|
|
{
|
|
SecretsVault.WatchLater = await Methods.GetLater();
|
|
|
|
foreach (string i in SecretsVault.WatchLater)
|
|
{
|
|
VideosResource.ListRequest request = SecretsVault.Service.Videos.List("snippet");
|
|
request.Id = i;
|
|
Video v = (await request.ExecuteAsync()).Items[0];
|
|
items.Add(new VideoPlaylistItem(v.Snippet.Thumbnails.Medium.Url, v.Snippet.Title, i));
|
|
}
|
|
|
|
selection = items.Find(i => i.Id == item.Id);
|
|
|
|
for (int k = 0; k < items.Count; k++)
|
|
items[k].Number = k + 1;
|
|
|
|
playlistName.Text = resources.GetString("/Main/later/Content");
|
|
playlistChannel.Text = SecretsVault.UserChannel.Snippet.Title;
|
|
|
|
playlistCounter.Text = $"{items.IndexOf(selection) + 1}/{SecretsVault.WatchLater.Count}";
|
|
}
|
|
else
|
|
{
|
|
//Retrieving data
|
|
PlaylistsResource.ListRequest playlistRequest = SecretsVault.Service.Playlists.List("snippet,contentDetails");
|
|
playlistRequest.Id = id;
|
|
playlistRequest.Hl = SettingsStorage.RelevanceLanguage;
|
|
Playlist playlistItem = (await playlistRequest.ExecuteAsync()).Items[0];
|
|
|
|
PlaylistItemsResource.ListRequest listRequest = SecretsVault.Service.PlaylistItems.List("snippet");
|
|
listRequest.MaxResults = 50;
|
|
listRequest.PlaylistId = id;
|
|
|
|
PlaylistItemListResponse listResponse;
|
|
do
|
|
{
|
|
listResponse = await listRequest.ExecuteAsync();
|
|
listRequest.PageToken = listResponse.NextPageToken;
|
|
|
|
foreach (PlaylistItem i in listResponse.Items)
|
|
items.Add(new VideoPlaylistItem(i.Snippet.Thumbnails.Medium.Url, i.Snippet.Title, i.Snippet.ResourceId.VideoId));
|
|
}
|
|
while (!string.IsNullOrWhiteSpace(listRequest.PageToken));
|
|
|
|
selection = items.Find(i => i.Id == item.Id);
|
|
|
|
for (int k = 0; k < items.Count; k++)
|
|
items[k].Number = k + 1;
|
|
|
|
//Setting data
|
|
playlistName.Text = playlistItem.Snippet.Localized.Title;
|
|
playlistChannel.Text = Methods.GuardFromNull(playlistItem.Snippet.ChannelTitle);
|
|
|
|
playlistCounter.Text = $"{items.IndexOf(selection) + 1}/{playlistItem.ContentDetails.ItemCount}";
|
|
}
|
|
|
|
playlistList.ItemsSource = items;
|
|
playlistList.SelectedItem = selection;
|
|
pivot.SelectedItem = playlist;
|
|
|
|
await Task.Delay(500);
|
|
|
|
playlistScroll.ChangeView(null, playlistList.SelectedIndex * 86 + 89, null, true);
|
|
}
|
|
|
|
async void LoadInfo()
|
|
{
|
|
//Setting meta
|
|
title.Text = item.Snippet.Localized.Title;
|
|
date.Text = $"{resources.GetString("/VideoPage/publishedAt")}: {item.Snippet.PublishedAt} ({Methods.GetAgo(item.Snippet.PublishedAt.Value)})";
|
|
description.FormatText(item.Snippet.Localized.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(item1.Snippet.Thumbnails.Medium.Url.ToUri()) { DecodePixelHeight = 90, DecodePixelWidth = 90 };
|
|
channelName.Text = item.Snippet.ChannelTitle;
|
|
subscribers.Text = $"{item1.Statistics.SubscriberCount:0,0} {resources.GetString("/Cards/subscribers")}";
|
|
|
|
//Setting ratings
|
|
dislikes.Text = $"{item.Statistics.DislikeCount:0,0}";
|
|
likes.Text = $"{item.Statistics.LikeCount:0,0}";
|
|
try { rating.Value = (double)item.Statistics.DislikeCount / (double)(item.Statistics.DislikeCount + item.Statistics.LikeCount) * 100; }
|
|
catch { rating.Visibility = Visibility.Collapsed; }
|
|
|
|
//Setting User's rate
|
|
if (SecretsVault.IsAuthorized)
|
|
{
|
|
VideoRating rating = (await SecretsVault.Service.Videos.GetRating(item.Id).ExecuteAsync()).Items[0];
|
|
if (rating.Rating == "like")
|
|
{
|
|
userRating = Rating.Like;
|
|
like.Foreground = new SolidColorBrush(Colors.Green);
|
|
}
|
|
else if (rating.Rating == "dislike")
|
|
{
|
|
userRating = Rating.Dislike;
|
|
dislike.Foreground = new SolidColorBrush(Colors.Red);
|
|
}
|
|
|
|
if(SecretsVault.Subscriptions.Exists(i => i.Snippet.ResourceId.ChannelId == item.Snippet.ChannelId))
|
|
{
|
|
subscribe.Background = new SolidColorBrush(Colors.Transparent);
|
|
subscribe.Foreground = new SolidColorBrush(Colors.Gray);
|
|
subscribe.Content = resources.GetString("/Cards/unsubscribe");
|
|
}
|
|
if (item.Snippet.ChannelId == SecretsVault.AccountId)
|
|
subscribe.Visibility = Visibility.Collapsed;
|
|
}
|
|
else
|
|
{
|
|
download.Visibility = Visibility.Collapsed;
|
|
addTo.Visibility = Visibility.Collapsed;
|
|
subscribe.Visibility = Visibility.Collapsed;
|
|
}
|
|
|
|
|
|
if ((history = HistorySet.Items.Find(i => i.Id == item.Id)) != null && history.LeftOn.TotalSeconds >= 30 && Methods.GetDuration(item.ContentDetails.Duration).TotalSeconds - history.LeftOn.TotalSeconds >= 30)
|
|
{
|
|
left.Visibility = Visibility.Visible;
|
|
left.Content = $"\xE122 {resources.GetString("/VideoPage/continue")}: {history.LeftOn.ToString(@"hh\:mm\:ss")}";
|
|
}
|
|
|
|
//Initializing player
|
|
player.Initialize(item, item1.Snippet.Thumbnails.Medium.Url, incognito);
|
|
|
|
LoadRelatedVideos();
|
|
}
|
|
|
|
void LoadStream()
|
|
{
|
|
liveTimer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(10) };
|
|
liveTimer.Tick += LiveStatsUpdate;
|
|
liveTimer.Start();
|
|
LiveStatsUpdate();
|
|
|
|
if(string.IsNullOrWhiteSpace(item.LiveStreamingDetails.ActiveLiveChatId))
|
|
pivot.Items.Remove(commentsPlaceholder);
|
|
else
|
|
{
|
|
commentsPlaceholder.Header = resources.GetString("/VideoPage/chat");
|
|
commentsPlaceholder.Content = new Chat(item.LiveStreamingDetails.ActiveLiveChatId);
|
|
pivot.SelectedItem = commentsPlaceholder;
|
|
}
|
|
download.Visibility = Visibility.Collapsed;
|
|
}
|
|
|
|
private async void LiveStatsUpdate(object sender = null, object e = null)
|
|
{
|
|
VideosResource.ListRequest request = SecretsVault.Service.Videos.List("liveStreamingDetails");
|
|
request.Id = item.Id;
|
|
|
|
views.Text = $"{(await request.ExecuteAsync()).Items[0].LiveStreamingDetails.ConcurrentViewers} {resources.GetString("/Cards/viewers")}";
|
|
}
|
|
|
|
void LoadStats()
|
|
{
|
|
views.Text = $"{item.Statistics.ViewCount:0,0} {resources.GetString("/Cards/views")}";
|
|
|
|
comments.Initialize(item);
|
|
LoadDownloads();
|
|
}
|
|
|
|
async void LoadDownloads()
|
|
{
|
|
try
|
|
{
|
|
MediaStreamInfoSet infoSet = await new YoutubeClient().GetVideoMediaStreamInfosAsync(item.Id);
|
|
foreach (MuxedStreamInfo i in infoSet.Muxed)
|
|
{
|
|
MenuFlyoutItem menuItem = new MenuFlyoutItem()
|
|
{
|
|
Text = i.VideoQualityLabel,
|
|
Tag = new object[] { i, i.VideoQualityLabel }
|
|
};
|
|
menuItem.Click += downloadItemSelected;
|
|
downloadSelector.Items.Add(menuItem);
|
|
}
|
|
|
|
MenuFlyoutItem audioItem = new MenuFlyoutItem()
|
|
{
|
|
Text = resources.GetString("/VideoPage/audio"),
|
|
Tag = new object[] { infoSet.Audio[0], resources.GetString("/Cards/audioOnly") }
|
|
};
|
|
audioItem.Click += downloadItemSelected;
|
|
downloadSelector.Items.Add(audioItem);
|
|
}
|
|
catch
|
|
{
|
|
download.Visibility = Visibility.Collapsed;
|
|
}
|
|
}
|
|
|
|
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");
|
|
request.RegionCode = SettingsStorage.Region;
|
|
request.RelevanceLanguage = SettingsStorage.RelevanceLanguage;
|
|
request.RelatedToVideoId = item.Id;
|
|
request.SafeSearch = (SearchResource.ListRequest.SafeSearchEnum)SettingsStorage.SafeSearch;
|
|
request.MaxResults = 20;
|
|
request.Type = "video";
|
|
|
|
SearchListResponse response = await request.ExecuteAsync();
|
|
|
|
foreach (SearchResult video in response.Items)
|
|
relatedVideos.Add(new VideoCard(video.Id.VideoId));
|
|
|
|
relatedVideos.Children.Insert(1, new Controls.Adverts.CardAdvert());
|
|
}
|
|
|
|
private void Player_Minimize(object sender, params object[] e)
|
|
{
|
|
isExtended = (bool)e[0];
|
|
if(isExtended)
|
|
{
|
|
grid.ColumnDefinitions[1].Width = new GridLength(0);
|
|
commandbar.Visibility = Visibility.Collapsed;
|
|
|
|
mainScroll.ChangeView(0, 0, null);
|
|
|
|
mainScroll.Margin = new Thickness(0);
|
|
mainScroll.VerticalScrollMode = ScrollMode.Disabled;
|
|
|
|
Methods.MainPage.MinimizeVideo();
|
|
}
|
|
else
|
|
{
|
|
grid.ColumnDefinitions[1].Width = new GridLength(400);
|
|
commandbar.Visibility = Visibility.Visible;
|
|
|
|
mainScroll.Margin = new Thickness(0,0,0,50);
|
|
mainScroll.VerticalScrollMode = ScrollMode.Auto;
|
|
|
|
Methods.MainPage.MaximizeVideo();
|
|
}
|
|
}
|
|
|
|
private void gotoChannel_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
Methods.MainPage.GoToChannel(item.Snippet.ChannelId);
|
|
}
|
|
|
|
private async void openBrowser_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
player.Pause();
|
|
string timecode = player.Player.Position.TotalSeconds > 10 ?
|
|
"&t=" + (int)player.Player.Position.TotalSeconds + "s" : string.Empty;
|
|
|
|
await Launcher.LaunchUriAsync($"https://www.youtube.com/watch?v={item.Id}{timecode}".ToUri());
|
|
}
|
|
|
|
public void refresh_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
Methods.MainPage.VideoContent.Refresh();
|
|
}
|
|
|
|
public void CloseVideo()
|
|
{
|
|
player.Controls_CloseRequested(this, null);
|
|
}
|
|
|
|
private void grid_SizeChanged(object sender, SizeChangedEventArgs e)
|
|
{
|
|
if (e.NewSize.Width > 1000 && mainContent.Children.Contains(pivot))
|
|
{
|
|
mainContent.Children.Remove(pivot);
|
|
tabsPlaceholder.Children.Add(pivot);
|
|
|
|
pivot.SelectedItem = descriptionPanel;
|
|
descriptionPanel.Opacity = 1;
|
|
pivot.Items.RemoveAt(0);
|
|
mainContent.Children.Add(descriptionPanel);
|
|
|
|
grid.ColumnDefinitions[1].Width = new GridLength(400);
|
|
|
|
pivot.SelectedIndex = 0;
|
|
}
|
|
else if (e.NewSize.Width <= 1000 && mainContent.Children.Contains(descriptionPanel))
|
|
{
|
|
mainContent.Children.Remove(descriptionPanel);
|
|
pivot.Items.Insert(0, descriptionPanel);
|
|
|
|
tabsPlaceholder.Children.Remove(pivot);
|
|
mainContent.Children.Add(pivot);
|
|
|
|
grid.ColumnDefinitions[1].Width = new GridLength(0);
|
|
|
|
pivot.SelectedIndex = 0;
|
|
}
|
|
}
|
|
|
|
private void Share(DataTransferManager sender, DataRequestedEventArgs args)
|
|
{
|
|
player.Pause();
|
|
|
|
Methods.Share(args,
|
|
item.Snippet.Thumbnails.Medium.Url,
|
|
item.Snippet.Title,
|
|
$"https://www.youtube.com/watch?v={item.Id}",
|
|
resources.GetString("/Cards/videoShare"));
|
|
}
|
|
|
|
private void share_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
DataTransferManager.GetForCurrentView().DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(Share);
|
|
DataTransferManager.ShowShareUI();
|
|
}
|
|
|
|
private async void dislike_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (SecretsVault.IsAuthorized)
|
|
switch (userRating)
|
|
{
|
|
case Rating.Like:
|
|
like.Foreground = new SolidColorBrush(Colors.Gray);
|
|
likes.Text = (int.Parse(likes.Text, NumberStyles.AllowThousands) - 1).ToString("0,0");
|
|
|
|
dislike.Foreground = new SolidColorBrush(Colors.Red);
|
|
dislikes.Text = (int.Parse(dislikes.Text, NumberStyles.AllowThousands) + 1).ToString("0,0");
|
|
rating.Value--;
|
|
await SecretsVault.Service.Videos.Rate(item.Id, VideosResource.RateRequest.RatingEnum.Dislike).ExecuteAsync();
|
|
|
|
userRating = Rating.Dislike;
|
|
break;
|
|
|
|
case Rating.None:
|
|
dislike.Foreground = new SolidColorBrush(Colors.Red);
|
|
dislikes.Text = (int.Parse(dislikes.Text, NumberStyles.AllowThousands) + 1).ToString("0,0");
|
|
rating.Maximum++;
|
|
await SecretsVault.Service.Videos.Rate(item.Id, VideosResource.RateRequest.RatingEnum.Dislike).ExecuteAsync();
|
|
|
|
userRating = Rating.Dislike;
|
|
break;
|
|
|
|
case Rating.Dislike:
|
|
dislike.Foreground = new SolidColorBrush(Colors.Gray);
|
|
dislikes.Text = (int.Parse(dislikes.Text, NumberStyles.AllowThousands) - 1).ToString("0,0");
|
|
rating.Maximum--;
|
|
await SecretsVault.Service.Videos.Rate(item.Id, VideosResource.RateRequest.RatingEnum.None).ExecuteAsync();
|
|
break;
|
|
}
|
|
}
|
|
|
|
private async void like_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if(SecretsVault.IsAuthorized)
|
|
switch (userRating)
|
|
{
|
|
case Rating.Dislike:
|
|
dislike.Foreground = new SolidColorBrush(Colors.Gray);
|
|
dislikes.Text = (int.Parse(dislikes.Text, NumberStyles.AllowThousands) - 1).ToString("0,0");
|
|
|
|
like.Foreground = new SolidColorBrush(Colors.Green);
|
|
likes.Text = (int.Parse(likes.Text, NumberStyles.AllowThousands) + 1).ToString("0,0");
|
|
rating.Value++;
|
|
await SecretsVault.Service.Videos.Rate(item.Id, VideosResource.RateRequest.RatingEnum.Like).ExecuteAsync();
|
|
|
|
userRating = Rating.Like;
|
|
break;
|
|
|
|
case Rating.None:
|
|
like.Foreground = new SolidColorBrush(Colors.Green);
|
|
likes.Text = (int.Parse(likes.Text, NumberStyles.AllowThousands) + 1).ToString("0,0");
|
|
rating.Maximum++;
|
|
rating.Value++;
|
|
await SecretsVault.Service.Videos.Rate(item.Id, VideosResource.RateRequest.RatingEnum.Like).ExecuteAsync();
|
|
|
|
userRating = Rating.Like;
|
|
break;
|
|
|
|
case Rating.Like:
|
|
like.Foreground = new SolidColorBrush(Colors.Gray);
|
|
likes.Text = (int.Parse(likes.Text, NumberStyles.AllowThousands) - 1).ToString("0,0");
|
|
rating.Maximum--;
|
|
rating.Value--;
|
|
await SecretsVault.Service.Videos.Rate(item.Id, VideosResource.RateRequest.RatingEnum.None).ExecuteAsync();
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if ((e.AddedItems[0] as VideoPlaylistItem).Id != item.Id)
|
|
Methods.MainPage.GoToVideo((e.AddedItems[0] as VideoPlaylistItem).Id, playlistId);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
private async void subscribe_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (await SecretsVault.ChangeSubscriptionState(item.Snippet.ChannelId))
|
|
{
|
|
subscribe.Background = new SolidColorBrush(Colors.Transparent);
|
|
subscribe.Foreground = new SolidColorBrush(Colors.Gray);
|
|
subscribe.Content = resources.GetString("/Cards/unsubscribe");
|
|
}
|
|
else
|
|
{
|
|
subscribe.Background = new SolidColorBrush(Colors.Red);
|
|
subscribe.Foreground = new SolidColorBrush(Colors.White);
|
|
subscribe.Content = resources.GetString("/Cards/subscribe/Content");
|
|
}
|
|
}
|
|
|
|
async void LoadAddTo()
|
|
{
|
|
try
|
|
{
|
|
if (SecretsVault.UserChannel == null)
|
|
{
|
|
addTo.Visibility = Visibility.Collapsed;
|
|
return;
|
|
}
|
|
|
|
if (SecretsVault.WatchLater.Contains(item.Id))
|
|
(addList.Items[1] as ToggleMenuFlyoutItem).IsChecked = true;
|
|
|
|
PlaylistsResource.ListRequest request = SecretsVault.Service.Playlists.List("snippet");
|
|
request.Mine = true;
|
|
request.MaxResults = 50;
|
|
|
|
PlaylistListResponse response = await request.ExecuteAsync();
|
|
|
|
PlaylistItemsResource.ListRequest itemRequest = SecretsVault.Service.PlaylistItems.List("snippet");
|
|
itemRequest.VideoId = item.Id;
|
|
|
|
foreach (Playlist i in response.Items)
|
|
{
|
|
itemRequest.PlaylistId = i.Id;
|
|
ToggleMenuFlyoutItem menuItem = new ToggleMenuFlyoutItem
|
|
{
|
|
Text = i.Snippet.Title,
|
|
IsChecked = (await itemRequest.ExecuteAsync()).Items.Count > 0,
|
|
Tag = i,
|
|
Icon = new FontIcon
|
|
{
|
|
Glyph = "\xE728"
|
|
}
|
|
};
|
|
menuItem.Click += Item_Click;
|
|
addList.Items.Add(menuItem);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
addTo.Visibility = Visibility.Collapsed;
|
|
}
|
|
}
|
|
|
|
private async void Item_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if(((ToggleMenuFlyoutItem)sender).IsChecked)
|
|
{
|
|
try
|
|
{
|
|
PlaylistItem playlist = new PlaylistItem
|
|
{
|
|
Snippet = new PlaylistItemSnippet
|
|
{
|
|
PlaylistId = (((ToggleMenuFlyoutItem)sender).Tag as Playlist).Id,
|
|
ResourceId = new ResourceId
|
|
{
|
|
VideoId = item.Id,
|
|
Kind = "youtube#video"
|
|
}
|
|
}
|
|
};
|
|
PlaylistItemsResource.InsertRequest request = SecretsVault.Service.PlaylistItems.Insert(playlist, "snippet");
|
|
|
|
await request.ExecuteAsync();
|
|
}
|
|
catch
|
|
{
|
|
((ToggleMenuFlyoutItem)sender).IsChecked = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
PlaylistItemsResource.ListRequest itemRequest = SecretsVault.Service.PlaylistItems.List("snippet");
|
|
itemRequest.VideoId = item.Id;
|
|
itemRequest.PlaylistId = ((Playlist)((ToggleMenuFlyoutItem)sender).Tag).Id;
|
|
|
|
PlaylistItemsResource.DeleteRequest request = SecretsVault.Service.PlaylistItems.Delete((await itemRequest.ExecuteAsync()).Items[0].Id);
|
|
|
|
await request.ExecuteAsync();
|
|
}
|
|
catch
|
|
{
|
|
((ToggleMenuFlyoutItem)sender).IsChecked = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
private async void NewPlaylist_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
await playlistDialog.ShowAsync();
|
|
}
|
|
|
|
private async void Wl_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (wl.IsChecked)
|
|
{
|
|
try
|
|
{
|
|
PlaylistItem playlist = new PlaylistItem
|
|
{
|
|
Snippet = new PlaylistItemSnippet
|
|
{
|
|
PlaylistId = "WL",
|
|
ResourceId = new ResourceId
|
|
{
|
|
VideoId = item.Id,
|
|
Kind = "youtube#video"
|
|
}
|
|
}
|
|
};
|
|
PlaylistItemsResource.InsertRequest request = SecretsVault.Service.PlaylistItems.Insert(playlist, "snippet");
|
|
|
|
await request.ExecuteAsync();
|
|
}
|
|
catch
|
|
{
|
|
wl.IsChecked = false;
|
|
}
|
|
}
|
|
else
|
|
wl.IsChecked = true;
|
|
}
|
|
|
|
private async void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
|
|
{
|
|
string privacy = "private";
|
|
switch(newListDisc.SelectedIndex)
|
|
{
|
|
case 0:
|
|
privacy = "public";
|
|
break;
|
|
case 1:
|
|
privacy = "private";
|
|
break;
|
|
case 2:
|
|
privacy = "unlisted";
|
|
break;
|
|
}
|
|
|
|
Playlist newItem = new Playlist
|
|
{
|
|
Snippet = new PlaylistSnippet
|
|
{
|
|
Title = newListName.Text
|
|
},
|
|
Status = new PlaylistStatus
|
|
{
|
|
PrivacyStatus = privacy,
|
|
}
|
|
};
|
|
|
|
Playlist i;
|
|
|
|
try { i = await SecretsVault.Service.Playlists.Insert(newItem, "snippet,status").ExecuteAsync(); }
|
|
catch
|
|
{
|
|
return;
|
|
}
|
|
|
|
ToggleMenuFlyoutItem menuItem = new ToggleMenuFlyoutItem
|
|
{
|
|
Text = i.Snippet.Title,
|
|
IsChecked = true,
|
|
Tag = i,
|
|
Icon = new FontIcon
|
|
{
|
|
Glyph = "\xE728"
|
|
}
|
|
};
|
|
menuItem.Click += Item_Click;
|
|
addList.Items.Add(menuItem);
|
|
|
|
Item_Click(menuItem, null);
|
|
}
|
|
|
|
private void Left_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
Player.Player.Position = history.LeftOn;
|
|
}
|
|
}
|
|
}
|