619 lines
23 KiB
C#
619 lines
23 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;
|
|
|
|
// 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 RightPaneState { Full, Collapsed, Hidden }
|
|
|
|
public sealed partial class MainPage : Page
|
|
{
|
|
private bool loggedIn = false;
|
|
UserCredential credential;
|
|
|
|
RightPaneState paneState = RightPaneState.Full;
|
|
bool isForcedCollapsed = false;
|
|
|
|
public bool Logged
|
|
{
|
|
get
|
|
{
|
|
return loggedIn;
|
|
}
|
|
}
|
|
|
|
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
|
|
List<Notification> notifications = new List<Notification>();
|
|
public MainPage()
|
|
{
|
|
this.InitializeComponent();
|
|
|
|
if(settings.Values["language"] == null)
|
|
settings.Values.Add("language", 0);
|
|
if (settings.Values["quality"] == null)
|
|
settings.Values.Add("quality", 0);
|
|
|
|
if (settings.Values["newVideoNotification"] == null)
|
|
settings.Values.Add("newVideoNotification", true);
|
|
if (settings.Values["newCommentNotification"] == null)
|
|
settings.Values.Add("newCommentNotification", true);
|
|
if (settings.Values["newPostNotification"] == null)
|
|
settings.Values.Add("newPostNotification", 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["volume"] == null)
|
|
settings.Values.Add("volume", 100);
|
|
|
|
content.Navigate(typeof(Home));
|
|
}
|
|
|
|
protected override void OnNavigatedTo(NavigationEventArgs e)
|
|
{
|
|
base.OnNavigatedTo(e);
|
|
SetTitleBar();
|
|
}
|
|
|
|
private void SetTitleBar()
|
|
{
|
|
var titleBar = ApplicationView.GetForCurrentView().TitleBar;
|
|
|
|
titleBar.BackgroundColor = titleBar.ButtonBackgroundColor = Colors.Red;
|
|
titleBar.ForegroundColor = titleBar.ButtonForegroundColor = Colors.White;
|
|
titleBar.ButtonHoverBackgroundColor = Colors.IndianRed;
|
|
titleBar.ButtonPressedBackgroundColor = Colors.DarkRed;
|
|
}
|
|
|
|
private void menuButton_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
menu.IsPaneOpen = !menu.IsPaneOpen;
|
|
//AddNotification(new Notification("Internal notification", "Menu state has been changed", DateTime.Now, NotificationType.Update));
|
|
}
|
|
|
|
public void AddNotification(Notification notification , bool needNotify = true)
|
|
{
|
|
notificationMenu.Content = "";
|
|
notifications.Add(notification);
|
|
noNotifText.Visibility = Visibility.Collapsed;
|
|
notificationPanel.Visibility = Visibility.Visible;
|
|
StackPanel stack = new StackPanel();
|
|
stack.Orientation = Orientation.Horizontal;
|
|
stack.Children.Add(new PersonPicture()
|
|
{
|
|
Height = 50,
|
|
HorizontalAlignment = HorizontalAlignment.Left,
|
|
Margin = new Thickness(0, 0, 10, 0),
|
|
VerticalAlignment = VerticalAlignment.Top,
|
|
ProfilePicture = new BitmapImage(new Uri(notification.Avatar))
|
|
});
|
|
StackPanel stackPanel = new StackPanel();
|
|
//Channel
|
|
stackPanel.Children.Add(new TextBlock()
|
|
{
|
|
FontSize = 14,
|
|
FontStyle = Windows.UI.Text.FontStyle.Italic,
|
|
Foreground = new SolidColorBrush(Colors.Gray),
|
|
Text = notification.Header
|
|
});
|
|
//Content
|
|
stackPanel.Children.Add(new TextBlock()
|
|
{
|
|
TextWrapping = TextWrapping.WrapWholeWords,
|
|
Text = notification.message,
|
|
});
|
|
//Time
|
|
stackPanel.Children.Add(new TextBlock()
|
|
{
|
|
FontSize = 13,
|
|
Foreground = new SolidColorBrush(Colors.Gray),
|
|
Text = notification.returnTimecode()
|
|
});
|
|
stack.Children.Add(stackPanel);
|
|
|
|
notificationArray.Items.Add(new ListBoxItem()
|
|
{
|
|
Padding = new Thickness(10),
|
|
MinHeight = 80,
|
|
Content = stack
|
|
});
|
|
|
|
//Sending notification
|
|
if(needNotify)
|
|
{
|
|
if(notification.Type == NotificationType.Update)
|
|
{
|
|
ToastContent toast = new ToastContent()
|
|
{
|
|
Visual = new ToastVisual()
|
|
{
|
|
BindingGeneric = new ToastBindingGeneric()
|
|
{
|
|
Children =
|
|
{
|
|
new AdaptiveText()
|
|
{
|
|
Text = notification.Header,
|
|
HintMaxLines = 2
|
|
},
|
|
new AdaptiveText()
|
|
{
|
|
Text = notification.message
|
|
}
|
|
},
|
|
HeroImage = new ToastGenericHeroImage()
|
|
{
|
|
Source = notification.Thumbnail
|
|
},
|
|
AppLogoOverride = new ToastGenericAppLogo()
|
|
{
|
|
Source = notification.Avatar,
|
|
HintCrop = ToastGenericAppLogoCrop.Circle
|
|
}
|
|
}
|
|
},
|
|
Actions = new ToastActionsCustom()
|
|
{
|
|
Buttons =
|
|
{
|
|
new ToastButton("View full post", "action=viewupdatenotification")
|
|
{
|
|
ActivationType = ToastActivationType.Foreground
|
|
},
|
|
new ToastButton("Manage notifications", "action=notificationsettings")
|
|
{
|
|
ActivationType = ToastActivationType.Foreground
|
|
}
|
|
}
|
|
},
|
|
Launch = "action=viewupdatenotification"
|
|
};
|
|
ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification(toast.GetXml()));
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if(topHamburger.SelectedItem != null)
|
|
bottomHaburger.SelectedItem = null;
|
|
MenuSelectionChanged();
|
|
} catch { }
|
|
}
|
|
|
|
private void bottomHaburgerSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if(bottomHaburger.SelectedItem != null)
|
|
topHamburger.SelectedItem = null;
|
|
MenuSelectionChanged();
|
|
} catch { }
|
|
}
|
|
|
|
private void MenuSelectionChanged()
|
|
{
|
|
if(topHamburger.SelectedIndex == 0)
|
|
{
|
|
content.Navigate(typeof(Home));
|
|
headerText.Text = "Home";
|
|
menu.DisplayMode = SplitViewDisplayMode.CompactInline;
|
|
isForcedCollapsed = false;
|
|
menu.IsPaneOpen = true;
|
|
}
|
|
else if (topHamburger.SelectedIndex == 1)
|
|
{
|
|
content.Navigate(typeof(Video));
|
|
headerText.Text = "Video";
|
|
menu.DisplayMode = SplitViewDisplayMode.CompactOverlay;
|
|
menu.IsPaneOpen = false;
|
|
isForcedCollapsed = true;
|
|
}
|
|
else if (bottomHaburger.SelectedIndex == 4)
|
|
{
|
|
content.Navigate(typeof(Settings));
|
|
headerText.Text = "Settings";
|
|
menu.DisplayMode = SplitViewDisplayMode.CompactOverlay;
|
|
menu.IsPaneOpen = false;
|
|
isForcedCollapsed = true;
|
|
}
|
|
else if (bottomHaburger.SelectedIndex == 1)
|
|
{
|
|
content.Navigate(typeof(Channel));
|
|
headerText.Text = "Channel overview";
|
|
menu.DisplayMode = SplitViewDisplayMode.CompactOverlay;
|
|
menu.IsPaneOpen = false;
|
|
isForcedCollapsed = true;
|
|
}
|
|
else if (bottomHaburger.SelectedIndex == 3)
|
|
{
|
|
if(content.SourcePageType == typeof(Settings))
|
|
bottomHaburger.SelectedIndex = 3;
|
|
else if (content.SourcePageType == typeof(Home))
|
|
topHamburger.SelectedIndex = 0;
|
|
else if (content.SourcePageType == typeof(Channel))
|
|
bottomHaburger.SelectedIndex = 1;
|
|
}
|
|
}
|
|
|
|
private void notification_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
notificationPane.IsOpen = !notificationPane.IsOpen;
|
|
notificationMenu.Content = "";
|
|
}
|
|
|
|
private void clearNotifications_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
notifications.Clear();
|
|
notificationArray.Items.Clear();
|
|
|
|
noNotifText.Visibility = Visibility.Visible;
|
|
notificationPanel.Visibility = Visibility.Collapsed;
|
|
}
|
|
|
|
private void refresh_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
Type t = content.CurrentSourcePageType;
|
|
content.Navigate(t);
|
|
}
|
|
|
|
private void feddback_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
bottomHaburger.SelectedIndex = 4;
|
|
Settings s = content.Content as Settings;
|
|
s.pivot.SelectedIndex = 3;
|
|
}
|
|
|
|
public void PreDefineFeedback(bool isProblem, string meta)
|
|
{
|
|
bottomHaburger.SelectedIndex = 4;
|
|
Settings s = content.Content as Settings;
|
|
s.pivot.SelectedIndex = 3;
|
|
s.fb.PreDefine(isProblem, meta);
|
|
}
|
|
|
|
private void menu_PaneClosed(SplitView sender, object args)
|
|
{
|
|
try
|
|
{
|
|
subsMenuTitle.Visibility = Visibility.Collapsed;
|
|
subsMenuStroke.X2 = 40;
|
|
subsMenuStroke.Y1 = subsMenuStroke.Y2 = 0;
|
|
subscriptionsTitle.Height = 2;
|
|
subsLogErr.Visibility = Visibility.Collapsed;
|
|
} catch { }
|
|
}
|
|
|
|
private void menu_PaneOpened(SplitView sender, object args)
|
|
{
|
|
try
|
|
{
|
|
subsMenuTitle.Visibility = Visibility.Visible;
|
|
subsMenuStroke.X2 = 165;
|
|
subsMenuStroke.Y1 = subsMenuStroke.Y2 = 10;
|
|
subscriptionsTitle.Height = 17;
|
|
subsLogErr.Visibility = Visibility.Visible;
|
|
} catch { }
|
|
}
|
|
|
|
private void LoggedAvatar_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
AccountManagement.IsOpen = true;
|
|
}
|
|
|
|
private void createAccount_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
Process.Start("https://accounts.google.com/signup/");
|
|
}
|
|
|
|
private void signIn_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
LogIn().Wait();
|
|
}
|
|
|
|
private async Task LogIn()
|
|
{
|
|
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
|
|
SecretsVault.Secrets,
|
|
new[] { YouTubeService.Scope.Youtube },
|
|
"user",
|
|
CancellationToken.None
|
|
);
|
|
}
|
|
|
|
private void searchField_TextChanged(object sender, TextChangedEventArgs e)
|
|
{
|
|
if (searchField.Text.Length > 2)
|
|
{
|
|
searchSuggestions.Visibility = Visibility.Visible;
|
|
buildSearchSuggestionsTree(searchField.Text);
|
|
}
|
|
else searchField_LostFocus(this, null);
|
|
}
|
|
|
|
async void buildSearchSuggestionsTree(string keyword)
|
|
{
|
|
searchSuggestionsList.Items.Clear();
|
|
searchStandby.Visibility = Visibility.Visible;
|
|
searchSuggestionsList.Visibility = Visibility.Collapsed;
|
|
|
|
XmlDocument doc = new XmlDocument();
|
|
await Task.Run(() =>
|
|
{
|
|
doc.Load(string.Format("http://suggestqueries.google.com/complete/search?output=toolbar&hl={0}&q={1}", "en", keyword));
|
|
});
|
|
|
|
for (int k = 0; k < 5; k++)
|
|
try
|
|
{
|
|
searchSuggestionsList.Items.Add(new ListBoxItem()
|
|
{
|
|
Content = doc["toplevel"].ChildNodes[k]["suggestion"].GetAttribute("data")
|
|
});
|
|
}
|
|
catch (NullReferenceException)
|
|
{
|
|
searchSuggestionsList.Items.Clear();
|
|
searchSuggestionsList.Items.Add(new ListBoxItem()
|
|
{
|
|
Content = "No suggestions found.",
|
|
IsEnabled = false,
|
|
Foreground = new SolidColorBrush(Colors.Gray)
|
|
});
|
|
}
|
|
|
|
/*ListBoxItem separator = new ListBoxItem()
|
|
{
|
|
Padding = new Thickness(0),
|
|
IsEnabled = false
|
|
};
|
|
StackPanel stack = new StackPanel() { Orientation = Orientation.Horizontal };
|
|
stack.Children.Add(new TextBlock()
|
|
{
|
|
Foreground = new SolidColorBrush(Colors.Gray),
|
|
Text = "Previous requests",
|
|
FontSize = 12,
|
|
Margin = new Thickness(0),
|
|
Padding = new Thickness(0, 0, 5, 0)
|
|
});
|
|
stack.Children.Add(new Line()
|
|
{
|
|
X1 = 0,
|
|
X2 = 250,
|
|
Y1 = 10,
|
|
Y2 = 10,
|
|
Stroke = new SolidColorBrush(Colors.Gray),
|
|
StrokeThickness = 2
|
|
});
|
|
separator.Content = stack;
|
|
searchSuggestionsList.Items.Add(separator);
|
|
|
|
if (settings.Values["history0"] != null)
|
|
for (int k = 0; k < 5; k++)
|
|
try
|
|
{
|
|
searchSuggestionsList.Items.Add(new ListBoxItem()
|
|
{
|
|
Content = settings.Values["history" + k]
|
|
});
|
|
}
|
|
catch (NullReferenceException)
|
|
{
|
|
break;
|
|
}
|
|
else searchSuggestionsList.Items.Add(new ListBoxItem()
|
|
{
|
|
Content = "You have no previous requests.",
|
|
Foreground = new SolidColorBrush(Colors.Gray),
|
|
IsEnabled = false
|
|
});*/
|
|
|
|
searchStandby.Visibility = Visibility.Collapsed;
|
|
searchSuggestionsList.Visibility = Visibility.Visible;
|
|
}
|
|
|
|
private void searchField_LostFocus(object sender, RoutedEventArgs e)
|
|
{
|
|
searchSuggestions.Visibility = Visibility.Collapsed;
|
|
}
|
|
|
|
private void searchButton_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if(searchField.Text != "")
|
|
StartSearch(searchField.Text);
|
|
}
|
|
|
|
private async void StartSearch(string keyword)
|
|
{
|
|
content.Navigate(typeof(Search));
|
|
topHamburger.SelectedItem = null;
|
|
bottomHaburger.SelectedItem = null;
|
|
|
|
/*{
|
|
List<string> history = new List<string>();
|
|
for(int k = 0; k < 5; k++)
|
|
try
|
|
{
|
|
history.Add(settings.Values["history" + k].ToString());
|
|
}
|
|
catch(NullReferenceException)
|
|
{
|
|
break;
|
|
}
|
|
history.Insert(0, keyword);
|
|
if (history.Count > 5)
|
|
history.RemoveAt(5);
|
|
|
|
for(int k = 0; k < history.Count; k++)
|
|
try
|
|
{
|
|
settings.Values["history" + k] = history[k];
|
|
}
|
|
catch (NullReferenceException)
|
|
{
|
|
settings.Values.Add("history" + k, keyword);
|
|
}
|
|
}*/
|
|
|
|
YouTubeService ytService = new YouTubeService(new BaseClientService.Initializer()
|
|
{
|
|
ApiKey = "AIzaSyBgHrCnrlzlVmk0cJKL8RqP9Y8x6XSuk_0",
|
|
ApplicationName = this.GetType().ToString()
|
|
});
|
|
|
|
var searchListRequest = ytService.Search.List("snippet");
|
|
searchListRequest.Q = keyword;
|
|
searchListRequest.MaxResults = 25;
|
|
|
|
var response = await searchListRequest.ExecuteAsync();
|
|
|
|
Search s = content.Content as Search;
|
|
s.SetResults(keyword, (int)response.PageInfo.TotalResults);
|
|
Debug.WriteLine("building items tree...");
|
|
foreach (SearchResult result in response.Items)
|
|
s.AddItem(result, Logged);
|
|
s.ring.IsActive = false;
|
|
s.content.Visibility = Visibility.Visible;
|
|
Debug.WriteLine("done");
|
|
}
|
|
|
|
private void searchField_KeyUp(object sender, KeyRoutedEventArgs e)
|
|
{
|
|
if (e.Key == Windows.System.VirtualKey.Enter)
|
|
{
|
|
searchButton_Click(this, null);
|
|
content.Focus(FocusState.Pointer);
|
|
searchSuggestions.Visibility = Visibility.Collapsed;
|
|
}
|
|
}
|
|
|
|
public static string NormalizeDuration(string code)
|
|
{
|
|
Debug.WriteLine(string.Format("Source string: '{0}'", code));
|
|
string temp = code.Trim('P', 'T', 'S');
|
|
Debug.WriteLine(string.Format("Trimmed string: '{0}'", temp));
|
|
temp = temp.Replace('H', '|');
|
|
temp = temp.Replace('M', '|');
|
|
if (temp.StartsWith('|'))
|
|
temp.TrimStart('|');
|
|
if (temp.EndsWith('|'))
|
|
temp.TrimEnd('|');
|
|
Debug.WriteLine(string.Format("End string: '{0}'", temp));
|
|
string[] arr = temp.Split('|');
|
|
Debug.WriteLine(string.Format("Array length: {0}", arr.Length));
|
|
foreach (string str in arr)
|
|
Debug.WriteLine(str);
|
|
|
|
switch(arr.Length)
|
|
{
|
|
case 3:
|
|
return new TimeSpan(Convert.ToInt32(arr[0]), Convert.ToInt32(arr[1]), Convert.ToInt32(arr[2])).ToString();
|
|
case 2:
|
|
return new TimeSpan(0, Convert.ToInt32(arr[0]), Convert.ToInt32(arr[1])).ToString();
|
|
case 1:
|
|
return new TimeSpan(0, 0, Convert.ToInt32(arr[0])).ToString();
|
|
default:
|
|
return "";
|
|
}
|
|
}
|
|
|
|
private void searchSuggestionsList_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
if(e.AddedItems.Count > 0)
|
|
{
|
|
ListBoxItem item = e.AddedItems[0] as ListBoxItem;
|
|
searchField.Text = item.Content.ToString();
|
|
searchButton_Click(this, null);
|
|
}
|
|
}
|
|
|
|
public void GoToChannel(string id)
|
|
{
|
|
headerText.Text = "Channel overview";
|
|
content.Navigate(typeof(Channel));
|
|
Channel page = content.Content as Channel;
|
|
page.Initialize(id);
|
|
}
|
|
|
|
private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
|
|
{
|
|
if(isForcedCollapsed)
|
|
{
|
|
if (e.NewSize.Width >= 600 && paneState != RightPaneState.Collapsed)
|
|
{
|
|
menu.DisplayMode = SplitViewDisplayMode.CompactOverlay;
|
|
menu.IsPaneOpen = false;
|
|
paneState = RightPaneState.Collapsed;
|
|
}
|
|
else if (e.NewSize.Width < 600 && paneState != RightPaneState.Hidden)
|
|
{
|
|
menu.DisplayMode = SplitViewDisplayMode.Overlay;
|
|
menu.IsPaneOpen = false;
|
|
paneState = RightPaneState.Hidden;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (e.NewSize.Width >= 1000 && paneState != RightPaneState.Full)
|
|
{
|
|
menu.DisplayMode = SplitViewDisplayMode.CompactInline;
|
|
menu.IsPaneOpen = true;
|
|
paneState = RightPaneState.Full;
|
|
}
|
|
else if(e.NewSize.Width >= 600 && e.NewSize.Width < 1000 && paneState != RightPaneState.Collapsed)
|
|
{
|
|
menu.DisplayMode = SplitViewDisplayMode.CompactOverlay;
|
|
menu.IsPaneOpen = false;
|
|
paneState = RightPaneState.Collapsed;
|
|
}
|
|
else if(e.NewSize.Width < 600 && paneState != RightPaneState.Hidden)
|
|
{
|
|
menu.DisplayMode = SplitViewDisplayMode.Overlay;
|
|
menu.IsPaneOpen = false;
|
|
paneState = RightPaneState.Hidden;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|