+49
-26
@@ -1,7 +1,10 @@
|
|||||||
using FoxTube.Pages;
|
using FoxTube.Classes;
|
||||||
using System.Diagnostics;
|
using FoxTube.Controls;
|
||||||
|
using FoxTube.Pages;
|
||||||
|
using Microsoft.AppCenter.Analytics;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Windows.ApplicationModel.Activation;
|
using Windows.ApplicationModel.Activation;
|
||||||
using Windows.UI.Notifications;
|
using Windows.Globalization;
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
|
|
||||||
@@ -9,47 +12,67 @@ namespace FoxTube
|
|||||||
{
|
{
|
||||||
sealed partial class App : Application
|
sealed partial class App : Application
|
||||||
{
|
{
|
||||||
public App()
|
public App() =>
|
||||||
{
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
|
||||||
|
|
||||||
/*protected override void OnLaunched(LaunchActivatedEventArgs e)
|
/*void Initialize()
|
||||||
{
|
{
|
||||||
if (!(Window.Current.Content is Frame))
|
Settings.LoadData();
|
||||||
Window.Current.Content = new Frame();
|
|
||||||
|
|
||||||
if (e.PrelaunchActivated == false)
|
switch (Settings.Theme)
|
||||||
{
|
{
|
||||||
if ((Window.Current.Content as Frame).Content == null)
|
case 0:
|
||||||
(Window.Current.Content as Frame).Navigate(typeof(MainPage), e.Arguments);
|
RequestedTheme = ApplicationTheme.Light;
|
||||||
|
break;
|
||||||
Window.Current.Activate();
|
case 1:
|
||||||
|
RequestedTheme = ApplicationTheme.Dark;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
ApplicationLanguages.PrimaryLanguageOverride = Settings.Language;
|
||||||
|
|
||||||
|
Processes.InitializeApp();
|
||||||
|
|
||||||
|
Suspending += (s, e) => Processes.SuspendApp();
|
||||||
|
UnhandledException += (s, e) => Analytics.TrackEvent("The app crashed", new Dictionary<string, string>()
|
||||||
|
{
|
||||||
|
{ "Exception", e.Exception.GetType().ToString() },
|
||||||
|
{ "Details", e.Message },
|
||||||
|
{ "StackTrace", e.Exception.StackTrace }
|
||||||
|
});
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
protected override void OnBackgroundActivated(BackgroundActivatedEventArgs args)
|
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (!e.PrelaunchActivated && Window.Current.Content == null)
|
||||||
|
Window.Current.Content = new MainPage(e.SplashScreen, e.Arguments);
|
||||||
|
Window.Current.Activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async void OnBackgroundActivated(BackgroundActivatedEventArgs args)
|
||||||
|
{
|
||||||
|
var deferral = args.TaskInstance.GetDeferral();
|
||||||
base.OnBackgroundActivated(args);
|
base.OnBackgroundActivated(args);
|
||||||
|
|
||||||
|
await Methods.ProcessBackgroundToast((args.TaskInstance.TriggerDetails as ToastNotificationActivatedEventArgs).Argument);
|
||||||
|
|
||||||
|
deferral.Complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnActivated(IActivatedEventArgs e)
|
protected override void OnActivated(IActivatedEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnActivated(e);
|
base.OnActivated(e);
|
||||||
|
|
||||||
//TODO: Check this shit
|
if (Window.Current.Content == null)
|
||||||
if (!(Window.Current.Content is Frame rootFrame))
|
Window.Current.Content = new MainPage(e.SplashScreen, e);
|
||||||
{
|
|
||||||
rootFrame = new Frame();
|
|
||||||
Window.Current.Content = rootFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rootFrame.Content == null)
|
|
||||||
rootFrame.Navigate(typeof(MainPage));
|
|
||||||
|
|
||||||
Window.Current.Activate();
|
Window.Current.Activate();
|
||||||
|
|
||||||
Debug.WriteLine("Hello, World");
|
/*if(e.Kind == ActivationKind.ToastNotification)
|
||||||
|
{
|
||||||
|
if (UserManagement.IsAuthorized)
|
||||||
|
Methods.ProcessToast((e as ToastNotificationActivatedEventArgs).Argument);
|
||||||
|
else
|
||||||
|
UserManagement.AuthorizationStateChanged += (arg) => Methods.ProcessToast((e as ToastNotificationActivatedEventArgs).Argument);
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FoxTube.Classes
|
||||||
|
{
|
||||||
|
public static class Downloads
|
||||||
|
{
|
||||||
|
public static void Cancel(string id)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using Google.Apis.YouTube.v3.Data;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace FoxTube
|
||||||
|
{
|
||||||
|
public delegate void AuthorizationChangedEventHandler(bool isAuthorized);
|
||||||
|
public delegate void SubscriptionChangedEventHandler(string action, Subscription subscription);
|
||||||
|
public delegate void ProVersionStateChangedEventHandler(bool purchased, string price);
|
||||||
|
public delegate void NavigatingOccured(Type sourcePageType, object parameter);
|
||||||
|
public delegate void NavigationOccured(IList pivotCollection, int? selectedPivot);
|
||||||
|
public delegate void SimpleEventHandler();
|
||||||
|
|
||||||
|
public enum LoadingScreenState
|
||||||
|
{
|
||||||
|
Loading = 0,
|
||||||
|
Loaded = 1,
|
||||||
|
Error = 2,
|
||||||
|
Blocked = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface INavigationPage
|
||||||
|
{
|
||||||
|
object Parameter { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Extensions
|
||||||
|
{
|
||||||
|
public static Uri ToUri(this string str) =>
|
||||||
|
string.IsNullOrWhiteSpace(str) ? null : new Uri(str);
|
||||||
|
|
||||||
|
public static bool Belongs<T>(this T obj, params T[] values) =>
|
||||||
|
values.Contains(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
using FoxTube.Classes;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Windows.UI;
|
||||||
|
using Windows.UI.ViewManagement;
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
|
||||||
|
namespace FoxTube
|
||||||
|
{
|
||||||
|
public static class Methods
|
||||||
|
{
|
||||||
|
public static void ProcessToast(string argument)
|
||||||
|
{
|
||||||
|
string[] args = argument.Split('|');
|
||||||
|
|
||||||
|
switch (args[0])
|
||||||
|
{
|
||||||
|
case "changelog":
|
||||||
|
case "inbox":
|
||||||
|
Navigation.GoToDeveloper(args[1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "video":
|
||||||
|
Navigation.GoToVideo(args[1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "channel":
|
||||||
|
Navigation.GoToChannel(args[1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "download":
|
||||||
|
Navigation.GoToDownloads();
|
||||||
|
break;
|
||||||
|
case "clipboard":
|
||||||
|
switch (args[1])
|
||||||
|
{
|
||||||
|
case "video":
|
||||||
|
Navigation.GoToVideo(args[2]);
|
||||||
|
break;
|
||||||
|
case "channel":
|
||||||
|
Navigation.GoToChannel(args[2]);
|
||||||
|
break;
|
||||||
|
case "playlist":
|
||||||
|
Navigation.GoToPlaylist(args[2]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task ProcessBackgroundToast(string argument)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string[] args = argument.Split('|');
|
||||||
|
|
||||||
|
switch (args[0])
|
||||||
|
{
|
||||||
|
case "dcancel":
|
||||||
|
Downloads.Cancel(args[1]);
|
||||||
|
break;
|
||||||
|
case "later":
|
||||||
|
await UserManagement.AddItemToWL(args[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetTitleBar()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
titleBar.ButtonForegroundColor = Colors.White;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
using FoxTube.Classes;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FoxTube
|
||||||
|
{
|
||||||
|
public static class Navigation
|
||||||
|
{
|
||||||
|
public static void GoToSubscriptions()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public static void GoToSearch(SearchParameters args)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void GoToChannel(string id)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void GoToHome()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void GoToVideo(string id, string playlistId = null, bool incognito = false)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void GoToDeveloper(string id)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void GoToPlaylist(string id)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void GoToHistory()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void GoToDownloads()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,248 @@
|
|||||||
|
using Microsoft.AppCenter;
|
||||||
|
using Microsoft.AppCenter.Analytics;
|
||||||
|
using Microsoft.Services.Store.Engagement;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using Windows.ApplicationModel.Background;
|
||||||
|
using Windows.ApplicationModel.DataTransfer;
|
||||||
|
using Windows.ApplicationModel.Resources;
|
||||||
|
using Windows.Data.Xml.Dom;
|
||||||
|
using Windows.System;
|
||||||
|
using Windows.System.Power;
|
||||||
|
using Windows.UI.Core;
|
||||||
|
using Windows.UI.Notifications;
|
||||||
|
using Windows.UI.Popups;
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
|
||||||
|
namespace FoxTube.Classes
|
||||||
|
{
|
||||||
|
public static class Processes
|
||||||
|
{
|
||||||
|
static CoreWindowActivationState windowState = CoreWindowActivationState.CodeActivated;
|
||||||
|
static ResourceLoader resources = ResourceLoader.GetForViewIndependentUse("Inbox");
|
||||||
|
|
||||||
|
static Stopwatch sw = new Stopwatch();
|
||||||
|
public static async void InitializeApp() => await CoreWindow.GetForCurrentThread().Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
|
||||||
|
{
|
||||||
|
CheckVersion();
|
||||||
|
|
||||||
|
RegisterToastTask();
|
||||||
|
if (Settings.DevNotifications || Settings.VideoNotifications)
|
||||||
|
RegisterTask();
|
||||||
|
else
|
||||||
|
UnregisterTask();
|
||||||
|
|
||||||
|
AppCenter.Start("45774462-9ea7-438a-96fc-03982666f39e", typeof(Analytics));
|
||||||
|
AppCenter.SetCountryCode(Settings.Region);
|
||||||
|
|
||||||
|
sw.Start();
|
||||||
|
|
||||||
|
Window.Current.Activated += (s, e) => windowState = e.WindowActivationState;
|
||||||
|
|
||||||
|
// TODO: Initialize other stuff
|
||||||
|
|
||||||
|
if (Settings.ProcessClipboard)
|
||||||
|
{
|
||||||
|
Clipboard.ContentChanged += ParseClipboard;
|
||||||
|
ParseClipboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
PromptFeedback();
|
||||||
|
});
|
||||||
|
|
||||||
|
public static void SuspendApp()
|
||||||
|
{
|
||||||
|
sw.Stop();
|
||||||
|
|
||||||
|
Settings.Uptime += sw.Elapsed;
|
||||||
|
|
||||||
|
// TODO: Save other stuff
|
||||||
|
|
||||||
|
Analytics.TrackEvent("Session terminated", new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "Uptime", sw.Elapsed.ToString() },
|
||||||
|
{ "Total time", Settings.Uptime.ToString() }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async void ParseClipboard(object sender = null, object e = null)
|
||||||
|
{
|
||||||
|
if (windowState != CoreWindowActivationState.Deactivated || !Settings.ProcessClipboard)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string link = await Clipboard.GetContent().GetTextAsync();
|
||||||
|
|
||||||
|
if (!link.Contains("youtube") && !link.Contains("youtu.be"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
string type = string.Empty;
|
||||||
|
string name = string.Empty;
|
||||||
|
|
||||||
|
if (YoutubeExplode.YoutubeClient.TryParseChannelId(link, out string id))
|
||||||
|
{
|
||||||
|
type = "channel";
|
||||||
|
name = (await new YoutubeExplode.YoutubeClient().GetChannelAsync(id)).Title;
|
||||||
|
}
|
||||||
|
else if (YoutubeExplode.YoutubeClient.TryParsePlaylistId(link, out id))
|
||||||
|
{
|
||||||
|
type = "playlist";
|
||||||
|
name = (await new YoutubeExplode.YoutubeClient().GetPlaylistAsync(id)).Title;
|
||||||
|
}
|
||||||
|
else if (YoutubeExplode.YoutubeClient.TryParseUsername(link, out id))
|
||||||
|
{
|
||||||
|
id = await new YoutubeExplode.YoutubeClient().GetChannelIdAsync(id);
|
||||||
|
type = "channel";
|
||||||
|
name = (await new YoutubeExplode.YoutubeClient().GetChannelAsync(id)).Title;
|
||||||
|
}
|
||||||
|
else if (YoutubeExplode.YoutubeClient.TryParseVideoId(link, out id))
|
||||||
|
{
|
||||||
|
type = "video";
|
||||||
|
name = (await new YoutubeExplode.YoutubeClient().GetVideoAsync(id)).Title;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(id))
|
||||||
|
return;
|
||||||
|
|
||||||
|
XmlDocument toastXml = new XmlDocument();
|
||||||
|
toastXml.LoadXml($@"<toast launch='clipboard|{type}|{id}'>
|
||||||
|
<visual>
|
||||||
|
<binding template='ToastGeneric'>
|
||||||
|
<text>{resources.GetString("/Toasts/clipboardHead")}</text>
|
||||||
|
<text>{name}</text>
|
||||||
|
<text>{resources.GetString($"/Generic/{type}")}</text>
|
||||||
|
</binding>
|
||||||
|
</visual>
|
||||||
|
<actions>
|
||||||
|
<action content='{resources.GetString("/Toasts/clipboardOpen")}' arguments='clipboard|{type}|{id}'/>
|
||||||
|
</actions>
|
||||||
|
</toast>");
|
||||||
|
ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification(toastXml));
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CheckVersion()
|
||||||
|
{
|
||||||
|
if (Settings.GetCurrentVersion() == Settings.Version)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
XmlDocument toast = new XmlDocument();
|
||||||
|
toast.LoadXml($@"<toast activationType='foreground' launch='changelog|{Settings.GetCurrentVersion()}'>
|
||||||
|
<visual>
|
||||||
|
<binding template='ToastGeneric'>
|
||||||
|
<image placement='hero' src='ms-appx:///Assets/WhatsNewThumb.png'/>
|
||||||
|
<image placement='appLogoOverride' hint-crop='circle' src='ms-appx:///Assets/NewsAvatar.png'/>
|
||||||
|
<text>{resources.GetString("/Inbox/changelog")}</text>
|
||||||
|
<text>{resources.GetString("/Inbox/whatsNew")} {Settings.GetCurrentVersion()}</text>
|
||||||
|
</binding>
|
||||||
|
</visual>
|
||||||
|
</toast>");
|
||||||
|
|
||||||
|
ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification(toast));
|
||||||
|
|
||||||
|
Settings.Version = Settings.GetCurrentVersion();
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
static async void RegisterToastTask()
|
||||||
|
{
|
||||||
|
if (BackgroundTaskRegistration.AllTasks.Any(i => i.Value.Name.Equals("foxtubeToast")))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var backgroundRequest = await BackgroundExecutionManager.RequestAccessAsync();
|
||||||
|
if (backgroundRequest == BackgroundAccessStatus.DeniedBySystemPolicy ||
|
||||||
|
backgroundRequest == BackgroundAccessStatus.DeniedByUser ||
|
||||||
|
backgroundRequest == BackgroundAccessStatus.Unspecified)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BackgroundTaskBuilder builder = new BackgroundTaskBuilder() { Name = "foxtubeToast" };
|
||||||
|
builder.SetTrigger(new ToastNotificationActionTrigger());
|
||||||
|
|
||||||
|
BackgroundTaskRegistration registration = builder.Register();
|
||||||
|
}
|
||||||
|
|
||||||
|
static async void RegisterTask()
|
||||||
|
{
|
||||||
|
if (BackgroundTaskRegistration.AllTasks.Any(i => i.Value.Name.Equals("foxtubeBackground")))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var backgroundRequest = await BackgroundExecutionManager.RequestAccessAsync();
|
||||||
|
if (backgroundRequest == BackgroundAccessStatus.DeniedBySystemPolicy ||
|
||||||
|
backgroundRequest == BackgroundAccessStatus.DeniedByUser ||
|
||||||
|
backgroundRequest == BackgroundAccessStatus.Unspecified ||
|
||||||
|
PowerManager.EnergySaverStatus == EnergySaverStatus.On)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BackgroundTaskBuilder builder = new BackgroundTaskBuilder()
|
||||||
|
{
|
||||||
|
Name = "foxtubeBackgound",
|
||||||
|
IsNetworkRequested = true,
|
||||||
|
TaskEntryPoint = "FoxTube.Background.BackgroundProcessor"
|
||||||
|
};
|
||||||
|
builder.SetTrigger(new TimeTrigger(15, false));
|
||||||
|
|
||||||
|
BackgroundTaskRegistration registration = builder.Register();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UnregisterTask()
|
||||||
|
{
|
||||||
|
if (!(BackgroundTaskRegistration.AllTasks.Values.ToList().Find(i => i.Name == "foxtubeBackground") is IBackgroundTaskRegistration task))
|
||||||
|
return;
|
||||||
|
|
||||||
|
task.Unregister(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async void PromptFeedback()
|
||||||
|
{
|
||||||
|
if (Settings.Uptime.TotalHours >= 12 && Settings.PromptFeedback)
|
||||||
|
{
|
||||||
|
Analytics.TrackEvent("Prompting feedback", new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "Total uptime", Settings.Uptime.ToString() }
|
||||||
|
});
|
||||||
|
|
||||||
|
MessageDialog dialog = new MessageDialog(resources.GetString("/Dialogs/feedbackMessage"));
|
||||||
|
dialog.Commands.Add(new UICommand(resources.GetString("/Dialogs/dontAsk"), (command) => Settings.PromptFeedback = false));
|
||||||
|
dialog.Commands.Add(new UICommand(resources.GetString("/Dialogs/promptLater")));
|
||||||
|
dialog.Commands.Add(new UICommand(resources.GetString("/Dialogs/sure"), async (command) =>
|
||||||
|
{
|
||||||
|
Settings.PromptFeedback = false;
|
||||||
|
if (StoreServicesFeedbackLauncher.IsSupported())
|
||||||
|
await StoreServicesFeedbackLauncher.GetDefault().LaunchAsync();
|
||||||
|
else
|
||||||
|
await Launcher.LaunchUriAsync("mailto:feedback@xfox111.net".ToUri());
|
||||||
|
}));
|
||||||
|
dialog.DefaultCommandIndex = 2;
|
||||||
|
dialog.CancelCommandIndex = 1;
|
||||||
|
await dialog.ShowAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.Uptime.TotalHours >= 24 && Settings.PromptReview)
|
||||||
|
{
|
||||||
|
Analytics.TrackEvent("Prompting review", new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "Total uptime", Settings.Uptime.ToString() }
|
||||||
|
});
|
||||||
|
|
||||||
|
MessageDialog dialog = new MessageDialog(resources.GetString("/Dialogs/rate"));
|
||||||
|
dialog.Commands.Add(new UICommand(resources.GetString("/Dialogs/dontAsk"), (command) => Settings.PromptReview = false));
|
||||||
|
dialog.Commands.Add(new UICommand(resources.GetString("/Dialogs/promptLater")));
|
||||||
|
dialog.Commands.Add(new UICommand(resources.GetString("/Dialogs/sure"), async (command) =>
|
||||||
|
{
|
||||||
|
Settings.PromptReview = false;
|
||||||
|
await Launcher.LaunchUriAsync("ms-windows-store://review/?ProductId=9NCQQXJTDLFH".ToUri());
|
||||||
|
}));
|
||||||
|
dialog.DefaultCommandIndex = 2;
|
||||||
|
dialog.CancelCommandIndex = 1;
|
||||||
|
await dialog.ShowAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FoxTube.Classes
|
||||||
|
{
|
||||||
|
public class SearchParameters
|
||||||
|
{
|
||||||
|
public SearchParameters(string query)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using Windows.Services.Store;
|
||||||
|
|
||||||
|
namespace FoxTube
|
||||||
|
{
|
||||||
|
public static class Service
|
||||||
|
{
|
||||||
|
public static bool AdsCheckPerformed { get; private set; } = false;
|
||||||
|
public static bool AdsDisabled { get; private set; } = true;
|
||||||
|
public static event ProVersionStateChangedEventHandler Purchased;
|
||||||
|
|
||||||
|
public static NetworkCredential EmailCredential => new NetworkCredential("foxtube.bot@xfox111.net", "JkY39w$.7?bT57O,8k3a");
|
||||||
|
|
||||||
|
private static bool TestAds => false; //TODO: Change this bool
|
||||||
|
public static string AppId => TestAds ? "d25517cb-12d4-4699-8bdc-52040c712cab" : "9ncqqxjtdlfh";
|
||||||
|
public static string AdUnitId => TestAds ? "test" : "1100037769";
|
||||||
|
|
||||||
|
public static async void CheckAddons()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
StoreProductQueryResult requset = await StoreContext.GetDefault().GetAssociatedStoreProductsAsync(new[] { "Durable" });
|
||||||
|
|
||||||
|
if (requset.Products["9NP1QK556625"].IsInUserCollection)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AdsDisabled = false;
|
||||||
|
Purchased?.Invoke(false, requset.Products["9NP1QK556625"].Price.FormattedPrice);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async void GetPro()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
StorePurchaseResult request = await StoreContext.GetDefault().RequestPurchaseAsync("9NP1QK556625");
|
||||||
|
|
||||||
|
if (!request.Status.Belongs(StorePurchaseStatus.AlreadyPurchased, StorePurchaseStatus.Succeeded))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Purchased?.Invoke(true, "");
|
||||||
|
AdsDisabled = true;
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using Windows.ApplicationModel;
|
||||||
|
using Windows.Storage;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace FoxTube.Classes
|
||||||
|
{
|
||||||
|
public static class Settings
|
||||||
|
{
|
||||||
|
public class SettingsContainer
|
||||||
|
{
|
||||||
|
public string videoQuality = "remember";
|
||||||
|
public string rememberedQuality = "1080p";
|
||||||
|
|
||||||
|
public bool videoNotifications = true;
|
||||||
|
public bool devNotifications = true;
|
||||||
|
|
||||||
|
public bool checkConnection = true;
|
||||||
|
public bool autoplay = true;
|
||||||
|
public double volume = 100;
|
||||||
|
|
||||||
|
public string language = GetLanguage();
|
||||||
|
public string relevanceLanguage = CultureInfo.InstalledUICulture.TwoLetterISOLanguageName;
|
||||||
|
public string region = CultureInfo.InstalledUICulture.Name.Split('-')[1];
|
||||||
|
public int safeSearch = 0;
|
||||||
|
|
||||||
|
public bool[] hasAccount = new bool[5] { false, false, false, false, false };
|
||||||
|
public int theme = 2;
|
||||||
|
|
||||||
|
public string version = GetCurrentVersion();
|
||||||
|
public bool mature = false;
|
||||||
|
|
||||||
|
public TimeSpan uptime = TimeSpan.FromSeconds(0);
|
||||||
|
public bool promptReview = true;
|
||||||
|
public bool promptFeedback = true;
|
||||||
|
|
||||||
|
public bool processClipboard = true;
|
||||||
|
public bool minimizeCommandbar = false;
|
||||||
|
|
||||||
|
static string GetLanguage()
|
||||||
|
{
|
||||||
|
if ((new[] { "ua", "ru", "by", "kz", "kg", "md", "lv", "ee" }).Contains(CultureInfo.InstalledUICulture.TwoLetterISOLanguageName))
|
||||||
|
return "ru-RU";
|
||||||
|
else
|
||||||
|
return "en-US";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetCurrentVersion()
|
||||||
|
{
|
||||||
|
PackageVersion ver = Package.Current.Id.Version;
|
||||||
|
return $"{ver.Major}.{ver.Minor}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string VideoQuality
|
||||||
|
{
|
||||||
|
get => Container.videoQuality;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.videoQuality = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static string RememberedQuality
|
||||||
|
{
|
||||||
|
get => Container.rememberedQuality;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.rememberedQuality = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool VideoNotifications
|
||||||
|
{
|
||||||
|
get => Container.videoNotifications;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.videoNotifications = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static bool DevNotifications
|
||||||
|
{
|
||||||
|
get => Container.devNotifications;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.devNotifications = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool CheckConnection
|
||||||
|
{
|
||||||
|
get => Container.checkConnection;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.checkConnection = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static bool Autoplay
|
||||||
|
{
|
||||||
|
get => Container.autoplay;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.autoplay = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static double Volume
|
||||||
|
{
|
||||||
|
get => Container.volume;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.volume = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string Language
|
||||||
|
{
|
||||||
|
get => Container.language;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.language = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static string RelevanceLanguage
|
||||||
|
{
|
||||||
|
get => Container.relevanceLanguage;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.relevanceLanguage = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static string Region
|
||||||
|
{
|
||||||
|
get => Container.region;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.region = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static int SafeSearch
|
||||||
|
{
|
||||||
|
get => Container.safeSearch;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.safeSearch = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static bool[] HasAccount => Container.hasAccount;
|
||||||
|
public static void SetAccount(int index, bool isAuthorized)
|
||||||
|
{
|
||||||
|
HasAccount[index] = isAuthorized;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
public static int Theme
|
||||||
|
{
|
||||||
|
get => Container.theme;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.theme = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string Version
|
||||||
|
{
|
||||||
|
get => Container.version;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.version = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static bool Mature
|
||||||
|
{
|
||||||
|
get => Container.mature;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.mature = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TimeSpan Uptime
|
||||||
|
{
|
||||||
|
get => Container.uptime;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.uptime = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static bool PromptReview
|
||||||
|
{
|
||||||
|
get => Container.promptReview;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.promptReview = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static bool PromptFeedback
|
||||||
|
{
|
||||||
|
get => Container.promptFeedback;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.promptFeedback = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool ProcessClipboard
|
||||||
|
{
|
||||||
|
get => Container.processClipboard;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.processClipboard = value;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AppBarClosedDisplayMode AppBarClosedMode
|
||||||
|
{
|
||||||
|
get => Container.minimizeCommandbar ? AppBarClosedDisplayMode.Minimal : AppBarClosedDisplayMode.Compact;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Container.minimizeCommandbar = value == AppBarClosedDisplayMode.Minimal;
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Settings storage
|
||||||
|
static readonly ApplicationDataContainer storage = ApplicationData.Current.RoamingSettings;
|
||||||
|
static SettingsContainer Container = new SettingsContainer();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads saved settings from storage
|
||||||
|
/// </summary>
|
||||||
|
public static void LoadData()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Container = JsonConvert.DeserializeObject<SettingsContainer>(storage.Values["settings"] as string);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Container = new SettingsContainer();
|
||||||
|
SaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SaveData() =>
|
||||||
|
storage.Values["settings"] = JsonConvert.SerializeObject(Container);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
using Google.Apis.YouTube.v3.Data;
|
||||||
|
using YoutubeExplode.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Google.Apis.Oauth2.v2.Data;
|
||||||
|
using Google.Apis.Auth.OAuth2;
|
||||||
|
using Google.Apis.YouTube.v3;
|
||||||
|
using Google.Apis.Services;
|
||||||
|
using System.Threading;
|
||||||
|
using YoutubeExplode;
|
||||||
|
using System.Net.Http;
|
||||||
|
|
||||||
|
namespace FoxTube.Classes
|
||||||
|
{
|
||||||
|
public class User
|
||||||
|
{
|
||||||
|
public List<Subscription> Subscriptions { get; }
|
||||||
|
|
||||||
|
public List<YoutubeExplode.Models.Video> WatchLater { get; }
|
||||||
|
public List<YoutubeExplode.Models.Video> WebHistory { get; }
|
||||||
|
public List<object> AppHistory { get; }
|
||||||
|
|
||||||
|
public Userinfoplus UserInfo { get; }
|
||||||
|
public UserCredential Credential { get; }
|
||||||
|
|
||||||
|
public YouTubeService Service { get; }
|
||||||
|
|
||||||
|
public YoutubeClient YoutubeClient { get; }
|
||||||
|
|
||||||
|
public string AccountId { get; }
|
||||||
|
public Google.Apis.YouTube.v3.Data.Channel Channel { get; }
|
||||||
|
|
||||||
|
public async void Deauthenticate()
|
||||||
|
{
|
||||||
|
await Credential.RevokeTokenAsync(CancellationToken.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
public User(UserCredential credential)
|
||||||
|
{
|
||||||
|
Credential = credential;
|
||||||
|
Service = new YouTubeService(new BaseClientService.Initializer
|
||||||
|
{
|
||||||
|
HttpClientInitializer = Credential,
|
||||||
|
ApplicationName = "FoxTube"
|
||||||
|
});
|
||||||
|
|
||||||
|
HttpClient httpClient = new HttpClient();
|
||||||
|
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", credential.Token.AccessToken);
|
||||||
|
YoutubeClient = new YoutubeClient(httpClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void RefreshToken() =>
|
||||||
|
await Credential.RefreshTokenAsync(CancellationToken.None);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Subscribes or unsibscribes authorized user from the channel
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The ID of channel which has to be added/removed</param>
|
||||||
|
/// <returns>Returns 'true' if channel is in subscriptions now; 'false' if it's not</returns>
|
||||||
|
public async Task<bool> ChangeSubscriptionState(string id)
|
||||||
|
{
|
||||||
|
if (Subscriptions.Find(i => i.Snippet.ResourceId.ChannelId == id) is Subscription subscription)
|
||||||
|
{
|
||||||
|
try { await Service.Subscriptions.Delete(subscription.Id).ExecuteAsync(); }
|
||||||
|
catch { return true; }
|
||||||
|
|
||||||
|
//SubscriptionsChanged?.Invoke("remove", subscription);
|
||||||
|
Subscriptions.Remove(subscription);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var request = Service.Subscriptions.Insert(new Subscription
|
||||||
|
{
|
||||||
|
Snippet = new SubscriptionSnippet
|
||||||
|
{
|
||||||
|
ResourceId = new ResourceId
|
||||||
|
{
|
||||||
|
ChannelId = id,
|
||||||
|
Kind = "youtube#channel"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "snippet");
|
||||||
|
|
||||||
|
if (!(await request.ExecuteAsync() is Subscription sub))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Subscriptions.Add(sub);
|
||||||
|
//SubscriptionsChanged?.Invoke("add", sub);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
using FoxTube.Classes;
|
||||||
|
using Google.Apis.Auth.OAuth2;
|
||||||
|
using Google.Apis.Oauth2.v2.Data;
|
||||||
|
using Google.Apis.Services;
|
||||||
|
using Google.Apis.YouTube.v3;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using YoutubeExplode;
|
||||||
|
|
||||||
|
namespace FoxTube
|
||||||
|
{
|
||||||
|
public static class UserManagement
|
||||||
|
{
|
||||||
|
public static event AuthorizationChangedEventHandler AuthorizationStateChanged;
|
||||||
|
public static event SubscriptionChangedEventHandler SubscriptionChanged;
|
||||||
|
|
||||||
|
static ClientSecrets[] Secrets => new ClientSecrets[5]
|
||||||
|
{
|
||||||
|
new ClientSecrets
|
||||||
|
{
|
||||||
|
ClientId = "349735264870-2ekqlm0a4mkg3mmrfcv90s3qp3o15dq0.apps.googleusercontent.com",
|
||||||
|
ClientSecret = "BkVZOAaCU2Zclf0Zlicg6y2_"
|
||||||
|
},
|
||||||
|
new ClientSecrets
|
||||||
|
{
|
||||||
|
ClientId = "1096685398208-ha281qmg52ga8g8nn4n6943oct1tq6nj.apps.googleusercontent.com",
|
||||||
|
ClientSecret = "Cew9WbJcsoisYnR-Wuyhukov"
|
||||||
|
},
|
||||||
|
new ClientSecrets
|
||||||
|
{
|
||||||
|
ClientId = "1096685398208-59ktbv2jsvalrmli1pevur9aujnjhjeb.apps.googleusercontent.com",
|
||||||
|
ClientSecret = "eHvXHlIJ9r64yReOmMnuben7"
|
||||||
|
},
|
||||||
|
new ClientSecrets
|
||||||
|
{
|
||||||
|
ClientId = "1096685398208-ebckt9ncp69qutsmdbbufov60nq4rvpa.apps.googleusercontent.com",
|
||||||
|
ClientSecret = "XCaBFmjoT2ZAKsGf-y80lBvc"
|
||||||
|
},
|
||||||
|
new ClientSecrets
|
||||||
|
{
|
||||||
|
ClientId = "1096685398208-ligbo8gqkp4qar1uo0e5o5di434qklma.apps.googleusercontent.com",
|
||||||
|
ClientSecret = "oXauUkFY9I7Q1CmNkKGmszRQ"
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static YouTubeService NoAuthService { get; } = new YouTubeService(new BaseClientService.Initializer
|
||||||
|
{
|
||||||
|
ApiKey = "AIzaSyBgHrCnrlzlVmk0cJKL8RqP9Y8x6XSuk_0",
|
||||||
|
ApplicationName = "FoxTube"
|
||||||
|
});
|
||||||
|
static YoutubeClient NoAuthClient { get; } = new YoutubeClient();
|
||||||
|
|
||||||
|
public static YouTubeService Service => Current == null ? NoAuthService : Current.Service;
|
||||||
|
public static YoutubeClient YoutubeClient => Current == null ? NoAuthClient : Current.YoutubeClient;
|
||||||
|
|
||||||
|
public static bool IsAuthorized => Current != null;
|
||||||
|
|
||||||
|
public static User Current { get; set; }
|
||||||
|
|
||||||
|
static (Userinfoplus info, UserCredential credential)[] UserInfos = new (Userinfoplus, UserCredential)[5];
|
||||||
|
|
||||||
|
public static bool CheckPerformed { get; }
|
||||||
|
|
||||||
|
public static void Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task AddItemToWL(string id)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async void CreateNew()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async void Logout()
|
||||||
|
{
|
||||||
|
Current?.Deauthenticate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace FoxTube
|
||||||
|
{
|
||||||
|
public class ViewModel : Page
|
||||||
|
{
|
||||||
|
public List<Microsoft.UI.Xaml.Controls.NavigationViewItem> PivotItems { get; } = new List<Microsoft.UI.Xaml.Controls.NavigationViewItem>();
|
||||||
|
|
||||||
|
public object Parameter { get; private set; }
|
||||||
|
|
||||||
|
public void PivotChanged(int index) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
<StackPanel
|
||||||
|
x:Class="FoxTube.Controls.AccountManager"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
xmlns:ui="using:Microsoft.UI.Xaml.Controls"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
|
||||||
|
<ui:NavigationViewItem Width="42" Visibility="Visible" Name="manager" Padding="0" Tapped="Manager_Tapped">
|
||||||
|
<ui:NavigationViewItem.ContextFlyout>
|
||||||
|
<Flyout>
|
||||||
|
<Grid Width="300" Margin="-10">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="60"/>
|
||||||
|
<RowDefinition/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Image Stretch="UniformToFill" MaxHeight="60" Source="https://yt3.ggpht.com/TckH7MhPH7UcxPnHeEj6R78xe1uOmrlHdUD1Usy7sr36xLDzl86NxAyfmDOIUrxl6kpiBgtKgA=w2276-fcrop64=1,00005a57ffffa5a8-nd-c0xffffffff-rj-k-no"/>
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.Background>
|
||||||
|
<SolidColorBrush Color="Black" Opacity=".5"/>
|
||||||
|
</Grid.Background>
|
||||||
|
<PersonPicture HorizontalAlignment="Left" Margin="5" Height="50"/>
|
||||||
|
<StackPanel VerticalAlignment="Center" Grid.Column="1">
|
||||||
|
<TextBlock Text="Michael Gordeev" FontWeight="Bold"/>
|
||||||
|
<TextBlock Text="michael.xfox@outlook.com" Style="{StaticResource CaptionTextBlockStyle}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<ui:NavigationViewItem Grid.Column="2" Width="42" Icon="BlockContact" Foreground="Red"/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<ui:NavigationViewList Grid.Row="1">
|
||||||
|
<ui:NavigationViewItem Content="My channel" Icon="Contact"/>
|
||||||
|
<ui:NavigationViewItem Content="Upload a video" Icon="Upload" Tapped="NavigationViewItem_Tapped"/>
|
||||||
|
<ui:NavigationViewItemSeparator/>
|
||||||
|
<ui:NavigationViewItem>
|
||||||
|
<StackPanel Orientation="Horizontal" Padding="5" Margin="-5,0,0,0">
|
||||||
|
<PersonPicture Height="20" Margin="-5,0,15,0">
|
||||||
|
<PersonPicture.ProfilePicture>
|
||||||
|
<BitmapImage UriSource="https://yt3.ggpht.com/a/AGF-l7_hHK5yjEPhlM72Tmk26zoOVkNx88pWoZnFVQ=s240-mo-c-c0xffffffff-rj-k-no" DecodePixelHeight="20" DecodePixelWidth="20"/>
|
||||||
|
</PersonPicture.ProfilePicture>
|
||||||
|
</PersonPicture>
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock FontSize="14" Text="BadComedian"/>
|
||||||
|
<TextBlock Text="eugene.comedian@fondkino-sdoh.net" FontSize="11" Margin="0,-4,0,0"/>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</ui:NavigationViewItem>
|
||||||
|
<ui:NavigationViewItem Content="Add account" Icon="Add"/>
|
||||||
|
<ui:NavigationViewItemSeparator/>
|
||||||
|
<ui:NavigationViewItem Name="removeAds" Content="Remove ads (5$)" Icon="Shop" Tapped="RemoveAds_Tapped"/>
|
||||||
|
<ui:NavigationViewItem Content="Settings" Icon="Setting" Tapped="Settings_Click"/>
|
||||||
|
</ui:NavigationViewList>
|
||||||
|
</Grid>
|
||||||
|
</Flyout>
|
||||||
|
</ui:NavigationViewItem.ContextFlyout>
|
||||||
|
|
||||||
|
<PersonPicture Height="25" Margin="-8,0,0,0"/>
|
||||||
|
</ui:NavigationViewItem>
|
||||||
|
|
||||||
|
<ui:NavigationViewItem Width="42" Name="account" Tapped="Manager_Tapped" Icon="AddFriend">
|
||||||
|
<ui:NavigationViewItem.ContextFlyout>
|
||||||
|
<ui:MenuBarItemFlyout>
|
||||||
|
<MenuFlyoutItem Icon="Add" Text="Add new account" Click="SignIn_Click"/>
|
||||||
|
<MenuFlyoutItem Icon="Setting" Text="Settings" Click="Settings_Click"/>
|
||||||
|
</ui:MenuBarItemFlyout>
|
||||||
|
</ui:NavigationViewItem.ContextFlyout>
|
||||||
|
</ui:NavigationViewItem>
|
||||||
|
</StackPanel>
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
using Microsoft.AppCenter.Analytics;
|
||||||
|
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.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Windows.UI.Xaml.Controls.Primitives;
|
||||||
|
using Windows.UI.Xaml.Data;
|
||||||
|
using Windows.UI.Xaml.Input;
|
||||||
|
using Windows.UI.Xaml.Media;
|
||||||
|
using Windows.UI.Xaml.Media.Imaging;
|
||||||
|
using Windows.UI.Xaml.Navigation;
|
||||||
|
|
||||||
|
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
|
||||||
|
|
||||||
|
namespace FoxTube.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class AccountManager : StackPanel
|
||||||
|
{
|
||||||
|
public AccountManager()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
Service.Purchased += (purchased, price) =>
|
||||||
|
{
|
||||||
|
/*removeAds.Visibility = purchased ? Visibility.Collapsed : Visibility.Visible;
|
||||||
|
removeAds.Content = $"{resources.GetString("/Main/adsFree/Content")} ({price})";*/
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Service.AdsCheckPerformed)
|
||||||
|
Service.CheckAddons();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignIn_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
UserManagement.CreateNew();
|
||||||
|
Analytics.TrackEvent("Initialized authorization sequence");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logout_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
manager.ContextFlyout.Hide();
|
||||||
|
UserManagement.Logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void Logged() //=> await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
|
||||||
|
{
|
||||||
|
account.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
|
/*ToolTipService.SetToolTip(avatar, $"{UserManagement.Current.UserInfo.Name} ({UserManagement.Current.UserInfo.Email})");
|
||||||
|
name.Text = UserManagement.Current.UserInfo.Name;
|
||||||
|
email.Text = UserManagement.Current.UserInfo.Email;
|
||||||
|
avatar.ProfilePicture = new BitmapImage(UserManagement.Current.UserInfo.Picture.ToUri()) { DecodePixelHeight = 65, DecodePixelWidth = 65 };
|
||||||
|
(icon.Fill as ImageBrush).ImageSource = new BitmapImage(UserManagement.Current.UserInfo.Picture.ToUri()) { DecodePixelHeight = 25, DecodePixelWidth = 25 };*/
|
||||||
|
|
||||||
|
manager.Visibility = Visibility.Visible;
|
||||||
|
}//);
|
||||||
|
|
||||||
|
public void Quit()
|
||||||
|
{
|
||||||
|
manager.Visibility = Visibility.Collapsed;
|
||||||
|
account.Visibility = Visibility.Visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NavigationViewItem_Tapped(object sender, TappedRoutedEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager_Tapped(object sender, TappedRoutedEventArgs e) =>
|
||||||
|
(sender as Microsoft.UI.Xaml.Controls.NavigationViewItem).ContextFlyout.ShowAt(sender as FrameworkElement);
|
||||||
|
|
||||||
|
private void Settings_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Settings_Click(object sender, TappedRoutedEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveAds_Tapped(object sender, TappedRoutedEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,220 @@
|
|||||||
|
<UserControl
|
||||||
|
x:Class="FoxTube.Controls.ContentFrame"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<VisualStateManager.VisualStateGroups>
|
||||||
|
<VisualStateGroup>
|
||||||
|
<VisualState x:Name="blocked">
|
||||||
|
<Storyboard>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="block" Storyboard.TargetProperty="Visibility">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="block" Storyboard.TargetProperty="Opacity"
|
||||||
|
From="0" To="1" Duration="0:0:1"/>
|
||||||
|
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ring" Storyboard.TargetProperty="Width"
|
||||||
|
EnableDependentAnimation="True"
|
||||||
|
From="100" To="200" Duration="0:0:0.5"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ring" Storyboard.TargetProperty="Height"
|
||||||
|
EnableDependentAnimation="True"
|
||||||
|
From="100" To="200" Duration="0:0:0.5"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ring" Storyboard.TargetProperty="Opacity"
|
||||||
|
From="1" To="0" Duration="0:0:0.5">
|
||||||
|
<DoubleAnimation.EasingFunction>
|
||||||
|
<ExponentialEase EasingMode="EaseIn"/>
|
||||||
|
</DoubleAnimation.EasingFunction>
|
||||||
|
</DoubleAnimation>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ring" Storyboard.TargetProperty="IsActive">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0:0:0.5" Value="False"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
|
||||||
|
<DoubleAnimation Storyboard.TargetName="content" Storyboard.TargetProperty="Opacity"
|
||||||
|
Duration="0" To="0"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="loadingScreen" Storyboard.TargetProperty="Opacity"
|
||||||
|
To="0" Duration="0:0:0.1"/>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
|
||||||
|
<VisualState x:Name="wifiError">
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="content" Storyboard.TargetProperty="Opacity"
|
||||||
|
Duration="0:0:0.1" To="0"/>
|
||||||
|
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="block" Storyboard.TargetProperty="Visibility">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="generalBtns" Storyboard.TargetProperty="Visibility">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="networkBtns" Storyboard.TargetProperty="Visibility">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="icon" Storyboard.TargetProperty="Glyph">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value=""/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ring" Storyboard.TargetProperty="Width"
|
||||||
|
EnableDependentAnimation="True"
|
||||||
|
From="100" To="200" Duration="0:0:0.5"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ring" Storyboard.TargetProperty="Height"
|
||||||
|
EnableDependentAnimation="True"
|
||||||
|
From="100" To="200" Duration="0:0:0.5"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ring" Storyboard.TargetProperty="Opacity"
|
||||||
|
From="1" To="0" Duration="0:0:0.5">
|
||||||
|
<DoubleAnimation.EasingFunction>
|
||||||
|
<ExponentialEase EasingMode="EaseIn"/>
|
||||||
|
</DoubleAnimation.EasingFunction>
|
||||||
|
</DoubleAnimation>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ring" Storyboard.TargetProperty="IsActive">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0:0:0.5" Value="False"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
|
||||||
|
<DoubleAnimation Storyboard.TargetName="loadingScreen" Storyboard.TargetProperty="Opacity"
|
||||||
|
From="0" To="1" Duration="0:0:0.5" BeginTime="0:0:0.5">
|
||||||
|
<DoubleAnimation.EasingFunction>
|
||||||
|
<ExponentialEase EasingMode="EaseIn"/>
|
||||||
|
</DoubleAnimation.EasingFunction>
|
||||||
|
</DoubleAnimation>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
|
||||||
|
<VisualState x:Name="commonError">
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="content" Storyboard.TargetProperty="Opacity"
|
||||||
|
Duration="0:0:0.1" To="0"/>
|
||||||
|
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="block" Storyboard.TargetProperty="Visibility">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="generalBtns" Storyboard.TargetProperty="Visibility">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="networkBtns" Storyboard.TargetProperty="Visibility">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="icon" Storyboard.TargetProperty="Glyph">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value=""/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ring" Storyboard.TargetProperty="Width"
|
||||||
|
EnableDependentAnimation="True"
|
||||||
|
From="100" To="200" Duration="0:0:0.5"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ring" Storyboard.TargetProperty="Height"
|
||||||
|
EnableDependentAnimation="True"
|
||||||
|
From="100" To="200" Duration="0:0:0.5"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ring" Storyboard.TargetProperty="Opacity"
|
||||||
|
From="1" To="0" Duration="0:0:0.5">
|
||||||
|
<DoubleAnimation.EasingFunction>
|
||||||
|
<ExponentialEase EasingMode="EaseIn"/>
|
||||||
|
</DoubleAnimation.EasingFunction>
|
||||||
|
</DoubleAnimation>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ring" Storyboard.TargetProperty="IsActive">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0:0:0.5" Value="False"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
|
||||||
|
<DoubleAnimation Storyboard.TargetName="loadingScreen" Storyboard.TargetProperty="Opacity"
|
||||||
|
From="0" To="1" Duration="0:0:0.5" BeginTime="0:0:0.5">
|
||||||
|
<DoubleAnimation.EasingFunction>
|
||||||
|
<ExponentialEase EasingMode="EaseIn"/>
|
||||||
|
</DoubleAnimation.EasingFunction>
|
||||||
|
</DoubleAnimation>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
|
||||||
|
<VisualState x:Name="loading">
|
||||||
|
<Storyboard>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="block" Storyboard.TargetProperty="Visibility">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="loadingScreen" Storyboard.TargetProperty="Opacity"
|
||||||
|
To="0" Duration="0:0:0.1"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="content" Storyboard.TargetProperty="Opacity"
|
||||||
|
Duration="0:0:0.2" To="0"/>
|
||||||
|
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ring" Storyboard.TargetProperty="IsActive">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="True"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ring" Storyboard.TargetProperty="Width"
|
||||||
|
EnableDependentAnimation="True"
|
||||||
|
From="0" To="100" Duration="0:0:0.5"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ring" Storyboard.TargetProperty="Height"
|
||||||
|
EnableDependentAnimation="True"
|
||||||
|
From="0" To="100" Duration="0:0:0.5"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ring" Storyboard.TargetProperty="Opacity"
|
||||||
|
From="0" To="1" Duration="0:0:0.5">
|
||||||
|
<DoubleAnimation.EasingFunction>
|
||||||
|
<ExponentialEase EasingMode="EaseIn"/>
|
||||||
|
</DoubleAnimation.EasingFunction>
|
||||||
|
</DoubleAnimation>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
|
||||||
|
<VisualState x:Name="loaded">
|
||||||
|
<Storyboard>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="block" Storyboard.TargetProperty="Visibility">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ring" Storyboard.TargetProperty="Width"
|
||||||
|
EnableDependentAnimation="True"
|
||||||
|
From="100" To="200" Duration="0:0:0.5"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ring" Storyboard.TargetProperty="Height"
|
||||||
|
EnableDependentAnimation="True"
|
||||||
|
From="100" To="200" Duration="0:0:0.5"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="ring" Storyboard.TargetProperty="Opacity"
|
||||||
|
From="1" To="0" Duration="0:0:0.5">
|
||||||
|
<DoubleAnimation.EasingFunction>
|
||||||
|
<ExponentialEase EasingMode="EaseIn"/>
|
||||||
|
</DoubleAnimation.EasingFunction>
|
||||||
|
</DoubleAnimation>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ring" Storyboard.TargetProperty="IsActive">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0:0:0.5" Value="False"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
|
||||||
|
<DoubleAnimation Storyboard.TargetName="content" Storyboard.TargetProperty="Opacity"
|
||||||
|
From="0" To="1" Duration="0:0:0.2" BeginTime="0:0:0.5"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="loadingScreen" Storyboard.TargetProperty="Opacity"
|
||||||
|
To="0" Duration="0:0:0.1"/>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
</VisualStateGroup>
|
||||||
|
</VisualStateManager.VisualStateGroups>
|
||||||
|
|
||||||
|
<Frame Name="content" Navigating="Content_Navigating" Opacity="0"/>
|
||||||
|
|
||||||
|
<ProgressRing Width="100" Height="100" Name="ring" IsActive="True"/>
|
||||||
|
<FontIcon Glyph="" FontSize="100" Name="block" Visibility="Collapsed"/>
|
||||||
|
|
||||||
|
<StackPanel VerticalAlignment="Center" Name="loadingScreen" Opacity="0">
|
||||||
|
<FontIcon Name="icon" Glyph="" FontSize="100" HorizontalAlignment="Center"/>
|
||||||
|
|
||||||
|
<TextBlock Name="title" Text="We are unable to display the page" FontSize="48" HorizontalAlignment="Center" TextWrapping="WrapWholeWords"/>
|
||||||
|
<TextBlock Name="description" Text="It could be caused by YouTube internal server error or by application's bug. Please, try again later" HorizontalAlignment="Center" TextWrapping="WrapWholeWords"/>
|
||||||
|
|
||||||
|
<StackPanel Name="networkBtns">
|
||||||
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||||
|
<Button Content="Open network settings" Margin="0,0,5,0" Click="Network_Click"/>
|
||||||
|
<Button Content="Open troubleshooter" Background="Red" Foreground="White" Click="Troubleshooter_Click"/>
|
||||||
|
</StackPanel>
|
||||||
|
<TextBlock Text="OR" FontSize="20" HorizontalAlignment="Center" Margin="5"/>
|
||||||
|
<Button Content="Refresh page" HorizontalAlignment="Center" Background="Red" Foreground="White" Click="Refresh_Click"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Name="generalBtns" Orientation="Horizontal" HorizontalAlignment="Center">
|
||||||
|
<Button Content="Refresh page" Margin="0,0,5,0" Click="Refresh_Click"/>
|
||||||
|
<Button Name="feedback" Content="Leave feedback" Background="Red" Foreground="White" Click="Feedback_Click"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<TextBlock Name="error" Foreground="Gray" Text="Exception:" HorizontalAlignment="Center" IsTextSelectionEnabled="True"/>
|
||||||
|
<TextBlock Name="message" Foreground="Gray" Text="Message:" HorizontalAlignment="Center" IsTextSelectionEnabled="True" TextWrapping="WrapWholeWords"/>
|
||||||
|
<TextBlock Name="stackTrace" Foreground="Gray" Text="Stack trace:" HorizontalAlignment="Center" IsTextSelectionEnabled="True" TextWrapping="WrapWholeWords"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
using Microsoft.Services.Store.Engagement;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using Windows.ApplicationModel.Resources;
|
||||||
|
using Windows.System;
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Windows.UI.Xaml.Navigation;
|
||||||
|
|
||||||
|
namespace FoxTube.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class ContentFrame : UserControl
|
||||||
|
{
|
||||||
|
readonly ResourceLoader resources = ResourceLoader.GetForCurrentView("Loading");
|
||||||
|
|
||||||
|
public LoadingScreenState State { get; private set; } = LoadingScreenState.Loaded;
|
||||||
|
public Type SourcePageType => content.CurrentSourcePageType;
|
||||||
|
public bool CanGoBack => content.CanGoBack;
|
||||||
|
public object FrameContent => content.Content;
|
||||||
|
|
||||||
|
public event NavigationOccured Navigated;
|
||||||
|
|
||||||
|
public ContentFrame()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
if (!StoreServicesFeedbackLauncher.IsSupported())
|
||||||
|
feedback.Visibility = Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Navigate(Type pageType, object parameter) =>
|
||||||
|
content.Navigate(pageType, parameter);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Navigates on the same page and deletes last back stack entry
|
||||||
|
/// </summary>
|
||||||
|
public void Refresh()
|
||||||
|
{
|
||||||
|
content.Navigate(content.CurrentSourcePageType, (content.Content as ViewModel).Parameter);
|
||||||
|
content.BackStack.RemoveAt(content.BackStack.Count - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GoBack() =>
|
||||||
|
content.GoBack();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears frame back stack
|
||||||
|
/// </summary>
|
||||||
|
public void ClearHistory() =>
|
||||||
|
content.BackStack.Clear();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Hides loading indicator and show blocked icon
|
||||||
|
/// </summary>
|
||||||
|
public void Block()
|
||||||
|
{
|
||||||
|
blocked.Storyboard.Begin();
|
||||||
|
State = LoadingScreenState.Blocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shows error screen with common error message
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="error">Error name (Exception name also will do)</param>
|
||||||
|
/// <param name="message">Error description or exception message</param>
|
||||||
|
/// <param name="stackTrace">Exception's stack trace</param>
|
||||||
|
public void ShowError(string error = "Unknown", string message = "N/A", string stackTrace = null)
|
||||||
|
{
|
||||||
|
title.Text = resources.GetString("/Loading/generalTitle");
|
||||||
|
description.Text = resources.GetString("/Loading/general");
|
||||||
|
|
||||||
|
this.error.Text = $"{resources.GetString("/Loading/error")}: {error}";
|
||||||
|
this.message.Text = $"{resources.GetString("/Loading/message")}: {message}";
|
||||||
|
this.stackTrace.Text = $"{resources.GetString("/Loading/stackTrace")}: {stackTrace}";
|
||||||
|
|
||||||
|
this.stackTrace.Visibility = string.IsNullOrWhiteSpace(stackTrace) ? Visibility.Collapsed : Visibility.Visible;
|
||||||
|
|
||||||
|
commonError.Storyboard.Begin();
|
||||||
|
State = LoadingScreenState.Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shows error screen with network error message
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="error">Error name (Exception name also will do)</param>
|
||||||
|
/// <param name="message">Error description or exception message</param>
|
||||||
|
/// <param name="stackTrace">Exception's stack trace</param>
|
||||||
|
public void ShowConnectionError(string error = "Unknown", string message = "N/A", string stackTrace = null)
|
||||||
|
{
|
||||||
|
title.Text = resources.GetString("/Loading/generalTitle");
|
||||||
|
description.Text = resources.GetString("/Loading/general");
|
||||||
|
|
||||||
|
this.error.Text = $"{resources.GetString("/Loading/error")}: {error}";
|
||||||
|
this.message.Text = $"{resources.GetString("/Loading/message")}: {message}";
|
||||||
|
this.stackTrace.Text = $"{resources.GetString("/Loading/stackTrace")}: {stackTrace}";
|
||||||
|
|
||||||
|
this.stackTrace.Visibility = string.IsNullOrWhiteSpace(stackTrace) ? Visibility.Collapsed : Visibility.Visible;
|
||||||
|
|
||||||
|
wifiError.Storyboard.Begin();
|
||||||
|
State = LoadingScreenState.Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Hides loading UI
|
||||||
|
/// </summary>
|
||||||
|
public void Complete(IEnumerable pivotCollection = null, int? selectedPivot = null)
|
||||||
|
{
|
||||||
|
Navigated?.Invoke(pivotCollection, selectedPivot);
|
||||||
|
loaded.Storyboard.Begin();
|
||||||
|
State = LoadingScreenState.Loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Content_Navigating(object sender, NavigatingCancelEventArgs e)
|
||||||
|
{
|
||||||
|
loading.Storyboard.Begin();
|
||||||
|
State = LoadingScreenState.Loading;
|
||||||
|
}
|
||||||
|
|
||||||
|
async void Troubleshooter_Click(object sender, RoutedEventArgs e) =>
|
||||||
|
await Launcher.LaunchUriAsync("ms-settings:troubleshoot".ToUri());
|
||||||
|
|
||||||
|
async void Network_Click(object sender, RoutedEventArgs e) =>
|
||||||
|
await Launcher.LaunchUriAsync("ms-settings:network".ToUri());
|
||||||
|
|
||||||
|
async void Feedback_Click(object sender, RoutedEventArgs e) =>
|
||||||
|
await StoreServicesFeedbackLauncher.GetDefault().LaunchAsync();
|
||||||
|
|
||||||
|
void Refresh_Click(object sender, RoutedEventArgs e) =>
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<UserControl
|
||||||
|
x:Class="FoxTube.Controls.MainFrame"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:controls="using:FoxTube.Controls"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<controls:ContentFrame x:Name="content" Navigated="Content_Navigated"/>
|
||||||
|
<controls:ContentFrame x:Name="video" Visibility="Collapsed"/>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
using System;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace FoxTube.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class MainFrame : UserControl
|
||||||
|
{
|
||||||
|
public static MainFrame Current { get; private set; }
|
||||||
|
|
||||||
|
public event NavigatingOccured Navigating;
|
||||||
|
public event NavigationOccured Navigated;
|
||||||
|
|
||||||
|
public bool CanGoBack => !VideoMinimized || content.CanGoBack;
|
||||||
|
public bool IsVideoOpened { get; } = false;
|
||||||
|
public bool VideoMinimized => video.Width != double.NaN;
|
||||||
|
public Type SourcePageType => content.SourcePageType;
|
||||||
|
|
||||||
|
public MainFrame()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
Current = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NavigateTo(Type pageType, object parameter = null)
|
||||||
|
{
|
||||||
|
if (content.SourcePageType == pageType && parameter == (content.FrameContent as INavigationPage).Parameter)
|
||||||
|
return;
|
||||||
|
|
||||||
|
content.Navigate(pageType, parameter);
|
||||||
|
|
||||||
|
if (video.FrameContent != null && !VideoMinimized)
|
||||||
|
MinimizeVideo();
|
||||||
|
|
||||||
|
Navigating?.Invoke(pageType, parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Refresh()
|
||||||
|
{
|
||||||
|
content.Refresh();
|
||||||
|
Navigating?.Invoke(SourcePageType, (content.Content as ViewModel).Parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Video control methods
|
||||||
|
public void OpenVideo(string id, string playlistId = null, bool incognito = false)
|
||||||
|
{
|
||||||
|
/*if (VideoMinimized)
|
||||||
|
MaximizeVideo();
|
||||||
|
|
||||||
|
video.Navigate(typeof(VideoPage), (id, playlistId, incognito));
|
||||||
|
|
||||||
|
MainPage.Current.UpdateView();*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MinimizeVideo(bool player = false)
|
||||||
|
{
|
||||||
|
/*if (video.FrameContent == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
video.Margin = new Thickness(0, 0, 25, 50);
|
||||||
|
video.HorizontalAlignment = HorizontalAlignment.Right;
|
||||||
|
video.VerticalAlignment = VerticalAlignment.Bottom;
|
||||||
|
video.Width = 432;
|
||||||
|
|
||||||
|
if (!player)
|
||||||
|
(video.FrameContent as VideoPage).Minimize();
|
||||||
|
|
||||||
|
MainPage.Current.UpdateView();*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MaximizeVideo(bool player = false)
|
||||||
|
{
|
||||||
|
/*if (video.FrameContent == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
video.Margin = new Thickness(0);
|
||||||
|
video.VerticalAlignment = VerticalAlignment.Stretch;
|
||||||
|
video.HorizontalAlignment = HorizontalAlignment.Stretch;
|
||||||
|
video.Width = double.NaN;
|
||||||
|
|
||||||
|
if (!player)
|
||||||
|
(video.FrameContent as VideoPage).Maximize();
|
||||||
|
|
||||||
|
MainPage.Current.UpdateView();*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CloseVideo()
|
||||||
|
{
|
||||||
|
/*if (ApplicationView.GetForCurrentView().IsFullScreenMode)
|
||||||
|
ApplicationView.GetForCurrentView().ExitFullScreenMode();
|
||||||
|
|
||||||
|
video.FrameContent = null;
|
||||||
|
video.ClearHistory();
|
||||||
|
|
||||||
|
if (VideoMinimized)
|
||||||
|
MaximizeVideo();
|
||||||
|
|
||||||
|
GC.Collect();
|
||||||
|
|
||||||
|
MainPage.Current.UpdateView();*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RefreshVideo()
|
||||||
|
{
|
||||||
|
/*if (video.FrameContent == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (VideoMinimized)
|
||||||
|
MaximizeVideo();
|
||||||
|
|
||||||
|
video.Refresh();
|
||||||
|
|
||||||
|
Methods.MainPage.UpdateView();*/
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public void AuthorizationChanged(bool isAuthorized)
|
||||||
|
{
|
||||||
|
//TODO: Uncomment this
|
||||||
|
/*switch (isAuthorized)
|
||||||
|
{
|
||||||
|
case true:
|
||||||
|
if (content.FrameContent == null)
|
||||||
|
NavigateTo(typeof(Home));
|
||||||
|
else if (!content.SourcePageType.Name.Belongs("Downloads", "Settings"))
|
||||||
|
content.Refresh();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case false:
|
||||||
|
NavigateTo(typeof(Home));
|
||||||
|
|
||||||
|
content.ClearHistory();
|
||||||
|
video.ClearHistory();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshVideo();*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BackRequested()
|
||||||
|
{
|
||||||
|
if (video.FrameContent != null && !VideoMinimized)
|
||||||
|
{
|
||||||
|
if (video.CanGoBack)
|
||||||
|
video.GoBack();
|
||||||
|
else if (video.State != LoadingScreenState.Loaded)
|
||||||
|
CloseVideo();
|
||||||
|
else
|
||||||
|
MinimizeVideo();
|
||||||
|
}
|
||||||
|
else if (content.CanGoBack)
|
||||||
|
content.GoBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Content_Navigated(System.Collections.IEnumerable pivotCollection, int? selectedPivot) =>
|
||||||
|
Navigated?.Invoke(pivotCollection, selectedPivot);
|
||||||
|
}
|
||||||
|
}
|
||||||
+62
-25
@@ -105,6 +105,29 @@
|
|||||||
<Compile Include="App.xaml.cs">
|
<Compile Include="App.xaml.cs">
|
||||||
<DependentUpon>App.xaml</DependentUpon>
|
<DependentUpon>App.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Classes\Downloads.cs" />
|
||||||
|
<Compile Include="Classes\Extensions.cs" />
|
||||||
|
<Compile Include="Classes\Methods.cs" />
|
||||||
|
<Compile Include="Classes\Navigation.cs" />
|
||||||
|
<Compile Include="Classes\Processes.cs" />
|
||||||
|
<Compile Include="Classes\SearchParameters.cs" />
|
||||||
|
<Compile Include="Classes\Service.cs" />
|
||||||
|
<Compile Include="Classes\Settings.cs" />
|
||||||
|
<Compile Include="Classes\User.cs" />
|
||||||
|
<Compile Include="Classes\UserManagement.cs" />
|
||||||
|
<Compile Include="Classes\ViewModel.cs" />
|
||||||
|
<Compile Include="Controls\AccountManager.xaml.cs">
|
||||||
|
<DependentUpon>AccountManager.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Controls\ContentFrame.xaml.cs">
|
||||||
|
<DependentUpon>ContentFrame.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Controls\MainFrame.xaml.cs">
|
||||||
|
<DependentUpon>MainFrame.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Pages\Home.xaml.cs">
|
||||||
|
<DependentUpon>Home.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Pages\MainPage.xaml.cs">
|
<Compile Include="Pages\MainPage.xaml.cs">
|
||||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -180,23 +203,40 @@
|
|||||||
<Content Include="Assets\Square44x44Logo.scale-200.png" />
|
<Content Include="Assets\Square44x44Logo.scale-200.png" />
|
||||||
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||||
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
|
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
|
||||||
|
<PRIResource Include="Strings\en-US\Loading.resw" />
|
||||||
|
<PRIResource Include="Strings\en-US\Generic.resw" />
|
||||||
|
<PRIResource Include="Strings\en-US\Toasts.resw" />
|
||||||
|
<PRIResource Include="Strings\en-US\Dialogs.resw" />
|
||||||
|
<PRIResource Include="Strings\en-US\Inbox.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\Report.resw" />
|
<PRIResource Include="Strings\ru-RU\Report.resw" />
|
||||||
<PRIResource Include="Strings\en-US\Report.resw" />
|
<PRIResource Include="Strings\en-US.old\Report.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\Translate.resw" />
|
<PRIResource Include="Strings\ru-RU\Translate.resw" />
|
||||||
<PRIResource Include="Strings\en-US\Translate.resw" />
|
<PRIResource Include="Strings\en-US.old\Translate.resw" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ApplicationDefinition Include="App.xaml">
|
<ApplicationDefinition Include="App.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</ApplicationDefinition>
|
</ApplicationDefinition>
|
||||||
<Page Include="Pages\MainPage.xaml">
|
<Page Include="Controls\AccountManager.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Themes\Generic.xaml">
|
<Page Include="Controls\ContentFrame.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Controls\MainFrame.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Pages\Home.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Pages\MainPage.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Themes\Resources.xaml">
|
<Page Include="Themes\Resources.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
@@ -255,39 +295,39 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PRIResource Include="Strings\ru-RU\VideoPage.resw" />
|
<PRIResource Include="Strings\ru-RU\VideoPage.resw" />
|
||||||
<PRIResource Include="Strings\en-US\VideoPage.resw" />
|
<PRIResource Include="Strings\en-US.old\VideoPage.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\Channel.resw" />
|
<PRIResource Include="Strings\ru-RU\Channel.resw" />
|
||||||
<PRIResource Include="Strings\en-US\Channel.resw" />
|
<PRIResource Include="Strings\en-US.old\Channel.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\Chat.resw" />
|
<PRIResource Include="Strings\ru-RU\Chat.resw" />
|
||||||
<PRIResource Include="Strings\en-US\Chat.resw" />
|
<PRIResource Include="Strings\en-US.old\Chat.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\Cards.resw" />
|
<PRIResource Include="Strings\ru-RU\Cards.resw" />
|
||||||
<PRIResource Include="Strings\en-US\Cards.resw" />
|
<PRIResource Include="Strings\en-US.old\Cards.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\Methods.resw" />
|
<PRIResource Include="Strings\ru-RU\Methods.resw" />
|
||||||
<PRIResource Include="Strings\en-US\Methods.resw" />
|
<PRIResource Include="Strings\en-US.old\Methods.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\Search.resw" />
|
<PRIResource Include="Strings\ru-RU\Search.resw" />
|
||||||
<PRIResource Include="Strings\en-US\Search.resw" />
|
<PRIResource Include="Strings\en-US.old\Search.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\Playlist.resw" />
|
<PRIResource Include="Strings\ru-RU\Playlist.resw" />
|
||||||
<PRIResource Include="Strings\en-US\Playlist.resw" />
|
<PRIResource Include="Strings\en-US.old\Playlist.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\Downloads.resw" />
|
<PRIResource Include="Strings\ru-RU\Downloads.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\CommentsPage.resw" />
|
<PRIResource Include="Strings\ru-RU\CommentsPage.resw" />
|
||||||
<PRIResource Include="Strings\en-US\Downloads.resw" />
|
<PRIResource Include="Strings\en-US.old\Downloads.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\Home.resw" />
|
<PRIResource Include="Strings\ru-RU\Home.resw" />
|
||||||
<PRIResource Include="Strings\en-US\Home.resw" />
|
<PRIResource Include="Strings\en-US.old\Home.resw" />
|
||||||
<PRIResource Include="Strings\en-US\CommentsPage.resw" />
|
<PRIResource Include="Strings\en-US.old\CommentsPage.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\LoadingPage.resw" />
|
<PRIResource Include="Strings\ru-RU\LoadingPage.resw" />
|
||||||
<PRIResource Include="Strings\en-US\LoadingPage.resw" />
|
<PRIResource Include="Strings\en-US.old\LoadingPage.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\Inbox.resw" />
|
<PRIResource Include="Strings\ru-RU\Inbox.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\General.resw" />
|
<PRIResource Include="Strings\ru-RU\General.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\About.resw" />
|
<PRIResource Include="Strings\ru-RU\About.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\Settings.resw" />
|
<PRIResource Include="Strings\ru-RU\Settings.resw" />
|
||||||
<PRIResource Include="Strings\en-US\Inbox.resw" />
|
<PRIResource Include="Strings\en-US.old\Inbox.resw" />
|
||||||
<PRIResource Include="Strings\en-US\About.resw" />
|
<PRIResource Include="Strings\en-US.old\About.resw" />
|
||||||
<PRIResource Include="Strings\en-US\General.resw" />
|
<PRIResource Include="Strings\en-US.old\General.resw" />
|
||||||
<PRIResource Include="Strings\en-US\Settings.resw" />
|
<PRIResource Include="Strings\en-US.old\Settings.resw" />
|
||||||
<PRIResource Include="Strings\ru-RU\Main.resw">
|
<PRIResource Include="Strings\ru-RU\Main.resw">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</PRIResource>
|
</PRIResource>
|
||||||
<PRIResource Include="Strings\en-US\Main.resw" />
|
<PRIResource Include="Strings\en-US.old\Main.resw" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\FoxTube.Background\FoxTube.Background.csproj">
|
<ProjectReference Include="..\FoxTube.Background\FoxTube.Background.csproj">
|
||||||
@@ -303,10 +343,7 @@
|
|||||||
<Name>Microsoft Engagement Framework</Name>
|
<Name>Microsoft Engagement Framework</Name>
|
||||||
</SDKReference>
|
</SDKReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup />
|
||||||
<Folder Include="Classes\" />
|
|
||||||
<Folder Include="Controls\" />
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<local:ViewModel
|
||||||
|
x:Class="FoxTube.Pages.Home"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="using:FoxTube"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
xmlns:ui="using:Microsoft.UI.Xaml.Controls"
|
||||||
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
|
|
||||||
|
<local:ViewModel.PivotItems>
|
||||||
|
<ui:NavigationViewItem Content="Recommended"/>
|
||||||
|
<ui:NavigationViewItem Content="Trending"/>
|
||||||
|
<ui:NavigationViewItem Content="Subscriptions"/>
|
||||||
|
</local:ViewModel.PivotItems>
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</local:ViewModel>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
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.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Windows.UI.Xaml.Controls.Primitives;
|
||||||
|
using Windows.UI.Xaml.Data;
|
||||||
|
using Windows.UI.Xaml.Input;
|
||||||
|
using Windows.UI.Xaml.Media;
|
||||||
|
using Windows.UI.Xaml.Navigation;
|
||||||
|
|
||||||
|
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
|
||||||
|
|
||||||
|
namespace FoxTube.Pages
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class Home : ViewModel
|
||||||
|
{
|
||||||
|
public Home()
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+263
-2
@@ -2,13 +2,274 @@
|
|||||||
x:Class="FoxTube.Pages.MainPage"
|
x:Class="FoxTube.Pages.MainPage"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:local="using:FoxTube.Pages"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
xmlns:ui="using:Microsoft.UI.Xaml.Controls"
|
||||||
|
xmlns:data="using:Google.Apis.YouTube.v3.Data"
|
||||||
|
xmlns:controls="using:FoxTube.Controls">
|
||||||
|
|
||||||
|
<Page.Background>
|
||||||
|
<AcrylicBrush BackgroundSource="HostBackdrop" TintColor="{StaticResource SystemColorBackgroundColor}" TintOpacity=".5"/>
|
||||||
|
</Page.Background>
|
||||||
|
<Page.Resources>
|
||||||
|
<AcrylicBrush x:Key="NavigationViewTopPaneBackground" BackgroundSource="HostBackdrop" TintColor="Red" TintOpacity=".7" FallbackColor="Red"/>
|
||||||
|
</Page.Resources>
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
|
<VisualStateManager.VisualStateGroups>
|
||||||
|
<VisualStateGroup x:Name="SplashScreenStates">
|
||||||
|
<VisualState x:Name="FadeOut">
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="splashImage" Storyboard.TargetProperty="Opacity"
|
||||||
|
From="1" To="0" BeginTime="0:0:0.5" Duration="0:0:0.5">
|
||||||
|
<DoubleAnimation.EasingFunction>
|
||||||
|
<QuadraticEase EasingMode="EaseInOut"/>
|
||||||
|
</DoubleAnimation.EasingFunction>
|
||||||
|
</DoubleAnimation>
|
||||||
|
|
||||||
|
<DoubleAnimation Storyboard.TargetName="splashRing" Storyboard.TargetProperty="Opacity"
|
||||||
|
From="1" To="0" Duration="0:0:0.5">
|
||||||
|
<DoubleAnimation.EasingFunction>
|
||||||
|
<ExponentialEase EasingMode="EaseIn"/>
|
||||||
|
</DoubleAnimation.EasingFunction>
|
||||||
|
</DoubleAnimation>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="splashRing" Storyboard.TargetProperty="Width"
|
||||||
|
From="50" To="180" Duration="0:0:0.5" EnableDependentAnimation="True">
|
||||||
|
<DoubleAnimation.EasingFunction>
|
||||||
|
<QuadraticEase EasingMode="EaseIn"/>
|
||||||
|
</DoubleAnimation.EasingFunction>
|
||||||
|
</DoubleAnimation>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="splashRing" Storyboard.TargetProperty="Height"
|
||||||
|
From="50" To="100" Duration="0:0:0.5" EnableDependentAnimation="True">
|
||||||
|
<DoubleAnimation.EasingFunction>
|
||||||
|
<QuadraticEase EasingMode="EaseIn"/>
|
||||||
|
</DoubleAnimation.EasingFunction>
|
||||||
|
</DoubleAnimation>
|
||||||
|
|
||||||
|
<DoubleAnimation Storyboard.TargetName="splashScreen" Storyboard.TargetProperty="Opacity"
|
||||||
|
From="1" To="0" BeginTime="0:0:1" Duration="0:0:0.5">
|
||||||
|
<DoubleAnimation.EasingFunction>
|
||||||
|
<QuadraticEase EasingMode="EaseInOut"/>
|
||||||
|
</DoubleAnimation.EasingFunction>
|
||||||
|
</DoubleAnimation>
|
||||||
|
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="splashScreen" Storyboard.TargetProperty="Visibility">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0:0:1.5" Value="Collapsed"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="split" Storyboard.TargetProperty="IsPaneOpen">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0:0:1.5" Value="True"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
</VisualStateGroup>
|
||||||
|
|
||||||
|
<VisualStateGroup x:Name="PaneStates">
|
||||||
|
<VisualState x:Name="ExpandedMode">
|
||||||
|
<VisualState.StateTriggers>
|
||||||
|
<AdaptiveTrigger x:Name="ExpandedThresholdWidth" MinWindowWidth="1008"/>
|
||||||
|
</VisualState.StateTriggers>
|
||||||
|
<VisualState.Setters>
|
||||||
|
<Setter Target="split.DisplayMode" Value="CompactInline"/>
|
||||||
|
<Setter Target="split.IsPaneOpen" Value="True"/>
|
||||||
|
</VisualState.Setters>
|
||||||
|
</VisualState>
|
||||||
|
<VisualState x:Name="CompactMode">
|
||||||
|
<VisualState.StateTriggers>
|
||||||
|
<AdaptiveTrigger x:Name="CompactThresholdWidth" MinWindowWidth="641"/>
|
||||||
|
</VisualState.StateTriggers>
|
||||||
|
<VisualState.Setters>
|
||||||
|
<Setter Target="split.DisplayMode" Value="CompactOverlay"/>
|
||||||
|
</VisualState.Setters>
|
||||||
|
</VisualState>
|
||||||
|
</VisualStateGroup>
|
||||||
|
|
||||||
|
<VisualStateGroup x:Name="SearchStates">
|
||||||
|
<VisualState x:Name="SearchExpanded">
|
||||||
|
<VisualState.StateTriggers>
|
||||||
|
<AdaptiveTrigger MinWindowWidth="1000"/>
|
||||||
|
</VisualState.StateTriggers>
|
||||||
|
<Storyboard>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="search" Storyboard.TargetProperty="Visibility">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="searchBtn" Storyboard.TargetProperty="Visibility">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimation EnableDependentAnimation="True"
|
||||||
|
Storyboard.TargetName="search" Storyboard.TargetProperty="Width"
|
||||||
|
From="0" To="300" Duration="0:0:1">
|
||||||
|
<DoubleAnimation.EasingFunction>
|
||||||
|
<QuadraticEase EasingMode="EaseInOut"/>
|
||||||
|
</DoubleAnimation.EasingFunction>
|
||||||
|
</DoubleAnimation>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
<VisualState x:Name="SearchCollapsed">
|
||||||
|
<VisualState.StateTriggers>
|
||||||
|
<AdaptiveTrigger MinWindowWidth="0"/>
|
||||||
|
</VisualState.StateTriggers>
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation EnableDependentAnimation="True"
|
||||||
|
Storyboard.TargetName="search" Storyboard.TargetProperty="Width"
|
||||||
|
From="300" To="0" Duration="0:0:1">
|
||||||
|
<DoubleAnimation.EasingFunction>
|
||||||
|
<QuadraticEase EasingMode="EaseInOut"/>
|
||||||
|
</DoubleAnimation.EasingFunction>
|
||||||
|
</DoubleAnimation>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="search" Storyboard.TargetProperty="Visibility">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0:0:1" Value="Collapsed"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="searchBtn" Storyboard.TargetProperty="Visibility">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0:0:1" Value="Visible"/>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
</VisualStateGroup>
|
||||||
|
</VisualStateManager.VisualStateGroups>
|
||||||
|
|
||||||
|
<ui:NavigationView PaneDisplayMode="Top" SelectionChanged="Nav_SelectionChanged" Name="nav" IsSettingsVisible="False"
|
||||||
|
BackRequested="Nav_BackRequested" IsBackEnabled="{x:Bind content.CanGoBack}">
|
||||||
|
<ui:NavigationView.AutoSuggestBox>
|
||||||
|
<AutoSuggestBox x:Name="search" LostFocus="Search_LostFocus" QueryIcon="Find" QuerySubmitted="Search_QuerySubmitted" TextChanged="Search_TextChanged" PlaceholderText="Search" Width="300"/>
|
||||||
|
</ui:NavigationView.AutoSuggestBox>
|
||||||
|
|
||||||
|
<ui:NavigationView.PaneHeader>
|
||||||
|
<ui:NavigationViewItem Icon="GlobalNavigationButton" Width="42" Name="menu" Tapped="Menu_Tapped"/>
|
||||||
|
</ui:NavigationView.PaneHeader>
|
||||||
|
|
||||||
|
<ui:NavigationView.PaneFooter>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<ui:NavigationViewItem Icon="Find" Width="42" Name="searchBtn" Tapped="SearchBtn_Tapped"/>
|
||||||
|
<ui:NavigationViewItem Width="42" Name="feedback" Tapped="Feedback_Click">
|
||||||
|
<ui:NavigationViewItem.Icon>
|
||||||
|
<FontIcon Glyph=""/>
|
||||||
|
</ui:NavigationViewItem.Icon>
|
||||||
|
</ui:NavigationViewItem>
|
||||||
|
<controls:AccountManager x:Name="accountManager"/>
|
||||||
|
</StackPanel>
|
||||||
|
</ui:NavigationView.PaneFooter>
|
||||||
|
|
||||||
|
<SplitView OpenPaneLength="300" Name="split" DisplayMode="Overlay" CompactPaneLength="42"
|
||||||
|
PaneClosing="Split_PaneToggled" PaneOpened="Split_PaneToggled">
|
||||||
|
<SplitView.PaneBackground>
|
||||||
|
<AcrylicBrush BackgroundSource="Backdrop" TintColor="{StaticResource SystemColorBackgroundColor}" TintOpacity=".5"/>
|
||||||
|
</SplitView.PaneBackground>
|
||||||
|
|
||||||
|
<SplitView.Pane>
|
||||||
|
<ScrollViewer>
|
||||||
|
<StackPanel>
|
||||||
|
<ui:NavigationViewList>
|
||||||
|
<ui:NavigationViewList.ItemContainerTransitions>
|
||||||
|
<TransitionCollection>
|
||||||
|
<EntranceThemeTransition IsStaggeringEnabled="True"/>
|
||||||
|
</TransitionCollection>
|
||||||
|
</ui:NavigationViewList.ItemContainerTransitions>
|
||||||
|
|
||||||
|
<ui:NavigationViewItem Icon="Home" Content="Home" Tapped="Home_Tapped"/>
|
||||||
|
<ui:NavigationViewItem Icon="People" Content="Subscriptions" Name="subscriptions" Tapped="Subscriptions_Tapped" Visibility="Collapsed"/>
|
||||||
|
|
||||||
|
<ui:NavigationViewItemHeader Content="My library" Name="libraryHeader" Visibility="Collapsed"/>
|
||||||
|
<ui:NavigationViewItem Content="History" Name="history" Tapped="History_Tapped" Visibility="Collapsed">
|
||||||
|
<ui:NavigationViewItem.Icon>
|
||||||
|
<FontIcon Glyph=""/>
|
||||||
|
</ui:NavigationViewItem.Icon>
|
||||||
|
</ui:NavigationViewItem>
|
||||||
|
<ui:NavigationViewItem Icon="Like" Content="Liked videos" Name="likedVideos" Tapped="LikedVideos_Tapped" Visibility="Collapsed"/>
|
||||||
|
<ui:NavigationViewItem Icon="Clock" Content="Watch later" Name="watchLater" Tapped="WatchLater_Tapped" Visibility="Collapsed"/>
|
||||||
|
<ui:NavigationViewItem Icon="Download" Content="Downloads" Name="downloads" Tapped="Downloads_Tapped"/>
|
||||||
|
</ui:NavigationViewList>
|
||||||
|
|
||||||
|
<ui:NavigationViewList Name="subscriptionsList">
|
||||||
|
<ui:NavigationViewList.ItemContainerTransitions>
|
||||||
|
<TransitionCollection>
|
||||||
|
<EntranceThemeTransition IsStaggeringEnabled="True"/>
|
||||||
|
</TransitionCollection>
|
||||||
|
</ui:NavigationViewList.ItemContainerTransitions>
|
||||||
|
<ui:NavigationViewList.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="data:Subscription">
|
||||||
|
<StackPanel Orientation="Horizontal" Padding="5" Margin="-5,0,0,0">
|
||||||
|
<PersonPicture Height="20" Margin="-5,0,15,0">
|
||||||
|
<PersonPicture.ProfilePicture>
|
||||||
|
<BitmapImage UriSource="{Binding Snippet.Thumbnails.Medium.Url}" DecodePixelHeight="20" DecodePixelWidth="20"/>
|
||||||
|
</PersonPicture.ProfilePicture>
|
||||||
|
</PersonPicture>
|
||||||
|
<TextBlock FontSize="14" Text="{Binding Snippet.Title}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ui:NavigationViewList.ItemTemplate>
|
||||||
|
|
||||||
|
<ui:NavigationViewItemHeader Content="Subscriptions" Name="subscriptionsHeader" Visibility="Collapsed"/>
|
||||||
|
</ui:NavigationViewList>
|
||||||
|
|
||||||
|
<ui:NavigationViewList>
|
||||||
|
<ui:NavigationViewList.ItemContainerTransitions>
|
||||||
|
<TransitionCollection>
|
||||||
|
<EntranceThemeTransition IsStaggeringEnabled="True"/>
|
||||||
|
</TransitionCollection>
|
||||||
|
</ui:NavigationViewList.ItemContainerTransitions>
|
||||||
|
|
||||||
|
<ui:NavigationViewItemHeader Content="Best of YouTube" Name="collectionsHeader"/>
|
||||||
|
<ui:NavigationViewItem Content="Music" Tapped="Music_Tapped">
|
||||||
|
<ui:NavigationViewItem.Icon>
|
||||||
|
<FontIcon Glyph=""/>
|
||||||
|
</ui:NavigationViewItem.Icon>
|
||||||
|
</ui:NavigationViewItem>
|
||||||
|
<ui:NavigationViewItem Content="Sports" Tapped="Sports_Tapped">
|
||||||
|
<ui:NavigationViewItem.Icon>
|
||||||
|
<FontIcon Glyph=""/>
|
||||||
|
</ui:NavigationViewItem.Icon>
|
||||||
|
</ui:NavigationViewItem>
|
||||||
|
<ui:NavigationViewItem Content="Movies" Tapped="Movies_Tapped">
|
||||||
|
<ui:NavigationViewItem.Icon>
|
||||||
|
<FontIcon Glyph=""/>
|
||||||
|
</ui:NavigationViewItem.Icon>
|
||||||
|
</ui:NavigationViewItem>
|
||||||
|
<ui:NavigationViewItem Content="News" Tapped="News_Tapped">
|
||||||
|
<ui:NavigationViewItem.Icon>
|
||||||
|
<FontIcon Glyph=""/>
|
||||||
|
</ui:NavigationViewItem.Icon>
|
||||||
|
</ui:NavigationViewItem>
|
||||||
|
<ui:NavigationViewItem Content="Live" Tapped="Live_Tapped">
|
||||||
|
<ui:NavigationViewItem.Icon>
|
||||||
|
<FontIcon Glyph=""/>
|
||||||
|
</ui:NavigationViewItem.Icon>
|
||||||
|
</ui:NavigationViewItem>
|
||||||
|
<ui:NavigationViewItem Content="Spotlight" Tapped="Spotlight_Tapped">
|
||||||
|
<ui:NavigationViewItem.Icon>
|
||||||
|
<FontIcon Glyph=""/>
|
||||||
|
</ui:NavigationViewItem.Icon>
|
||||||
|
</ui:NavigationViewItem>
|
||||||
|
<ui:NavigationViewItem Content="360° video" Tapped="SphereVideo_Tapped">
|
||||||
|
<ui:NavigationViewItem.Icon>
|
||||||
|
<FontIcon Glyph=""/>
|
||||||
|
</ui:NavigationViewItem.Icon>
|
||||||
|
</ui:NavigationViewItem>
|
||||||
|
</ui:NavigationViewList>
|
||||||
|
</StackPanel>
|
||||||
|
</ScrollViewer>
|
||||||
|
</SplitView.Pane>
|
||||||
|
|
||||||
|
<SplitView.Content>
|
||||||
|
<controls:MainFrame x:Name="content" Navigated="Content_Navigated" Navigating="Content_Navigating"/>
|
||||||
|
</SplitView.Content>
|
||||||
|
</SplitView>
|
||||||
|
</ui:NavigationView>
|
||||||
|
|
||||||
|
<TextBlock x:Name="appTitle" Text="FoxTube" VerticalAlignment="Top" HorizontalAlignment="Left" Style="{StaticResource CaptionTextBlockStyle}" Margin="12,8"/>
|
||||||
|
|
||||||
|
<Grid Background="#282828" x:Name="splashScreen" Visibility="Visible">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition Height="180"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Canvas Grid.RowSpan="2">
|
||||||
|
<Image Source="/Assets/SplashScreen.png" Name="splashImage"/>
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
<ProgressRing x:Name="splashRing" HorizontalAlignment="Center" Width="50" Height="50" IsActive="True" Grid.Row="1"/>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
+255
-16
@@ -1,30 +1,269 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.Threading.Tasks;
|
||||||
using System.Linq;
|
using System.Xml;
|
||||||
using System.Runtime.InteropServices.WindowsRuntime;
|
using FoxTube.Classes;
|
||||||
using Windows.Foundation;
|
using Google.Apis.YouTube.v3.Data;
|
||||||
using Windows.Foundation.Collections;
|
using Microsoft.Services.Store.Engagement;
|
||||||
|
using Windows.ApplicationModel.Activation;
|
||||||
|
using Windows.Graphics.Display;
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
using Windows.UI.Xaml.Controls.Primitives;
|
|
||||||
using Windows.UI.Xaml.Data;
|
|
||||||
using Windows.UI.Xaml.Input;
|
using Windows.UI.Xaml.Input;
|
||||||
using Windows.UI.Xaml.Media;
|
|
||||||
using Windows.UI.Xaml.Navigation;
|
|
||||||
|
|
||||||
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
|
|
||||||
|
|
||||||
namespace FoxTube.Pages
|
namespace FoxTube.Pages
|
||||||
{
|
{
|
||||||
/// <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 sealed partial class MainPage : Page
|
||||||
{
|
{
|
||||||
public MainPage()
|
public MainPage(SplashScreen splash, object args)
|
||||||
{
|
{
|
||||||
this.InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
SetSplashScreen(splash);
|
||||||
|
Methods.SetTitleBar();
|
||||||
|
|
||||||
|
UserManagement.AuthorizationStateChanged += AuthorizationStateChanged;
|
||||||
|
UserManagement.SubscriptionChanged += SubscriptionChanged;
|
||||||
|
|
||||||
|
if (StoreServicesFeedbackLauncher.IsSupported())
|
||||||
|
feedback.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
|
//TODO: Initialize stuff
|
||||||
|
//TODO: Remove this method
|
||||||
|
Begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
async void Begin()
|
||||||
|
{
|
||||||
|
await Task.Delay(5000);
|
||||||
|
FadeOut.Storyboard.Begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSplashScreen(SplashScreen splash)
|
||||||
|
{
|
||||||
|
double ScaleFactor = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
|
||||||
|
|
||||||
|
splashImage.SetValue(Canvas.LeftProperty, splash.ImageLocation.Left);
|
||||||
|
splashImage.SetValue(Canvas.TopProperty, splash.ImageLocation.Top);
|
||||||
|
if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
|
||||||
|
{
|
||||||
|
splashImage.Height = splash.ImageLocation.Height / ScaleFactor;
|
||||||
|
splashImage.Width = splash.ImageLocation.Width / ScaleFactor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
splashImage.Height = splash.ImageLocation.Height;
|
||||||
|
splashImage.Width = splash.ImageLocation.Width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SubscriptionChanged(string action, Subscription subscription)
|
||||||
|
{
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case "add":
|
||||||
|
subscriptionsHeader.Visibility = Visibility.Visible;
|
||||||
|
if (subscriptionsList.Items.Count < 10)
|
||||||
|
subscriptionsList.Items.Add(subscription);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "remove":
|
||||||
|
if (subscriptionsList.Items.Contains(subscription))
|
||||||
|
{
|
||||||
|
subscriptionsList.Items.Remove(subscription);
|
||||||
|
if (UserManagement.Current.Subscriptions.Count >= 10)
|
||||||
|
subscriptionsList.Items.Add(UserManagement.Current.Subscriptions[9]);
|
||||||
|
else if (UserManagement.Current.Subscriptions.Count == 0)
|
||||||
|
subscriptionsHeader.Visibility = Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthorizationStateChanged(bool isAuthorized)
|
||||||
|
{
|
||||||
|
if (isAuthorized)
|
||||||
|
{
|
||||||
|
accountManager.Logged();
|
||||||
|
|
||||||
|
subscriptions.Visibility =
|
||||||
|
libraryHeader.Visibility =
|
||||||
|
history.Visibility =
|
||||||
|
likedVideos.Visibility =
|
||||||
|
watchLater.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
|
if (UserManagement.Current.Subscriptions.Count > 0)
|
||||||
|
{
|
||||||
|
subscriptionsHeader.Visibility = Visibility.Visible;
|
||||||
|
for (int k = 0; k < UserManagement.Current.Subscriptions.Count && k < 10; k++)
|
||||||
|
subscriptionsList.Items.Add(UserManagement.Current.Subscriptions[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
accountManager.Quit();
|
||||||
|
|
||||||
|
subscriptions.Visibility =
|
||||||
|
libraryHeader.Visibility =
|
||||||
|
history.Visibility =
|
||||||
|
likedVideos.Visibility =
|
||||||
|
watchLater.Visibility =
|
||||||
|
subscriptionsHeader.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
|
subscriptionsList.Items.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
content.AuthorizationChanged(isAuthorized);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateView()
|
||||||
|
{
|
||||||
|
nav.IsBackEnabled = content.CanGoBack;
|
||||||
|
|
||||||
|
if(content.SourcePageType.Name.Belongs("Subscriptions", "Home", "Settings"))
|
||||||
|
{
|
||||||
|
ExpandedThresholdWidth.MinWindowWidth = 1008;
|
||||||
|
split.IsPaneOpen = split.DisplayMode == SplitViewDisplayMode.CompactInline ? true : false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ExpandedThresholdWidth.MinWindowWidth = short.MaxValue;
|
||||||
|
split.IsPaneOpen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async void Search_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args) => await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
|
||||||
|
{
|
||||||
|
//TODO: Finish search bar
|
||||||
|
if (search.Text.Length < 3 || args.Reason != AutoSuggestionBoxTextChangeReason.UserInput)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
doc.Load($"http://suggestqueries.google.com/complete/search?ds=yt&client=toolbar&q={search.Text}&hl={Settings.RelevanceLanguage}");
|
||||||
|
|
||||||
|
List<string> items = new List<string>();
|
||||||
|
|
||||||
|
for (int i = 0; i < doc["toplevel"].ChildNodes.Count && i < 5; i++)
|
||||||
|
items.Add(doc["toplevel"].ChildNodes[i]["suggestion"].GetAttribute("data"));
|
||||||
|
search.ItemsSource = items;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
search.ItemsSource = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
private void Split_PaneToggled(SplitView sender, object args)
|
||||||
|
{
|
||||||
|
subscriptionsHeader.Visibility = split.IsPaneOpen && subscriptionsList.Items.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
|
||||||
|
libraryHeader.Visibility =
|
||||||
|
collectionsHeader.Visibility =
|
||||||
|
libraryHeader.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nav_SelectionChanged(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewSelectionChangedEventArgs args)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Simple UI interaction events
|
||||||
|
void Nav_BackRequested(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewBackRequestedEventArgs args) =>
|
||||||
|
content.BackRequested();
|
||||||
|
|
||||||
|
void Menu_Tapped(object sender, TappedRoutedEventArgs e) =>
|
||||||
|
split.IsPaneOpen = !split.IsPaneOpen;
|
||||||
|
|
||||||
|
async void Feedback_Click(object sender, RoutedEventArgs e) =>
|
||||||
|
await StoreServicesFeedbackLauncher.GetDefault().LaunchAsync();
|
||||||
|
|
||||||
|
void Home_Tapped(object sender, TappedRoutedEventArgs e) =>
|
||||||
|
Navigation.GoToHome();
|
||||||
|
|
||||||
|
void Subscriptions_Tapped(object sender, TappedRoutedEventArgs e) =>
|
||||||
|
Navigation.GoToSubscriptions();
|
||||||
|
|
||||||
|
void History_Tapped(object sender, TappedRoutedEventArgs e) =>
|
||||||
|
Navigation.GoToHistory();
|
||||||
|
|
||||||
|
void LikedVideos_Tapped(object sender, TappedRoutedEventArgs e) =>
|
||||||
|
Navigation.GoToPlaylist(UserManagement.Current.Channel.ContentDetails.RelatedPlaylists.Likes);
|
||||||
|
|
||||||
|
void WatchLater_Tapped(object sender, TappedRoutedEventArgs e) =>
|
||||||
|
Navigation.GoToPlaylist("WL");
|
||||||
|
|
||||||
|
void Downloads_Tapped(object sender, TappedRoutedEventArgs e) =>
|
||||||
|
Navigation.GoToDownloads();
|
||||||
|
|
||||||
|
void Music_Tapped(object sender, TappedRoutedEventArgs e) =>
|
||||||
|
Navigation.GoToChannel("UC-9-kyTW8ZkZNDHQJ6FgpwQ");
|
||||||
|
|
||||||
|
void Sports_Tapped(object sender, TappedRoutedEventArgs e) =>
|
||||||
|
Navigation.GoToChannel("UCEgdi0XIXXZ-qJOFPf4JSKw");
|
||||||
|
|
||||||
|
void Movies_Tapped(object sender, TappedRoutedEventArgs e) =>
|
||||||
|
Navigation.GoToChannel("UClgRkhTL3_hImCAmdLfDE4g");
|
||||||
|
|
||||||
|
void News_Tapped(object sender, TappedRoutedEventArgs e) =>
|
||||||
|
Navigation.GoToChannel("UCYfdidRxbB8Qhf0Nx7ioOYw");
|
||||||
|
|
||||||
|
void Live_Tapped(object sender, TappedRoutedEventArgs e) =>
|
||||||
|
Navigation.GoToChannel("UC4R8DWoMoI7CAwX8_LjQHig");
|
||||||
|
|
||||||
|
void Spotlight_Tapped(object sender, TappedRoutedEventArgs e) =>
|
||||||
|
Navigation.GoToChannel("UC8iNz9uwDGfomRnnKKbOhOQ");
|
||||||
|
|
||||||
|
private void SphereVideo_Tapped(object sender, TappedRoutedEventArgs e) =>
|
||||||
|
Navigation.GoToChannel("UCzuqhhs6NWbgTzMuM09WKDQ");
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Search bar methods
|
||||||
|
async void SearchBtn_Tapped(object sender, TappedRoutedEventArgs e)
|
||||||
|
{
|
||||||
|
menu.Visibility =
|
||||||
|
accountManager.Visibility =
|
||||||
|
feedback.Visibility = Visibility.Collapsed;
|
||||||
|
nav.IsBackButtonVisible = Microsoft.UI.Xaml.Controls.NavigationViewBackButtonVisible.Collapsed;
|
||||||
|
|
||||||
|
SearchExpanded.Storyboard.Begin();
|
||||||
|
await Task.Delay(1);
|
||||||
|
search.Focus(FocusState.Pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
async void Search_LostFocus(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (ActualWidth >= 1000)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SearchCollapsed.Storyboard.Begin();
|
||||||
|
await Task.Delay(1000);
|
||||||
|
|
||||||
|
menu.Visibility =
|
||||||
|
accountManager.Visibility =
|
||||||
|
feedback.Visibility = Visibility.Visible;
|
||||||
|
nav.IsBackButtonVisible = Microsoft.UI.Xaml.Controls.NavigationViewBackButtonVisible.Visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Search_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(search.Text))
|
||||||
|
Navigation.GoToSearch(new SearchParameters(search.Text));
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void Content_Navigated(System.Collections.IList pivotCollection, int? selectedPivot)
|
||||||
|
{
|
||||||
|
nav.MenuItemsSource = pivotCollection;
|
||||||
|
if(selectedPivot.HasValue)
|
||||||
|
nav.SelectedItem = pivotCollection[selectedPivot.Value];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Content_Navigating(Type sourcePageType, object parameter)
|
||||||
|
{
|
||||||
|
nav.MenuItems.Clear();
|
||||||
|
UpdateView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,144 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="all.Content" xml:space="preserve">
|
||||||
|
<value>All</value>
|
||||||
|
</data>
|
||||||
|
<data name="changelog" xml:space="preserve">
|
||||||
|
<value>Changelog</value>
|
||||||
|
</data>
|
||||||
|
<data name="changelogs.Content" xml:space="preserve">
|
||||||
|
<value>Changelogs</value>
|
||||||
|
</data>
|
||||||
|
<data name="dev" xml:space="preserve">
|
||||||
|
<value>Developer's message</value>
|
||||||
|
</data>
|
||||||
|
<data name="filter.Header" xml:space="preserve">
|
||||||
|
<value>Filter</value>
|
||||||
|
</data>
|
||||||
|
<data name="messages.Content" xml:space="preserve">
|
||||||
|
<value>Messages</value>
|
||||||
|
</data>
|
||||||
|
<data name="select.Text" xml:space="preserve">
|
||||||
|
<value>Select item from the list</value>
|
||||||
|
</data>
|
||||||
|
<data name="whatsnew" xml:space="preserve">
|
||||||
|
<value>What's new in v</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="dontAsk" xml:space="preserve">
|
||||||
|
<value>Don't ask me anymore</value>
|
||||||
|
</data>
|
||||||
|
<data name="feedbackMessage" xml:space="preserve">
|
||||||
|
<value>Have some thoughts to share about the app or any suggestions? Leave feedback!</value>
|
||||||
|
</data>
|
||||||
|
<data name="promptLater" xml:space="preserve">
|
||||||
|
<value>Maybe later</value>
|
||||||
|
</data>
|
||||||
|
<data name="rate" xml:space="preserve">
|
||||||
|
<value>Like our app? Review it on Microsoft Store!</value>
|
||||||
|
</data>
|
||||||
|
<data name="sure" xml:space="preserve">
|
||||||
|
<value>Sure!</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="channel" xml:space="preserve">
|
||||||
|
<value>Channel</value>
|
||||||
|
</data>
|
||||||
|
<data name="playlist" xml:space="preserve">
|
||||||
|
<value>Playlist</value>
|
||||||
|
</data>
|
||||||
|
<data name="video" xml:space="preserve">
|
||||||
|
<value>Video</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
@@ -117,28 +117,10 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<data name="all.Content" xml:space="preserve">
|
|
||||||
<value>All</value>
|
|
||||||
</data>
|
|
||||||
<data name="changelog" xml:space="preserve">
|
<data name="changelog" xml:space="preserve">
|
||||||
<value>Changelog</value>
|
<value>Changelog</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="changelogs.Content" xml:space="preserve">
|
<data name="whatsNew" xml:space="preserve">
|
||||||
<value>Changelogs</value>
|
<value>What's new in version</value>
|
||||||
</data>
|
|
||||||
<data name="dev" xml:space="preserve">
|
|
||||||
<value>Developer's message</value>
|
|
||||||
</data>
|
|
||||||
<data name="filter.Header" xml:space="preserve">
|
|
||||||
<value>Filter</value>
|
|
||||||
</data>
|
|
||||||
<data name="messages.Content" xml:space="preserve">
|
|
||||||
<value>Messages</value>
|
|
||||||
</data>
|
|
||||||
<data name="select.Text" xml:space="preserve">
|
|
||||||
<value>Select item from the list</value>
|
|
||||||
</data>
|
|
||||||
<data name="whatsnew" xml:space="preserve">
|
|
||||||
<value>What's new in v</value>
|
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="error" xml:space="preserve">
|
||||||
|
<value>Error</value>
|
||||||
|
</data>
|
||||||
|
<data name="feedback.Content" xml:space="preserve">
|
||||||
|
<value>Leave feedback</value>
|
||||||
|
</data>
|
||||||
|
<data name="general" xml:space="preserve">
|
||||||
|
<value>It could be caused by YouTube internal server error or by application's bug. Please, try again later</value>
|
||||||
|
</data>
|
||||||
|
<data name="generalTitle" xml:space="preserve">
|
||||||
|
<value>We are unable to display the page</value>
|
||||||
|
</data>
|
||||||
|
<data name="message" xml:space="preserve">
|
||||||
|
<value>Message</value>
|
||||||
|
</data>
|
||||||
|
<data name="network.Content" xml:space="preserve">
|
||||||
|
<value>Open network settings</value>
|
||||||
|
</data>
|
||||||
|
<data name="or.Text" xml:space="preserve">
|
||||||
|
<value>OR</value>
|
||||||
|
</data>
|
||||||
|
<data name="refresh.Content" xml:space="preserve">
|
||||||
|
<value>Refresh page</value>
|
||||||
|
</data>
|
||||||
|
<data name="stackTrace" xml:space="preserve">
|
||||||
|
<value>Stack trace</value>
|
||||||
|
</data>
|
||||||
|
<data name="troubleshooter.Content" xml:space="preserve">
|
||||||
|
<value>Open troubleshooter</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="clipboardHead" xml:space="preserve">
|
||||||
|
<value>We've found this on your clipboard</value>
|
||||||
|
</data>
|
||||||
|
<data name="clipboardOpen" xml:space="preserve">
|
||||||
|
<value>Open in FoxTube</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
@@ -1,375 +0,0 @@
|
|||||||
<ResourceDictionary
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:local="using:FoxTube.Controls.Player"
|
|
||||||
xmlns:controls="using:FoxTube.Controls"
|
|
||||||
xmlns:adverts="using:FoxTube.Controls.Adverts">
|
|
||||||
|
|
||||||
<Style TargetType="local:PlayerControls">
|
|
||||||
<Setter Property="Background" Value="Transparent" />
|
|
||||||
<Setter Property="UseSystemFocusVisuals" Value="True" />
|
|
||||||
<Setter Property="IsTextScaleFactorEnabled" Value="False" />
|
|
||||||
<Setter Property="Template">
|
|
||||||
<Setter.Value>
|
|
||||||
<ControlTemplate TargetType="local:PlayerControls">
|
|
||||||
<Grid Background="Transparent" Name="root">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<Grid.Resources>
|
|
||||||
<Style x:Key="PlayerSeek" TargetType="Slider">
|
|
||||||
<Setter Property="Margin" Value="0"/>
|
|
||||||
<Setter Property="Template">
|
|
||||||
<Setter.Value>
|
|
||||||
<ControlTemplate TargetType="Slider">
|
|
||||||
<Grid>
|
|
||||||
<Grid.Resources>
|
|
||||||
<Style TargetType="Thumb">
|
|
||||||
<Setter Property="Background" Value="Red" />
|
|
||||||
<Setter Property="Template">
|
|
||||||
<Setter.Value>
|
|
||||||
<ControlTemplate TargetType="Thumb">
|
|
||||||
<Ellipse Fill="{TemplateBinding Background}"/>
|
|
||||||
</ControlTemplate>
|
|
||||||
</Setter.Value>
|
|
||||||
</Setter>
|
|
||||||
</Style>
|
|
||||||
</Grid.Resources>
|
|
||||||
<VisualStateManager.VisualStateGroups>
|
|
||||||
<VisualStateGroup x:Name="CommonStates">
|
|
||||||
<VisualState x:Name="Normal"/>
|
|
||||||
<VisualState x:Name="Pressed">
|
|
||||||
<Storyboard>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalTrackRect" Storyboard.TargetProperty="Fill">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SliderTrackFillPressed}" />
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalThumb" Storyboard.TargetProperty="Background">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SliderThumbBackgroundPressed}" />
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SliderContainer" Storyboard.TargetProperty="Background">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SliderContainerBackgroundPressed}" />
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
</Storyboard>
|
|
||||||
</VisualState>
|
|
||||||
<VisualState x:Name="Disabled">
|
|
||||||
<Storyboard>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalDecreaseRect" Storyboard.TargetProperty="Fill">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SliderTrackValueFillDisabled}" />
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalTrackRect" Storyboard.TargetProperty="Fill">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SliderTrackFillDisabled}" />
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalThumb" Storyboard.TargetProperty="Background">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SliderThumbBackgroundDisabled}" />
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SliderContainer" Storyboard.TargetProperty="Background">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SliderContainerBackgroundDisabled}" />
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
</Storyboard>
|
|
||||||
</VisualState>
|
|
||||||
<VisualState x:Name="PointerOver">
|
|
||||||
<Storyboard>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalTrackRect" Storyboard.TargetProperty="Fill">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SliderTrackFillPointerOver}" />
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalThumb" Storyboard.TargetProperty="Background">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SliderThumbBackgroundPointerOver}" />
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SliderContainer" Storyboard.TargetProperty="Background">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SliderContainerBackgroundPointerOver}" />
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
</Storyboard>
|
|
||||||
</VisualState>
|
|
||||||
</VisualStateGroup>
|
|
||||||
<VisualStateGroup x:Name="FocusEngagementStates">
|
|
||||||
<VisualState x:Name="FocusDisengaged"/>
|
|
||||||
<VisualState x:Name="FocusEngagedHorizontal">
|
|
||||||
<Storyboard>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SliderContainer" Storyboard.TargetProperty="(Control.IsTemplateFocusTarget)">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="False" />
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalThumb" Storyboard.TargetProperty="(Control.IsTemplateFocusTarget)">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="True" />
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
</Storyboard>
|
|
||||||
</VisualState>
|
|
||||||
</VisualStateGroup>
|
|
||||||
</VisualStateManager.VisualStateGroups>
|
|
||||||
|
|
||||||
<Grid x:Name="SliderContainer" Control.IsTemplateFocusTarget="True" Background="{ThemeResource SliderContainerBackground}">
|
|
||||||
<Grid x:Name="HorizontalTemplate">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
<ColumnDefinition/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
|
|
||||||
<Rectangle x:Name="HorizontalTrackRect" Height="{StaticResource SliderTrackThemeHeight}" Fill="{TemplateBinding Background}" Grid.ColumnSpan="3"/>
|
|
||||||
|
|
||||||
<ProgressBar x:Name="DownloadProgressIndicator" Grid.ColumnSpan="3"
|
|
||||||
Height="{ThemeResource SliderTrackThemeHeight}"
|
|
||||||
Foreground="{ThemeResource SystemControlHighlightChromeAltLowBrush}"
|
|
||||||
Background="Transparent"
|
|
||||||
BorderBrush="Transparent"
|
|
||||||
BorderThickness="1"/>
|
|
||||||
|
|
||||||
<Rectangle Height="4" x:Name="HorizontalDecreaseRect" Fill="{StaticResource SystemAccentColor}"/>
|
|
||||||
|
|
||||||
<Thumb x:Name="HorizontalThumb"
|
|
||||||
Height="15" Width="15" Grid.Column="1"
|
|
||||||
AutomationProperties.AccessibilityView="Raw">
|
|
||||||
<Thumb.DataContext>
|
|
||||||
<Grid>
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="112"/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<Image x:Name="ThumbnailImage" Width="192"/>
|
|
||||||
<TextBlock Grid.Row="1" x:Name="TimeElapsedPreview"/>
|
|
||||||
</Grid>
|
|
||||||
</Thumb.DataContext>
|
|
||||||
</Thumb>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</ControlTemplate>
|
|
||||||
</Setter.Value>
|
|
||||||
</Setter>
|
|
||||||
</Style>
|
|
||||||
</Grid.Resources>
|
|
||||||
|
|
||||||
<VisualStateManager.VisualStateGroups>
|
|
||||||
<VisualStateGroup x:Name="ControlPanelVisibilityStates">
|
|
||||||
<VisualState x:Name="ControlPanelFadeIn">
|
|
||||||
<Storyboard>
|
|
||||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Border">
|
|
||||||
<EasingDoubleKeyFrame KeyTime="0" Value="0" />
|
|
||||||
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1" />
|
|
||||||
</DoubleAnimationUsingKeyFrames>
|
|
||||||
</Storyboard>
|
|
||||||
</VisualState>
|
|
||||||
<VisualState x:Name="ControlPanelFadeOut">
|
|
||||||
<Storyboard>
|
|
||||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Border">
|
|
||||||
<EasingDoubleKeyFrame KeyTime="0" Value="1" />
|
|
||||||
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0" />
|
|
||||||
</DoubleAnimationUsingKeyFrames>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsHitTestVisible" Storyboard.TargetName="Border">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="False" />
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
</Storyboard>
|
|
||||||
</VisualState>
|
|
||||||
</VisualStateGroup>
|
|
||||||
|
|
||||||
<VisualStateGroup x:Name="MediaStates">
|
|
||||||
<VisualState x:Name="Normal" />
|
|
||||||
<VisualState x:Name="Buffering">
|
|
||||||
<Storyboard>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="BufferingProgressBar">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
</Storyboard>
|
|
||||||
</VisualState>
|
|
||||||
<VisualState x:Name="Loading">
|
|
||||||
<Storyboard>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="BufferingProgressBar">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
<DoubleAnimation Storyboard.TargetName="ProgressSlider"
|
|
||||||
Storyboard.TargetProperty="Opacity"
|
|
||||||
To="0"
|
|
||||||
Duration="0" />
|
|
||||||
</Storyboard>
|
|
||||||
</VisualState>
|
|
||||||
<!--<VisualState x:Name="Error">
|
|
||||||
<Storyboard>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ErrorBorder">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0">
|
|
||||||
<DiscreteObjectKeyFrame.Value>
|
|
||||||
<Visibility>Visible</Visibility>
|
|
||||||
</DiscreteObjectKeyFrame.Value>
|
|
||||||
</DiscreteObjectKeyFrame>
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
</Storyboard>
|
|
||||||
</VisualState>-->
|
|
||||||
<VisualState x:Name="Disabled">
|
|
||||||
<Storyboard/>
|
|
||||||
</VisualState>
|
|
||||||
</VisualStateGroup>
|
|
||||||
|
|
||||||
<VisualStateGroup x:Name="PlayPauseStates">
|
|
||||||
<VisualState x:Name="PlayState" />
|
|
||||||
<VisualState x:Name="PauseState">
|
|
||||||
<Storyboard>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlayPauseSymbol" Storyboard.TargetProperty="Symbol">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="Pause" />
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
</Storyboard>
|
|
||||||
</VisualState>
|
|
||||||
</VisualStateGroup>
|
|
||||||
<VisualStateGroup x:Name="FullWindowStates">
|
|
||||||
<VisualState x:Name="NonFullWindowState" />
|
|
||||||
<VisualState x:Name="FullWindowState">
|
|
||||||
<Storyboard>
|
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FullWindowSymbol" Storyboard.TargetProperty="Symbol">
|
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="BackToWindow" />
|
|
||||||
</ObjectAnimationUsingKeyFrames>
|
|
||||||
</Storyboard>
|
|
||||||
</VisualState>
|
|
||||||
</VisualStateGroup>
|
|
||||||
</VisualStateManager.VisualStateGroups>
|
|
||||||
|
|
||||||
<Border x:Name="Border">
|
|
||||||
<Border.Resources>
|
|
||||||
<Style TargetType="Button" BasedOn="{StaticResource ButtonRevealStyle}">
|
|
||||||
<Setter Property="Width" Value="50"/>
|
|
||||||
<Setter Property="Height" Value="50"/>
|
|
||||||
<Setter Property="FontSize" Value="20"/>
|
|
||||||
<Setter Property="Background" Value="Transparent"/>
|
|
||||||
<Setter Property="FontFamily" Value="Segoe UI, Segoe MDL2 Assets"/>
|
|
||||||
</Style>
|
|
||||||
</Border.Resources>
|
|
||||||
<Grid x:Name="ControlPanelGrid">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
|
|
||||||
<Grid x:Name="header">
|
|
||||||
<Grid.Background>
|
|
||||||
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
|
|
||||||
<GradientStop Color="Black"/>
|
|
||||||
<GradientStop Color="#00000000" Offset="1"/>
|
|
||||||
</LinearGradientBrush>
|
|
||||||
</Grid.Background>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
<ColumnDefinition/>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
|
|
||||||
<Button x:Name="MinimizeButton" HorizontalAlignment="Left" VerticalAlignment="Top" Content=""/>
|
|
||||||
|
|
||||||
<StackPanel VerticalAlignment="Top" Grid.Column="1" Margin="10,0">
|
|
||||||
<TextBlock x:Name="title" Text="Name" TextTrimming="CharacterEllipsis" MaxLines="1" Style="{StaticResource TitleTextBlockStyle}"/>
|
|
||||||
<TextBlock x:Name="channel" Text="Channel" TextTrimming="CharacterEllipsis" FontStyle="Italic"/>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<StackPanel x:Name="RightHeaderControls" Orientation="Horizontal" VerticalAlignment="Top" Grid.Column="2">
|
|
||||||
<Button x:Name="CloseButton" HorizontalAlignment="Right" VerticalAlignment="Top" Content=""/>
|
|
||||||
<Button x:Name="CastButton" Content=""/>
|
|
||||||
<Button x:Name="CompactOverlayButton" HorizontalAlignment="Right" VerticalAlignment="Top" Content=""/>
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Grid x:Name="centerTrigger" Grid.Row="1"/>
|
|
||||||
|
|
||||||
<Grid x:Name="center" Grid.Row="1" Visibility="Collapsed" Background="#7F000000">
|
|
||||||
<Button x:Name="drag" IsHitTestVisible="False" Height="32" Width="47" Margin="0,0,47,0" Content="" Visibility="Collapsed" Padding="0" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" VerticalAlignment="Top" HorizontalAlignment="Right"/>
|
|
||||||
<StackPanel x:Name="centerControls" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
||||||
<ProgressBar x:Name="SeekIndicator" Background="Transparent" VerticalAlignment="Bottom"/>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Grid x:Name="footer" Grid.Row="2">
|
|
||||||
<Grid.Background>
|
|
||||||
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
|
|
||||||
<GradientStop Color="Black" Offset="1"/>
|
|
||||||
<GradientStop Color="#00000000" Offset="0"/>
|
|
||||||
</LinearGradientBrush>
|
|
||||||
</Grid.Background>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
<ColumnDefinition/>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
|
|
||||||
<ProgressBar x:Name="BufferingProgressBar" VerticalAlignment="Bottom" Grid.ColumnSpan="3" Background="Transparent" IsIndeterminate="True" Visibility="Collapsed"/>
|
|
||||||
|
|
||||||
<StackPanel x:Name="LeftFooterControls" Orientation="Horizontal" VerticalAlignment="Bottom">
|
|
||||||
<Button x:Name="PlayPauseButton">
|
|
||||||
<SymbolIcon x:Name="PlayPauseSymbol" Symbol="Play"/>
|
|
||||||
<Button.KeyboardAccelerators>
|
|
||||||
<KeyboardAccelerator Key="Space"/>
|
|
||||||
</Button.KeyboardAccelerators>
|
|
||||||
</Button>
|
|
||||||
<Button x:Name="PreviousButton" Content="" Visibility="Collapsed"/>
|
|
||||||
<Button x:Name="NextButton" Content=""/>
|
|
||||||
<Button x:Name="VolumeMenuButton" Content="">
|
|
||||||
<Button.Flyout>
|
|
||||||
<Flyout>
|
|
||||||
<StackPanel Orientation="Horizontal" Margin="-10">
|
|
||||||
<Button x:Name="AudioMuteButton" Content="" FontFamily="Segoe MDL2 Assets" Height="50" Width="50" Background="Transparent" FontSize="20"/>
|
|
||||||
<Slider x:Name="VolumeSlider" Width="150" Margin="10,5,10,0" VerticalAlignment="Center" TickPlacement="Outside" TickFrequency="10"/>
|
|
||||||
</StackPanel>
|
|
||||||
</Flyout>
|
|
||||||
</Button.Flyout>
|
|
||||||
</Button>
|
|
||||||
<Button x:Name="PlayLiveButton" Width="NaN" Visibility="Collapsed">
|
|
||||||
<TextBlock x:Uid="/VideoPage/live" Text="🔴 LIVE"/>
|
|
||||||
</Button>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<Grid x:Name="CenterFooterControls" Height="50" Grid.Column="1" VerticalAlignment="Bottom">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition/>
|
|
||||||
<RowDefinition/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<TextBlock Grid.Row="1" Margin="5,0" VerticalAlignment="Center" HorizontalAlignment="Left" x:Name="TimeElapsedElement" Text="00:00"/>
|
|
||||||
<TextBlock Grid.Row="1" Margin="5,0" VerticalAlignment="Center" HorizontalAlignment="Right" x:Name="TimeRemainingElement" Text="00:00"/>
|
|
||||||
<Slider x:Name="ProgressSlider" Style="{StaticResource PlayerSeek}" IsThumbToolTipEnabled="False" HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="5,0"/>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<StackPanel x:Name="RightFooterControls" Grid.Column="2" VerticalAlignment="Bottom" Orientation="Horizontal">
|
|
||||||
<Button x:Name="SkipBackwardButton" Content="">
|
|
||||||
<Button.KeyboardAccelerators>
|
|
||||||
<KeyboardAccelerator Key="Left"/>
|
|
||||||
</Button.KeyboardAccelerators>
|
|
||||||
</Button>
|
|
||||||
<Button x:Name="SkipForwardButton" Content="">
|
|
||||||
<Button.KeyboardAccelerators>
|
|
||||||
<KeyboardAccelerator Key="Right"/>
|
|
||||||
</Button.KeyboardAccelerators>
|
|
||||||
</Button>
|
|
||||||
<Line Stroke="White" StrokeThickness="2" Y1="5" Y2="45"/>
|
|
||||||
<Button x:Name="CaptionsMenuButton" Content="">
|
|
||||||
<Button.Flyout>
|
|
||||||
<Flyout>
|
|
||||||
<StackPanel Width="225">
|
|
||||||
<ToggleSwitch x:Name="CaptionsToggleSwitch" OnContent="Subtitles" OffContent="Subtitles" x:Uid="/VideoPage/subsSwitch"/>
|
|
||||||
<ComboBox x:Name="CaptionsSelector" Header="Language" x:Uid="/VideoPage/subsSelector" PlaceholderText="No captions are available" HorizontalAlignment="Stretch"/>
|
|
||||||
</StackPanel>
|
|
||||||
</Flyout>
|
|
||||||
</Button.Flyout>
|
|
||||||
</Button>
|
|
||||||
<Button x:Name="SettingsMenuButton" Content="">
|
|
||||||
<Button.Flyout>
|
|
||||||
<Flyout>
|
|
||||||
<StackPanel>
|
|
||||||
<Slider x:Name="PlaybackSpeedSlider" x:Uid="/VideoPage/playbackSpeed" Orientation="Horizontal" TickPlacement="Outside" StepFrequency=".1" Value="1" Maximum="3" Header="Playback speed"/>
|
|
||||||
<ComboBox Width="225" x:Name="QualitySelector" Header="Language" x:Uid="/VideoPage/qualitySelector"/>
|
|
||||||
</StackPanel>
|
|
||||||
</Flyout>
|
|
||||||
</Button.Flyout>
|
|
||||||
</Button>
|
|
||||||
<Button x:Name="FullWindowButton">
|
|
||||||
<SymbolIcon x:Name="FullWindowSymbol" Symbol="FullScreen"/>
|
|
||||||
<Button.KeyboardAccelerators>
|
|
||||||
<KeyboardAccelerator Key="F11"/>
|
|
||||||
</Button.KeyboardAccelerators>
|
|
||||||
</Button>
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Border>
|
|
||||||
|
|
||||||
<controls:LiveCaptions Visibility="Collapsed" x:Name="CaptionControl"/>
|
|
||||||
|
|
||||||
<adverts:PlayerAdvert Grid.Row="1" x:Name="AdvertControl" VerticalAlignment="Bottom"/>
|
|
||||||
</Grid>
|
|
||||||
</ControlTemplate>
|
|
||||||
</Setter.Value>
|
|
||||||
</Setter>
|
|
||||||
</Style>
|
|
||||||
</ResourceDictionary>
|
|
||||||
@@ -7,6 +7,15 @@
|
|||||||
<Style TargetType="Button" BasedOn="{StaticResource ButtonRevealStyle}">
|
<Style TargetType="Button" BasedOn="{StaticResource ButtonRevealStyle}">
|
||||||
<Setter Property="FontSize" Value="14"/>
|
<Setter Property="FontSize" Value="14"/>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="NavigationViewHeaderButton" TargetType="Button" BasedOn="{StaticResource ButtonRevealStyle}">
|
||||||
|
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
|
||||||
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
|
<Setter Property="Height" Value="41"/>
|
||||||
|
<Setter Property="Width" Value="60"/>
|
||||||
|
<Setter Property="FontSize" Value="15"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
<Style TargetType="ListViewItem" BasedOn="{StaticResource ListViewItemRevealStyle}"/>
|
<Style TargetType="ListViewItem" BasedOn="{StaticResource ListViewItemRevealStyle}"/>
|
||||||
<Style TargetType="TextBlock">
|
<Style TargetType="TextBlock">
|
||||||
<Setter Property="SelectionHighlightColor" Value="Red"/>
|
<Setter Property="SelectionHighlightColor" Value="Red"/>
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 102 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
+3792
File diff suppressed because one or more lines are too long
+3267
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 241 KiB |
Binary file not shown.
Reference in New Issue
Block a user