Archived
1
0
This repository has been archived on 2026-04-22. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
FoxTube/FoxTube/Pages/MainPage.xaml.cs
T
Michael Gordeev 35ddf4a012 #176: Done
2018-09-14 18:10:54 +03:00

677 lines
27 KiB
C#

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;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Shapes;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using System.Diagnostics;
using Microsoft.Toolkit.Uwp.Notifications;
using Windows.UI.Notifications;
using Windows.UI.Xaml.Media.Imaging;
using Windows.Storage;
using System.Xml;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Upload;
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.Globalization;
using Windows.ApplicationModel.Core;
using Windows.System;
using Windows.UI.Xaml.Documents;
using Google.Apis.Oauth2.v2;
using Google.Apis.Oauth2.v2.Data;
using FoxTube.Controls;
using FoxTube.Pages;
using Microsoft.Toolkit.Uwp.UI.Controls;
using Windows.ApplicationModel;
using System.Net;
using Windows.UI.Popups;
using Windows.Networking.Connectivity;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace FoxTube
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public enum Sender { Menu, Frame, None }
public sealed partial class MainPage : Page
{
public DownloadAgent Agent = new DownloadAgent();
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
NotificationsCenter notificationsCenter = new NotificationsCenter();
Sender s = Sender.None;
public MainPage()
{
this.InitializeComponent();
if (settings.Values["quality"] == null)
settings.Values.Add("quality", 1);
if (settings.Values["newVideoNotification"] == null)
settings.Values.Add("newVideoNotification", true);
if (settings.Values["newmessagesNotification"] == null)
settings.Values.Add("newmessagesNotification", true);
if (settings.Values["moblieWarning"] == null)
settings.Values.Add("moblieWarning", false);
if (settings.Values["videoAutoplay"] == null)
settings.Values.Add("videoAutoplay", true);
if (settings.Values["themeMode"] == null)
settings.Values.Add("themeMode", 2);
if (settings.Values["volume"] == null)
settings.Values.Add("volume", 100);
if (settings.Values["region"] == null)
settings.Values.Add("region", CultureInfo.CurrentCulture.Name);
if (settings.Values["safeSearch"] == null)
settings.Values.Add("safeSearch", 0);
if (settings.Values["defaultDownload"] == null)
settings.Values.Add("defaultDownload", Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\DownloadedVideos");
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}")
{
try
{
XmlDocument changelog = new XmlDocument();
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&apos;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());
settings.Values["ver"] = $"{ver.Major}.{ver.Minor}";
}
catch { }
}
notificationsCenter.Initialize();
SecretsVault.AuthorizationStateChanged += Vault_AuthorizationStateChanged;
SecretsVault.SubscriptionsChanged += SecretsVault_SubscriptionsChanged;
SetTitleBar();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
SetTitleBar();
}
public void SetTitleBar()
{
var titleBar = ApplicationView.GetForCurrentView().TitleBar;
titleBar.ButtonBackgroundColor = Colors.Transparent;
titleBar.ButtonHoverBackgroundColor = Colors.IndianRed;
titleBar.ButtonPressedBackgroundColor = Colors.DarkRed;
titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
if((int)settings.Values["themeMode"] == 2)
{
Color uiTheme = new UISettings().GetColorValue(UIColorType.Background);
if (uiTheme == Colors.Black)
titleBar.ButtonForegroundColor = Colors.White;
else
titleBar.ButtonForegroundColor = Colors.Black;
}
else
{
if (RequestedTheme == ElementTheme.Dark)
titleBar.ButtonForegroundColor = Colors.White;
else if (RequestedTheme == ElementTheme.Light)
titleBar.ButtonForegroundColor = Colors.Black;
}
CoreApplicationViewTitleBar coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
coreTitleBar.ExtendViewIntoTitleBar = true;
}
private void SecretsVault_SubscriptionsChanged(object sender, params object[] args)
{
if ((string)args[0] == "add" && nav.MenuItems.Count < 19)
{
Subscription s = args[1] as Subscription;
StackPanel panel = new StackPanel() { Orientation = Orientation.Horizontal };
panel.Children.Add(new PersonPicture()
{
Height = 20,
Margin = new Thickness(0, 0, 13, 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()
});
}
else if ((string)args[0] == "remove" && (int)args[1] < 10)
nav.MenuItems.RemoveAt((int)args[1] + 9);
}
private async void Vault_AuthorizationStateChanged(object sender, EventArgs e)
{
if(SecretsVault.IsAuthorized)
{
account.Visibility = Visibility.Collapsed;
try
{
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));
}
catch { }
avatar.Visibility = Visibility.Visible;
toChannel.Visibility = Visibility.Visible;
toSubscriptions.Visibility = Visibility.Visible;
libHeader.Visibility = Visibility.Visible;
toHistory.Visibility = Visibility.Visible;
toLiked.Visibility = Visibility.Visible;
toLater.Visibility = Visibility.Visible;
toDownloads.Visibility = Visibility.Visible;
subsHeader.Visibility = Visibility.Visible;
if (SecretsVault.Subscriptions.Count > 0)
{
subsHeader.Visibility = Visibility.Visible;
for(int k = 0; k < SecretsVault.Subscriptions.Count && k < 10; k++)
try
{
Subscription s = SecretsVault.Subscriptions[k];
StackPanel panel = new StackPanel() { Orientation = Orientation.Horizontal };
panel.Children.Add(new PersonPicture()
{
Height = 20,
Margin = new Thickness(0, 0, 13, 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()
});
}
catch { continue; }
}
}
else
{
account.Visibility = Visibility.Visible;
avatar.Visibility = Visibility.Collapsed;
toChannel.Visibility = Visibility.Collapsed;
toSubscriptions.Visibility = Visibility.Collapsed;
libHeader.Visibility = Visibility.Collapsed;
toHistory.Visibility = Visibility.Collapsed;
toLiked.Visibility = Visibility.Collapsed;
toLater.Visibility = Visibility.Collapsed;
toDownloads.Visibility = Visibility.Collapsed;
subsHeader.Visibility = Visibility.Collapsed;
subsHeader.Visibility = Visibility.Collapsed;
for(int k = 9; k < nav.MenuItems.Count; k++)
nav.MenuItems.RemoveAt(k);
}
nav.SelectedItem = toHome;
content.Navigate(typeof(Home));
if (videoPlaceholder.Content != null)
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:"));
}
private async void createAccount_Click(object sender, RoutedEventArgs e)
{
await Launcher.LaunchUriAsync(new Uri("https://accounts.google.com/signup/v2/webcreateaccount?ManageAccount&flowName=GlifWebSignIn&flowEntry=SignUp"));
}
private void signIn_Click(object sender, RoutedEventArgs e)
{
SecretsVault.Authorize();
}
private void myChannel_Click(object sender, RoutedEventArgs e)
{
content.Navigate(typeof(Channel), SecretsVault.UserChannel.Id);
}
private void logout_Click(object sender, RoutedEventArgs e)
{
SecretsVault.Deauthenticate();
}
public void GoToSearch(SearchParameters args)
{
MinimizeAsInitializer();
content.Navigate(typeof(Search), args);
}
public void GoToChannel(string id)
{
MinimizeAsInitializer();
content.Navigate(typeof(ChannelPage), id);
}
public async void GoToVideo(string id, string playlistId = null)
{
var connection = NetworkInformation.GetInternetConnectionProfile().GetConnectionCost();
if ((bool)settings.Values["moblieWarning"] && (connection.NetworkCostType == NetworkCostType.Fixed || connection.NetworkCostType == NetworkCostType.Variable))
{
bool cancel = false;
MessageDialog dialog = new MessageDialog("You are on metered connection now. Additional charges may apply. Do you want to continue?")
{
DefaultCommandIndex = 2,
CancelCommandIndex = 1
};
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) =>
{
//TO-DO: Adding video to "Watch later"
cancel = true;
}));
await dialog.ShowAsync();
if (cancel)
return;
}
nav.IsPaneOpen = false;
videoPlaceholder.Content = null;
MaximizeVideo();
Fullscreen(false);
videoPlaceholder.Navigate(typeof(VideoPage), new string[2] { id, playlistId });
}
public void GoToDeveloper(string id)
{
MinimizeAsInitializer();
content.Navigate(typeof(Settings), $"inbox&{id}");
}
public void GoToPlaylist(string id)
{
MinimizeAsInitializer();
content.Navigate(typeof(PlaylistPage), id);
}
private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (videoPlaceholder.Content != null)
(videoPlaceholder.Content as VideoPage).player.UpdateSize();
}
public void MinimizeAsInitializer()
{
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()
{
videoPlaceholder.Width = 432;
videoPlaceholder.Height = 243;
videoPlaceholder.VerticalAlignment = VerticalAlignment.Bottom;
videoPlaceholder.HorizontalAlignment = HorizontalAlignment.Right;
videoPlaceholder.Margin = new Thickness(0, 0, 25, 50);
if (content.CanGoBack)
nav.IsBackEnabled = true;
else
nav.IsBackEnabled = false;
}
public void MaximizeVideo()
{
videoPlaceholder.Width = double.NaN;
videoPlaceholder.Height = double.NaN;
videoPlaceholder.VerticalAlignment = VerticalAlignment.Stretch;
videoPlaceholder.HorizontalAlignment = HorizontalAlignment.Stretch;
videoPlaceholder.Margin = new Thickness(0);
nav.IsBackEnabled = true;
}
public void Fullscreen(bool on)
{
if (on)
{
nav.OpenPaneLength = 0;
nav.CompactPaneLength = 0;
if ((videoPlaceholder.Content as VideoPage).player.MiniView)
nav.Margin = new Thickness(0, -80, 0, 0);
else
nav.Margin = new Thickness(0, -91, 0, 0);
}
else
{
nav.Margin = new Thickness(0);
nav.OpenPaneLength = 300;
nav.CompactPaneLength = 48;
}
}
public void CloseVideo()
{
if (ApplicationView.GetForCurrentView().IsFullScreenMode)
{
ApplicationView.GetForCurrentView().ExitFullScreenMode();
Fullscreen(false);
}
(videoPlaceholder.Content as VideoPage).player.pointerCaptured = false;
videoPlaceholder.Content = null;
MaximizeVideo();
if (content.CanGoBack)
nav.IsBackEnabled = true;
else
nav.IsBackEnabled = false;
}
private void search_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
{
GoToSearch(new SearchParameters(search.Text));
}
private void search_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{
if (search.Text.Length > 2 && args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load($"http://suggestqueries.google.com/complete/search?ds=yt&client=toolbar&q={search.Text}");
List<string> suggestions = new List<string>();
for (int i = 0; i < doc["toplevel"].ChildNodes.Count && i < 5; i++)
suggestions.Add(doc["toplevel"].ChildNodes[i]["suggestion"].GetAttribute("data"));
search.ItemsSource = suggestions;
}
catch (WebException)
{
search.ItemsSource = new List<string>();
}
}
}
private void nav_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
if (s == Sender.None)
{
s = Sender.Menu;
if (args.IsSettingsSelected)
content.Navigate(typeof(Settings));
else
{
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;
}
private void content_Navigated(object sender, NavigationEventArgs e)
{
Dictionary<Type, Action> switchCase = new Dictionary<Type, Action>()
{
{ 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" }
};
try { switchCase[e.SourcePageType](); }
catch { }
if (s == Sender.None)
{
s = Sender.Frame;
Dictionary<Type, Action> navCase = new Dictionary<Type, Action>()
{
{ typeof(Settings), () =>
{
if(nav.SelectedItem != nav.SettingsItem)
nav.SelectedItem = nav.SettingsItem;
else
s = Sender.None;
} },
{ typeof(ChannelPage), () =>
{
if(SecretsVault.IsAuthorized)
{
if((content.Content as ChannelPage).channelId == SecretsVault.AccountId)
{
if(nav.SelectedItem != toChannel)
nav.SelectedItem = toChannel;
else
s = Sender.None;
}
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;
} },
{ typeof(PlaylistPage), () =>
{
if((content.Content as PlaylistPage).playlistId == SecretsVault.UserChannel.ContentDetails.RelatedPlaylists.Likes)
{
if(nav.SelectedItem != toLiked)
nav.SelectedItem = toLiked;
else
s = Sender.None;
}
else if ((content.Content as PlaylistPage).playlistId == SecretsVault.UserChannel.ContentDetails.RelatedPlaylists.WatchLater)
{
if(nav.SelectedItem != toLater)
nav.SelectedItem = toLater;
else
s = Sender.None;
}
else
{
nav.SelectedItem = null;
}
} },
{ typeof(Search), () => nav.SelectedItem = null },
{typeof(Subscriptions), () =>
{
if(nav.SelectedItem != toSubscriptions)
nav.SelectedItem = toSubscriptions;
else
s = Sender.None;
} },
{ typeof(History), () =>
{
if(nav.SelectedItem != toHistory)
nav.SelectedItem = toHistory;
else
s = Sender.None;
} },
{ typeof(Home), () =>
{
if(nav.SelectedItem != toHome)
nav.SelectedItem = toHome;
else
s = Sender.None;
} },
{ typeof(Downloads), () =>
{
if(nav.SelectedItem != toDownloads)
nav.SelectedItem = toDownloads;
else
s = Sender.None;
} }
};
try { navCase[e.SourcePageType](); }
catch
{
nav.SelectedItem = null;
}
}
else
s = Sender.None;
if (content.CanGoBack)
nav.IsBackEnabled = true;
else
nav.IsBackEnabled = false;
if (e.SourcePageType == typeof(Home) || e.SourcePageType == typeof(Settings) || e.SourcePageType == typeof(Subscriptions))
{
nav.ExpandedModeThresholdWidth = 1008;
if (nav.DisplayMode == NavigationViewDisplayMode.Expanded)
nav.IsPaneOpen = true;
}
else
nav.ExpandedModeThresholdWidth = int.MaxValue;
if (videoPlaceholder.Content != null && videoPlaceholder.HorizontalAlignment == HorizontalAlignment.Stretch)
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)
{
if ((videoPlaceholder.Content as VideoPage).loading.State != LoadingState.Loaded)
CloseVideo();
else if (videoPlaceholder.HorizontalAlignment == HorizontalAlignment.Stretch)
MinimizeAsInitializer();
else
content.GoBack();
}
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);
}
}
}
}