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
2019-08-25 23:57:26 +03:00

570 lines
23 KiB
C#

using System;
using System.Collections.Generic;
using Windows.UI;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Navigation;
using Windows.UI.Xaml.Media.Imaging;
using System.Xml;
using Google.Apis.YouTube.v3.Data;
using Windows.ApplicationModel.Core;
using Windows.System;
using FoxTube.Pages;
using Windows.UI.Popups;
using Windows.ApplicationModel.Resources;
using Microsoft.Services.Store.Engagement;
using Windows.UI.Xaml.Shapes;
using Windows.UI.Xaml.Media;
using FoxTube.Controls;
namespace FoxTube
{
/// <summary>
/// Main app's layout
/// </summary>
public sealed partial class MainPage : Page
{
bool wasInvoked = false;
readonly ResourceLoader resources = ResourceLoader.GetForCurrentView("Main");
Dictionary<Type, string> headers;
public ContentFrame PageContent => content;
public ContentFrame VideoContent => videoPlaceholder;
public MainPage()
{
headers = new Dictionary<Type, string>()
{
{ typeof(Settings), resources.GetString("/Main/settings/Content") },
{ typeof(ChannelPage), resources.GetString("/Main/channel") },
{ typeof(PlaylistPage), resources.GetString("/Main/playlist") },
{ typeof(Search), resources.GetString("/Main/searchPlaceholder/PlaceholderText") },
{ typeof(Subscriptions), resources.GetString("/Main/subscriptions/Content") },
{ typeof(History), resources.GetString("/Main/history/Content") },
{ typeof(Home), resources.GetString("/Main/home/Content") },
{ typeof(UploadPage), "Uploading a video" },
{ typeof(Downloads), resources.GetString("/Main/downloads/Content") }
};
InitializeComponent();
Window.Current.SetTitleBar(AppTitleBar);
CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
CoreApplication.GetCurrentView().TitleBar.LayoutMetricsChanged += (s, e) => SetTitleBar(s);
SecretsVault.AuthorizationStateChanged += AuthorizationStateChanged;
SecretsVault.SubscriptionsChanged += SecretsVault_SubscriptionsChanged;
SecretsVault.Purchased += async (sender, e) =>
{
removeAds.Visibility = (e[0] as bool?).Value ? Visibility.Collapsed : Visibility.Visible;
if (!(bool)e[0])
{
removeAds.Content = $"{resources.GetString("/Main/adsFree/Content")} ({e[1]})";
return;
}
MessageDialog dialog = new MessageDialog(resources.GetString("/Main/purchaseSuccess"));
dialog.Commands.Add(new UICommand(resources.GetString("/Main/close"), (command) => Methods.CloseApp()));
dialog.Commands.Add(new UICommand(resources.GetString("/Main/delay")));
dialog.CancelCommandIndex = 1;
dialog.DefaultCommandIndex = 0;
await dialog.ShowAsync();
};
SecretsVault.Initialize();
if(StoreServicesFeedbackLauncher.IsSupported())
feedback.Visibility = Visibility.Visible;
PromptFeedback();
}
async void PromptFeedback()
{
if (SettingsStorage.Uptime.TotalHours >= 12 && SettingsStorage.PromptFeedback)
{
MessageDialog dialog = new MessageDialog(resources.GetString("/Main/feedbackMessage"));
dialog.Commands.Add(new UICommand(resources.GetString("/Main/dontAsk"), (command) => SettingsStorage.PromptFeedback = false));
dialog.Commands.Add(new UICommand(resources.GetString("/Main/promptLater")));
dialog.Commands.Add(new UICommand(resources.GetString("/Main/sure"), async (command) =>
{
SettingsStorage.PromptFeedback = false;
if (StoreServicesFeedbackLauncher.IsSupported())
await StoreServicesFeedbackLauncher.GetDefault().LaunchAsync();
else
{
MessageDialog message = new MessageDialog(resources.GetString("/Main/feedbackFail"));
message.Commands.Add(new UICommand(resources.GetString("/Main/sendEmail"), async (c) => await Launcher.LaunchUriAsync("mailto:michael.xfox@outlook.com".ToUri())));
message.Commands.Add(new UICommand(resources.GetString("/Main/goBack")));
message.CancelCommandIndex = 1;
message.DefaultCommandIndex = 0;
await message.ShowAsync();
}
}));
dialog.DefaultCommandIndex = 2;
dialog.CancelCommandIndex = 1;
await dialog.ShowAsync();
}
if (SettingsStorage.Uptime.TotalHours >= 24 && SettingsStorage.PromptReview)
{
MessageDialog dialog = new MessageDialog(resources.GetString("/Main/rate"));
dialog.Commands.Add(new UICommand(resources.GetString("/Main/dontAsk"), (command) => SettingsStorage.PromptReview = false));
dialog.Commands.Add(new UICommand(resources.GetString("/Main/promptLater")));
dialog.Commands.Add(new UICommand(resources.GetString("/Main/sure"), async (command) =>
{
SettingsStorage.PromptReview = false;
await Launcher.LaunchUriAsync("ms-windows-store://review/?ProductId=9NCQQXJTDLFH".ToUri());
}));
dialog.DefaultCommandIndex = 2;
dialog.CancelCommandIndex = 1;
await dialog.ShowAsync();
}
}
public void SetTitleBar(CoreApplicationViewTitleBar coreTitleBar = null)
{
if (coreTitleBar != null)
{
bool full = ApplicationView.GetForCurrentView().IsFullScreenMode;
double left = 12 + (full ? 0 : coreTitleBar.SystemOverlayLeftInset);
AppTitle.Margin = new Thickness(left, 8, 0, 0);
AppTitleBar.Height = coreTitleBar.Height;
}
var titleBar = ApplicationView.GetForCurrentView().TitleBar;
titleBar.ButtonBackgroundColor = Colors.Transparent;
titleBar.ButtonHoverBackgroundColor = Colors.IndianRed;
titleBar.ButtonPressedBackgroundColor = Colors.DarkRed;
titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
titleBar.ButtonInactiveForegroundColor = Colors.Gray;
if(RequestedTheme == ElementTheme.Dark || (RequestedTheme == ElementTheme.Default && Application.Current.RequestedTheme == ApplicationTheme.Dark))
titleBar.ButtonForegroundColor = Colors.White;
else
titleBar.ButtonForegroundColor = Colors.Black;
}
private void SecretsVault_SubscriptionsChanged(object sender, params object[] args)
{
switch((string)args[0])
{
case "add":
if (nav.MenuItems.Count < 19)
nav.MenuItems.Add(args[1] as Subscription);
break;
case "remove":
if (nav.MenuItems.Find(i => ((i as Microsoft.UI.Xaml.Controls.NavigationViewItem).Content as StackPanel).Tag.ToString() == (string)args[1]) is Microsoft.UI.Xaml.Controls.NavigationViewItem item)
{
nav.MenuItems.Remove(item);
if (SecretsVault.Subscriptions.Count >= 10)
nav.MenuItems.Add(SecretsVault.Subscriptions[9]);
}
break;
}
}
private async void AuthorizationStateChanged(object sender, params object[] e)
{
wasInvoked = false;
switch (e[0] as bool?)
{
case true:
account.Visibility = Visibility.Collapsed;
ToolTipService.SetToolTip(avatar, $"{SecretsVault.UserInfo.Name} ({SecretsVault.UserInfo.Email})");
myNameFlyout.Text = SecretsVault.UserInfo.Name;
myEmail.Text = SecretsVault.UserInfo.Email;
avatarFlyout.ProfilePicture = new BitmapImage(SecretsVault.UserInfo.Picture.ToUri()) { DecodePixelHeight = 65, DecodePixelWidth = 65 };
((avatar.Content as Ellipse).Fill as ImageBrush).ImageSource = new BitmapImage(SecretsVault.UserInfo.Picture.ToUri()) { DecodePixelHeight = 25, DecodePixelWidth = 25 };
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;
if (SecretsVault.Subscriptions.Count > 0)
{
subsHeader.Visibility = Visibility.Visible;
for (int k = 0; k < SecretsVault.Subscriptions.Count && k < 10; k++)
nav.MenuItems.Add(SecretsVault.Subscriptions[k]);
}
HistorySet.Load();
if (content.Frame.Content != null)
content.Refresh();
else
content.Frame.Navigate(typeof(Home));
break;
case false:
content.Frame.Navigate(typeof(Home));
for (int k = nav.MenuItems.Count - 1; k > 8; k--)
nav.MenuItems.RemoveAt(k);
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;
subsHeader.Visibility = Visibility.Collapsed;
subsHeader.Visibility = Visibility.Collapsed;
content.Frame.BackStack.Clear();
content.Frame.ForwardStack.Clear();
break;
default:
MessageDialog dialog = new MessageDialog(resources.GetString("/Main/connectErrContent"), resources.GetString("/Main/connectErrHeader"));
dialog.Commands.Add(new UICommand(resources.GetString("/Main/tryAgain"), (command) =>
{
SecretsVault.Authorize();
}));
dialog.Commands.Add(new UICommand(resources.GetString("/Main/quit"), (command) =>
{
Methods.CloseApp();
}));
dialog.CancelCommandIndex = 1;
dialog.DefaultCommandIndex = 0;
await dialog.ShowAsync();
break;
}
if (videoPlaceholder.Frame.Content != null)
{
MaximizeVideo();
videoPlaceholder.Refresh();
}
DownloadAgent.Initialize();
}
private async void Feedback_Click(object sender, RoutedEventArgs e)
{
await StoreServicesFeedbackLauncher.GetDefault().LaunchAsync();
}
private void SignIn_Click(object sender, RoutedEventArgs e)
{
SecretsVault.Authorize();
}
private void Logout_Click(object sender, RoutedEventArgs e)
{
avatar.Flyout.Hide();
SecretsVault.Deauthenticate();
}
public void GoToSearch(SearchParameters args)
{
content.Frame.Navigate(typeof(Search), new object[] { args, content });
}
public void GoToChannel(string id)
{
content.Frame.Navigate(typeof(ChannelPage), id);
}
public void GoToHome()
{
content.Frame.Navigate(typeof(Home));
}
public void GoToVideo(string id, string playlistId = null, bool incognito = false)
{
MaximizeVideo();
nav.IsBackEnabled = true;
nav.ExpandedModeThresholdWidth = short.MaxValue;
nav.IsPaneOpen = false;
videoPlaceholder.Frame.Navigate(typeof(VideoPage), new object[3] { id, playlistId, incognito });
Title.Text = resources.GetString("/Main/video");
}
public void GoToDeveloper(string id)
{
content.Frame.Navigate(typeof(Settings), id);
}
public void GoToPlaylist(string id)
{
content.Frame.Navigate(typeof(PlaylistPage), id);
}
public void GoToHistory()
{
content.Frame.Navigate(typeof(History));
}
public void GoToDownloads()
{
content.Frame.Navigate(typeof(Downloads));
}
public void MinimizeAsInitializer()
{
if (videoPlaceholder.Frame.Content == null)
return;
if (videoPlaceholder.LoadingPage.State != LoadingState.Loaded)
CloseVideo();
else
(videoPlaceholder.Frame.Content as VideoPage).Player.Minimize();
Title.Text = headers[content.Frame.SourcePageType];
}
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.Frame.CanGoBack)
nav.IsBackEnabled = true;
else
nav.IsBackEnabled = false;
SetNavigationMenu();
Title.Text = headers[content.Frame.SourcePageType];
}
void SetNavigationMenu()
{
if (content.Frame.SourcePageType == typeof(Home) || content.Frame.SourcePageType == typeof(Settings) || content.Frame.SourcePageType == typeof(Subscriptions))
{
nav.ExpandedModeThresholdWidth = 1008;
nav.IsPaneOpen = nav.DisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Expanded ? true : false;
}
else
{
nav.ExpandedModeThresholdWidth = short.MaxValue;
nav.IsPaneOpen = 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);
if (videoPlaceholder.Frame.Content == null)
return;
nav.IsBackEnabled = true;
Title.Text = resources.GetString("/Main/video");
nav.ExpandedModeThresholdWidth = short.MaxValue;
nav.IsPaneOpen = false;
}
public void CloseVideo()
{
if (ApplicationView.GetForCurrentView().IsFullScreenMode)
ApplicationView.GetForCurrentView().ExitFullScreenMode();
videoPlaceholder.Frame.Content = null;
GC.Collect();
MaximizeVideo();
nav.IsBackEnabled = content.Frame.CanGoBack;
SetNavigationMenu();
Title.Text = headers[content.Frame.SourcePageType];
}
private void Search_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
{
if(!string.IsNullOrWhiteSpace(search.Text))
GoToSearch(new SearchParameters(search.Text));
}
private async void Search_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
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}&hl={SettingsStorage.RelevanceLanguage}");
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 { search.ItemsSource = new List<string>(); }
}
});
}
void SetNavigationItem(object item)
{
try
{
if (nav.SelectedItem != item)
nav.SelectedItem = item;
else
wasInvoked = false;
}
catch { }
}
public void Content_Navigated(object sender, NavigationEventArgs e)
{
Title.Text = headers[content.Frame.SourcePageType];
if (!wasInvoked)
{
wasInvoked = true;
if (e.SourcePageType == typeof(Settings))
SetNavigationItem(nav.SettingsItem);
else if (e.SourcePageType == typeof(Subscriptions))
SetNavigationItem(toSubscriptions);
else if (e.SourcePageType == typeof(Downloads))
SetNavigationItem(toDownloads);
else if (e.SourcePageType == typeof(Home))
SetNavigationItem(toHome);
else if (e.SourcePageType == typeof(Search))
SetNavigationItem(null);
else if(e.SourcePageType == typeof(ChannelPage))
{
if (SecretsVault.IsAuthorized)
{
if (e.Parameter.ToString() == SecretsVault.AccountId)
SetNavigationItem(toChannel);
else if (nav.MenuItems.Contains(SecretsVault.Subscriptions.Find(i => i.Snippet.ResourceId.ChannelId == e.Parameter.ToString())))
SetNavigationItem(SecretsVault.Subscriptions.Find(i => i.Snippet.ResourceId.ChannelId == e.Parameter.ToString()));
else
SetNavigationItem(null);
}
else
SetNavigationItem(null);
}
else if(e.SourcePageType == typeof(History))
SetNavigationItem(toHistory);
else if(e.SourcePageType == typeof(PlaylistPage))
{
if (SecretsVault.IsAuthorized)
{
if (e.Parameter.ToString() == SecretsVault.UserChannel.ContentDetails.RelatedPlaylists.Likes)
SetNavigationItem(toLiked);
else if (e.Parameter.Equals("WL"))
SetNavigationItem(toLater);
}
else
SetNavigationItem(null);
}
}
else
wasInvoked = false;
nav.IsBackEnabled = content.Frame.CanGoBack;
SetNavigationMenu();
if (videoPlaceholder.Frame.Content != null && videoPlaceholder.HorizontalAlignment == HorizontalAlignment.Stretch)
MinimizeAsInitializer();
}
private void RemoveAds_Tapped(object sender, TappedRoutedEventArgs e)
{
SecretsVault.GetAdblock();
}
private void Nav_SelectionChanged(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewSelectionChangedEventArgs args)
{
if (!wasInvoked)
{
if (content == null)
return;
wasInvoked = true;
if (args.IsSettingsSelected)
content.Frame.Navigate(typeof(Settings));
else
{
if (args.SelectedItem == toHome)
content.Frame.Navigate(typeof(Home));
else if (args.SelectedItem == toHistory)
content.Frame.Navigate(typeof(History));
else if (args.SelectedItem == toLiked)
content.Frame.Navigate(typeof(PlaylistPage), SecretsVault.UserChannel.ContentDetails.RelatedPlaylists.Likes);
else if (args.SelectedItem == toLater)
content.Frame.Navigate(typeof(PlaylistPage), "WL");
else if (args.SelectedItem == toSubscriptions)
content.Frame.Navigate(typeof(Subscriptions));
else if (args.SelectedItem == toDownloads)
content.Frame.Navigate(typeof(Downloads));
else if (args.SelectedItem == toChannel)
content.Frame.Navigate(typeof(ChannelPage), SecretsVault.UserChannel.Id);
else
content.Frame.Navigate(typeof(ChannelPage), (args.SelectedItem as Subscription).Snippet.ResourceId.ChannelId);
}
}
else
wasInvoked = false;
}
private void Nav_BackRequested(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewBackRequestedEventArgs args)
{
if (videoPlaceholder.Frame.Content != null && double.IsNaN(videoPlaceholder.Width))
{
if (videoPlaceholder.Frame.CanGoBack)
videoPlaceholder.Frame.GoBack();
else if (videoPlaceholder.LoadingPage.State != LoadingState.Loaded)
CloseVideo();
else
MinimizeAsInitializer();
}
else
content.Frame.GoBack();
}
private void Nav_PaneClosing(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewPaneClosingEventArgs args)
{
AppTitle.Visibility = Visibility.Collapsed;
}
private void Nav_PaneOpened(Microsoft.UI.Xaml.Controls.NavigationView sender, object args)
{
AppTitle.Visibility = Visibility.Visible;
}
private void NavigationViewItem_Tapped(object sender, TappedRoutedEventArgs e)
{
content.Frame.Navigate(typeof(UploadPage));
}
}
}