460 lines
17 KiB
C#
460 lines
17 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;
|
|
|
|
// 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 sealed partial class MainPage : Page
|
|
{
|
|
public DownloadAgent Agent = new DownloadAgent();
|
|
|
|
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
|
|
|
|
NotificationsCenter notificationsCenter = new NotificationsCenter();
|
|
public MainPage()
|
|
{
|
|
this.InitializeComponent();
|
|
|
|
if(settings.Values["language"] == null)
|
|
settings.Values.Add("language", 0);
|
|
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", false);
|
|
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");
|
|
|
|
SecretsVault.AuthorizationStateChanged += Vault_AuthorizationStateChanged;
|
|
SecretsVault.SubscriptionsChanged += SecretsVault_SubscriptionsChanged;
|
|
SecretsVault.CheckAuthorization();
|
|
if (!SecretsVault.IsAuthorized)
|
|
nav.SelectedItem = toHome;
|
|
}
|
|
|
|
protected override void OnNavigatedTo(NavigationEventArgs e)
|
|
{
|
|
base.OnNavigatedTo(e);
|
|
SetTitleBar();
|
|
}
|
|
|
|
public void SetTitleBar()
|
|
{
|
|
var titleBar = ApplicationView.GetForCurrentView().TitleBar;
|
|
|
|
titleBar.ButtonForegroundColor = Colors.Black;
|
|
titleBar.ButtonBackgroundColor = Colors.Transparent;
|
|
titleBar.ButtonHoverBackgroundColor = Colors.IndianRed;
|
|
titleBar.ButtonPressedBackgroundColor = Colors.DarkRed;
|
|
|
|
CoreApplicationViewTitleBar coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
|
|
coreTitleBar.ExtendViewIntoTitleBar = false;
|
|
}
|
|
|
|
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));
|
|
content.CacheSize = 0;
|
|
|
|
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 void feedback_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
content.Navigate(typeof(Settings), "feedback");
|
|
}
|
|
|
|
public void PreDefineFeedback(bool isProblem, string meta)
|
|
{
|
|
content.Navigate(typeof(Settings), $"feedback&isProblem={isProblem}&meta={meta}");
|
|
}
|
|
|
|
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(string keyword = null)
|
|
{
|
|
if(keyword != null)
|
|
search.Text = keyword;
|
|
|
|
if (!string.IsNullOrWhiteSpace(search.Text))
|
|
{
|
|
if (!(content.Content is Search))
|
|
content.Navigate(typeof(Search), search.Text);
|
|
else if ((content.Content as Search).Term != search.Text)
|
|
(content.Content as Search).Initialize(search.Text);
|
|
}
|
|
}
|
|
|
|
public void GoToChannel(string id)
|
|
{
|
|
MinimizeAsInitializer();
|
|
content.Navigate(typeof(ChannelPage), id);
|
|
}
|
|
|
|
public void GoToVideo(string id, string playlistId = null)
|
|
{
|
|
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");
|
|
}
|
|
|
|
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()
|
|
{
|
|
try { (videoPlaceholder.Content as VideoPage).player.minimize_Click(this, null); }
|
|
catch { }
|
|
}
|
|
|
|
public void MinimizeVideo()
|
|
{
|
|
DropShadowPanel ph = videoPlaceholder.Parent as DropShadowPanel;
|
|
|
|
ph.BlurRadius = 20;
|
|
ph.Width = 432;
|
|
ph.Height = 243;
|
|
ph.VerticalAlignment = VerticalAlignment.Bottom;
|
|
ph.HorizontalAlignment = HorizontalAlignment.Right;
|
|
ph.Margin = new Thickness(0, 0, 25, 50);
|
|
|
|
if (content.CanGoBack)
|
|
nav.IsBackEnabled = true;
|
|
else
|
|
nav.IsBackEnabled = false;
|
|
}
|
|
|
|
public void MaximizeVideo()
|
|
{
|
|
DropShadowPanel ph = videoPlaceholder.Parent as DropShadowPanel;
|
|
|
|
ph.BlurRadius = 0;
|
|
ph.Width = double.NaN;
|
|
ph.Height = double.NaN;
|
|
ph.VerticalAlignment = VerticalAlignment.Stretch;
|
|
ph.HorizontalAlignment = HorizontalAlignment.Stretch;
|
|
ph.Margin = new Thickness(0);
|
|
|
|
nav.IsBackEnabled = true;
|
|
}
|
|
|
|
public void Fullscreen(bool on)
|
|
{
|
|
if(on)
|
|
{
|
|
nav.Margin = new Thickness(-48, -93, 0, 0);
|
|
nav.OpenPaneLength = 48;
|
|
}
|
|
else
|
|
{
|
|
nav.Margin = new Thickness(0);
|
|
nav.OpenPaneLength = 300;
|
|
}
|
|
}
|
|
|
|
public void CloseVideo()
|
|
{
|
|
if (ApplicationView.GetForCurrentView().IsFullScreenMode)
|
|
{
|
|
ApplicationView.GetForCurrentView().ExitFullScreenMode();
|
|
Fullscreen(false);
|
|
}
|
|
videoPlaceholder.Content = null;
|
|
MaximizeVideo();
|
|
|
|
if (content.CanGoBack)
|
|
nav.IsBackEnabled = true;
|
|
else
|
|
nav.IsBackEnabled = false;
|
|
}
|
|
|
|
private void search_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
|
|
{
|
|
GoToSearch();
|
|
}
|
|
|
|
private void search_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
|
|
{
|
|
if(search.Text.Length > 2)
|
|
{
|
|
XmlDocument doc = new XmlDocument();
|
|
doc.Load($"http://suggestqueries.google.com/complete/search?output=toolbar&hl={(settings.Values["region"] as string).Remove(2)}&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;
|
|
}
|
|
}
|
|
|
|
private void nav_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
|
|
{
|
|
if (args.IsSettingsSelected)
|
|
content.Navigate(typeof(Settings));
|
|
else
|
|
{
|
|
if (args.SelectedItem == toHome)
|
|
content.Navigate(typeof(Home));
|
|
else if (args.SelectedItem == toHistory)
|
|
content.Navigate(typeof(Settings));
|
|
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(Settings));
|
|
else if (args.SelectedItem == toDownloads)
|
|
content.Navigate(typeof(Downloads));
|
|
else if (args.SelectedItem == toChannel)
|
|
content.Navigate(typeof(Channel), SecretsVault.UserChannel.Id);
|
|
else
|
|
content.Navigate(typeof(ChannelPage), SecretsVault.Subscriptions[Convert.ToInt32((args.SelectedItem as NavigationViewItem).Name)].Snippet.ResourceId.ChannelId);
|
|
}
|
|
}
|
|
|
|
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(History), () => header.Text = "History" },
|
|
{ typeof(Home), () => header.Text = "Home" },
|
|
{ typeof(Downloads), () => header.Text = "Downloads" }
|
|
};
|
|
|
|
switchCase[e.SourcePageType]();
|
|
|
|
if (content.CanGoBack)
|
|
nav.IsBackEnabled = true;
|
|
else
|
|
nav.IsBackEnabled = false;
|
|
|
|
if (videoPlaceholder.Content != null && (videoPlaceholder.Parent as DropShadowPanel).HorizontalAlignment == HorizontalAlignment.Stretch)
|
|
MinimizeAsInitializer();
|
|
}
|
|
|
|
private void toChannel_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
nav.SelectedItem = null;
|
|
GoToChannel(SecretsVault.UserChannel.Id);
|
|
}
|
|
|
|
private void nav_BackRequested(NavigationView sender, NavigationViewBackRequestedEventArgs args)
|
|
{
|
|
if (videoPlaceholder.Content != null)
|
|
{
|
|
DropShadowPanel panel = videoPlaceholder.Parent as DropShadowPanel;
|
|
if (panel.HorizontalAlignment == HorizontalAlignment.Stretch)
|
|
MinimizeAsInitializer();
|
|
else
|
|
content.GoBack();
|
|
}
|
|
else
|
|
content.GoBack();
|
|
}
|
|
}
|
|
}
|