Merged PR 26: Submission #6
##Potential 1.0 release candidate. If there is no critical issues will be found this submission will be pushed to public - Updated package version - In-video advert now doesn't appear on minimized playback - Fixed small header appearing on channel page - Fixed home page loading after in long active sessions - Optimization, bugfixes and refactoring - Fixed crash when local watch history reaches 87 entries (now its capacity is 200) - Added backward navigation to video page - Improved authentication process - Removed outdated logo from 'About' page and updated Twitter link - Updated package version
This commit is contained in:
@@ -259,3 +259,4 @@ paket-files/
|
|||||||
# Python Tools for Visual Studio (PTVS)
|
# Python Tools for Visual Studio (PTVS)
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
|
/Src/Trailer
|
||||||
|
|||||||
+37
-37
@@ -10,7 +10,6 @@ using System.Xml;
|
|||||||
using Windows.ApplicationModel;
|
using Windows.ApplicationModel;
|
||||||
using Windows.ApplicationModel.Activation;
|
using Windows.ApplicationModel.Activation;
|
||||||
using Windows.ApplicationModel.Background;
|
using Windows.ApplicationModel.Background;
|
||||||
using Windows.ApplicationModel.Core;
|
|
||||||
using Windows.Globalization;
|
using Windows.Globalization;
|
||||||
using Windows.Storage;
|
using Windows.Storage;
|
||||||
using Windows.System.Power;
|
using Windows.System.Power;
|
||||||
@@ -57,7 +56,7 @@ namespace FoxTube
|
|||||||
public async void CheckVersion()
|
public async void CheckVersion()
|
||||||
{
|
{
|
||||||
PackageVersion ver = Package.Current.Id.Version;
|
PackageVersion ver = Package.Current.Id.Version;
|
||||||
if (SettingsStorage.Version != $"{ver.Major}.{ver.Minor}")
|
if (SettingsStorage.Version != $"{ver.Major}.{ver.Minor}.{ver.Build}")
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -68,40 +67,34 @@ namespace FoxTube
|
|||||||
|
|
||||||
ToastNotificationManager.CreateToastNotifier().Show(Background.Notification.GetChangelogToast(e.GetAttribute("version")));
|
ToastNotificationManager.CreateToastNotifier().Show(Background.Notification.GetChangelogToast(e.GetAttribute("version")));
|
||||||
|
|
||||||
SettingsStorage.Version = $"{ver.Major}.{ver.Minor}";
|
SettingsStorage.Version = $"{ver.Major}.{ver.Minor}.{ver.Build}";
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("Unable to retrieve changelog");
|
Analytics.TrackEvent("Unable to retrieve changelog", new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "Exception", e.GetType().ToString() },
|
||||||
|
{ "Message", e.Message },
|
||||||
|
{ "App version", $"{ver.Major}.{ver.Minor}.{ver.Revision}.{ver.Build}" }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
||||||
{
|
{
|
||||||
// Do not repeat app initialization when the Window already has content,
|
|
||||||
// just ensure that the window is active
|
|
||||||
if (!(Window.Current.Content is Frame rootFrame))
|
if (!(Window.Current.Content is Frame rootFrame))
|
||||||
{
|
{
|
||||||
// Create a Frame to act as the navigation context and navigate to the first page
|
|
||||||
rootFrame = new Frame();
|
rootFrame = new Frame();
|
||||||
|
|
||||||
rootFrame.NavigationFailed += OnNavigationFailed;
|
rootFrame.NavigationFailed += OnNavigationFailed;
|
||||||
|
|
||||||
// Place the frame in the current Window
|
|
||||||
Window.Current.Content = rootFrame;
|
Window.Current.Content = rootFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.PrelaunchActivated == false)
|
if (e.PrelaunchActivated == false)
|
||||||
{
|
{
|
||||||
if (rootFrame.Content == null)
|
if (rootFrame.Content == null)
|
||||||
{
|
|
||||||
// When the navigation stack isn't restored navigate to the first page,
|
|
||||||
// configuring the new page by passing required information as a navigation
|
|
||||||
// parameter
|
|
||||||
rootFrame.Navigate(typeof(MainPage), e.Arguments);
|
rootFrame.Navigate(typeof(MainPage), e.Arguments);
|
||||||
}
|
|
||||||
// Ensure the current window is active
|
|
||||||
Window.Current.Activate();
|
Window.Current.Activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +146,7 @@ namespace FoxTube
|
|||||||
BackgroundTaskRegistration registration = builder.Register();
|
BackgroundTaskRegistration registration = builder.Register();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async override void OnBackgroundActivated(BackgroundActivatedEventArgs args)
|
protected override void OnBackgroundActivated(BackgroundActivatedEventArgs args)
|
||||||
{
|
{
|
||||||
var deferral = args.TaskInstance.GetDeferral();
|
var deferral = args.TaskInstance.GetDeferral();
|
||||||
base.OnBackgroundActivated(args);
|
base.OnBackgroundActivated(args);
|
||||||
@@ -167,11 +160,10 @@ namespace FoxTube
|
|||||||
case "later":
|
case "later":
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!SecretsVault.IsAuthorized)
|
SecretsVault.AuthorizationStateChanged += async (s, e) =>
|
||||||
SecretsVault.CheckAuthorization(false);
|
{
|
||||||
if (!SecretsVault.IsAuthorized)
|
if ((bool)e[0])
|
||||||
throw new Exception("Not authenticated");
|
{
|
||||||
|
|
||||||
PlaylistItem item = new PlaylistItem()
|
PlaylistItem item = new PlaylistItem()
|
||||||
{
|
{
|
||||||
Snippet = new PlaylistItemSnippet()
|
Snippet = new PlaylistItemSnippet()
|
||||||
@@ -187,9 +179,17 @@ namespace FoxTube
|
|||||||
|
|
||||||
await SecretsVault.Service.PlaylistItems.Insert(item, "snippet").ExecuteAsync();
|
await SecretsVault.Service.PlaylistItems.Insert(item, "snippet").ExecuteAsync();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
SecretsVault.CheckAuthorization(false);
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Debug.WriteLine(e.Message);
|
Analytics.TrackEvent("Failed to add video to WL from toast", new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "Exception", e.GetType().ToString() },
|
||||||
|
{ "Message", e.Message },
|
||||||
|
{ "Video ID", arguments[1] }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -211,18 +211,24 @@ namespace FoxTube
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rootFrame.Content == null)
|
if (rootFrame.Content == null)
|
||||||
{
|
|
||||||
rootFrame.Navigate(typeof(MainPage));
|
rootFrame.Navigate(typeof(MainPage));
|
||||||
}
|
|
||||||
|
|
||||||
Window.Current.Activate();
|
Window.Current.Activate();
|
||||||
|
|
||||||
switch (e.Kind)
|
switch (e.Kind)
|
||||||
{
|
{
|
||||||
case ActivationKind.Protocol:
|
|
||||||
break;
|
|
||||||
case ActivationKind.ToastNotification:
|
case ActivationKind.ToastNotification:
|
||||||
string[] args = (e as ToastNotificationActivatedEventArgs).Argument.Split('|');
|
if (SecretsVault.IsAuthorized)
|
||||||
|
ProcessToast((e as ToastNotificationActivatedEventArgs).Argument);
|
||||||
|
else
|
||||||
|
SecretsVault.AuthorizationStateChanged += (s, arg) => ProcessToast((e as ToastNotificationActivatedEventArgs).Argument);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessToast(string arg)
|
||||||
|
{
|
||||||
|
string[] args = arg.Split('|');
|
||||||
switch (args[0])
|
switch (args[0])
|
||||||
{
|
{
|
||||||
case "changelog":
|
case "changelog":
|
||||||
@@ -237,6 +243,7 @@ namespace FoxTube
|
|||||||
case "channel":
|
case "channel":
|
||||||
Methods.MainPage.GoToChannel(args[1]);
|
Methods.MainPage.GoToChannel(args[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "download":
|
case "download":
|
||||||
Methods.MainPage.GoToDownloads();
|
Methods.MainPage.GoToDownloads();
|
||||||
break;
|
break;
|
||||||
@@ -244,13 +251,6 @@ namespace FoxTube
|
|||||||
DownloadAgent.Cancel(args[1]);
|
DownloadAgent.Cancel(args[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launch(string e = null)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
|
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
|
||||||
@@ -265,6 +265,7 @@ namespace FoxTube
|
|||||||
sw.Stop();
|
sw.Stop();
|
||||||
SettingsStorage.Uptime += sw.Elapsed;
|
SettingsStorage.Uptime += sw.Elapsed;
|
||||||
|
|
||||||
|
HistorySet.Save();
|
||||||
SettingsStorage.SaveData();
|
SettingsStorage.SaveData();
|
||||||
DownloadAgent.QuitPrompt();
|
DownloadAgent.QuitPrompt();
|
||||||
Controls.Player.ManifestGenerator.ClearRoaming();
|
Controls.Player.ManifestGenerator.ClearRoaming();
|
||||||
@@ -277,7 +278,6 @@ namespace FoxTube
|
|||||||
Analytics.TrackEvent("The app crashed", new Dictionary<string, string>()
|
Analytics.TrackEvent("The app crashed", new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "Exception", e.Exception.GetType().ToString() },
|
{ "Exception", e.Exception.GetType().ToString() },
|
||||||
{ "Class", e.ToString() },
|
|
||||||
{ "Details", e.Message }
|
{ "Details", e.Message }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,32 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<items>
|
<items>
|
||||||
<item time="2019-04-28" version="0.6">
|
<item time="2019-05-21" version="0.6.2">
|
||||||
|
<content>
|
||||||
|
<en-US>##[Patch #1]
|
||||||
|
### What's new:
|
||||||
|
- In-video advert now doesn't appear on minimized playback
|
||||||
|
- Fixed small header appearing on channel page
|
||||||
|
- Fixed home page loading in long active sessions
|
||||||
|
- Optimization and bugfixes
|
||||||
|
- Fixed crash when local watch history reaches 87 entries (now its capacity is 200)
|
||||||
|
- Added backward navigation to video page
|
||||||
|
- Improved authentication process
|
||||||
|
- Removed outdated logo from 'About' page and updated Twitter link
|
||||||
|
</en-US>
|
||||||
|
<ru-RU>##[Патч #1]
|
||||||
|
### Что нового:
|
||||||
|
- Теперь реклама в видео не появляется в компактном режиме
|
||||||
|
- Исправлено появление меленького заголовка на странице канала
|
||||||
|
- Исправлено отображение видео на домашней странице при долгой активной сессии
|
||||||
|
- Оптимизация и исправление ошибок
|
||||||
|
- Исправлен сбой приложения при достижении локальной историей 87 записей (текущая емкость журнала - 200 записей)
|
||||||
|
- Добавлена обратная навигация для страниц просмотра
|
||||||
|
- Улучшен процесс аутентификации
|
||||||
|
- Удален старый логотип с страницы 'О приложении' и обновлена ссылка на Твиттер
|
||||||
|
</ru-RU>
|
||||||
|
</content>
|
||||||
|
</item>
|
||||||
|
<item time="2019-05-20" version="0.6">
|
||||||
<content>
|
<content>
|
||||||
<en-US>##[Final pre-release version]
|
<en-US>##[Final pre-release version]
|
||||||
### What's new:
|
### What's new:
|
||||||
@@ -70,7 +96,7 @@ This is the final pre-release minor version. That means that until 1.0 release t
|
|||||||
- Fixed header titles
|
- Fixed header titles
|
||||||
- Some items were moved from menu to header
|
- Some items were moved from menu to header
|
||||||
- Added "Share" button to video cards
|
- Added "Share" button to video cards
|
||||||
- Added "Delete video from playlist" button to video cards on playlist page\
|
- Added "Delete video from playlist" button to video cards on playlist page
|
||||||
- Improved channel cover quality
|
- Improved channel cover quality
|
||||||
- If available, shows localized titles and descriptions (based on "Search relevance language" parameter set in settings)
|
- If available, shows localized titles and descriptions (based on "Search relevance language" parameter set in settings)
|
||||||
- Updated russian localization
|
- Updated russian localization
|
||||||
|
|||||||
@@ -6,13 +6,14 @@ using YoutubeExplode.Models.MediaStreams;
|
|||||||
using Google.Apis.YouTube.v3.Data;
|
using Google.Apis.YouTube.v3.Data;
|
||||||
using FoxTube.Controls;
|
using FoxTube.Controls;
|
||||||
using FoxTube.Pages;
|
using FoxTube.Pages;
|
||||||
|
using Microsoft.AppCenter.Analytics;
|
||||||
|
|
||||||
namespace FoxTube
|
namespace FoxTube
|
||||||
{
|
{
|
||||||
public static class DownloadAgent
|
public static class DownloadAgent
|
||||||
{
|
{
|
||||||
public static List<DownloadItem> items = new List<DownloadItem>();
|
public static List<DownloadItem> Items { get; set; } = new List<DownloadItem>();
|
||||||
private static ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
|
private static readonly ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
|
||||||
public static Downloads Page { get; set; }
|
public static Downloads Page { get; set; }
|
||||||
public static StorageFolder Downloads { get; set; }
|
public static StorageFolder Downloads { get; set; }
|
||||||
|
|
||||||
@@ -21,45 +22,52 @@ namespace FoxTube
|
|||||||
Downloads = await KnownFolders.VideosLibrary.CreateFolderAsync("FoxTube", CreationCollisionOption.OpenIfExists);
|
Downloads = await KnownFolders.VideosLibrary.CreateFolderAsync("FoxTube", CreationCollisionOption.OpenIfExists);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
List<DownloadItemContainer> containers = JsonConvert.DeserializeObject<List<DownloadItemContainer>>((string)settings.Values["downloads"]);
|
List<DownloadItemContainer> containers = JsonConvert.DeserializeObject<List<DownloadItemContainer>>((string)settings.Values[$"downloads"]);
|
||||||
containers.ForEach(i => items.Add(new DownloadItem(i)));
|
containers.ForEach(i => Items.Add(new DownloadItem(i)));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Analytics.TrackEvent("Failed to load downloads history", new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "Exception", e.GetType().ToString() },
|
||||||
|
{ "Message", e.Message }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
catch { }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Add(MediaStreamInfo info, Video meta, string qualty)
|
public static void Add(MediaStreamInfo info, Video meta, string qualty)
|
||||||
{
|
{
|
||||||
items.Insert(0, new DownloadItem(info, meta, qualty));
|
Items.Insert(0, new DownloadItem(info, meta, qualty));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Remove(DownloadItem item)
|
public static void Remove(DownloadItem item)
|
||||||
{
|
{
|
||||||
try { Page.Remove(item); }
|
Page?.Remove(item);
|
||||||
catch { }
|
Items.Remove(item);
|
||||||
items.Remove(item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void Cancel(string id)
|
public static void Cancel(string id)
|
||||||
{
|
{
|
||||||
DownloadItem item = items.Find(i => i.Container.Id == id);
|
DownloadItem item = Items.Find(i => i.Container.Id == id);
|
||||||
if (item != null)
|
if (item != null)
|
||||||
item.Cancel();
|
item.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void QuitPrompt()
|
public static void QuitPrompt()
|
||||||
{
|
{
|
||||||
foreach (DownloadItem i in items.FindAll(i => !i.Container.IsDownloaded))
|
foreach (DownloadItem i in Items.FindAll(i => !i.Container.IsDownloaded))
|
||||||
{
|
{
|
||||||
i.Cancel();
|
i.Cancel();
|
||||||
items.Remove(i);
|
Items.Remove(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DownloadItemContainer> containers = new List<DownloadItemContainer>();
|
List<DownloadItemContainer> containers = new List<DownloadItemContainer>();
|
||||||
items.ForEach(i => containers.Add(i.Container));
|
Items.ForEach(i => containers.Add(i.Container));
|
||||||
|
|
||||||
string data = JsonConvert.SerializeObject(containers);
|
string data = JsonConvert.SerializeObject(containers);
|
||||||
|
|
||||||
settings.Values["downloads"] = data;
|
settings.Values[$"downloads"] = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Windows.Storage;
|
||||||
|
|
||||||
|
namespace FoxTube
|
||||||
|
{
|
||||||
|
public class HistoryItem
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
public TimeSpan LeftOn { get; set; } = TimeSpan.FromSeconds(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class HistorySet
|
||||||
|
{
|
||||||
|
public static List<HistoryItem> Items { get; set; } = new List<HistoryItem>();
|
||||||
|
|
||||||
|
public static void Update(HistoryItem item)
|
||||||
|
{
|
||||||
|
if (!SecretsVault.IsAuthorized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Items.RemoveAll(i => i.Id == item.Id);
|
||||||
|
|
||||||
|
Items.Insert(0, item);
|
||||||
|
if (Items.Count > 200)
|
||||||
|
Items.RemoveRange(200, Items.Count - 200);
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Delete(HistoryItem item)
|
||||||
|
{
|
||||||
|
if (!SecretsVault.IsAuthorized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Items.Remove(item);
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Clear()
|
||||||
|
{
|
||||||
|
if (!SecretsVault.IsAuthorized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Items.Clear();
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Save()
|
||||||
|
{
|
||||||
|
List<HistoryItem>[] parts = new List<HistoryItem>[4]
|
||||||
|
{
|
||||||
|
new List<HistoryItem>(), new List<HistoryItem>(),
|
||||||
|
new List<HistoryItem>(), new List<HistoryItem>()
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach(HistoryItem i in Items)
|
||||||
|
if (parts[0].Count < 50)
|
||||||
|
parts[0].Add(i);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (parts[1].Count < 50)
|
||||||
|
parts[1].Add(i);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (parts[2].Count < 50)
|
||||||
|
parts[2].Add(i);
|
||||||
|
else
|
||||||
|
parts[3].Add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int k = 0; k < parts.Length; k++)
|
||||||
|
ApplicationData.Current.RoamingSettings.Values[$"history-{SecretsVault.AccountId}-level{k}"] = JsonConvert.SerializeObject(parts[k]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Load()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 4; k++)
|
||||||
|
Items.AddRange(JsonConvert.DeserializeObject<List<HistoryItem>>(ApplicationData.Current.RoamingSettings.Values[$"history-{SecretsVault.AccountId}-level{k}"] as string));
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -59,11 +59,11 @@ namespace FoxTube.Classes
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public InboxItem(string version, string content, string timeStamp)
|
public InboxItem(string version, string content, DateTime timeStamp)
|
||||||
{
|
{
|
||||||
Type = InboxItemType.PatchNote;
|
Type = InboxItemType.PatchNote;
|
||||||
Content = content;
|
Content = content;
|
||||||
TimeStamp = DateTime.Parse(timeStamp);
|
TimeStamp = timeStamp;
|
||||||
Id = version;
|
Id = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using AngleSharp.Dom.Html;
|
using AngleSharp.Dom.Html;
|
||||||
using AngleSharp.Parser.Html;
|
using AngleSharp.Parser.Html;
|
||||||
using Google.Apis.YouTube.v3.Data;
|
using Google.Apis.YouTube.v3.Data;
|
||||||
|
using Microsoft.AppCenter.Analytics;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -23,17 +24,11 @@ namespace FoxTube.Controls.Player
|
|||||||
public static async Task<Uri> GetManifest(Video meta, VideoStreamInfo requestedQuality, MediaStreamInfoSet list)
|
public static async Task<Uri> GetManifest(Video meta, VideoStreamInfo requestedQuality, MediaStreamInfoSet list)
|
||||||
{
|
{
|
||||||
StorageFile manifest;
|
StorageFile manifest;
|
||||||
try
|
try { manifest = await roaming.CreateFileAsync("manifest.mpd", CreationCollisionOption.ReplaceExisting); }
|
||||||
{
|
catch { manifest = await roaming.CreateFileAsync("manifest.mpd", CreationCollisionOption.GenerateUniqueName); }
|
||||||
manifest = await roaming.CreateFileAsync("manifest.mpd", CreationCollisionOption.ReplaceExisting);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
manifest = await roaming.CreateFileAsync("manifest.mpd", CreationCollisionOption.GenerateUniqueName);
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
XmlDocument doc = new XmlDocument();
|
XmlDocument doc = new XmlDocument();
|
||||||
|
|
||||||
XmlElement mpd = doc.CreateElement("MPD");
|
XmlElement mpd = doc.CreateElement("MPD");
|
||||||
@@ -75,6 +70,13 @@ namespace FoxTube.Controls.Player
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
Analytics.TrackEvent("Failed to generate manifest", new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "Exception", e.GetType().ToString() },
|
||||||
|
{ "Message", e.Message },
|
||||||
|
{ "Video ID", meta.Id },
|
||||||
|
{ "Requested quality", requestedQuality.VideoQualityLabel }
|
||||||
|
});
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-79
@@ -1,4 +1,5 @@
|
|||||||
using FoxTube.Pages;
|
using FoxTube.Pages;
|
||||||
|
using Microsoft.AppCenter.Analytics;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -10,7 +11,6 @@ using System.Xml;
|
|||||||
using Windows.ApplicationModel.Core;
|
using Windows.ApplicationModel.Core;
|
||||||
using Windows.ApplicationModel.DataTransfer;
|
using Windows.ApplicationModel.DataTransfer;
|
||||||
using Windows.ApplicationModel.Resources;
|
using Windows.ApplicationModel.Resources;
|
||||||
using Windows.Storage;
|
|
||||||
using Windows.Storage.Streams;
|
using Windows.Storage.Streams;
|
||||||
using Windows.System;
|
using Windows.System;
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
@@ -21,64 +21,21 @@ using YoutubeExplode.Models.MediaStreams;
|
|||||||
|
|
||||||
namespace FoxTube
|
namespace FoxTube
|
||||||
{
|
{
|
||||||
public interface NavigationPage
|
public delegate void Event();
|
||||||
|
|
||||||
|
public delegate void ObjectEventHandler(object sender = null, params object[] args);
|
||||||
|
|
||||||
|
public interface INavigationPage
|
||||||
{
|
{
|
||||||
object Parameter { get; set; }
|
object Parameter { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class HistoryItem
|
|
||||||
{
|
|
||||||
public string Id { get; set; }
|
|
||||||
public TimeSpan LeftOn { get; set; } = TimeSpan.FromSeconds(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class HistorySet
|
|
||||||
{
|
|
||||||
public static List<HistoryItem> Items { get; set; } = new List<HistoryItem>();
|
|
||||||
|
|
||||||
public static void Update(HistoryItem item)
|
|
||||||
{
|
|
||||||
if(Items.Exists(i => i.Id == item.Id))
|
|
||||||
Items.RemoveAll(i => i.Id == item.Id);
|
|
||||||
|
|
||||||
Items.Insert(0, item);
|
|
||||||
Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Delete(HistoryItem item)
|
|
||||||
{
|
|
||||||
Items.Remove(item);
|
|
||||||
Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Clear()
|
|
||||||
{
|
|
||||||
Items.Clear();
|
|
||||||
Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Save()
|
|
||||||
{
|
|
||||||
try { ApplicationData.Current.RoamingSettings.Values[$"history-{SecretsVault.AccountId}"] = JsonConvert.SerializeObject(Items); }
|
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Load()
|
|
||||||
{
|
|
||||||
if (ApplicationData.Current.RoamingSettings.Values[$"history-{SecretsVault.AccountId}"] != null)
|
|
||||||
Items = JsonConvert.DeserializeObject<List<HistoryItem>>(ApplicationData.Current.RoamingSettings.Values[$"history-{SecretsVault.AccountId}"] as string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Methods
|
public static class Methods
|
||||||
{
|
{
|
||||||
private static ResourceLoader resources = ResourceLoader.GetForCurrentView("Methods");
|
private static readonly ResourceLoader resources = ResourceLoader.GetForCurrentView("Methods");
|
||||||
public static CommentsPage CommentsPage { get; set; }
|
|
||||||
|
|
||||||
public static MainPage MainPage
|
public static CommentsPage CommentsPage { get; set; }
|
||||||
{
|
public static MainPage MainPage => (Window.Current.Content as Frame).Content as MainPage;
|
||||||
get { return (Window.Current.Content as Frame).Content as MainPage; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void CloseApp()
|
public static void CloseApp()
|
||||||
{
|
{
|
||||||
@@ -87,20 +44,15 @@ namespace FoxTube
|
|||||||
|
|
||||||
public static Uri ToUri(this string url)
|
public static Uri ToUri(this string url)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(url))
|
return string.IsNullOrWhiteSpace(url) ? null : new Uri(url);
|
||||||
return null;
|
|
||||||
else
|
|
||||||
return new Uri(url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GuardFromNull(string str)
|
public static string GuardFromNull(string str)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(str))
|
return str ?? string.Empty;
|
||||||
return string.Empty;
|
|
||||||
else
|
|
||||||
return str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete]
|
||||||
public static string GetChars(this string str, int count)
|
public static string GetChars(this string str, int count)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -140,6 +92,7 @@ namespace FoxTube
|
|||||||
return array.ToList().FindAll(match);
|
return array.ToList().FindAll(match);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete]
|
||||||
public static string ReplaceInvalidChars(this string str, char newValue)
|
public static string ReplaceInvalidChars(this string str, char newValue)
|
||||||
{
|
{
|
||||||
foreach (char i in Path.GetInvalidFileNameChars())
|
foreach (char i in Path.GetInvalidFileNameChars())
|
||||||
@@ -147,6 +100,7 @@ namespace FoxTube
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete]
|
||||||
public static string Last(this string[] arr)
|
public static string Last(this string[] arr)
|
||||||
{
|
{
|
||||||
return arr[arr.Length - 1];
|
return arr[arr.Length - 1];
|
||||||
@@ -161,13 +115,18 @@ namespace FoxTube
|
|||||||
catch (FormatException)
|
catch (FormatException)
|
||||||
{
|
{
|
||||||
TimeSpan time = XmlConvert.ToTimeSpan("PT" + str.Split('T')[1]);
|
TimeSpan time = XmlConvert.ToTimeSpan("PT" + str.Split('T')[1]);
|
||||||
TimeSpan date = TimeSpan.FromDays(int.Parse(str.Split('W')[0].Replace("P", "")) * 7);
|
TimeSpan date = TimeSpan.FromDays(int.Parse(str.Split('W')[0].Remove('P')) * 7);
|
||||||
date.Add(time);
|
date.Add(time);
|
||||||
|
|
||||||
return date;
|
return date;
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
Analytics.TrackEvent("Failed to parse duration", new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "Exception", e.GetType().ToString() },
|
||||||
|
{ "Message", e.Message }
|
||||||
|
});
|
||||||
return TimeSpan.FromMilliseconds(0);
|
return TimeSpan.FromMilliseconds(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,7 +163,7 @@ namespace FoxTube
|
|||||||
return Math.Round(span.TotalDays / 365) + " " + resources.GetString("/Methods/years");
|
return Math.Round(span.TotalDays / 365) + " " + resources.GetString("/Methods/years");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FormatText(ref TextBlock block, string text)
|
public static void FormatText(this TextBlock block, string text)
|
||||||
{
|
{
|
||||||
block.Inlines.Clear();
|
block.Inlines.Clear();
|
||||||
Regex filter = new Regex(@"\b((?:https?://|www\.)\S+)|(\S+@\S+)\b", RegexOptions.IgnoreCase);
|
Regex filter = new Regex(@"\b((?:https?://|www\.)\S+)|(\S+@\S+)\b", RegexOptions.IgnoreCase);
|
||||||
@@ -268,10 +227,9 @@ namespace FoxTube
|
|||||||
|
|
||||||
public async static void ProcessLink(string url)
|
public async static void ProcessLink(string url)
|
||||||
{
|
{
|
||||||
string output;
|
|
||||||
string type;
|
string type;
|
||||||
|
|
||||||
if (YoutubeClient.TryParseChannelId(url, out output))
|
if (YoutubeClient.TryParseChannelId(url, out string output))
|
||||||
{
|
{
|
||||||
type = "channel";
|
type = "channel";
|
||||||
goto LinkFound;
|
goto LinkFound;
|
||||||
@@ -313,32 +271,23 @@ namespace FoxTube
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async void Share(DataRequestedEventArgs args, string thumbnail, string title, string url, string type)
|
public static void Share(DataRequestedEventArgs args, string thumbnail, string title, string url, string type)
|
||||||
{
|
{
|
||||||
DataRequest request = args.Request;
|
DataRequest request = args.Request;
|
||||||
|
|
||||||
request.Data.Properties.Title = title;
|
request.Data.Properties.Title = title;
|
||||||
request.Data.Properties.Description = $"{resources.GetString("/Methods/sharing")} {type}";
|
request.Data.Properties.Description = $"{resources.GetString("/Methods/sharing")} {type}";
|
||||||
|
|
||||||
request.Data.SetText(title + "\n" + "#YouTube #FoxTube #SharedWithFoxTube");
|
request.Data.SetText(title + "\n" + "#YouTube #FoxTube #SharedWithFoxTube");
|
||||||
request.Data.SetWebLink(url.ToUri());
|
request.Data.SetWebLink(url.ToUri());
|
||||||
|
|
||||||
DataRequestDeferral deferral = request.GetDeferral();
|
request.Data.Properties.Thumbnail = RandomAccessStreamReference.CreateFromUri(thumbnail.ToUri());
|
||||||
try
|
request.Data.SetBitmap(RandomAccessStreamReference.CreateFromUri(thumbnail.ToUri()));
|
||||||
{
|
|
||||||
StorageFile thumbnailFile = await StorageFile.CreateStreamedFileFromUriAsync("tempThumb.jpg", thumbnail.ToUri(), null);
|
|
||||||
request.Data.Properties.Thumbnail = RandomAccessStreamReference.CreateFromFile(thumbnailFile);
|
|
||||||
StorageFile imageFile = thumbnailFile;
|
|
||||||
|
|
||||||
request.Data.SetBitmap(RandomAccessStreamReference.CreateFromFile(imageFile));
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
deferral.Complete();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<List<string>> GetHistory()
|
public static async Task<List<string>> GetHistory()
|
||||||
{
|
{
|
||||||
|
SecretsVault.RefreshToken();
|
||||||
List<string> list = new List<string>();
|
List<string> list = new List<string>();
|
||||||
|
|
||||||
string output = await SecretsVault.HttpClient.GetStringAsync($"https://www.youtube.com/list_ajax?style=json&action_get_list=1&list=HL&hl={SettingsStorage.RelevanceLanguage}");
|
string output = await SecretsVault.HttpClient.GetStringAsync($"https://www.youtube.com/list_ajax?style=json&action_get_list=1&list=HL&hl={SettingsStorage.RelevanceLanguage}");
|
||||||
@@ -352,6 +301,7 @@ namespace FoxTube
|
|||||||
|
|
||||||
public static async Task<List<string>> GetLater()
|
public static async Task<List<string>> GetLater()
|
||||||
{
|
{
|
||||||
|
SecretsVault.RefreshToken();
|
||||||
List<string> list = new List<string>();
|
List<string> list = new List<string>();
|
||||||
|
|
||||||
string output = await SecretsVault.HttpClient.GetStringAsync($"https://www.youtube.com/list_ajax?style=json&action_get_list=1&list=WL&hl={SettingsStorage.RelevanceLanguage}");
|
string output = await SecretsVault.HttpClient.GetStringAsync($"https://www.youtube.com/list_ajax?style=json&action_get_list=1&list=WL&hl={SettingsStorage.RelevanceLanguage}");
|
||||||
|
|||||||
@@ -4,10 +4,6 @@ using static Google.Apis.YouTube.v3.SearchResource.ListRequest;
|
|||||||
|
|
||||||
namespace FoxTube
|
namespace FoxTube
|
||||||
{
|
{
|
||||||
public delegate void Event();
|
|
||||||
|
|
||||||
public delegate void ObjectEventHandler(object sender = null, params object[] args);
|
|
||||||
|
|
||||||
public class SearchParameters
|
public class SearchParameters
|
||||||
{
|
{
|
||||||
public class Filters
|
public class Filters
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ using System.Net.Http;
|
|||||||
using Google.Apis.Oauth2.v2.Data;
|
using Google.Apis.Oauth2.v2.Data;
|
||||||
using Google.Apis.Oauth2.v2;
|
using Google.Apis.Oauth2.v2;
|
||||||
using static Google.Apis.Auth.OAuth2.UwpCodeReceiver;
|
using static Google.Apis.Auth.OAuth2.UwpCodeReceiver;
|
||||||
|
using Microsoft.AppCenter.Analytics;
|
||||||
|
|
||||||
namespace FoxTube
|
namespace FoxTube
|
||||||
{
|
{
|
||||||
@@ -24,7 +25,7 @@ namespace FoxTube
|
|||||||
public static event ObjectEventHandler SubscriptionsChanged;
|
public static event ObjectEventHandler SubscriptionsChanged;
|
||||||
public static event ObjectEventHandler Purchased; //Rising when app finds out that it's not a PRO version
|
public static event ObjectEventHandler Purchased; //Rising when app finds out that it's not a PRO version
|
||||||
|
|
||||||
//Private properties
|
//Properties
|
||||||
private static ClientSecrets Secrets => new ClientSecrets()
|
private static ClientSecrets Secrets => new ClientSecrets()
|
||||||
{
|
{
|
||||||
ClientId = "349735264870-2ekqlm0a4mkg3mmrfcv90s3qp3o15dq0.apps.googleusercontent.com",
|
ClientId = "349735264870-2ekqlm0a4mkg3mmrfcv90s3qp3o15dq0.apps.googleusercontent.com",
|
||||||
@@ -41,15 +42,16 @@ namespace FoxTube
|
|||||||
ApplicationName = "FoxTube"
|
ApplicationName = "FoxTube"
|
||||||
};
|
};
|
||||||
public static YouTubeService Service => IsAuthorized ? new YouTubeService(Initializer) : NoAuthService;
|
public static YouTubeService Service => IsAuthorized ? new YouTubeService(Initializer) : NoAuthService;
|
||||||
|
|
||||||
public static HttpClient HttpClient { get; } = new HttpClient();
|
public static HttpClient HttpClient { get; } = new HttpClient();
|
||||||
private static bool TestAds => true; //Change this bool
|
private static bool TestAds => true; //TODO: Change this bool
|
||||||
public static string AppId => TestAds ? "d25517cb-12d4-4699-8bdc-52040c712cab" : "9ncqqxjtdlfh";
|
public static string AppId => TestAds ? "d25517cb-12d4-4699-8bdc-52040c712cab" : "9ncqqxjtdlfh";
|
||||||
public static string AdUnitId => TestAds ? "test" : "1100044398";
|
public static string AdUnitId => TestAds ? "test" : "1100044398";
|
||||||
public static bool AdsDisabled { get; private set; } = true;
|
public static bool AdsDisabled { get; private set; } = true;
|
||||||
|
|
||||||
//User info
|
//User info
|
||||||
public static bool IsAuthorized => Credential != null;
|
public static bool IsAuthorized => Credential != null;
|
||||||
private static UserCredential Credential { get; set; }
|
private static UserCredential Credential { get; set; } = null;
|
||||||
|
|
||||||
public static string AccountId => UserChannel?.Id;
|
public static string AccountId => UserChannel?.Id;
|
||||||
public static Channel UserChannel { get; private set; }
|
public static Channel UserChannel { get; private set; }
|
||||||
@@ -61,6 +63,11 @@ namespace FoxTube
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
public static void RefreshToken()
|
||||||
|
{
|
||||||
|
Credential?.RefreshTokenAsync(CancellationToken.None);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Subscribes or unsibscribes authorized user from the channel
|
/// Subscribes or unsibscribes authorized user from the channel
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -68,9 +75,6 @@ namespace FoxTube
|
|||||||
/// <returns>Returns 'true' if channel is in subscriptions now; 'false' if it's not</returns>
|
/// <returns>Returns 'true' if channel is in subscriptions now; 'false' if it's not</returns>
|
||||||
public static async Task<bool> ChangeSubscriptionState(string id)
|
public static async Task<bool> ChangeSubscriptionState(string id)
|
||||||
{
|
{
|
||||||
if (!IsAuthorized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(Subscriptions.Exists(x => x.Snippet.ResourceId.ChannelId == id))
|
if(Subscriptions.Exists(x => x.Snippet.ResourceId.ChannelId == id))
|
||||||
{
|
{
|
||||||
Subscription s = Subscriptions.Find(x => x.Snippet.ResourceId.ChannelId == id);
|
Subscription s = Subscriptions.Find(x => x.Snippet.ResourceId.ChannelId == id);
|
||||||
@@ -78,7 +82,7 @@ namespace FoxTube
|
|||||||
try { await Service.Subscriptions.Delete(s.Id).ExecuteAsync(); }
|
try { await Service.Subscriptions.Delete(s.Id).ExecuteAsync(); }
|
||||||
catch { return true; }
|
catch { return true; }
|
||||||
|
|
||||||
SubscriptionsChanged?.Invoke(null, "remove", s);
|
SubscriptionsChanged?.Invoke(null, "remove", s.Snippet.ResourceId.ChannelId);
|
||||||
Subscriptions.Remove(s);
|
Subscriptions.Remove(s);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -145,15 +149,19 @@ namespace FoxTube
|
|||||||
if (e.Message.Contains("UserCancel"))
|
if (e.Message.Contains("UserCancel"))
|
||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
throw e;
|
Analytics.TrackEvent("Failed to authorize", new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "Exception", e.GetType().ToString() },
|
||||||
|
{ "Message", e.Message }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Credential == null || !retrieveSubs)
|
if (Credential == null || !retrieveSubs)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SettingsStorage.HasAccount = true;
|
|
||||||
|
|
||||||
HttpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Credential.Token.AccessToken);
|
HttpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Credential.Token.AccessToken);
|
||||||
|
|
||||||
|
SettingsStorage.HasAccount = true;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -161,12 +169,8 @@ namespace FoxTube
|
|||||||
#region Retrieving user's data
|
#region Retrieving user's data
|
||||||
UserInfo = await new Oauth2Service(Initializer).Userinfo.Get().ExecuteAsync();
|
UserInfo = await new Oauth2Service(Initializer).Userinfo.Get().ExecuteAsync();
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
WatchLater = await Methods.GetLater();
|
WatchLater = await Methods.GetLater();
|
||||||
History = await Methods.GetHistory();
|
History = await Methods.GetHistory();
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
|
|
||||||
SubscriptionsResource.ListRequest subRequest = Service.Subscriptions.List("snippet");
|
SubscriptionsResource.ListRequest subRequest = Service.Subscriptions.List("snippet");
|
||||||
subRequest.Mine = true;
|
subRequest.Mine = true;
|
||||||
@@ -196,9 +200,14 @@ namespace FoxTube
|
|||||||
|
|
||||||
AuthorizationStateChanged?.Invoke(args: true);
|
AuthorizationStateChanged?.Invoke(args: true);
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
AuthorizationStateChanged?.Invoke(args: new bool?[] { null });
|
AuthorizationStateChanged?.Invoke(args: new bool?[] { null });
|
||||||
|
Analytics.TrackEvent("Failed to retrieve user's info", new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "Exception", e.GetType().ToString() },
|
||||||
|
{ "Message", e.Message }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,14 +226,19 @@ namespace FoxTube
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static async void Deauthenticate()
|
public static async void Deauthenticate()
|
||||||
{
|
{
|
||||||
if(await Credential.RevokeTokenAsync(CancellationToken.None))
|
if (!await Credential.RevokeTokenAsync(CancellationToken.None))
|
||||||
{
|
return;
|
||||||
|
|
||||||
Credential = null;
|
Credential = null;
|
||||||
|
UserChannel = null;
|
||||||
|
UserInfo = null;
|
||||||
|
History.Clear();
|
||||||
|
WatchLater.Clear();
|
||||||
|
Subscriptions.Clear();
|
||||||
|
ApplicationData.Current.RoamingSettings.Values["subscriptions"] = "";
|
||||||
|
|
||||||
AuthorizationStateChanged?.Invoke(args: false);
|
AuthorizationStateChanged?.Invoke(args: false);
|
||||||
SettingsStorage.HasAccount = false;
|
SettingsStorage.HasAccount = false;
|
||||||
|
|
||||||
ApplicationData.Current.RoamingSettings.Values["subscriptions"] = "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -249,32 +263,24 @@ namespace FoxTube
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
StoreContext store = StoreContext.GetDefault();
|
StoreProductQueryResult requset = await StoreContext.GetDefault().GetAssociatedStoreProductsAsync(new[] { "Durable" });
|
||||||
StoreProductQueryResult requset = await store.GetAssociatedStoreProductsAsync(new[] { "Durable" });
|
|
||||||
Dictionary<string, StoreProduct> l = new Dictionary<string, StoreProduct>();
|
if (requset.Products["9NP1QK556625"].IsInUserCollection)
|
||||||
requset.Products.ForEach(i => l.Add(i.Key, i.Value));
|
return;
|
||||||
|
|
||||||
if (!requset.Products["9NP1QK556625"].IsInUserCollection)
|
|
||||||
{
|
|
||||||
AdsDisabled = false;
|
AdsDisabled = false;
|
||||||
Purchased?.Invoke(null, false, requset.Products["9NP1QK556625"].Price.FormattedPrice);
|
Purchased?.Invoke(null, false, requset.Products["9NP1QK556625"].Price.FormattedPrice);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async void GetAdblock()
|
public static async void GetAdblock()
|
||||||
{
|
{
|
||||||
StoreContext store = StoreContext.GetDefault();
|
StorePurchaseResult request = await StoreContext.GetDefault().RequestPurchaseAsync("9NP1QK556625");
|
||||||
StorePurchaseResult request = await store.RequestPurchaseAsync("9NP1QK556625");
|
|
||||||
|
|
||||||
switch (request.Status)
|
switch (request.Status)
|
||||||
{
|
{
|
||||||
case StorePurchaseStatus.AlreadyPurchased:
|
case StorePurchaseStatus.AlreadyPurchased:
|
||||||
Purchased?.Invoke(args: true);
|
|
||||||
AdsDisabled = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StorePurchaseStatus.Succeeded:
|
case StorePurchaseStatus.Succeeded:
|
||||||
Purchased?.Invoke(args: true);
|
Purchased?.Invoke(args: true);
|
||||||
AdsDisabled = true;
|
AdsDisabled = true;
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using Newtonsoft.Json;
|
using Microsoft.AppCenter.Analytics;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Windows.ApplicationModel;
|
using Windows.ApplicationModel;
|
||||||
@@ -221,7 +223,7 @@ namespace FoxTube
|
|||||||
|
|
||||||
//Settings storage
|
//Settings storage
|
||||||
private static readonly ApplicationDataContainer storage = ApplicationData.Current.RoamingSettings;
|
private static readonly ApplicationDataContainer storage = ApplicationData.Current.RoamingSettings;
|
||||||
private static SettingsContainer Container;
|
private static SettingsContainer Container = new SettingsContainer();
|
||||||
|
|
||||||
public static void LoadData()
|
public static void LoadData()
|
||||||
{
|
{
|
||||||
@@ -229,10 +231,15 @@ namespace FoxTube
|
|||||||
{
|
{
|
||||||
Container = JsonConvert.DeserializeObject<SettingsContainer>(storage.Values["settings"] as string);
|
Container = JsonConvert.DeserializeObject<SettingsContainer>(storage.Values["settings"] as string);
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Container = new SettingsContainer();
|
|
||||||
SaveData();
|
SaveData();
|
||||||
|
if (storage.Values["settings"] != null)
|
||||||
|
Analytics.TrackEvent("Failed to retrieve settings", new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "Exception", e.GetType().ToString() },
|
||||||
|
{ "Message", e.Message }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,21 +13,14 @@ namespace FoxTube.Controls.Adverts
|
|||||||
{
|
{
|
||||||
NativeAdsManagerV2 manager = new NativeAdsManagerV2(SecretsVault.AppId, SecretsVault.AdUnitId);
|
NativeAdsManagerV2 manager = new NativeAdsManagerV2(SecretsVault.AppId, SecretsVault.AdUnitId);
|
||||||
public NativeAdV2 advert;
|
public NativeAdV2 advert;
|
||||||
public CardAdvert(bool isOnVideoPage = false)
|
public CardAdvert()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
if(!isOnVideoPage)
|
|
||||||
MainPage.VideoPageSizeChanged += Methods_VideoPageSizeChanged;
|
|
||||||
manager.AdReady += AdReady;
|
manager.AdReady += AdReady;
|
||||||
manager.ErrorOccurred += ErrorOccurred;
|
manager.ErrorOccurred += ErrorOccurred;
|
||||||
manager.RequestAd();
|
manager.RequestAd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Methods_VideoPageSizeChanged(object sender = null, params object[] args)
|
|
||||||
{
|
|
||||||
Visibility = !(bool)args[0] && advert != null ? Visibility.Visible : Visibility.Collapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ErrorOccurred(object sender, NativeAdErrorEventArgs e)
|
private void ErrorOccurred(object sender, NativeAdErrorEventArgs e)
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.WriteLine("Error has occured while loading ad");
|
System.Diagnostics.Debug.WriteLine("Error has occured while loading ad");
|
||||||
|
|||||||
@@ -9,22 +9,18 @@
|
|||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
d:DesignHeight="290"
|
d:DesignHeight="290"
|
||||||
d:DesignWidth="384"
|
d:DesignWidth="384"
|
||||||
|
MaxWidth="700"
|
||||||
Opacity="0"
|
Opacity="0"
|
||||||
Name="card">
|
Name="card"
|
||||||
|
SizeChanged="Card_SizeChanged">
|
||||||
|
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<Storyboard x:Name="show">
|
<Storyboard x:Name="show">
|
||||||
<DoubleAnimation Storyboard.TargetName="card" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="{StaticResource CardOpacityDuration}"/>
|
<DoubleAnimation Storyboard.TargetName="card" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="{StaticResource CardOpacityDuration}"/>
|
||||||
</Storyboard>
|
</Storyboard>
|
||||||
<Storyboard x:Name="hide">
|
|
||||||
<DoubleAnimation Storyboard.TargetName="card" Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="{StaticResource CardOpacityDuration}"/>
|
|
||||||
</Storyboard>
|
|
||||||
<Storyboard x:Name="showThumb">
|
<Storyboard x:Name="showThumb">
|
||||||
<DoubleAnimation Storyboard.TargetName="cover" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="{StaticResource CardOpacityDuration}"/>
|
<DoubleAnimation Storyboard.TargetName="cover" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="{StaticResource CardOpacityDuration}"/>
|
||||||
</Storyboard>
|
</Storyboard>
|
||||||
<Storyboard x:Name="hideThumb">
|
|
||||||
<DoubleAnimation Storyboard.TargetName="cover" Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="{StaticResource CardOpacityDuration}"/>
|
|
||||||
</Storyboard>
|
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
<Button Padding="0" Margin="1" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Click="Button_Click">
|
<Button Padding="0" Margin="1" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Click="Button_Click">
|
||||||
@@ -61,13 +57,13 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<TextBlock Height="75" Name="description" Grid.Row="2" Margin="10" Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin molestie vulputate leo, sed faucibus ex rutrum nec. Donec quis diam nisi. Suspendisse sollicitudin sapien quis eros vulputate, sed scelerisque enim ullamcorper. Donec vulputate commodo mi, vel vestibulum quam posuere ac. Curabitur ac nunc augue. Phasellus aliquam neque ac condimentum bibendum." TextWrapping="WrapWholeWords" TextTrimming="CharacterEllipsis"/>
|
<TextBlock Height="75" Name="description" Grid.Row="2" MaxLines="3" Margin="10,0" Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin molestie vulputate leo, sed faucibus ex rutrum nec. Donec quis diam nisi. Suspendisse sollicitudin sapien quis eros vulputate, sed scelerisque enim ullamcorper. Donec vulputate commodo mi, vel vestibulum quam posuere ac. Curabitur ac nunc augue. Phasellus aliquam neque ac condimentum bibendum." TextWrapping="WrapWholeWords" TextTrimming="CharacterEllipsis"/>
|
||||||
|
|
||||||
<TextBlock Grid.Row="3" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Height="50" Margin="10" TextAlignment="Center" Padding="0,16,0,0" Foreground="Gray">
|
<TextBlock Grid.Row="3" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Height="50" Margin="5" TextAlignment="Center" Padding="0,16,0,0" Foreground="Gray">
|
||||||
<Hyperlink Click="Hyperlink_Click"><Run x:Uid="/Cards/login">Log in</Run></Hyperlink> <Run x:Uid="/Cards/tomanage">to manage your subscriptions</Run>
|
<Hyperlink Click="Hyperlink_Click"><Run x:Uid="/Cards/login">Log in</Run></Hyperlink> <Run x:Uid="/Cards/tomanage">to manage your subscriptions</Run>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
|
|
||||||
<Grid Visibility="Collapsed" Grid.Row="3" VerticalAlignment="Stretch" Margin="10" Name="subscriptionPane" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}">
|
<Grid Visibility="Collapsed" Grid.Row="3" VerticalAlignment="Stretch" Margin="5" Name="subscriptionPane" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}">
|
||||||
<Button x:Uid="/Cards/subscribe" VerticalAlignment="Stretch" Click="subscribe_Click" Name="subscribe" HorizontalAlignment="Stretch" Height="50" Background="Red" Foreground="White" FontSize="18" FontWeight="SemiBold" Content="Subscirbe" Margin="0,0,0,0"/>
|
<Button x:Uid="/Cards/subscribe" VerticalAlignment="Stretch" Click="subscribe_Click" Name="subscribe" HorizontalAlignment="Stretch" Height="50" Background="Red" Foreground="White" FontSize="18" FontWeight="SemiBold" Content="Subscirbe" Margin="0,0,0,0"/>
|
||||||
<ToggleButton Name="notify" Height="50" Width="50" Visibility="Collapsed" FontFamily="Segoe MDL2 Assets" FontSize="18" FontWeight="SemiBold" Content="" Foreground="White" Background="Red" HorizontalAlignment="Right"/>
|
<ToggleButton Name="notify" Height="50" Width="50" Visibility="Collapsed" FontFamily="Segoe MDL2 Assets" FontSize="18" FontWeight="SemiBold" Content="" Foreground="White" Background="Red" HorizontalAlignment="Right"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -127,5 +127,10 @@ namespace FoxTube.Controls
|
|||||||
{
|
{
|
||||||
showThumb.Begin();
|
showThumb.Begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Card_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||||
|
{
|
||||||
|
Height = e.NewSize.Width * 0.75;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace FoxTube.Controls
|
|||||||
VerticalAlignment = VerticalAlignment.Top,
|
VerticalAlignment = VerticalAlignment.Top,
|
||||||
TextWrapping = TextWrapping.WrapWholeWords
|
TextWrapping = TextWrapping.WrapWholeWords
|
||||||
};
|
};
|
||||||
Methods.FormatText(ref block, message.Snippet.DisplayMessage);
|
block.FormatText(message.Snippet.DisplayMessage);
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ namespace FoxTube.Controls
|
|||||||
author.Text = comment.Snippet.TopLevelComment.Snippet.AuthorDisplayName;
|
author.Text = comment.Snippet.TopLevelComment.Snippet.AuthorDisplayName;
|
||||||
|
|
||||||
meta.Text = string.Format("{0} {1}", Methods.GetAgo(comment.Snippet.TopLevelComment.Snippet.PublishedAt.Value), comment.Snippet.TopLevelComment.Snippet.UpdatedAt != comment.Snippet.TopLevelComment.Snippet.PublishedAt ? resources.GetString("/CommentsPage/edited") : "");
|
meta.Text = string.Format("{0} {1}", Methods.GetAgo(comment.Snippet.TopLevelComment.Snippet.PublishedAt.Value), comment.Snippet.TopLevelComment.Snippet.UpdatedAt != comment.Snippet.TopLevelComment.Snippet.PublishedAt ? resources.GetString("/CommentsPage/edited") : "");
|
||||||
Methods.FormatText(ref text, comment.Snippet.TopLevelComment.Snippet.TextDisplay);
|
text.FormatText(comment.Snippet.TopLevelComment.Snippet.TextDisplay);
|
||||||
|
|
||||||
try { avatar.ProfilePicture = new BitmapImage(new Uri(comment.Snippet.TopLevelComment.Snippet.AuthorProfileImageUrl)) { DecodePixelWidth = 50, DecodePixelHeight = 50 }; }
|
try { avatar.ProfilePicture = new BitmapImage(new Uri(comment.Snippet.TopLevelComment.Snippet.AuthorProfileImageUrl)) { DecodePixelWidth = 50, DecodePixelHeight = 50 }; }
|
||||||
catch { }
|
catch { }
|
||||||
@@ -127,7 +127,7 @@ namespace FoxTube.Controls
|
|||||||
author.Text = comment.Snippet.AuthorDisplayName;
|
author.Text = comment.Snippet.AuthorDisplayName;
|
||||||
|
|
||||||
meta.Text = string.Format("{0} {1}", Methods.GetAgo(comment.Snippet.PublishedAt.Value), comment.Snippet.UpdatedAt != comment.Snippet.PublishedAt ? resources.GetString("/CommentsPage/edited") : "");
|
meta.Text = string.Format("{0} {1}", Methods.GetAgo(comment.Snippet.PublishedAt.Value), comment.Snippet.UpdatedAt != comment.Snippet.PublishedAt ? resources.GetString("/CommentsPage/edited") : "");
|
||||||
Methods.FormatText(ref text, comment.Snippet.TextDisplay);
|
text.FormatText(comment.Snippet.TextDisplay);
|
||||||
|
|
||||||
try { avatar.ProfilePicture = new BitmapImage(new Uri(comment.Snippet.AuthorProfileImageUrl)) { DecodePixelWidth = 50, DecodePixelHeight = 50 }; }
|
try { avatar.ProfilePicture = new BitmapImage(new Uri(comment.Snippet.AuthorProfileImageUrl)) { DecodePixelWidth = 50, DecodePixelHeight = 50 }; }
|
||||||
catch { }
|
catch { }
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<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"
|
||||||
|
xmlns:foxtube="using:FoxTube"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Frame x:Name="content" Navigating="Content_Navigating"/>
|
||||||
|
<foxtube:LoadingPage x:Name="loading" RefreshPage="Loading_RefreshPage" Visibility="Collapsed"/>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Windows.UI.Xaml.Navigation;
|
||||||
|
|
||||||
|
namespace FoxTube.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class ContentFrame : UserControl
|
||||||
|
{
|
||||||
|
public Frame Frame => content;
|
||||||
|
public LoadingPage LoadingPage => loading;
|
||||||
|
public event NavigatedEventHandler Navigated;
|
||||||
|
|
||||||
|
public ContentFrame()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
content.Navigated += (s, e) => Navigated?.Invoke(s, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Content_Navigating(object sender, NavigatingCancelEventArgs e)
|
||||||
|
{
|
||||||
|
loading.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Loading_RefreshPage(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
content.Navigate(content.CurrentSourcePageType, (content.Content as INavigationPage).Parameter);
|
||||||
|
content.BackStack.RemoveAt(content.BackStack.Count - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Refresh()
|
||||||
|
{
|
||||||
|
Loading_RefreshPage(this, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,7 +9,6 @@ using YoutubeExplode;
|
|||||||
using Windows.Storage;
|
using Windows.Storage;
|
||||||
using Google.Apis.YouTube.v3.Data;
|
using Google.Apis.YouTube.v3.Data;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Xml;
|
|
||||||
using Windows.UI.Popups;
|
using Windows.UI.Popups;
|
||||||
using Windows.UI.Notifications;
|
using Windows.UI.Notifications;
|
||||||
using Microsoft.Toolkit.Uwp.Notifications;
|
using Microsoft.Toolkit.Uwp.Notifications;
|
||||||
|
|||||||
@@ -412,25 +412,6 @@ namespace FoxTube
|
|||||||
{
|
{
|
||||||
ClosedCaptions = await new YoutubeClient().GetVideoClosedCaptionTrackInfosAsync(meta.Id);
|
ClosedCaptions = await new YoutubeClient().GetVideoClosedCaptionTrackInfosAsync(meta.Id);
|
||||||
|
|
||||||
/*foreach (MuxedStreamInfo i in MediaStreams.Muxed)
|
|
||||||
quality.Items.Add(new ComboBoxItem
|
|
||||||
{
|
|
||||||
Content = $"{i.VideoQualityLabel} (muxed)",
|
|
||||||
Tag = i
|
|
||||||
});
|
|
||||||
foreach (VideoStreamInfo i in MediaStreams.Video)
|
|
||||||
quality.Items.Add(new ComboBoxItem
|
|
||||||
{
|
|
||||||
Content = $"{i.VideoQualityLabel} (video-only)",
|
|
||||||
Tag = i
|
|
||||||
});
|
|
||||||
foreach (AudioStreamInfo i in MediaStreams.Audio)
|
|
||||||
quality.Items.Add(new ComboBoxItem
|
|
||||||
{
|
|
||||||
Content = $"{i.Bitrate} (audio-only)",
|
|
||||||
Tag = i
|
|
||||||
});*/
|
|
||||||
|
|
||||||
uint screenHeight = DisplayInformation.GetForCurrentView().ScreenHeightInRawPixels;
|
uint screenHeight = DisplayInformation.GetForCurrentView().ScreenHeightInRawPixels;
|
||||||
|
|
||||||
List<string> qualityList = MediaStreams.GetAllVideoQualityLabels().ToList();
|
List<string> qualityList = MediaStreams.GetAllVideoQualityLabels().ToList();
|
||||||
@@ -461,8 +442,8 @@ namespace FoxTube
|
|||||||
|
|
||||||
string s = SettingsStorage.VideoQuality == "remember" ? SettingsStorage.RememberedQuality : SettingsStorage.VideoQuality;
|
string s = SettingsStorage.VideoQuality == "remember" ? SettingsStorage.RememberedQuality : SettingsStorage.VideoQuality;
|
||||||
|
|
||||||
if (quality.Items.Any(i => (i as ComboBoxItem).Content as string == s))
|
if (quality.Items.Any(i => ((i as ComboBoxItem).Content as string).Contains(s)))
|
||||||
quality.SelectedItem = quality.Items.Find(i => (i as ComboBoxItem).Content as string == s);
|
quality.SelectedItem = quality.Items.Find(i => ((i as ComboBoxItem).Content as string).Contains(s));
|
||||||
else
|
else
|
||||||
quality.SelectedIndex = 0;
|
quality.SelectedIndex = 0;
|
||||||
|
|
||||||
@@ -518,5 +499,11 @@ namespace FoxTube
|
|||||||
quality.SelectedIndex = 0;
|
quality.SelectedIndex = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void PushAdvert()
|
||||||
|
{
|
||||||
|
if(State == PlayerDisplayState.Normal)
|
||||||
|
Advert.PushAdvert();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,20 +6,6 @@ using Google.Apis.YouTube.v3.Data;
|
|||||||
using Windows.UI.Xaml.Media.Imaging;
|
using Windows.UI.Xaml.Media.Imaging;
|
||||||
using Windows.Media;
|
using Windows.Media;
|
||||||
using Windows.Storage.Streams;
|
using Windows.Storage.Streams;
|
||||||
using YoutubeExplode.Models.MediaStreams;
|
|
||||||
using YoutubeExplode;
|
|
||||||
using System.IO;
|
|
||||||
using FoxTube.Classes;
|
|
||||||
using Windows.Media.Core;
|
|
||||||
using System.Linq;
|
|
||||||
using Windows.Media.Playback;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Windows.Media.Editing;
|
|
||||||
using Windows.Storage.Pickers;
|
|
||||||
using Windows.Storage;
|
|
||||||
using Windows.Media.MediaProperties;
|
|
||||||
using FoxTube.Controls.Player;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using Windows.UI.Xaml.Media;
|
using Windows.UI.Xaml.Media;
|
||||||
|
|
||||||
namespace FoxTube
|
namespace FoxTube
|
||||||
@@ -180,7 +166,7 @@ namespace FoxTube
|
|||||||
|
|
||||||
private void VideoSource_MarkerReached(object sender, TimelineMarkerRoutedEventArgs e)
|
private void VideoSource_MarkerReached(object sender, TimelineMarkerRoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Controls.Advert.PushAdvert();
|
Controls.PushAdvert();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,28 +4,23 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
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"
|
||||||
xmlns:Windows10version1809="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract, 7)"
|
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
d:DesignHeight="290"
|
d:DesignHeight="290"
|
||||||
d:DesignWidth="384"
|
d:DesignWidth="384"
|
||||||
|
MaxWidth="700"
|
||||||
Opacity="0"
|
Opacity="0"
|
||||||
Name="card">
|
Name="card"
|
||||||
|
SizeChanged="Card_SizeChanged">
|
||||||
|
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<Storyboard x:Name="show">
|
<Storyboard x:Name="show">
|
||||||
<DoubleAnimation Storyboard.TargetName="card" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="{StaticResource CardOpacityDuration}"/>
|
<DoubleAnimation Storyboard.TargetName="card" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="{StaticResource CardOpacityDuration}"/>
|
||||||
</Storyboard>
|
</Storyboard>
|
||||||
<Storyboard x:Name="hide">
|
|
||||||
<DoubleAnimation Storyboard.TargetName="card" Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="{StaticResource CardOpacityDuration}"/>
|
|
||||||
</Storyboard>
|
|
||||||
<Storyboard x:Name="showThumb">
|
<Storyboard x:Name="showThumb">
|
||||||
<DoubleAnimation Storyboard.TargetName="thumbnail" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="{StaticResource CardOpacityDuration}"/>
|
<DoubleAnimation Storyboard.TargetName="thumbnail" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="{StaticResource CardOpacityDuration}"/>
|
||||||
</Storyboard>
|
</Storyboard>
|
||||||
<Storyboard x:Name="hideThumb">
|
|
||||||
<DoubleAnimation Storyboard.TargetName="thumbnail" Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="{StaticResource CardOpacityDuration}"/>
|
|
||||||
</Storyboard>
|
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
<Button Padding="0" Margin="1" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Click="Button_Click">
|
<Button Padding="0" Margin="1" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Click="Button_Click">
|
||||||
|
|||||||
@@ -45,10 +45,8 @@ namespace FoxTube.Controls
|
|||||||
ChannelsResource.ListRequest r = SecretsVault.Service.Channels.List("snippet");
|
ChannelsResource.ListRequest r = SecretsVault.Service.Channels.List("snippet");
|
||||||
r.Id = item.Snippet.ChannelId;
|
r.Id = item.Snippet.ChannelId;
|
||||||
|
|
||||||
try { thumbnail.Source = new BitmapImage(item.Snippet.Thumbnails.Medium.Url.ToUri()); }
|
thumbnail.Source = new BitmapImage(item.Snippet.Thumbnails.Medium.Url.ToUri());
|
||||||
catch { }
|
avatar.ProfilePicture = new BitmapImage(new Uri((await r.ExecuteAsync()).Items[0].Snippet.Thumbnails.Medium.Url)) { DecodePixelWidth = 46, DecodePixelHeight = 46 };
|
||||||
try { avatar.ProfilePicture = new BitmapImage(new Uri((await r.ExecuteAsync()).Items[0].Snippet.Thumbnails.Medium.Url)) { DecodePixelWidth = 46, DecodePixelHeight = 46 }; }
|
|
||||||
catch { }
|
|
||||||
|
|
||||||
show.Begin();
|
show.Begin();
|
||||||
}
|
}
|
||||||
@@ -90,5 +88,10 @@ namespace FoxTube.Controls
|
|||||||
{
|
{
|
||||||
showThumb.Begin();
|
showThumb.Begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Card_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||||
|
{
|
||||||
|
Height = e.NewSize.Width * 0.75;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,22 +9,18 @@
|
|||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
d:DesignHeight="290"
|
d:DesignHeight="290"
|
||||||
d:DesignWidth="384"
|
d:DesignWidth="384"
|
||||||
|
MaxWidth="700"
|
||||||
Opacity="0"
|
Opacity="0"
|
||||||
Name="card">
|
Name="card"
|
||||||
|
SizeChanged="Card_SizeChanged">
|
||||||
|
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<Storyboard x:Name="show">
|
<Storyboard x:Name="show">
|
||||||
<DoubleAnimation Storyboard.TargetName="card" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="{StaticResource CardOpacityDuration}"/>
|
<DoubleAnimation Storyboard.TargetName="card" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="{StaticResource CardOpacityDuration}"/>
|
||||||
</Storyboard>
|
</Storyboard>
|
||||||
<Storyboard x:Name="hide">
|
|
||||||
<DoubleAnimation Storyboard.TargetName="card" Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="{StaticResource CardOpacityDuration}"/>
|
|
||||||
</Storyboard>
|
|
||||||
<Storyboard x:Name="showThumb">
|
<Storyboard x:Name="showThumb">
|
||||||
<DoubleAnimation Storyboard.TargetName="thumbnail" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="{StaticResource CardOpacityDuration}"/>
|
<DoubleAnimation Storyboard.TargetName="thumbnail" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="{StaticResource CardOpacityDuration}"/>
|
||||||
</Storyboard>
|
</Storyboard>
|
||||||
<Storyboard x:Name="hideThumb">
|
|
||||||
<DoubleAnimation Storyboard.TargetName="thumbnail" Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="{StaticResource CardOpacityDuration}"/>
|
|
||||||
</Storyboard>
|
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
<Button Padding="0" Margin="1" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Click="Button_Click">
|
<Button Padding="0" Margin="1" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Click="Button_Click">
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ using Windows.UI.Popups;
|
|||||||
using YoutubeExplode.Models.MediaStreams;
|
using YoutubeExplode.Models.MediaStreams;
|
||||||
using Windows.Foundation;
|
using Windows.Foundation;
|
||||||
using FoxTube.Pages;
|
using FoxTube.Pages;
|
||||||
|
using Windows.Networking.Connectivity;
|
||||||
|
|
||||||
namespace FoxTube.Controls
|
namespace FoxTube.Controls
|
||||||
{
|
{
|
||||||
@@ -25,7 +26,6 @@ namespace FoxTube.Controls
|
|||||||
ResourceLoader resources = ResourceLoader.GetForCurrentView("Cards");
|
ResourceLoader resources = ResourceLoader.GetForCurrentView("Cards");
|
||||||
|
|
||||||
public string playlistId;
|
public string playlistId;
|
||||||
public string videoId;
|
|
||||||
Video item;
|
Video item;
|
||||||
HistoryItem history;
|
HistoryItem history;
|
||||||
|
|
||||||
@@ -48,9 +48,7 @@ namespace FoxTube.Controls
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
videoId = id;
|
|
||||||
playlistId = playlist;
|
playlistId = playlist;
|
||||||
|
|
||||||
delete.Visibility = string.IsNullOrWhiteSpace(playlistId) ? Visibility.Collapsed : Visibility.Visible;
|
delete.Visibility = string.IsNullOrWhiteSpace(playlistId) ? Visibility.Collapsed : Visibility.Visible;
|
||||||
|
|
||||||
VideosResource.ListRequest request = SecretsVault.Service.Videos.List("snippet,contentDetails,statistics,liveStreamingDetails");
|
VideosResource.ListRequest request = SecretsVault.Service.Videos.List("snippet,contentDetails,statistics,liveStreamingDetails");
|
||||||
@@ -100,12 +98,10 @@ namespace FoxTube.Controls
|
|||||||
}
|
}
|
||||||
LoadAddTo();
|
LoadAddTo();
|
||||||
|
|
||||||
try { thumbnail.Source = new BitmapImage(item.Snippet.Thumbnails.Medium.Url.ToUri()); }
|
thumbnail.Source = new BitmapImage(item.Snippet.Thumbnails.Medium.Url.ToUri());
|
||||||
catch { }
|
avatar.ProfilePicture = new BitmapImage((await new YoutubeClient().GetChannelAsync(item.Snippet.ChannelId)).LogoUrl.ToUri()) { DecodePixelWidth = 46, DecodePixelHeight = 46 };
|
||||||
try { avatar.ProfilePicture = new BitmapImage((await new YoutubeClient().GetChannelAsync(item.Snippet.ChannelId)).LogoUrl.ToUri()) { DecodePixelWidth = 46, DecodePixelHeight = 46 }; }
|
|
||||||
catch { }
|
|
||||||
|
|
||||||
if (SecretsVault.History.Contains(videoId))
|
if (SecretsVault.History.Contains(item.Id))
|
||||||
watched.Visibility = Visibility.Visible;
|
watched.Visibility = Visibility.Visible;
|
||||||
if (HistorySet.Items.Exists(i => i.Id == item.Id))
|
if (HistorySet.Items.Exists(i => i.Id == item.Id))
|
||||||
{
|
{
|
||||||
@@ -123,7 +119,7 @@ namespace FoxTube.Controls
|
|||||||
{
|
{
|
||||||
{ "Exception", e.GetType().ToString() },
|
{ "Exception", e.GetType().ToString() },
|
||||||
{ "Message", e.Message },
|
{ "Message", e.Message },
|
||||||
{ "Video ID", videoId }
|
{ "Video ID", item.Id }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,7 +128,7 @@ namespace FoxTube.Controls
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MediaStreamInfoSet infoSet = await new YoutubeClient().GetVideoMediaStreamInfosAsync(videoId);
|
MediaStreamInfoSet infoSet = await new YoutubeClient().GetVideoMediaStreamInfosAsync(item.Id);
|
||||||
foreach (MuxedStreamInfo i in infoSet.Muxed)
|
foreach (MuxedStreamInfo i in infoSet.Muxed)
|
||||||
{
|
{
|
||||||
MenuFlyoutItem menuItem = new MenuFlyoutItem()
|
MenuFlyoutItem menuItem = new MenuFlyoutItem()
|
||||||
@@ -165,10 +161,16 @@ namespace FoxTube.Controls
|
|||||||
|
|
||||||
public async void LoadMeta()
|
public async void LoadMeta()
|
||||||
{
|
{
|
||||||
videoId = item.Id;
|
|
||||||
title.Text = item.Snippet.Title;
|
title.Text = item.Snippet.Title;
|
||||||
channelName.Text = item.Snippet.ChannelTitle;
|
channelName.Text = item.Snippet.ChannelTitle;
|
||||||
|
|
||||||
|
if (item.Snippet.Title == "Deleted video")
|
||||||
|
{
|
||||||
|
ContextFlyout = null;
|
||||||
|
show.Begin();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (item.Snippet.LiveBroadcastContent == "live")
|
if (item.Snippet.LiveBroadcastContent == "live")
|
||||||
{
|
{
|
||||||
views.Text = $"{item.LiveStreamingDetails.ConcurrentViewers:0,0} {resources.GetString("/Cards/viewers")}";
|
views.Text = $"{item.LiveStreamingDetails.ConcurrentViewers:0,0} {resources.GetString("/Cards/viewers")}";
|
||||||
@@ -197,12 +199,10 @@ namespace FoxTube.Controls
|
|||||||
info.Text = $"{item.ContentDetails.Duration.GetDuration()} | {Methods.GetAgo(item.Snippet.PublishedAt.Value)}";
|
info.Text = $"{item.ContentDetails.Duration.GetDuration()} | {Methods.GetAgo(item.Snippet.PublishedAt.Value)}";
|
||||||
}
|
}
|
||||||
|
|
||||||
try { thumbnail.Source = new BitmapImage(item.Snippet.Thumbnails.Medium.Url.ToUri()); }
|
thumbnail.Source = new BitmapImage(item.Snippet.Thumbnails.Medium.Url.ToUri());
|
||||||
catch { }
|
avatar.ProfilePicture = new BitmapImage((await new YoutubeClient().GetChannelAsync(item.Snippet.ChannelId)).LogoUrl.ToUri()) { DecodePixelHeight = 50, DecodePixelWidth = 50 };
|
||||||
try { avatar.ProfilePicture = new BitmapImage((await new YoutubeClient().GetChannelAsync(item.Snippet.ChannelId)).LogoUrl.ToUri()) { DecodePixelHeight = 50, DecodePixelWidth = 50 }; }
|
|
||||||
catch { }
|
|
||||||
|
|
||||||
if (SecretsVault.History.Contains(videoId))
|
if (SecretsVault.History.Contains(item.Id))
|
||||||
watched.Visibility = Visibility.Visible;
|
watched.Visibility = Visibility.Visible;
|
||||||
if (HistorySet.Items.Exists(i => i.Id == item.Id))
|
if (HistorySet.Items.Exists(i => i.Id == item.Id))
|
||||||
leftOn.Value = 100 * HistorySet.Items.Find(i => i.Id == item.Id).LeftOn.TotalSeconds / Methods.GetDuration(item.ContentDetails.Duration).TotalSeconds;
|
leftOn.Value = 100 * HistorySet.Items.Find(i => i.Id == item.Id).LeftOn.TotalSeconds / Methods.GetDuration(item.ContentDetails.Duration).TotalSeconds;
|
||||||
@@ -244,7 +244,44 @@ namespace FoxTube.Controls
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Methods.MainPage.GoToVideo(videoId, playlistId == "HL" ? null : playlistId, ((FrameworkElement)sender).Name == "incognito" ? true : false);
|
ConnectionCost connection = NetworkInformation.GetInternetConnectionProfile().GetConnectionCost();
|
||||||
|
if (SettingsStorage.CheckConnection && (connection.NetworkCostType == NetworkCostType.Fixed || connection.NetworkCostType == NetworkCostType.Variable))
|
||||||
|
{
|
||||||
|
MessageDialog dialog = new MessageDialog(resources.GetString("/Main/metered"))
|
||||||
|
{
|
||||||
|
DefaultCommandIndex = 2,
|
||||||
|
CancelCommandIndex = 1
|
||||||
|
};
|
||||||
|
dialog.Commands.Add(new UICommand(resources.GetString("/Main/yes"), null, false));
|
||||||
|
dialog.Commands.Add(new UICommand(resources.GetString("/Main/no"), null, true));
|
||||||
|
if(SecretsVault.IsAuthorized)
|
||||||
|
dialog.Commands.Add(new UICommand(resources.GetString("/Main/metered"), async (command) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PlaylistItem playlistItem = new PlaylistItem()
|
||||||
|
{
|
||||||
|
Snippet = new PlaylistItemSnippet()
|
||||||
|
{
|
||||||
|
ResourceId = new ResourceId()
|
||||||
|
{
|
||||||
|
Kind = "youtube#video",
|
||||||
|
VideoId = item.Id
|
||||||
|
},
|
||||||
|
PlaylistId = "WL"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
await SecretsVault.Service.PlaylistItems.Insert(playlistItem, "snippet").ExecuteAsync();
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}, true));
|
||||||
|
|
||||||
|
if ((bool)(await dialog.ShowAsync()).Id)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Methods.MainPage.GoToVideo(item.Id, playlistId == "HL" ? null : playlistId, ((FrameworkElement)sender).Name == "incognito" ? true : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Share(DataTransferManager sender, DataRequestedEventArgs args)
|
private void Share(DataTransferManager sender, DataRequestedEventArgs args)
|
||||||
@@ -252,7 +289,7 @@ namespace FoxTube.Controls
|
|||||||
Methods.Share(args,
|
Methods.Share(args,
|
||||||
item.Snippet.Thumbnails.Medium.Url,
|
item.Snippet.Thumbnails.Medium.Url,
|
||||||
item.Snippet.Title,
|
item.Snippet.Title,
|
||||||
$"https://www.youtube.com/watch?v={videoId}",
|
$"https://www.youtube.com/watch?v={item.Id}",
|
||||||
resources.GetString("/Cards/videoShare"));
|
resources.GetString("/Cards/videoShare"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,13 +307,13 @@ namespace FoxTube.Controls
|
|||||||
private void GetLink_Click(object sender, RoutedEventArgs e)
|
private void GetLink_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
DataPackage data = new DataPackage();
|
DataPackage data = new DataPackage();
|
||||||
data.SetText($"https://www.youtube.com/watch?v={videoId}");
|
data.SetText($"https://www.youtube.com/watch?v={item.Id}");
|
||||||
Clipboard.SetContent(data);
|
Clipboard.SetContent(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void InBrowser_Click(object sender, RoutedEventArgs e)
|
private async void InBrowser_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
await Launcher.LaunchUriAsync($"https://www.youtube.com/watch?v={videoId}".ToUri());
|
await Launcher.LaunchUriAsync($"https://www.youtube.com/watch?v={item.Id}".ToUri());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Thumbnail_ImageOpened(object sender, RoutedEventArgs e)
|
private void Thumbnail_ImageOpened(object sender, RoutedEventArgs e)
|
||||||
@@ -400,6 +437,8 @@ namespace FoxTube.Controls
|
|||||||
}
|
}
|
||||||
|
|
||||||
async void LoadAddTo()
|
async void LoadAddTo()
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (SecretsVault.UserChannel == null)
|
if (SecretsVault.UserChannel == null)
|
||||||
{
|
{
|
||||||
@@ -436,6 +475,11 @@ namespace FoxTube.Controls
|
|||||||
addTo.Items.Add(menuItem);
|
addTo.Items.Add(menuItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
addTo.Visibility = Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async void Item_Click(object sender, RoutedEventArgs e)
|
private async void Item_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -497,7 +541,7 @@ namespace FoxTube.Controls
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
HistorySet.Delete(history);
|
HistorySet.Delete(history);
|
||||||
(Methods.MainPage.PageContent as History).Delete(this);
|
(Methods.MainPage.PageContent.Frame.Content as History).Delete(this);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -512,12 +556,17 @@ namespace FoxTube.Controls
|
|||||||
|
|
||||||
await SecretsVault.Service.PlaylistItems.Delete(playlistItem.Id).ExecuteAsync();
|
await SecretsVault.Service.PlaylistItems.Delete(playlistItem.Id).ExecuteAsync();
|
||||||
|
|
||||||
(Methods.MainPage.PageContent as PlaylistPage).DeleteItem(this);
|
(Methods.MainPage.PageContent.Frame.Content as PlaylistPage).DeleteItem(this);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Card_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||||
|
{
|
||||||
|
Height = e.NewSize.Width * 0.75;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<PackageCertificateThumbprint>50B93E6A246058D555BA65CD203D7A02064A7409</PackageCertificateThumbprint>
|
<PackageCertificateThumbprint>50B93E6A246058D555BA65CD203D7A02064A7409</PackageCertificateThumbprint>
|
||||||
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
|
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
|
||||||
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
|
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
|
||||||
<AppxPackageDir>E:\XFox\Documents\FoxTube builds\0.5\</AppxPackageDir>
|
<AppxPackageDir>E:\XFox\Documents\FoxTube builds\0.6\</AppxPackageDir>
|
||||||
<AppxBundle>Always</AppxBundle>
|
<AppxBundle>Always</AppxBundle>
|
||||||
<AppxBundlePlatforms>x86|x64|arm</AppxBundlePlatforms>
|
<AppxBundlePlatforms>x86|x64|arm</AppxBundlePlatforms>
|
||||||
<AppInstallerUpdateFrequency>1</AppInstallerUpdateFrequency>
|
<AppInstallerUpdateFrequency>1</AppInstallerUpdateFrequency>
|
||||||
@@ -103,6 +103,7 @@
|
|||||||
<Compile Include="App.xaml.cs">
|
<Compile Include="App.xaml.cs">
|
||||||
<DependentUpon>App.xaml</DependentUpon>
|
<DependentUpon>App.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Classes\HistorySet.cs" />
|
||||||
<Compile Include="Classes\InboxItem.cs" />
|
<Compile Include="Classes\InboxItem.cs" />
|
||||||
<Compile Include="Classes\Methods.cs" />
|
<Compile Include="Classes\Methods.cs" />
|
||||||
<Compile Include="Classes\SearchPaameters.cs" />
|
<Compile Include="Classes\SearchPaameters.cs" />
|
||||||
@@ -130,6 +131,9 @@
|
|||||||
<DependentUpon>CommentCard.xaml</DependentUpon>
|
<DependentUpon>CommentCard.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Classes\DownloadAgent.cs" />
|
<Compile Include="Classes\DownloadAgent.cs" />
|
||||||
|
<Compile Include="Controls\ContentFrame.xaml.cs">
|
||||||
|
<DependentUpon>ContentFrame.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Controls\DownloadItem.xaml.cs">
|
<Compile Include="Controls\DownloadItem.xaml.cs">
|
||||||
<DependentUpon>DownloadItem.xaml</DependentUpon>
|
<DependentUpon>DownloadItem.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -309,6 +313,10 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Include="Controls\ContentFrame.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
<Page Include="Controls\DownloadItem.xaml">
|
<Page Include="Controls\DownloadItem.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3" IgnorableNamespaces="uap mp uap3">
|
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3" IgnorableNamespaces="uap mp uap3">
|
||||||
<Identity Name="53949MichaelXFoxGordeev.FoxTube" Publisher="CN=FD7A34DD-FE4D-4D7D-9D33-2DA9EBBE7725" Version="0.6.0.0" />
|
<Identity Name="53949MichaelXFoxGordeev.FoxTube" Publisher="CN=FD7A34DD-FE4D-4D7D-9D33-2DA9EBBE7725" Version="0.6.2.0" />
|
||||||
<mp:PhoneIdentity PhoneProductId="04fd81c1-6473-4174-afd7-4ac71dd85721" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
<mp:PhoneIdentity PhoneProductId="04fd81c1-6473-4174-afd7-4ac71dd85721" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||||
<Properties>
|
<Properties>
|
||||||
<DisplayName>FoxTube</DisplayName>
|
<DisplayName>FoxTube</DisplayName>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ namespace FoxTube.Pages
|
|||||||
public Home1()
|
public Home1()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
Methods.MainPage.PageContent.LoadingPage.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void Initialize()
|
public async void Initialize()
|
||||||
|
|||||||
@@ -8,30 +8,28 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:pages="using:FoxTube.Pages"
|
xmlns:pages="using:FoxTube.Pages"
|
||||||
xmlns:controls="using:FoxTube.Controls"
|
xmlns:controls="using:FoxTube.Controls"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d"
|
||||||
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
|
|
||||||
<Page.Resources>
|
<Page.Resources>
|
||||||
<Storyboard x:Name="showHeader">
|
<Storyboard x:Name="showHeader">
|
||||||
<DoubleAnimation Storyboard.TargetName="ColapsedHeader" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="{StaticResource CardOpacityDuration}"/>
|
<DoubleAnimation Storyboard.TargetName="ColapsedHeader" Storyboard.TargetProperty="Opacity" To="1" Duration="{StaticResource CardOpacityDuration}"/>
|
||||||
</Storyboard>
|
</Storyboard>
|
||||||
<Storyboard x:Name="hideHeader">
|
<Storyboard x:Name="hideHeader">
|
||||||
<DoubleAnimation Storyboard.TargetName="ColapsedHeader" Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="{StaticResource CardOpacityDuration}"/>
|
<DoubleAnimation Storyboard.TargetName="ColapsedHeader" Storyboard.TargetProperty="Opacity" To="0" Duration="{StaticResource CardOpacityDuration}"/>
|
||||||
</Storyboard>
|
</Storyboard>
|
||||||
<Storyboard x:Name="showThumb">
|
<Storyboard x:Name="showThumb">
|
||||||
<DoubleAnimation Storyboard.TargetName="channelCover" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="{StaticResource CardOpacityDuration}"/>
|
<DoubleAnimation Storyboard.TargetName="channelCover" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="{StaticResource CardOpacityDuration}"/>
|
||||||
</Storyboard>
|
</Storyboard>
|
||||||
<Storyboard x:Name="hideThumb">
|
|
||||||
<DoubleAnimation Storyboard.TargetName="channelCover" Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="{StaticResource CardOpacityDuration}"/>
|
|
||||||
</Storyboard>
|
|
||||||
</Page.Resources>
|
</Page.Resources>
|
||||||
|
|
||||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" SizeChanged="Grid_SizeChanged">
|
<Grid SizeChanged="Grid_SizeChanged">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition/>
|
<RowDefinition/>
|
||||||
<RowDefinition Height="auto"/>
|
<RowDefinition Height="auto"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<Pivot SelectedIndex="0" Name="content" IsHeaderItemsCarouselEnabled="False" SelectionChanged="Content_SelectionChanged">
|
<Pivot Name="content" IsHeaderItemsCarouselEnabled="False" SelectionChanged="Content_SelectionChanged">
|
||||||
<PivotItem x:Uid="/Channel/videos" Header="Videos">
|
<PivotItem x:Uid="/Channel/videos" Header="Videos">
|
||||||
<Grid>
|
<Grid>
|
||||||
<ParallaxView Source="{x:Bind videoScroll}" VerticalShift="100">
|
<ParallaxView Source="{x:Bind videoScroll}" VerticalShift="100">
|
||||||
@@ -40,27 +38,27 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</ParallaxView>
|
</ParallaxView>
|
||||||
<ScrollViewer ViewChanged="ScrollViewer_ViewChanged" Name="videoScroll">
|
<ScrollViewer ViewChanged="ScrollViewer_ViewChanged" Name="videoScroll">
|
||||||
<StackPanel Background="{ThemeResource AppBarBackgroundThemeBrush}" Margin="0,300,0,0" Name="infoStack" Visibility="Visible">
|
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Name="infoStack">
|
||||||
<Grid Name="infoPanel">
|
<Grid Name="infoPanel" Height="80">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="120"/>
|
<ColumnDefinition Width="120"/>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Ellipse HorizontalAlignment="Left" Margin="10,-40,0,0" Fill="Black" Width="100" Height="1"/>
|
<Ellipse Fill="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="5,-30,5,0"/>
|
||||||
<PersonPicture Name="avatar" HorizontalAlignment="Left" Margin="10,-40,0,0"/>
|
<PersonPicture Name="avatar" Margin="10,-30,10,0"/>
|
||||||
<StackPanel Grid.Column="1" Orientation="Vertical" Margin="10,0,0,5">
|
|
||||||
|
<StackPanel Grid.Column="1">
|
||||||
<TextBlock Name="title" FontWeight="SemiBold" FontSize="22" Text="Channel name"/>
|
<TextBlock Name="title" FontWeight="SemiBold" FontSize="22" Text="Channel name"/>
|
||||||
<TextBlock Name="subscribers" Foreground="Gray" Text="1,000,000 subscribers"/>
|
<TextBlock Name="subscribers" Foreground="Gray" Text="1,000,000 subscribers"/>
|
||||||
<TextBlock Name="videosCount" Foreground="Gray" Text="563,000 videos"/>
|
<TextBlock Name="videosCount" Foreground="Gray" Text="563,000 videos"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<TextBlock Grid.Column="2" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Height="50" Margin="10" TextAlignment="Center" Padding="0,16,0,0" Foreground="Gray">
|
|
||||||
|
<TextBlock x:Name="logIn" Grid.Column="2" VerticalAlignment="Center" Margin="10" Width="250" HorizontalTextAlignment="Center" Foreground="Gray">
|
||||||
<Hyperlink Click="Hyperlink_Click"><Run x:Uid="/Cards/login">Log in</Run></Hyperlink> <Run x:Uid="/Cards/tomanage">to manage your subscriptions</Run>
|
<Hyperlink Click="Hyperlink_Click"><Run x:Uid="/Cards/login">Log in</Run></Hyperlink> <Run x:Uid="/Cards/tomanage">to manage your subscriptions</Run>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
|
|
||||||
<Grid Visibility="Collapsed" Grid.Column="2" VerticalAlignment="Bottom" Margin="10" Name="subscriptionPane" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
<Button Visibility="Collapsed" x:Name="subscribe" x:Uid="/Cards/subscribe" Grid.Column="2" Content="Subscribe" Height="50" Width="250" Margin="10" VerticalAlignment="Center" FontSize="18" FontWeight="SemiBold" Foreground="White" Background="Red"/>
|
||||||
<Button x:Uid="/Cards/subscribe" Click="Subscribe_Click" Name="subscribe" Width="250" Height="50" Background="Red" Foreground="White" FontSize="18" FontWeight="SemiBold" Content="Subscirbe"/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<pages:VideoGrid x:Name="videoList"/>
|
<pages:VideoGrid x:Name="videoList"/>
|
||||||
<controls:ShowMore Clicked="VideoMore_Clicked" x:Name="videoMore"/>
|
<controls:ShowMore Clicked="VideoMore_Clicked" x:Name="videoMore"/>
|
||||||
@@ -69,30 +67,30 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</PivotItem>
|
</PivotItem>
|
||||||
<PivotItem x:Uid="/Channel/playlists" Header="Playlists">
|
<PivotItem x:Uid="/Channel/playlists" Header="Playlists">
|
||||||
<ScrollViewer>
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<StackPanel Margin="10" Visibility="Visible">
|
<ScrollViewer>
|
||||||
|
<StackPanel>
|
||||||
<pages:VideoGrid x:Name="playlistList"/>
|
<pages:VideoGrid x:Name="playlistList"/>
|
||||||
<controls:ShowMore Clicked="ShowMorePlaylists_Click" x:Name="playlistMore"/>
|
<controls:ShowMore Clicked="ShowMorePlaylists_Click" x:Name="playlistMore"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<local:LoadingPage Visibility="Collapsed" x:Name="playlistLoading"/>
|
|
||||||
</Grid>
|
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
<local:LoadingPage Visibility="Collapsed" x:Name="playlistLoading" RefreshPage="Refresh_Click"/>
|
||||||
|
</Grid>
|
||||||
</PivotItem>
|
</PivotItem>
|
||||||
<PivotItem x:Uid="/Channel/about" Header="About channel">
|
<PivotItem x:Uid="/Channel/about" Header="About channel">
|
||||||
<ScrollViewer>
|
<ScrollViewer>
|
||||||
<TextBlock Name="description" TextWrapping="WrapWholeWords" Margin="10" IsTextSelectionEnabled="True" Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum justo erat, dapibus sit amet maximus eget, volutpat non turpis. Suspendisse. "/>
|
<TextBlock Name="description" TextWrapping="WrapWholeWords" IsTextSelectionEnabled="True" Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum justo erat, dapibus sit amet maximus eget, volutpat non turpis. Suspendisse."/>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</PivotItem>
|
</PivotItem>
|
||||||
|
|
||||||
<Pivot.RightHeader>
|
<Pivot.RightHeader>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal" Margin="10,0">
|
||||||
<StackPanel Orientation="Horizontal" Name="ColapsedHeader" Opacity="0">
|
<StackPanel Orientation="Horizontal" Name="ColapsedHeader" Opacity="0" Margin="10,0">
|
||||||
<PersonPicture Height="32" Name="collapsedAvatar"/>
|
<PersonPicture Height="32" Name="collapsedAvatar"/>
|
||||||
<TextBlock Text="Channel name" VerticalAlignment="Center" Margin="10,0" Name="collapsedTitle"/>
|
<TextBlock Text="Channel name" VerticalAlignment="Center" Margin="10,0" Name="collapsedTitle"/>
|
||||||
<Button x:Uid="/Cards/subscribe" Background="Red" Foreground="White" FontWeight="SemiBold" Content="Subscribe" Width="150" Name="collapsedBtn" Click="Subscribe_Click" Padding="2"/>
|
<Button x:Uid="/Cards/subscribe" Background="Red" Foreground="White" FontWeight="SemiBold" Content="Subscribe" Width="150" Name="collapsedBtn" Click="Subscribe_Click" Padding="2" Visibility="Collapsed"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<AutoSuggestBox FontSize="14" x:Uid="/Channel/search" VerticalAlignment="Center" Width="250" Margin="8" PlaceholderText="Search on channel" QueryIcon="Find" Name="search" QuerySubmitted="AutoSuggestBox_QuerySubmitted"/>
|
<AutoSuggestBox x:Uid="/Channel/search" VerticalAlignment="Center" Width="250" PlaceholderText="Search on channel" QueryIcon="Find" Name="search" QuerySubmitted="AutoSuggestBox_QuerySubmitted"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Pivot.RightHeader>
|
</Pivot.RightHeader>
|
||||||
</Pivot>
|
</Pivot>
|
||||||
@@ -102,7 +100,5 @@
|
|||||||
<AppBarButton x:Uid="/Channel/refresh" Icon="Refresh" Label="Refresh" Name="refresh" Click="Refresh_Click"/>
|
<AppBarButton x:Uid="/Channel/refresh" Icon="Refresh" Label="Refresh" Name="refresh" Click="Refresh_Click"/>
|
||||||
<AppBarButton x:Uid="/Channel/share" Icon="Share" Label="Share" Name="share" Click="Share_Click"/>
|
<AppBarButton x:Uid="/Channel/share" Icon="Share" Label="Share" Name="share" Click="Share_Click"/>
|
||||||
</CommandBar>
|
</CommandBar>
|
||||||
|
|
||||||
<local:LoadingPage Grid.RowSpan="2" Visibility="Collapsed" x:Name="loading" RefreshPage="Refresh_Click"/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
@@ -21,12 +21,11 @@ namespace FoxTube.Pages
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Channel page
|
/// Channel page
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class ChannelPage : Page, NavigationPage
|
public sealed partial class ChannelPage : Page, INavigationPage
|
||||||
{
|
{
|
||||||
public object Parameter { get; set; } = null;
|
public object Parameter { get; set; } = null;
|
||||||
readonly ResourceLoader resources = ResourceLoader.GetForCurrentView("Cards");
|
readonly ResourceLoader resources = ResourceLoader.GetForCurrentView("Cards");
|
||||||
|
|
||||||
public string channelId;
|
|
||||||
public Channel item;
|
public Channel item;
|
||||||
|
|
||||||
SearchResource.ListRequest request;
|
SearchResource.ListRequest request;
|
||||||
@@ -37,35 +36,22 @@ namespace FoxTube.Pages
|
|||||||
public ChannelPage()
|
public ChannelPage()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
DataTransferManager.GetForCurrentView().DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(Share);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnNavigatedTo(e);
|
base.OnNavigatedTo(e);
|
||||||
|
|
||||||
Parameter = e.Parameter;
|
Parameter = e.Parameter;
|
||||||
if ((string)e.Parameter == null)
|
|
||||||
loading.Error("NullReferenceException", "Unable to initialize search. Search term is not stated.");
|
|
||||||
else
|
|
||||||
Initialize(e.Parameter as string);
|
Initialize(e.Parameter as string);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void Initialize(string id)
|
public async void Initialize(string id)
|
||||||
{
|
{
|
||||||
loading.Refresh();
|
|
||||||
playlistLoading.Refresh();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (id == SecretsVault.AccountId)
|
|
||||||
{
|
|
||||||
infoPanel.ColumnDefinitions[2].Width = new GridLength(0);
|
|
||||||
collapsedBtn.Visibility = Visibility.Collapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
ChannelsResource.ListRequest infoRequest = SecretsVault.Service.Channels.List("snippet,statistics,brandingSettings");
|
ChannelsResource.ListRequest infoRequest = SecretsVault.Service.Channels.List("snippet,statistics,brandingSettings");
|
||||||
infoRequest.Id = channelId = id;
|
infoRequest.Id = id;
|
||||||
|
|
||||||
item = (await infoRequest.ExecuteAsync()).Items[0];
|
item = (await infoRequest.ExecuteAsync()).Items[0];
|
||||||
|
|
||||||
@@ -73,14 +59,13 @@ namespace FoxTube.Pages
|
|||||||
subscribers.Text = $"{item.Statistics.SubscriberCount:0,0} {resources.GetString("/Cards/subscribers")}";
|
subscribers.Text = $"{item.Statistics.SubscriberCount:0,0} {resources.GetString("/Cards/subscribers")}";
|
||||||
videosCount.Text = $"{item.Statistics.VideoCount:0,0} {resources.GetString("/Cards/videos")}";
|
videosCount.Text = $"{item.Statistics.VideoCount:0,0} {resources.GetString("/Cards/videos")}";
|
||||||
|
|
||||||
if (!item.BrandingSettings.Image.BannerImageUrl.Contains("default"))
|
if (item.BrandingSettings != null && !item.BrandingSettings.Image.BannerImageUrl.Contains("default"))
|
||||||
try { channelCover.Source = new BitmapImage(item.BrandingSettings.Image.BannerTabletExtraHdImageUrl == null ? item.BrandingSettings.Image.BannerImageUrl.ToUri() : item.BrandingSettings.Image.BannerTabletHdImageUrl.ToUri()); }
|
channelCover.Source = new BitmapImage(item.BrandingSettings.Image.BannerTabletExtraHdImageUrl == null ?
|
||||||
catch { }
|
item.BrandingSettings.Image.BannerImageUrl.ToUri() : item.BrandingSettings.Image.BannerTabletHdImageUrl.ToUri());
|
||||||
|
|
||||||
try { avatar.ProfilePicture = collapsedAvatar.ProfilePicture = new BitmapImage(item.Snippet.Thumbnails.Medium.Url.ToUri()) { DecodePixelHeight = 100, DecodePixelWidth = 100 }; }
|
avatar.ProfilePicture = collapsedAvatar.ProfilePicture = new BitmapImage(item.Snippet.Thumbnails.Medium.Url.ToUri()) { DecodePixelHeight = 100, DecodePixelWidth = 100 };
|
||||||
catch { }
|
|
||||||
|
|
||||||
Methods.FormatText(ref description, item.Snippet.Description);
|
description.FormatText(item.Snippet.Description);
|
||||||
|
|
||||||
request = SecretsVault.Service.Search.List("id");
|
request = SecretsVault.Service.Search.List("id");
|
||||||
request.ChannelId = id;
|
request.ChannelId = id;
|
||||||
@@ -100,34 +85,42 @@ namespace FoxTube.Pages
|
|||||||
|
|
||||||
if (SecretsVault.IsAuthorized)
|
if (SecretsVault.IsAuthorized)
|
||||||
{
|
{
|
||||||
if (SecretsVault.Subscriptions.Any(i => i.Snippet.ResourceId.ChannelId == channelId))
|
logIn.Visibility = Visibility.Collapsed;
|
||||||
|
if (SecretsVault.Subscriptions.Any(i => i.Snippet.ResourceId.ChannelId == item.Id))
|
||||||
{
|
{
|
||||||
subscribe.Background = new SolidColorBrush(Colors.Transparent);
|
subscribe.Background = Background;
|
||||||
subscribe.Foreground = new SolidColorBrush(Colors.Gray);
|
subscribe.Foreground = new SolidColorBrush(Colors.Gray);
|
||||||
subscribe.Content = resources.GetString("/Cards/unsubscribe");
|
subscribe.Content = resources.GetString("/Cards/unsubscribe");
|
||||||
collapsedBtn.Visibility = Visibility.Collapsed;
|
|
||||||
}
|
}
|
||||||
subscriptionPane.Visibility = Visibility.Visible;
|
else
|
||||||
|
collapsedBtn.Visibility = Visibility.Visible;
|
||||||
|
subscribe.Visibility = Visibility.Visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
loading.Close();
|
if (id == SecretsVault.AccountId)
|
||||||
|
{
|
||||||
|
infoPanel.ColumnDefinitions[2].Width = new GridLength(0);
|
||||||
|
collapsedBtn.Visibility = Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollViewer_ViewChanged(this, null);
|
||||||
|
|
||||||
|
Methods.MainPage.PageContent.LoadingPage.Close();
|
||||||
}
|
}
|
||||||
catch (System.Net.Http.HttpRequestException)
|
catch (System.Net.Http.HttpRequestException)
|
||||||
{
|
{
|
||||||
loading.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
Methods.MainPage.PageContent.LoadingPage.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
loading.Error(e.GetType().ToString(), e.Message);
|
Methods.MainPage.PageContent.LoadingPage.Error(e.GetType().ToString(), e.Message);
|
||||||
Analytics.TrackEvent("Channel loading error", new Dictionary<string, string>()
|
Analytics.TrackEvent("Channel loading error", new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "Exception", e.GetType().ToString() },
|
{ "Exception", e.GetType().ToString() },
|
||||||
{ "Message", e.Message },
|
{ "Message", e.Message },
|
||||||
{ "Channel ID", channelId }
|
{ "Channel ID", item.Id }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollViewer_ViewChanged(this, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async void LoadPlaylist()
|
async void LoadPlaylist()
|
||||||
@@ -162,7 +155,7 @@ namespace FoxTube.Pages
|
|||||||
{
|
{
|
||||||
{ "Exception", e.GetType().ToString() },
|
{ "Exception", e.GetType().ToString() },
|
||||||
{ "Message", e.Message },
|
{ "Message", e.Message },
|
||||||
{ "Channel ID", channelId }
|
{ "Channel ID", item.Id }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,9 +209,9 @@ namespace FoxTube.Pages
|
|||||||
|
|
||||||
private async void Subscribe_Click(object sender, RoutedEventArgs e)
|
private async void Subscribe_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if(await SecretsVault.ChangeSubscriptionState(channelId))
|
if(await SecretsVault.ChangeSubscriptionState(item.Id))
|
||||||
{
|
{
|
||||||
subscribe.Background = new SolidColorBrush(Colors.Transparent);
|
subscribe.Background = Background;
|
||||||
subscribe.Foreground = new SolidColorBrush(Colors.Gray);
|
subscribe.Foreground = new SolidColorBrush(Colors.Gray);
|
||||||
subscribe.Content = resources.GetString("/Cards/unsubscribe");
|
subscribe.Content = resources.GetString("/Cards/unsubscribe");
|
||||||
collapsedBtn.Visibility = Visibility.Collapsed;
|
collapsedBtn.Visibility = Visibility.Collapsed;
|
||||||
@@ -239,19 +232,19 @@ namespace FoxTube.Pages
|
|||||||
|
|
||||||
private void AutoSuggestBox_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
|
private void AutoSuggestBox_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
|
||||||
{
|
{
|
||||||
if(search.Text.Length > 2)
|
if (search.Text.Length < 3)
|
||||||
{
|
return;
|
||||||
|
|
||||||
if (content.Items.Count < 4)
|
if (content.Items.Count < 4)
|
||||||
content.Items.Add(new PivotItem()
|
content.Items.Add(new PivotItem()
|
||||||
{
|
{
|
||||||
Header = resources.GetString("/Channel/searchHeader"),
|
Header = resources.GetString("/Channel/searchHeader"),
|
||||||
Content = new Search()
|
Content = new ContentFrame()
|
||||||
});
|
});
|
||||||
|
|
||||||
((content.Items[3] as PivotItem).Content as Search).Initialize(new SearchParameters(search.Text, item.Id));
|
((content.Items[3] as PivotItem).Content as ContentFrame).Frame.Navigate(typeof(Search), new object[] { new SearchParameters(search.Text, item.Id), (content.Items[3] as PivotItem).Content as ContentFrame });
|
||||||
content.SelectedIndex = 3;
|
content.SelectedIndex = 3;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void ScrollViewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
|
private void ScrollViewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -259,20 +252,14 @@ namespace FoxTube.Pages
|
|||||||
Rect view = new Rect(0.0, 0.0, videoScroll.ActualWidth, videoScroll.ActualHeight);
|
Rect view = new Rect(0.0, 0.0, videoScroll.ActualWidth, videoScroll.ActualHeight);
|
||||||
|
|
||||||
if (view.Contains(new Point(panel.Left, panel.Bottom)))
|
if (view.Contains(new Point(panel.Left, panel.Bottom)))
|
||||||
{
|
|
||||||
if (ColapsedHeader.Opacity == 1)
|
|
||||||
hideHeader.Begin();
|
hideHeader.Begin();
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
if (ColapsedHeader.Opacity == 0)
|
|
||||||
showHeader.Begin();
|
showHeader.Begin();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void Refresh_Click(object sender, RoutedEventArgs e)
|
private void Refresh_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Methods.MainPage.GoToChannel(channelId);
|
Methods.MainPage.PageContent.Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void InBrowser_Click(object sender, RoutedEventArgs e)
|
private async void InBrowser_Click(object sender, RoutedEventArgs e)
|
||||||
@@ -282,6 +269,7 @@ namespace FoxTube.Pages
|
|||||||
|
|
||||||
private void Share_Click(object sender, RoutedEventArgs e)
|
private void Share_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
DataTransferManager.GetForCurrentView().DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(Share);
|
||||||
DataTransferManager.ShowShareUI();
|
DataTransferManager.ShowShareUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,32 +5,27 @@
|
|||||||
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"
|
||||||
xmlns:controls="using:FoxTube.Controls"
|
xmlns:controls="using:FoxTube.Controls"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d">
|
||||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
|
||||||
|
|
||||||
<Grid>
|
<Grid x:Name="grid">
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="auto"/>
|
|
||||||
<RowDefinition/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<Grid Name="grid">
|
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="auto"/>
|
<RowDefinition Height="auto"/>
|
||||||
<RowDefinition Height="30"/>
|
<RowDefinition Height="30"/>
|
||||||
|
<RowDefinition/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<TextBox x:Uid="/CommentsPage/textbox" Margin="5,5,42,5" PlaceholderText="Add a public comment" Name="newComment" VerticalAlignment="Center" MinHeight="32" TextWrapping="Wrap" AcceptsReturn="True"/>
|
<TextBox x:Uid="/CommentsPage/textbox" PlaceholderText="Add a public comment" Name="newComment" MinHeight="32" TextWrapping="Wrap" AcceptsReturn="True" Margin="0,0,40,0"/>
|
||||||
<Button HorizontalAlignment="Right" Name="send" Click="send_Click" VerticalAlignment="Top"
|
<Button HorizontalAlignment="Right" Name="send" Click="send_Click" VerticalAlignment="Top"
|
||||||
Height="32" Width="32"
|
Height="32" Width="32"
|
||||||
Margin="0,5,5,0" Padding="0"
|
Margin="5,0" Padding="0"
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
FontFamily="Segoe MDL2 Assets"
|
FontFamily="Segoe MDL2 Assets"
|
||||||
Content="" FontSize="30"/>
|
Content="" FontSize="30"/>
|
||||||
<ProgressBar Name="sending" IsIndeterminate="True" Foreground="Red" Visibility="Collapsed" VerticalAlignment="Bottom" HorizontalAlignment="Stretch"/>
|
<ProgressBar Name="sending" IsIndeterminate="True" Visibility="Collapsed" VerticalAlignment="Bottom" HorizontalAlignment="Stretch"/>
|
||||||
|
|
||||||
<TextBlock Name="counter" Grid.Row="1" Text="[Comments count] Comments" Margin="5,0,0,0" VerticalAlignment="Center" FontWeight="SemiBold"/>
|
<TextBlock Name="counter" Grid.Row="1" Text="[Comments count] Comments" VerticalAlignment="Center" FontWeight="SemiBold"/>
|
||||||
<StackPanel Padding="0" Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,0,10,0">
|
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||||
<TextBlock x:Uid="/CommentsPage/sortBy" Text="Sort by: " VerticalAlignment="Center" Margin="0,0,5,0"/>
|
<TextBlock x:Uid="/CommentsPage/sortBy" Text="Sort by: " VerticalAlignment="Center"/>
|
||||||
<Button Name="orderBtn" Background="Transparent" Content="Relevance" Foreground="Red" Padding="0" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,3">
|
<Button Name="orderBtn" Background="Transparent" Content="Relevance" Foreground="Red" Padding="0" VerticalAlignment="Bottom" Margin="5,3">
|
||||||
|
|
||||||
<Button.Flyout>
|
<Button.Flyout>
|
||||||
<MenuFlyout>
|
<MenuFlyout>
|
||||||
@@ -40,17 +35,17 @@
|
|||||||
</Button.Flyout>
|
</Button.Flyout>
|
||||||
</Button>
|
</Button>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<ScrollViewer Grid.Row="1" Name="scroll">
|
<ScrollViewer Grid.Row="2" Name="scroll">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<StackPanel Name="placeholder">
|
<StackPanel x:Name="list">
|
||||||
<StackPanel.ChildrenTransitions>
|
<StackPanel.ChildrenTransitions>
|
||||||
<TransitionCollection>
|
<TransitionCollection>
|
||||||
<EntranceThemeTransition IsStaggeringEnabled="True"/>
|
<EntranceThemeTransition IsStaggeringEnabled="True"/>
|
||||||
</TransitionCollection>
|
</TransitionCollection>
|
||||||
</StackPanel.ChildrenTransitions>
|
</StackPanel.ChildrenTransitions>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<controls:ShowMore x:Name="more" Clicked="ShowMore_Clicked"/>
|
<controls:ShowMore x:Name="more" Clicked="ShowMore_Clicked"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ using Google.Apis.YouTube.v3.Data;
|
|||||||
using FoxTube.Controls;
|
using FoxTube.Controls;
|
||||||
using Windows.UI.Popups;
|
using Windows.UI.Popups;
|
||||||
using Windows.ApplicationModel.Resources;
|
using Windows.ApplicationModel.Resources;
|
||||||
|
using Microsoft.AppCenter.Analytics;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace FoxTube.Pages
|
namespace FoxTube.Pages
|
||||||
{
|
{
|
||||||
@@ -52,18 +54,18 @@ namespace FoxTube.Pages
|
|||||||
|
|
||||||
foreach (CommentThread comment in response.Items)
|
foreach (CommentThread comment in response.Items)
|
||||||
{
|
{
|
||||||
if ((placeholder.Children.Count - 5) % 20 == 0 && !SecretsVault.AdsDisabled)
|
if ((list.Children.Count - 5) % 20 == 0 && !SecretsVault.AdsDisabled)
|
||||||
placeholder.Children.Add(new Controls.Adverts.CommentAdvert());
|
list.Children.Add(new Controls.Adverts.CommentAdvert());
|
||||||
placeholder.Children.Add(new CommentCard(comment));
|
list.Children.Add(new CommentCard(comment));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveComment(CommentCard commentCard, string topCommentId = null)
|
public void RemoveComment(CommentCard commentCard, string topCommentId = null)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(topCommentId))
|
if (string.IsNullOrWhiteSpace(topCommentId))
|
||||||
placeholder.Children.Remove(commentCard);
|
list.Children.Remove(commentCard);
|
||||||
else
|
else
|
||||||
(placeholder.Children.Find(i => (i as CommentCard).thread.Id == topCommentId) as CommentCard).DeleteComment(commentCard);
|
(list.Children.Find(i => (i as CommentCard).thread.Id == topCommentId) as CommentCard)?.DeleteComment(commentCard);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void toRelevance_Click(object sender, RoutedEventArgs e)
|
private async void toRelevance_Click(object sender, RoutedEventArgs e)
|
||||||
@@ -71,12 +73,12 @@ namespace FoxTube.Pages
|
|||||||
if (order == CommentThreadsResource.ListRequest.OrderEnum.Relevance)
|
if (order == CommentThreadsResource.ListRequest.OrderEnum.Relevance)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
more.Show();
|
more.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
order = CommentThreadsResource.ListRequest.OrderEnum.Relevance;
|
order = CommentThreadsResource.ListRequest.OrderEnum.Relevance;
|
||||||
orderBtn.Content = resources.GetString("/CommentsPage/relevance/Text");
|
orderBtn.Content = resources.GetString("/CommentsPage/relevance/Text");
|
||||||
|
|
||||||
placeholder.Children.Clear();
|
list.Children.Clear();
|
||||||
|
|
||||||
request.Order = order;
|
request.Order = order;
|
||||||
var response = await request.ExecuteAsync();
|
var response = await request.ExecuteAsync();
|
||||||
@@ -86,7 +88,11 @@ namespace FoxTube.Pages
|
|||||||
more.Visibility = Visibility.Collapsed;
|
more.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
foreach (CommentThread comment in response.Items)
|
foreach (CommentThread comment in response.Items)
|
||||||
placeholder.Children.Add(new CommentCard(comment));
|
{
|
||||||
|
if ((list.Children.Count - 5) % 20 == 0 && !SecretsVault.AdsDisabled)
|
||||||
|
list.Children.Add(new Controls.Adverts.CommentAdvert());
|
||||||
|
list.Children.Add(new CommentCard(comment));
|
||||||
|
}
|
||||||
|
|
||||||
more.Complete();
|
more.Complete();
|
||||||
}
|
}
|
||||||
@@ -96,12 +102,12 @@ namespace FoxTube.Pages
|
|||||||
if (order == CommentThreadsResource.ListRequest.OrderEnum.Time)
|
if (order == CommentThreadsResource.ListRequest.OrderEnum.Time)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
more.Show();
|
more.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
order = CommentThreadsResource.ListRequest.OrderEnum.Time;
|
order = CommentThreadsResource.ListRequest.OrderEnum.Time;
|
||||||
orderBtn.Content = resources.GetString("/CommentsPage/publish");
|
orderBtn.Content = resources.GetString("/CommentsPage/publish");
|
||||||
|
|
||||||
placeholder.Children.Clear();
|
list.Children.Clear();
|
||||||
|
|
||||||
request.Order = order;
|
request.Order = order;
|
||||||
var response = await request.ExecuteAsync();
|
var response = await request.ExecuteAsync();
|
||||||
@@ -111,12 +117,16 @@ namespace FoxTube.Pages
|
|||||||
more.Visibility = Visibility.Collapsed;
|
more.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
foreach (CommentThread comment in response.Items)
|
foreach (CommentThread comment in response.Items)
|
||||||
placeholder.Children.Add(new CommentCard(comment));
|
{
|
||||||
|
if ((list.Children.Count - 5) % 20 == 0 && !SecretsVault.AdsDisabled)
|
||||||
|
list.Children.Add(new Controls.Adverts.CommentAdvert());
|
||||||
|
list.Children.Add(new CommentCard(comment));
|
||||||
|
}
|
||||||
|
|
||||||
more.Complete();
|
more.Complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void send_Click(object sender, RoutedEventArgs e)
|
private async void send_Click(object sender, RoutedEventArgs args)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(newComment.Text))
|
if (string.IsNullOrWhiteSpace(newComment.Text))
|
||||||
return;
|
return;
|
||||||
@@ -125,13 +135,13 @@ namespace FoxTube.Pages
|
|||||||
send.IsEnabled = false;
|
send.IsEnabled = false;
|
||||||
sending.Visibility = Visibility.Visible;
|
sending.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
CommentThread thread = new CommentThread()
|
CommentThread thread = new CommentThread
|
||||||
{
|
{
|
||||||
Snippet = new CommentThreadSnippet()
|
Snippet = new CommentThreadSnippet
|
||||||
{
|
{
|
||||||
TopLevelComment = new Comment()
|
TopLevelComment = new Comment
|
||||||
{
|
{
|
||||||
Snippet = new CommentSnippet()
|
Snippet = new CommentSnippet
|
||||||
{
|
{
|
||||||
TextOriginal = newComment.Text
|
TextOriginal = newComment.Text
|
||||||
}
|
}
|
||||||
@@ -143,11 +153,20 @@ namespace FoxTube.Pages
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
CommentThread response = await SecretsVault.Service.CommentThreads.Insert(thread, "snippet").ExecuteAsync();
|
CommentThread response = await SecretsVault.Service.CommentThreads.Insert(thread, "snippet").ExecuteAsync();
|
||||||
placeholder.Children.Insert(0, new CommentCard(response));
|
list.Children.Insert(0, new CommentCard(response));
|
||||||
newComment.Text = "";
|
newComment.Text = "";
|
||||||
scroll.ChangeView(null, 0, null);
|
scroll.ChangeView(null, 0, null);
|
||||||
}
|
}
|
||||||
catch { await new MessageDialog("Failed to publish your comment. Please, try again later.").ShowAsync(); }
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
await new MessageDialog("Failed to publish your comment. Please, try again later.").ShowAsync();
|
||||||
|
Analytics.TrackEvent("Failed to post comment", new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "Exception", e.GetType().ToString() },
|
||||||
|
{ "Message", e.Message },
|
||||||
|
{ "Thread ID", threadId }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
newComment.IsEnabled = true;
|
newComment.IsEnabled = true;
|
||||||
send.IsEnabled = true;
|
send.IsEnabled = true;
|
||||||
@@ -159,17 +178,18 @@ namespace FoxTube.Pages
|
|||||||
request.PageToken = token;
|
request.PageToken = token;
|
||||||
var response = await request.ExecuteAsync();
|
var response = await request.ExecuteAsync();
|
||||||
|
|
||||||
foreach (CommentThread comment in response.Items)
|
|
||||||
{
|
|
||||||
if ((placeholder.Children.Count - 5) % 20 == 0 && !SecretsVault.AdsDisabled)
|
|
||||||
placeholder.Children.Add(new Controls.Adverts.CommentAdvert());
|
|
||||||
placeholder.Children.Add(new CommentCard(comment));
|
|
||||||
}
|
|
||||||
|
|
||||||
token = response.NextPageToken;
|
token = response.NextPageToken;
|
||||||
more.Complete();
|
|
||||||
if (string.IsNullOrWhiteSpace(token))
|
if (string.IsNullOrWhiteSpace(token))
|
||||||
more.Visibility = Visibility.Collapsed;
|
more.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
|
foreach (CommentThread comment in response.Items)
|
||||||
|
{
|
||||||
|
if ((list.Children.Count - 5) % 20 == 0 && !SecretsVault.AdsDisabled)
|
||||||
|
list.Children.Add(new Controls.Adverts.CommentAdvert());
|
||||||
|
list.Children.Add(new CommentCard(comment));
|
||||||
|
}
|
||||||
|
|
||||||
|
more.Complete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="auto"/>
|
<RowDefinition Height="auto"/>
|
||||||
<RowDefinition/>
|
<RowDefinition/>
|
||||||
<RowDefinition Height="auto"/>
|
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid Margin="10">
|
<Grid Margin="10">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
@@ -22,7 +21,6 @@
|
|||||||
<Button Grid.Column="1" x:Uid="/Downloads/openFolder" Content="Open folder" Name="open" Click="Open_Click" VerticalAlignment="Center"/>
|
<Button Grid.Column="1" x:Uid="/Downloads/openFolder" Content="Open folder" Name="open" Click="Open_Click" VerticalAlignment="Center"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|
||||||
<TextBlock x:Uid="/Downloads/noItems" Grid.Row="1" Name="empty" HorizontalAlignment="Center" VerticalAlignment="Top" FontSize="28" Text="You haven't downloaded anything yet" Margin="10" TextWrapping="WrapWholeWords" Foreground="Gray" FontWeight="SemiBold"/>
|
<TextBlock x:Uid="/Downloads/noItems" Grid.Row="1" Name="empty" HorizontalAlignment="Center" VerticalAlignment="Top" FontSize="28" Text="You haven't downloaded anything yet" Margin="10" TextWrapping="WrapWholeWords" Foreground="Gray" FontWeight="SemiBold"/>
|
||||||
|
|
||||||
<ScrollViewer Grid.Row="1">
|
<ScrollViewer Grid.Row="1">
|
||||||
@@ -34,9 +32,5 @@
|
|||||||
</StackPanel.ChildrenTransitions>
|
</StackPanel.ChildrenTransitions>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
|
||||||
<CommandBar Grid.Row="2">
|
|
||||||
<AppBarButton x:Uid="/Downloads/refresh" Label="Refresh" Icon="Refresh" Click="Refresh"/>
|
|
||||||
</CommandBar>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ using System;
|
|||||||
using Windows.System;
|
using Windows.System;
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Windows.UI.Xaml.Navigation;
|
||||||
|
|
||||||
namespace FoxTube.Pages
|
namespace FoxTube.Pages
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Downloads page
|
/// Downloads page
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class Downloads : Page, NavigationPage
|
public sealed partial class Downloads : Page, INavigationPage
|
||||||
{
|
{
|
||||||
public object Parameter { get; set; } = null;
|
public object Parameter { get; set; } = null;
|
||||||
public Downloads()
|
public Downloads()
|
||||||
@@ -17,7 +18,19 @@ namespace FoxTube.Pages
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
DownloadAgent.Page = this;
|
DownloadAgent.Page = this;
|
||||||
path.Text = DownloadAgent.Downloads.Path;
|
path.Text = DownloadAgent.Downloads.Path;
|
||||||
Refresh(this, null);
|
|
||||||
|
list.Children.Clear();
|
||||||
|
DownloadAgent.Items.ForEach(i => list.Children.Add(i));
|
||||||
|
|
||||||
|
empty.Visibility = list.Children.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
|
||||||
|
Methods.MainPage.PageContent.LoadingPage.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnNavigatedFrom(e);
|
||||||
|
DownloadAgent.Page = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Open_Click(object sender, RoutedEventArgs e)
|
private async void Open_Click(object sender, RoutedEventArgs e)
|
||||||
@@ -25,14 +38,6 @@ namespace FoxTube.Pages
|
|||||||
await Launcher.LaunchFolderAsync(DownloadAgent.Downloads);
|
await Launcher.LaunchFolderAsync(DownloadAgent.Downloads);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Refresh(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
list.Children.Clear();
|
|
||||||
DownloadAgent.items.ForEach(i => list.Children.Add(i));
|
|
||||||
|
|
||||||
empty.Visibility = list.Children.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Remove(DownloadItem item)
|
public void Remove(DownloadItem item)
|
||||||
{
|
{
|
||||||
list.Children.Remove(item);
|
list.Children.Remove(item);
|
||||||
|
|||||||
@@ -56,13 +56,6 @@
|
|||||||
</PivotItem>
|
</PivotItem>
|
||||||
</Pivot>
|
</Pivot>
|
||||||
|
|
||||||
<!--<ScrollViewer>
|
|
||||||
<StackPanel>
|
|
||||||
<local:VideoGrid x:Name="list"/>
|
|
||||||
<controls:ShowMore Clicked="ShowMore_Clicked" x:Name="more"/>
|
|
||||||
</StackPanel>
|
|
||||||
</ScrollViewer>-->
|
|
||||||
|
|
||||||
<CommandBar Grid.Row="1" DefaultLabelPosition="Right">
|
<CommandBar Grid.Row="1" DefaultLabelPosition="Right">
|
||||||
<AppBarButton x:Uid="/Playlist/refresh" Icon="Refresh" Label="Refresh" Name="refresh" Click="Refresh_Click"/>
|
<AppBarButton x:Uid="/Playlist/refresh" Icon="Refresh" Label="Refresh" Name="refresh" Click="Refresh_Click"/>
|
||||||
<AppBarButton x:Uid="/Playlist/openWeb" Label="Open in browser" Icon="Globe" Name="toBrowser" Click="toBrowser_Click"/>
|
<AppBarButton x:Uid="/Playlist/openWeb" Label="Open in browser" Icon="Globe" Name="toBrowser" Click="toBrowser_Click"/>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace FoxTube.Pages
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// YouTube history page
|
/// YouTube history page
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class History : Page, NavigationPage
|
public sealed partial class History : Page, INavigationPage
|
||||||
{
|
{
|
||||||
public object Parameter { get; set; } = null;
|
public object Parameter { get; set; } = null;
|
||||||
int page = 1;
|
int page = 1;
|
||||||
@@ -31,10 +31,12 @@ namespace FoxTube.Pages
|
|||||||
Parameter = e.Parameter;
|
Parameter = e.Parameter;
|
||||||
|
|
||||||
Initialize();
|
Initialize();
|
||||||
|
Methods.MainPage.PageContent.LoadingPage.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void Initialize()
|
public async void Initialize()
|
||||||
{
|
{
|
||||||
|
Methods.MainPage.VideoContent.LoadingPage.Close();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
loading.Refresh();
|
loading.Refresh();
|
||||||
@@ -71,7 +73,7 @@ namespace FoxTube.Pages
|
|||||||
|
|
||||||
private void Refresh_Click(object sender, RoutedEventArgs e)
|
private void Refresh_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Methods.MainPage.GoToHistory();
|
Methods.MainPage.VideoContent.Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void ShowMore_Clicked()
|
private async void ShowMore_Clicked()
|
||||||
@@ -148,7 +150,7 @@ namespace FoxTube.Pages
|
|||||||
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
|
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
|
||||||
{
|
{
|
||||||
for (int k = 25 * webPage++; k < 25 * webPage && k < SecretsVault.History.Count; k++)
|
for (int k = 25 * webPage++; k < 25 * webPage && k < SecretsVault.History.Count; k++)
|
||||||
websiteList.Add(new VideoCard(HistorySet.Items[k].Id, "HL"));
|
websiteList.Add(new VideoCard(SecretsVault.History[k], "HL"));
|
||||||
|
|
||||||
if (websiteList.Count >= SecretsVault.History.Count)
|
if (websiteList.Count >= SecretsVault.History.Count)
|
||||||
websiteMore.Visibility = Visibility.Collapsed;
|
websiteMore.Visibility = Visibility.Collapsed;
|
||||||
|
|||||||
+14
-30
@@ -7,16 +7,17 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:pages="using:FoxTube.Pages"
|
xmlns:pages="using:FoxTube.Pages"
|
||||||
xmlns:controls="using:FoxTube.Controls"
|
xmlns:controls="using:FoxTube.Controls"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d"
|
||||||
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
|
|
||||||
<Pivot SelectionChanged="pivot_SelectionChanged" Name="pivot">
|
|
||||||
<PivotItem Name="recommended" Header="Recommended" x:Uid="/Home/recommended">
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition/>
|
<RowDefinition/>
|
||||||
<RowDefinition Height="auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
<Pivot SelectionChanged="pivot_SelectionChanged" Name="pivot">
|
||||||
|
<PivotItem Name="recommended" Header="Recommended" x:Uid="/Home/recommended">
|
||||||
|
<Grid>
|
||||||
<ScrollViewer>
|
<ScrollViewer>
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<pages:VideoGrid x:Name="recGrid"/>
|
<pages:VideoGrid x:Name="recGrid"/>
|
||||||
@@ -24,20 +25,11 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
|
||||||
<CommandBar Grid.Row="1">
|
<local:LoadingPage x:Name="recsLoading" Grid.RowSpan="2" RefreshPage="Refresh_Click"/>
|
||||||
<AppBarButton Icon="Refresh" Label="Refresh" x:Uid="/Home/refresh" Click="Recommended_Refresh"/>
|
|
||||||
</CommandBar>
|
|
||||||
|
|
||||||
<local:LoadingPage x:Name="recsLoading" Grid.RowSpan="2" RefreshPage="Recommended_Refresh"/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</PivotItem>
|
</PivotItem>
|
||||||
<PivotItem Name="trending" Header="Trending" x:Uid="/Home/trending">
|
<PivotItem Name="trending" Header="Trending" x:Uid="/Home/trending">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition/>
|
|
||||||
<RowDefinition Height="auto"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
|
|
||||||
<ScrollViewer>
|
<ScrollViewer>
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<pages:VideoGrid x:Name="trendGrid"/>
|
<pages:VideoGrid x:Name="trendGrid"/>
|
||||||
@@ -45,20 +37,11 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
|
||||||
<CommandBar Grid.Row="1">
|
<local:LoadingPage x:Name="trendsLoading" Grid.RowSpan="2" RefreshPage="Refresh_Click"/>
|
||||||
<AppBarButton Icon="Refresh" Label="Refresh" x:Uid="/Home/refresh" Click="Trends_Refresh"/>
|
|
||||||
</CommandBar>
|
|
||||||
|
|
||||||
<local:LoadingPage x:Name="trendsLoading" Grid.RowSpan="2" RefreshPage="Trends_Refresh"/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</PivotItem>
|
</PivotItem>
|
||||||
<PivotItem Name="subscriptions" Header="Subscriptions" x:Uid="/Home/subs">
|
<PivotItem Name="subscriptions" Header="Subscriptions" x:Uid="/Home/subs">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition/>
|
|
||||||
<RowDefinition Height="auto"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
|
|
||||||
<ScrollViewer>
|
<ScrollViewer>
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<pages:VideoGrid x:Name="subsGrid"/>
|
<pages:VideoGrid x:Name="subsGrid"/>
|
||||||
@@ -66,12 +49,13 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
|
||||||
<CommandBar Grid.Row="1">
|
<local:LoadingPage x:Name="subsLoading" Grid.RowSpan="2" RefreshPage="Refresh_Click"/>
|
||||||
<AppBarButton Icon="Refresh" Label="Refresh" x:Uid="/Home/refresh" Click="Subscriptions_Refresh"/>
|
|
||||||
</CommandBar>
|
|
||||||
|
|
||||||
<local:LoadingPage x:Name="subsLoading" Grid.RowSpan="2" RefreshPage="Subscriptions_Refresh"/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</PivotItem>
|
</PivotItem>
|
||||||
</Pivot>
|
</Pivot>
|
||||||
|
|
||||||
|
<CommandBar Grid.Row="1" Name="commandbar">
|
||||||
|
<AppBarButton Icon="Refresh" Label="Refresh" x:Uid="/Home/refresh" Click="Refresh_Click"/>
|
||||||
|
</CommandBar>
|
||||||
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
+18
-21
@@ -14,7 +14,7 @@ namespace FoxTube
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Home page
|
/// Home page
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class Home : Page, NavigationPage
|
public sealed partial class Home : Page, INavigationPage
|
||||||
{
|
{
|
||||||
public object Parameter { get; set; } = null;
|
public object Parameter { get; set; } = null;
|
||||||
private bool trendLoaded = false, recLoaded = false, subsLoaded = false;
|
private bool trendLoaded = false, recLoaded = false, subsLoaded = false;
|
||||||
@@ -27,6 +27,7 @@ namespace FoxTube
|
|||||||
public Home()
|
public Home()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
SecretsVault.RefreshToken();
|
||||||
Initialize();
|
Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,6 +42,8 @@ namespace FoxTube
|
|||||||
|
|
||||||
private void pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
|
Methods.MainPage.PageContent.LoadingPage.Close();
|
||||||
|
|
||||||
if (pivot.SelectedItem == recommended && !recLoaded)
|
if (pivot.SelectedItem == recommended && !recLoaded)
|
||||||
LoadRecommendations();
|
LoadRecommendations();
|
||||||
else if (pivot.SelectedItem == trending && !trendLoaded)
|
else if (pivot.SelectedItem == trending && !trendLoaded)
|
||||||
@@ -52,6 +55,7 @@ namespace FoxTube
|
|||||||
#region Initializing tabs
|
#region Initializing tabs
|
||||||
async void LoadRecommendations()
|
async void LoadRecommendations()
|
||||||
{
|
{
|
||||||
|
recLoaded = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
recsLoading.Refresh();
|
recsLoading.Refresh();
|
||||||
@@ -71,12 +75,10 @@ namespace FoxTube
|
|||||||
}
|
}
|
||||||
catch (HttpRequestException)
|
catch (HttpRequestException)
|
||||||
{
|
{
|
||||||
recLoaded = false;
|
|
||||||
recsLoading.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
recsLoading.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
recLoaded = false;
|
|
||||||
recsLoading.Error(e.GetType().ToString(), e.Message);
|
recsLoading.Error(e.GetType().ToString(), e.Message);
|
||||||
|
|
||||||
Analytics.TrackEvent("Failed to load recommendations", new Dictionary<string, string>()
|
Analytics.TrackEvent("Failed to load recommendations", new Dictionary<string, string>()
|
||||||
@@ -88,6 +90,7 @@ namespace FoxTube
|
|||||||
}
|
}
|
||||||
async void LoadTrending()
|
async void LoadTrending()
|
||||||
{
|
{
|
||||||
|
trendLoaded = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
trendsLoading.Refresh();
|
trendsLoading.Refresh();
|
||||||
@@ -111,12 +114,10 @@ namespace FoxTube
|
|||||||
}
|
}
|
||||||
catch (HttpRequestException)
|
catch (HttpRequestException)
|
||||||
{
|
{
|
||||||
trendLoaded = false;
|
|
||||||
trendsLoading.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
trendsLoading.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
trendLoaded = false;
|
|
||||||
trendsLoading.Error(e.GetType().ToString(), e.Message);
|
trendsLoading.Error(e.GetType().ToString(), e.Message);
|
||||||
|
|
||||||
Analytics.TrackEvent("Failed to load trendings", new Dictionary<string, string>()
|
Analytics.TrackEvent("Failed to load trendings", new Dictionary<string, string>()
|
||||||
@@ -128,11 +129,11 @@ namespace FoxTube
|
|||||||
}
|
}
|
||||||
async void LoadSubscriptions()
|
async void LoadSubscriptions()
|
||||||
{
|
{
|
||||||
|
subsLoaded = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
subsLoading.Refresh();
|
subsLoading.Refresh();
|
||||||
|
|
||||||
await SecretsVault.HttpClient.GetStringAsync("https://www.youtube.com/list_ajax?style=json&action_get_list=1&list=WL");
|
|
||||||
string response = await SecretsVault.HttpClient.GetStringAsync("https://www.youtube.com/feed/subscriptions");
|
string response = await SecretsVault.HttpClient.GetStringAsync("https://www.youtube.com/feed/subscriptions");
|
||||||
|
|
||||||
foreach (Match match in Regex.Matches(response, @"\bdata-context-item-id=(\S*)\b", RegexOptions.IgnoreCase))
|
foreach (Match match in Regex.Matches(response, @"\bdata-context-item-id=(\S*)\b", RegexOptions.IgnoreCase))
|
||||||
@@ -148,12 +149,10 @@ namespace FoxTube
|
|||||||
}
|
}
|
||||||
catch (HttpRequestException)
|
catch (HttpRequestException)
|
||||||
{
|
{
|
||||||
subsLoaded = false;
|
|
||||||
subsLoading.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
subsLoading.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
subsLoaded = false;
|
|
||||||
subsLoading.Error(e.GetType().ToString(), e.Message);
|
subsLoading.Error(e.GetType().ToString(), e.Message);
|
||||||
|
|
||||||
Analytics.TrackEvent("Failed to load subscriptions", new Dictionary<string, string>()
|
Analytics.TrackEvent("Failed to load subscriptions", new Dictionary<string, string>()
|
||||||
@@ -198,26 +197,24 @@ namespace FoxTube
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Refreshing tabs
|
private void Refresh_Click(object sender, RoutedEventArgs e)
|
||||||
private void Recommended_Refresh(object sender, RoutedEventArgs e)
|
|
||||||
{
|
{
|
||||||
|
switch(pivot.SelectedIndex)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
recGrid.Clear();
|
recGrid.Clear();
|
||||||
|
|
||||||
LoadRecommendations();
|
LoadRecommendations();
|
||||||
}
|
break;
|
||||||
private void Trends_Refresh(object sender, RoutedEventArgs e)
|
case 1:
|
||||||
{
|
|
||||||
trendsRequest = null;
|
trendsRequest = null;
|
||||||
trendGrid.Clear();
|
trendGrid.Clear();
|
||||||
|
|
||||||
LoadTrending();
|
LoadTrending();
|
||||||
}
|
break;
|
||||||
private void Subscriptions_Refresh(object sender, RoutedEventArgs e)
|
case 2:
|
||||||
{
|
|
||||||
subsGrid.Clear();
|
subsGrid.Clear();
|
||||||
|
|
||||||
LoadSubscriptions();
|
LoadSubscriptions();
|
||||||
}
|
break;
|
||||||
#endregion
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,16 +4,16 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
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"
|
||||||
xmlns:Windows10version1809="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract, 7)"
|
mc:Ignorable="d"
|
||||||
mc:Ignorable="d">
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
|
|
||||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
<Grid>
|
||||||
<ProgressRing Name="ring" IsActive="True" Foreground="Red" Width="100" Height="100"/>
|
<ProgressRing Name="ring" IsActive="True" Foreground="Red" Width="100" Height="100"/>
|
||||||
|
|
||||||
<StackPanel Name="wifiTrouble" Visibility="Collapsed" VerticalAlignment="Center">
|
<StackPanel Name="wifiTrouble" Visibility="Collapsed" VerticalAlignment="Center">
|
||||||
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="" FontSize="100" HorizontalAlignment="Center"/>
|
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="" FontSize="100"/>
|
||||||
<TextBlock x:Uid="/LoadingPage/checkConnection" Text="Check your internet connection" TextWrapping="WrapWholeWords" FontSize="48" HorizontalAlignment="Center" HorizontalTextAlignment="Center"/>
|
<TextBlock x:Uid="/LoadingPage/checkConnection" Text="Check your internet connection" TextWrapping="WrapWholeWords" FontSize="48" HorizontalAlignment="Center"/>
|
||||||
<TextBlock x:Uid="/LoadingPage/wifiDesc" Text="Please, make sure you are connected to the internet and try again." HorizontalAlignment="Center" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center"/>
|
<TextBlock x:Uid="/LoadingPage/wifiDesc" Text="Please, make sure you are connected to the internet and try again." TextWrapping="WrapWholeWords" HorizontalAlignment="Center"/>
|
||||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||||
<Button x:Uid="/LoadingPage/openWifi" Content="Open network settings" Margin="5" Name="openWifi" Click="openWifi_Click"/>
|
<Button x:Uid="/LoadingPage/openWifi" Content="Open network settings" Margin="5" Name="openWifi" Click="openWifi_Click"/>
|
||||||
<Button x:Uid="/LoadingPage/openTroubleshooter" Content="Open troubleshooter" Background="Red" Foreground="White" Margin="5" Name="openTroubleshoot" Click="openTroubleshoot_Click"/>
|
<Button x:Uid="/LoadingPage/openTroubleshooter" Content="Open troubleshooter" Background="Red" Foreground="White" Margin="5" Name="openTroubleshoot" Click="openTroubleshoot_Click"/>
|
||||||
@@ -26,8 +26,8 @@
|
|||||||
|
|
||||||
<StackPanel Name="trouble" Visibility="Collapsed" VerticalAlignment="Center">
|
<StackPanel Name="trouble" Visibility="Collapsed" VerticalAlignment="Center">
|
||||||
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="" FontSize="100" HorizontalAlignment="Center"/>
|
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="" FontSize="100" HorizontalAlignment="Center"/>
|
||||||
<TextBlock x:Uid="/LoadingPage/err" Text="We are unable to display the page" FontSize="48" HorizontalAlignment="Center" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center"/>
|
<TextBlock x:Uid="/LoadingPage/err" Text="We are unable to display the page" FontSize="48" HorizontalAlignment="Center" TextWrapping="WrapWholeWords"/>
|
||||||
<TextBlock x:Uid="/LoadingPage/errDescription" Text="It could be caused by YouTube internal server error or by application's bug. Please, try again later" HorizontalAlignment="Center" HorizontalTextAlignment="Center" TextWrapping="WrapWholeWords"/>
|
<TextBlock x:Uid="/LoadingPage/errDescription" Text="It could be caused by YouTube internal server error or by application's bug. Please, try again later" HorizontalAlignment="Center" TextWrapping="WrapWholeWords"/>
|
||||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||||
<Button x:Uid="/LoadingPage/refresh" Name="refresh" Click="wifiRefresh_Click" Content="Refresh page" Margin="5"/>
|
<Button x:Uid="/LoadingPage/refresh" Name="refresh" Click="wifiRefresh_Click" Content="Refresh page" Margin="5"/>
|
||||||
<Button x:Uid="/LoadingPage/feedback" Content="Leave feedback" Background="Red" Foreground="White" Margin="5" Name="feedback" Click="feedback_Click"/>
|
<Button x:Uid="/LoadingPage/feedback" Content="Leave feedback" Background="Red" Foreground="White" Margin="5" Name="feedback" Click="feedback_Click"/>
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
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"
|
||||||
xmlns:ui="using:Microsoft.UI.Xaml.Controls">
|
xmlns:ui="using:Microsoft.UI.Xaml.Controls"
|
||||||
|
xmlns:controls="using:FoxTube.Controls">
|
||||||
|
|
||||||
<Grid Name="grid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
<Grid Name="grid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
<VisualStateManager.VisualStateGroups>
|
<VisualStateManager.VisualStateGroups>
|
||||||
@@ -34,8 +35,7 @@
|
|||||||
Style="{StaticResource CaptionTextBlockStyle}" />
|
Style="{StaticResource CaptionTextBlockStyle}" />
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<ui:NavigationView FontSize="14" SelectedItem="toHome" BackRequested="Nav_BackRequested" PaneClosing="Nav_PaneClosing" PaneOpened="Nav_PaneOpened" OpenPaneLength="300" Name="nav" SelectionChanged="Nav_SelectionChanged">
|
<ui:NavigationView SelectedItem="toHome" BackRequested="Nav_BackRequested" PaneClosing="Nav_PaneClosing" PaneOpened="Nav_PaneOpened" OpenPaneLength="300" Name="nav" SelectionChanged="Nav_SelectionChanged">
|
||||||
|
|
||||||
<ui:NavigationView.Header>
|
<ui:NavigationView.Header>
|
||||||
<Grid>
|
<Grid>
|
||||||
<TextBlock Name="Title" Style="{StaticResource TitleTextBlockStyle}"/>
|
<TextBlock Name="Title" Style="{StaticResource TitleTextBlockStyle}"/>
|
||||||
@@ -66,23 +66,6 @@
|
|||||||
</Ellipse>
|
</Ellipse>
|
||||||
</Button>
|
</Button>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<CommandBar HorizontalAlignment="Right" Background="Transparent" OverflowButtonVisibility="Collapsed" Visibility="Collapsed" Margin="100,0">
|
|
||||||
<AppBarButton Label="Leave feedback">
|
|
||||||
<AppBarButton.Icon>
|
|
||||||
<FontIcon Glyph=""/>
|
|
||||||
</AppBarButton.Icon>
|
|
||||||
</AppBarButton>
|
|
||||||
<AppBarButton Label="Add account">
|
|
||||||
<AppBarButton.Icon>
|
|
||||||
<FontIcon Glyph=""/>
|
|
||||||
</AppBarButton.Icon>
|
|
||||||
</AppBarButton>
|
|
||||||
<AppBarButton>
|
|
||||||
<AppBarButton.Content>
|
|
||||||
<PersonPicture/>
|
|
||||||
</AppBarButton.Content>
|
|
||||||
</AppBarButton>
|
|
||||||
</CommandBar>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</ui:NavigationView.Header>
|
</ui:NavigationView.Header>
|
||||||
|
|
||||||
@@ -116,30 +99,20 @@
|
|||||||
</ui:NavigationView.MenuItems>
|
</ui:NavigationView.MenuItems>
|
||||||
|
|
||||||
<ui:NavigationView.PaneFooter>
|
<ui:NavigationView.PaneFooter>
|
||||||
<ui:NavigationViewList>
|
|
||||||
<ui:NavigationViewList.ItemContainerTransitions>
|
|
||||||
<TransitionCollection>
|
|
||||||
<EntranceThemeTransition IsStaggeringEnabled="True"/>
|
|
||||||
<ReorderThemeTransition/>
|
|
||||||
</TransitionCollection>
|
|
||||||
</ui:NavigationViewList.ItemContainerTransitions>
|
|
||||||
<ui:NavigationViewItem Name="openWeb" Tapped="Web_Tapped" Icon="Globe" Content="Browser" Visibility="Collapsed"/>
|
|
||||||
|
|
||||||
<ui:NavigationViewItem Content="Remove ads" Visibility="Collapsed" Tapped="RemoveAds_Tapped" Name="removeAds">
|
<ui:NavigationViewItem Content="Remove ads" Visibility="Collapsed" Tapped="RemoveAds_Tapped" Name="removeAds">
|
||||||
<ui:NavigationViewItem.Icon>
|
<ui:NavigationViewItem.Icon>
|
||||||
<FontIcon Glyph=""/>
|
<FontIcon Glyph=""/>
|
||||||
</ui:NavigationViewItem.Icon>
|
</ui:NavigationViewItem.Icon>
|
||||||
</ui:NavigationViewItem>
|
</ui:NavigationViewItem>
|
||||||
</ui:NavigationViewList>
|
|
||||||
</ui:NavigationView.PaneFooter>
|
</ui:NavigationView.PaneFooter>
|
||||||
|
|
||||||
<ui:NavigationView.AutoSuggestBox>
|
<ui:NavigationView.AutoSuggestBox>
|
||||||
<AutoSuggestBox FontSize="14" x:Name="search" QueryIcon="Find" QuerySubmitted="Search_QuerySubmitted" TextChanged="Search_TextChanged" x:Uid="/Main/searchPlaceholder" PlaceholderText="Search"/>
|
<AutoSuggestBox x:Name="search" QueryIcon="Find" QuerySubmitted="Search_QuerySubmitted" TextChanged="Search_TextChanged" x:Uid="/Main/searchPlaceholder" PlaceholderText="Search"/>
|
||||||
</ui:NavigationView.AutoSuggestBox>
|
</ui:NavigationView.AutoSuggestBox>
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Frame Name="content" Navigated="Content_Navigated"/>
|
<controls:ContentFrame x:Name="content" Navigated="Content_Navigated"/>
|
||||||
<Frame Name="videoPlaceholder"/>
|
<controls:ContentFrame x:Name="videoPlaceholder"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
</ui:NavigationView>
|
</ui:NavigationView>
|
||||||
|
|||||||
+114
-173
@@ -6,7 +6,6 @@ using Windows.UI.Xaml;
|
|||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
using Windows.UI.Xaml.Input;
|
using Windows.UI.Xaml.Input;
|
||||||
using Windows.UI.Xaml.Navigation;
|
using Windows.UI.Xaml.Navigation;
|
||||||
using System.Diagnostics;
|
|
||||||
using Windows.UI.Xaml.Media.Imaging;
|
using Windows.UI.Xaml.Media.Imaging;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using Google.Apis.YouTube.v3.Data;
|
using Google.Apis.YouTube.v3.Data;
|
||||||
@@ -14,11 +13,11 @@ using Windows.ApplicationModel.Core;
|
|||||||
using Windows.System;
|
using Windows.System;
|
||||||
using FoxTube.Pages;
|
using FoxTube.Pages;
|
||||||
using Windows.UI.Popups;
|
using Windows.UI.Popups;
|
||||||
using Windows.Networking.Connectivity;
|
|
||||||
using Windows.ApplicationModel.Resources;
|
using Windows.ApplicationModel.Resources;
|
||||||
using Microsoft.Services.Store.Engagement;
|
using Microsoft.Services.Store.Engagement;
|
||||||
using Windows.UI.Xaml.Shapes;
|
using Windows.UI.Xaml.Shapes;
|
||||||
using Windows.UI.Xaml.Media;
|
using Windows.UI.Xaml.Media;
|
||||||
|
using FoxTube.Controls;
|
||||||
|
|
||||||
namespace FoxTube
|
namespace FoxTube
|
||||||
{
|
{
|
||||||
@@ -28,38 +27,14 @@ namespace FoxTube
|
|||||||
public sealed partial class MainPage : Page
|
public sealed partial class MainPage : Page
|
||||||
{
|
{
|
||||||
bool wasInvoked = false;
|
bool wasInvoked = false;
|
||||||
public static event ObjectEventHandler VideoPageSizeChanged;
|
|
||||||
readonly ResourceLoader resources = ResourceLoader.GetForCurrentView("Main");
|
readonly ResourceLoader resources = ResourceLoader.GetForCurrentView("Main");
|
||||||
Dictionary<Type, string> headers;
|
Dictionary<Type, string> headers;
|
||||||
|
|
||||||
public Page PageContent => content.Content as Page;
|
public ContentFrame PageContent => content;
|
||||||
|
public ContentFrame VideoContent => videoPlaceholder;
|
||||||
|
|
||||||
public MainPage()
|
public MainPage()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
|
||||||
|
|
||||||
Window.Current.SetTitleBar(AppTitleBar);
|
|
||||||
CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
|
|
||||||
CoreApplication.GetCurrentView().TitleBar.LayoutMetricsChanged += (s, e) => SetTitleBar(s);
|
|
||||||
|
|
||||||
SecretsVault.AuthorizationStateChanged += AuthorizationStateChanged;
|
|
||||||
SecretsVault.SubscriptionsChanged += SecretsVault_SubscriptionsChanged;
|
|
||||||
SecretsVault.Purchased += async (sender, e) =>
|
|
||||||
{
|
|
||||||
removeAds.Visibility = (e[0] as bool?).Value ? Visibility.Collapsed : Visibility.Visible;
|
|
||||||
removeAds.Content = $"{resources.GetString("/Main/adsFree/Content")} ({e[1]})";
|
|
||||||
if (!(bool)e[0])
|
|
||||||
return;
|
|
||||||
|
|
||||||
MessageDialog dialog = new MessageDialog(resources.GetString("/Main/purchaseSuccess"));
|
|
||||||
dialog.Commands.Add(new UICommand(resources.GetString("/Main/close"), (command) => Methods.CloseApp()));
|
|
||||||
dialog.Commands.Add(new UICommand(resources.GetString("/Main/delay")));
|
|
||||||
dialog.CancelCommandIndex = 1;
|
|
||||||
dialog.DefaultCommandIndex = 0;
|
|
||||||
await dialog.ShowAsync();
|
|
||||||
};
|
|
||||||
SecretsVault.Initialize();
|
|
||||||
|
|
||||||
headers = new Dictionary<Type, string>()
|
headers = new Dictionary<Type, string>()
|
||||||
{
|
{
|
||||||
{ typeof(Settings), resources.GetString("/Main/settings/Content") },
|
{ typeof(Settings), resources.GetString("/Main/settings/Content") },
|
||||||
@@ -72,6 +47,33 @@ namespace FoxTube
|
|||||||
{ typeof(Downloads), resources.GetString("/Main/downloads/Content") }
|
{ typeof(Downloads), resources.GetString("/Main/downloads/Content") }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
Window.Current.SetTitleBar(AppTitleBar);
|
||||||
|
CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
|
||||||
|
CoreApplication.GetCurrentView().TitleBar.LayoutMetricsChanged += (s, e) => SetTitleBar(s);
|
||||||
|
|
||||||
|
SecretsVault.AuthorizationStateChanged += AuthorizationStateChanged;
|
||||||
|
SecretsVault.SubscriptionsChanged += SecretsVault_SubscriptionsChanged;
|
||||||
|
SecretsVault.Purchased += async (sender, e) =>
|
||||||
|
{
|
||||||
|
removeAds.Visibility = (e[0] as bool?).Value ? Visibility.Collapsed : Visibility.Visible;
|
||||||
|
|
||||||
|
if (!(bool)e[0])
|
||||||
|
{
|
||||||
|
removeAds.Content = $"{resources.GetString("/Main/adsFree/Content")} ({e[1]})";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageDialog dialog = new MessageDialog(resources.GetString("/Main/purchaseSuccess"));
|
||||||
|
dialog.Commands.Add(new UICommand(resources.GetString("/Main/close"), (command) => Methods.CloseApp()));
|
||||||
|
dialog.Commands.Add(new UICommand(resources.GetString("/Main/delay")));
|
||||||
|
dialog.CancelCommandIndex = 1;
|
||||||
|
dialog.DefaultCommandIndex = 0;
|
||||||
|
await dialog.ShowAsync();
|
||||||
|
};
|
||||||
|
SecretsVault.Initialize();
|
||||||
|
|
||||||
if(StoreServicesFeedbackLauncher.IsSupported())
|
if(StoreServicesFeedbackLauncher.IsSupported())
|
||||||
feedback.Visibility = Visibility.Visible;
|
feedback.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
@@ -121,16 +123,15 @@ namespace FoxTube
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetPlaylist()
|
|
||||||
{
|
|
||||||
try { return (videoPlaceholder.Content as VideoPage).playlistId; }
|
|
||||||
catch { return null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetTitleBar(CoreApplicationViewTitleBar coreTitleBar = null)
|
public void SetTitleBar(CoreApplicationViewTitleBar coreTitleBar = null)
|
||||||
{
|
{
|
||||||
if (coreTitleBar != null)
|
if (coreTitleBar != null)
|
||||||
|
{
|
||||||
|
bool full = ApplicationView.GetForCurrentView().IsFullScreenMode;
|
||||||
|
double left = 12 + (full ? 0 : coreTitleBar.SystemOverlayLeftInset);
|
||||||
|
AppTitle.Margin = new Thickness(left, 8, 0, 0);
|
||||||
AppTitleBar.Height = coreTitleBar.Height;
|
AppTitleBar.Height = coreTitleBar.Height;
|
||||||
|
}
|
||||||
|
|
||||||
var titleBar = ApplicationView.GetForCurrentView().TitleBar;
|
var titleBar = ApplicationView.GetForCurrentView().TitleBar;
|
||||||
|
|
||||||
@@ -148,7 +149,7 @@ namespace FoxTube
|
|||||||
|
|
||||||
private void SecretsVault_SubscriptionsChanged(object sender, params object[] args)
|
private void SecretsVault_SubscriptionsChanged(object sender, params object[] args)
|
||||||
{
|
{
|
||||||
switch(args[0] as string)
|
switch((string)args[0])
|
||||||
{
|
{
|
||||||
case "add":
|
case "add":
|
||||||
if (nav.MenuItems.Count < 19)
|
if (nav.MenuItems.Count < 19)
|
||||||
@@ -156,20 +157,20 @@ namespace FoxTube
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "remove":
|
case "remove":
|
||||||
Microsoft.UI.Xaml.Controls.NavigationViewItem item = nav.MenuItems.Find(i => ((i as Microsoft.UI.Xaml.Controls.NavigationViewItem).Content as StackPanel).Tag.ToString() == (args[1] as Subscription).Snippet.ResourceId.ChannelId) as Microsoft.UI.Xaml.Controls.NavigationViewItem;
|
if (nav.MenuItems.Find(i => ((i as Microsoft.UI.Xaml.Controls.NavigationViewItem).Content as StackPanel).Tag.ToString() == (string)args[1]) is Microsoft.UI.Xaml.Controls.NavigationViewItem item)
|
||||||
if (item == null)
|
{
|
||||||
break;
|
|
||||||
else
|
|
||||||
nav.MenuItems.Remove(item);
|
nav.MenuItems.Remove(item);
|
||||||
|
|
||||||
if (SecretsVault.Subscriptions.Count >= 10)
|
if (SecretsVault.Subscriptions.Count >= 10)
|
||||||
nav.MenuItems.Add(SecretsVault.Subscriptions[9]);
|
nav.MenuItems.Add(SecretsVault.Subscriptions[9]);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void AuthorizationStateChanged(object sender, params object[] e)
|
private async void AuthorizationStateChanged(object sender, params object[] e)
|
||||||
{
|
{
|
||||||
|
wasInvoked = false;
|
||||||
|
|
||||||
switch (e[0] as bool?)
|
switch (e[0] as bool?)
|
||||||
{
|
{
|
||||||
case true:
|
case true:
|
||||||
@@ -183,7 +184,6 @@ namespace FoxTube
|
|||||||
|
|
||||||
avatar.Visibility = Visibility.Visible;
|
avatar.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
if(SecretsVault.UserChannel != null)
|
|
||||||
toChannel.Visibility = Visibility.Visible;
|
toChannel.Visibility = Visibility.Visible;
|
||||||
toSubscriptions.Visibility = Visibility.Visible;
|
toSubscriptions.Visibility = Visibility.Visible;
|
||||||
libHeader.Visibility = Visibility.Visible;
|
libHeader.Visibility = Visibility.Visible;
|
||||||
@@ -198,9 +198,16 @@ namespace FoxTube
|
|||||||
nav.MenuItems.Add(SecretsVault.Subscriptions[k]);
|
nav.MenuItems.Add(SecretsVault.Subscriptions[k]);
|
||||||
}
|
}
|
||||||
HistorySet.Load();
|
HistorySet.Load();
|
||||||
|
|
||||||
|
if (content.Frame.Content != null)
|
||||||
|
content.Refresh();
|
||||||
|
else
|
||||||
|
content.Frame.Navigate(typeof(Home));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case false:
|
case false:
|
||||||
|
content.Frame.Navigate(typeof(Home));
|
||||||
|
|
||||||
for (int k = nav.MenuItems.Count - 1; k > 8; k--)
|
for (int k = nav.MenuItems.Count - 1; k > 8; k--)
|
||||||
nav.MenuItems.RemoveAt(k);
|
nav.MenuItems.RemoveAt(k);
|
||||||
|
|
||||||
@@ -216,6 +223,9 @@ namespace FoxTube
|
|||||||
subsHeader.Visibility = Visibility.Collapsed;
|
subsHeader.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
subsHeader.Visibility = Visibility.Collapsed;
|
subsHeader.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
|
content.Frame.BackStack.Clear();
|
||||||
|
content.Frame.ForwardStack.Clear();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -237,17 +247,13 @@ namespace FoxTube
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Dispatcher.RunIdleAsync((command) => DownloadAgent.Initialize());
|
if (videoPlaceholder.Frame.Content != null)
|
||||||
|
{
|
||||||
|
MaximizeVideo();
|
||||||
|
videoPlaceholder.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
wasInvoked = false;
|
DownloadAgent.Initialize();
|
||||||
|
|
||||||
if (content.Content != null)
|
|
||||||
content.Navigate(content.CurrentSourcePageType, (content.Content as NavigationPage).Parameter);
|
|
||||||
else
|
|
||||||
content.Navigate(typeof(Home));
|
|
||||||
|
|
||||||
if (videoPlaceholder.Content != null)
|
|
||||||
GoToVideo((videoPlaceholder.Content as VideoPage).videoId, (videoPlaceholder.Content as VideoPage).playlistId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Feedback_Click(object sender, RoutedEventArgs e)
|
private async void Feedback_Click(object sender, RoutedEventArgs e)
|
||||||
@@ -262,120 +268,69 @@ namespace FoxTube
|
|||||||
|
|
||||||
private void Logout_Click(object sender, RoutedEventArgs e)
|
private void Logout_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
avatar.Flyout.Hide();
|
||||||
SecretsVault.Deauthenticate();
|
SecretsVault.Deauthenticate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GoToSearch(SearchParameters args)
|
public void GoToSearch(SearchParameters args)
|
||||||
{
|
{
|
||||||
nav.IsPaneOpen = false;
|
content.Frame.Navigate(typeof(Search), new object[] { args, content });
|
||||||
content.Navigate(typeof(Search), args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GoToChannel(string id)
|
public void GoToChannel(string id)
|
||||||
{
|
{
|
||||||
content.Navigate(typeof(ChannelPage), id);
|
content.Frame.Navigate(typeof(ChannelPage), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GoToHome()
|
public void GoToHome()
|
||||||
{
|
{
|
||||||
content.Navigate(typeof(Home));
|
content.Frame.Navigate(typeof(Home));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void GoToVideo(string id, string playlistId = null, bool incognito = false)
|
public void GoToVideo(string id, string playlistId = null, bool incognito = false)
|
||||||
{
|
{
|
||||||
if (SettingsStorage.CheckConnection)
|
MaximizeVideo();
|
||||||
try
|
|
||||||
{
|
|
||||||
bool cancel = false;
|
|
||||||
ConnectionCost connection = NetworkInformation.GetInternetConnectionProfile().GetConnectionCost();
|
|
||||||
if (connection.NetworkCostType == NetworkCostType.Fixed || connection.NetworkCostType == NetworkCostType.Variable)
|
|
||||||
{
|
|
||||||
MessageDialog dialog = new MessageDialog(resources.GetString("/Main/metered"))
|
|
||||||
{
|
|
||||||
DefaultCommandIndex = 2,
|
|
||||||
CancelCommandIndex = 1
|
|
||||||
};
|
|
||||||
dialog.Commands.Add(new UICommand(resources.GetString("/Main/yes")));
|
|
||||||
dialog.Commands.Add(new UICommand(resources.GetString("/Main/no"), (command) => cancel = true));
|
|
||||||
if (SecretsVault.IsAuthorized)
|
|
||||||
dialog.Commands.Add(new UICommand(resources.GetString("/Main/addLater"), (command) =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
PlaylistItem item = new PlaylistItem()
|
|
||||||
{
|
|
||||||
Snippet = new PlaylistItemSnippet()
|
|
||||||
{
|
|
||||||
ResourceId = new ResourceId()
|
|
||||||
{
|
|
||||||
Kind = "youtube#video",
|
|
||||||
VideoId = id
|
|
||||||
},
|
|
||||||
PlaylistId = "WL"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
SecretsVault.Service.PlaylistItems.Insert(item, "snippet").Execute();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Debug.WriteLine(e.Message);
|
|
||||||
}
|
|
||||||
cancel = true;
|
|
||||||
}));
|
|
||||||
|
|
||||||
await dialog.ShowAsync();
|
|
||||||
|
|
||||||
if (cancel)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
|
|
||||||
if (videoPlaceholder.Content != null)
|
|
||||||
(videoPlaceholder.Content as VideoPage).CloseVideo();
|
|
||||||
|
|
||||||
nav.IsBackEnabled = true;
|
nav.IsBackEnabled = true;
|
||||||
nav.ExpandedModeThresholdWidth = short.MaxValue;
|
nav.ExpandedModeThresholdWidth = short.MaxValue;
|
||||||
nav.IsPaneOpen = false;
|
nav.IsPaneOpen = false;
|
||||||
|
|
||||||
VideoPageSizeChanged?.Invoke(this, true);
|
videoPlaceholder.Frame.Navigate(typeof(VideoPage), new object[3] { id, playlistId, incognito });
|
||||||
videoPlaceholder.Navigate(typeof(VideoPage), new object[3] { id, playlistId, incognito });
|
|
||||||
|
|
||||||
Title.Text = resources.GetString("/Main/video");
|
Title.Text = resources.GetString("/Main/video");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GoToDeveloper(string id)
|
public void GoToDeveloper(string id)
|
||||||
{
|
{
|
||||||
content.Navigate(typeof(Settings), id);
|
content.Frame.Navigate(typeof(Settings), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GoToPlaylist(string id)
|
public void GoToPlaylist(string id)
|
||||||
{
|
{
|
||||||
content.Navigate(typeof(PlaylistPage), id);
|
content.Frame.Navigate(typeof(PlaylistPage), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GoToHistory()
|
public void GoToHistory()
|
||||||
{
|
{
|
||||||
content.Navigate(typeof(History));
|
content.Frame.Navigate(typeof(History));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GoToDownloads()
|
public void GoToDownloads()
|
||||||
{
|
{
|
||||||
content.Navigate(typeof(Downloads));
|
content.Frame.Navigate(typeof(Downloads));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MinimizeAsInitializer()
|
public void MinimizeAsInitializer()
|
||||||
{
|
{
|
||||||
if (videoPlaceholder.Content == null)
|
if (videoPlaceholder.Frame.Content == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((videoPlaceholder.Content as VideoPage).LoadingPage.State != LoadingState.Loaded)
|
if (videoPlaceholder.LoadingPage.State != LoadingState.Loaded)
|
||||||
CloseVideo();
|
CloseVideo();
|
||||||
else
|
else
|
||||||
(videoPlaceholder.Content as VideoPage).Player.Minimize();
|
(videoPlaceholder.Frame.Content as VideoPage).Player.Minimize();
|
||||||
|
|
||||||
Title.Text = headers[content.SourcePageType];
|
Title.Text = headers[content.Frame.SourcePageType];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MinimizeVideo()
|
public void MinimizeVideo()
|
||||||
@@ -386,27 +341,28 @@ namespace FoxTube
|
|||||||
videoPlaceholder.HorizontalAlignment = HorizontalAlignment.Right;
|
videoPlaceholder.HorizontalAlignment = HorizontalAlignment.Right;
|
||||||
videoPlaceholder.Margin = new Thickness(0, 0, 25, 50);
|
videoPlaceholder.Margin = new Thickness(0, 0, 25, 50);
|
||||||
|
|
||||||
if (content.CanGoBack)
|
if (content.Frame.CanGoBack)
|
||||||
nav.IsBackEnabled = true;
|
nav.IsBackEnabled = true;
|
||||||
else
|
else
|
||||||
nav.IsBackEnabled = false;
|
nav.IsBackEnabled = false;
|
||||||
|
|
||||||
VideoPageSizeChanged?.Invoke(this, false);
|
|
||||||
|
|
||||||
SetNavigationMenu();
|
SetNavigationMenu();
|
||||||
|
|
||||||
Title.Text = headers[content.SourcePageType];
|
Title.Text = headers[content.Frame.SourcePageType];
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetNavigationMenu()
|
void SetNavigationMenu()
|
||||||
{
|
{
|
||||||
if (content.SourcePageType == typeof(Home) || content.SourcePageType == typeof(Settings) || content.SourcePageType == typeof(Subscriptions))
|
if (content.Frame.SourcePageType == typeof(Home) || content.Frame.SourcePageType == typeof(Settings) || content.Frame.SourcePageType == typeof(Subscriptions))
|
||||||
{
|
{
|
||||||
nav.ExpandedModeThresholdWidth = 1008;
|
nav.ExpandedModeThresholdWidth = 1008;
|
||||||
nav.IsPaneOpen = nav.DisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Expanded ? true : false;
|
nav.IsPaneOpen = nav.DisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Expanded ? true : false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
nav.ExpandedModeThresholdWidth = short.MaxValue;
|
nav.ExpandedModeThresholdWidth = short.MaxValue;
|
||||||
|
nav.IsPaneOpen = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MaximizeVideo()
|
public void MaximizeVideo()
|
||||||
@@ -417,15 +373,13 @@ namespace FoxTube
|
|||||||
videoPlaceholder.HorizontalAlignment = HorizontalAlignment.Stretch;
|
videoPlaceholder.HorizontalAlignment = HorizontalAlignment.Stretch;
|
||||||
videoPlaceholder.Margin = new Thickness(0);
|
videoPlaceholder.Margin = new Thickness(0);
|
||||||
|
|
||||||
if (videoPlaceholder.Content == null)
|
if (videoPlaceholder.Frame.Content == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nav.IsBackEnabled = true;
|
nav.IsBackEnabled = true;
|
||||||
Title.Text = resources.GetString("/Main/video");
|
Title.Text = resources.GetString("/Main/video");
|
||||||
nav.ExpandedModeThresholdWidth = short.MaxValue;
|
nav.ExpandedModeThresholdWidth = short.MaxValue;
|
||||||
nav.IsPaneOpen = false;
|
nav.IsPaneOpen = false;
|
||||||
|
|
||||||
VideoPageSizeChanged?.Invoke(this, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CloseVideo()
|
public void CloseVideo()
|
||||||
@@ -433,20 +387,15 @@ namespace FoxTube
|
|||||||
if (ApplicationView.GetForCurrentView().IsFullScreenMode)
|
if (ApplicationView.GetForCurrentView().IsFullScreenMode)
|
||||||
ApplicationView.GetForCurrentView().ExitFullScreenMode();
|
ApplicationView.GetForCurrentView().ExitFullScreenMode();
|
||||||
|
|
||||||
videoPlaceholder.Content = null;
|
videoPlaceholder.Frame.Content = null;
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
MaximizeVideo();
|
MaximizeVideo();
|
||||||
|
|
||||||
if (content.CanGoBack)
|
nav.IsBackEnabled = content.Frame.CanGoBack;
|
||||||
nav.IsBackEnabled = true;
|
|
||||||
else
|
|
||||||
nav.IsBackEnabled = false;
|
|
||||||
|
|
||||||
VideoPageSizeChanged?.Invoke(this, false);
|
|
||||||
|
|
||||||
SetNavigationMenu();
|
SetNavigationMenu();
|
||||||
|
|
||||||
Title.Text = headers[content.SourcePageType];
|
Title.Text = headers[content.Frame.SourcePageType];
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Search_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
|
private void Search_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
|
||||||
@@ -464,7 +413,7 @@ namespace FoxTube
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
XmlDocument doc = new XmlDocument();
|
XmlDocument doc = new XmlDocument();
|
||||||
doc.Load($"http://suggestqueries.google.com/complete/search?ds=yt&client=toolbar&q={search.Text}");
|
doc.Load($"http://suggestqueries.google.com/complete/search?ds=yt&client=toolbar&q={search.Text}&hl={SettingsStorage.RelevanceLanguage}");
|
||||||
|
|
||||||
List<string> suggestions = new List<string>();
|
List<string> suggestions = new List<string>();
|
||||||
|
|
||||||
@@ -492,7 +441,7 @@ namespace FoxTube
|
|||||||
|
|
||||||
public void Content_Navigated(object sender, NavigationEventArgs e)
|
public void Content_Navigated(object sender, NavigationEventArgs e)
|
||||||
{
|
{
|
||||||
Title.Text = headers[content.SourcePageType];
|
Title.Text = headers[content.Frame.SourcePageType];
|
||||||
|
|
||||||
if (!wasInvoked)
|
if (!wasInvoked)
|
||||||
{
|
{
|
||||||
@@ -508,7 +457,9 @@ namespace FoxTube
|
|||||||
SetNavigationItem(toHome);
|
SetNavigationItem(toHome);
|
||||||
else if (e.SourcePageType == typeof(Search))
|
else if (e.SourcePageType == typeof(Search))
|
||||||
SetNavigationItem(null);
|
SetNavigationItem(null);
|
||||||
else if(e.SourcePageType == typeof(ChannelPage) && SecretsVault.IsAuthorized)
|
else if(e.SourcePageType == typeof(ChannelPage))
|
||||||
|
{
|
||||||
|
if (SecretsVault.IsAuthorized)
|
||||||
{
|
{
|
||||||
if (e.Parameter.ToString() == SecretsVault.AccountId)
|
if (e.Parameter.ToString() == SecretsVault.AccountId)
|
||||||
SetNavigationItem(toChannel);
|
SetNavigationItem(toChannel);
|
||||||
@@ -517,91 +468,86 @@ namespace FoxTube
|
|||||||
else
|
else
|
||||||
SetNavigationItem(null);
|
SetNavigationItem(null);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
SetNavigationItem(null);
|
||||||
|
}
|
||||||
else if(e.SourcePageType == typeof(History))
|
else if(e.SourcePageType == typeof(History))
|
||||||
SetNavigationItem(toHistory);
|
SetNavigationItem(toHistory);
|
||||||
else if(e.SourcePageType == typeof(PlaylistPage))
|
else if(e.SourcePageType == typeof(PlaylistPage))
|
||||||
|
{
|
||||||
|
if (SecretsVault.IsAuthorized)
|
||||||
{
|
{
|
||||||
if (e.Parameter.ToString() == SecretsVault.UserChannel.ContentDetails.RelatedPlaylists.Likes)
|
if (e.Parameter.ToString() == SecretsVault.UserChannel.ContentDetails.RelatedPlaylists.Likes)
|
||||||
SetNavigationItem(toLiked);
|
SetNavigationItem(toLiked);
|
||||||
else if (e.Parameter.Equals("WL"))
|
else if (e.Parameter.Equals("WL"))
|
||||||
SetNavigationItem(toLater);
|
SetNavigationItem(toLater);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
SetNavigationItem(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
wasInvoked = false;
|
wasInvoked = false;
|
||||||
|
|
||||||
if (content.CanGoBack)
|
nav.IsBackEnabled = content.Frame.CanGoBack;
|
||||||
nav.IsBackEnabled = true;
|
|
||||||
else
|
|
||||||
nav.IsBackEnabled = false;
|
|
||||||
|
|
||||||
SetNavigationMenu();
|
SetNavigationMenu();
|
||||||
|
|
||||||
if (videoPlaceholder.Content != null && videoPlaceholder.HorizontalAlignment == HorizontalAlignment.Stretch)
|
if (videoPlaceholder.Frame.Content != null && videoPlaceholder.HorizontalAlignment == HorizontalAlignment.Stretch)
|
||||||
MinimizeAsInitializer();
|
MinimizeAsInitializer();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenContext(object sender, TappedRoutedEventArgs e)
|
|
||||||
{
|
|
||||||
((Microsoft.UI.Xaml.Controls.NavigationViewItem)sender).ContextFlyout.ShowAt((Microsoft.UI.Xaml.Controls.NavigationViewItem)sender);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RemoveAds_Tapped(object sender, TappedRoutedEventArgs e)
|
private void RemoveAds_Tapped(object sender, TappedRoutedEventArgs e)
|
||||||
{
|
{
|
||||||
SecretsVault.GetAdblock();
|
SecretsVault.GetAdblock();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Web_Tapped(object sender, TappedRoutedEventArgs e)
|
|
||||||
{
|
|
||||||
content.Navigate(typeof(Home1));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Nav_SelectionChanged(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewSelectionChangedEventArgs args)
|
private void Nav_SelectionChanged(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewSelectionChangedEventArgs args)
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
if (!wasInvoked)
|
if (!wasInvoked)
|
||||||
{
|
{
|
||||||
|
if (content == null)
|
||||||
|
return;
|
||||||
wasInvoked = true;
|
wasInvoked = true;
|
||||||
if (args.IsSettingsSelected)
|
if (args.IsSettingsSelected)
|
||||||
content.Navigate(typeof(Settings));
|
content.Frame.Navigate(typeof(Settings));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (args.SelectedItem == toHome)
|
if (args.SelectedItem == toHome)
|
||||||
content.Navigate(typeof(Home));
|
content.Frame.Navigate(typeof(Home));
|
||||||
else if (args.SelectedItem == toHistory)
|
else if (args.SelectedItem == toHistory)
|
||||||
content.Navigate(typeof(History));
|
content.Frame.Navigate(typeof(History));
|
||||||
else if (args.SelectedItem == toLiked)
|
else if (args.SelectedItem == toLiked)
|
||||||
content.Navigate(typeof(PlaylistPage), SecretsVault.UserChannel.ContentDetails.RelatedPlaylists.Likes);
|
content.Frame.Navigate(typeof(PlaylistPage), SecretsVault.UserChannel.ContentDetails.RelatedPlaylists.Likes);
|
||||||
else if (args.SelectedItem == toLater)
|
else if (args.SelectedItem == toLater)
|
||||||
content.Navigate(typeof(PlaylistPage), "WL");
|
content.Frame.Navigate(typeof(PlaylistPage), "WL");
|
||||||
else if (args.SelectedItem == toSubscriptions)
|
else if (args.SelectedItem == toSubscriptions)
|
||||||
content.Navigate(typeof(Subscriptions));
|
content.Frame.Navigate(typeof(Subscriptions));
|
||||||
else if (args.SelectedItem == toDownloads)
|
else if (args.SelectedItem == toDownloads)
|
||||||
content.Navigate(typeof(Downloads));
|
content.Frame.Navigate(typeof(Downloads));
|
||||||
else if (args.SelectedItem == toChannel)
|
else if (args.SelectedItem == toChannel)
|
||||||
content.Navigate(typeof(ChannelPage), SecretsVault.UserChannel.Id);
|
content.Frame.Navigate(typeof(ChannelPage), SecretsVault.UserChannel.Id);
|
||||||
else
|
else
|
||||||
content.Navigate(typeof(ChannelPage), (args.SelectedItem as Subscription).Snippet.ResourceId.ChannelId);
|
content.Frame.Navigate(typeof(ChannelPage), (args.SelectedItem as Subscription).Snippet.ResourceId.ChannelId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
wasInvoked = false;
|
wasInvoked = false;
|
||||||
}
|
}
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Nav_BackRequested(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewBackRequestedEventArgs args)
|
private void Nav_BackRequested(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewBackRequestedEventArgs args)
|
||||||
{
|
{
|
||||||
if (videoPlaceholder.Content != null && videoPlaceholder.Width == double.NaN)
|
if (videoPlaceholder.Frame.Content != null && double.IsNaN(videoPlaceholder.Width))
|
||||||
{
|
{
|
||||||
if ((videoPlaceholder.Content as VideoPage).LoadingPage.State != LoadingState.Loaded)
|
if (videoPlaceholder.Frame.CanGoBack)
|
||||||
|
videoPlaceholder.Frame.GoBack();
|
||||||
|
else if (videoPlaceholder.LoadingPage.State != LoadingState.Loaded)
|
||||||
CloseVideo();
|
CloseVideo();
|
||||||
else if (videoPlaceholder.HorizontalAlignment == HorizontalAlignment.Stretch)
|
else
|
||||||
MinimizeAsInitializer();
|
MinimizeAsInitializer();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
content.GoBack();
|
content.Frame.GoBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Nav_PaneClosing(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewPaneClosingEventArgs args)
|
private void Nav_PaneClosing(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewPaneClosingEventArgs args)
|
||||||
@@ -612,11 +558,6 @@ namespace FoxTube
|
|||||||
private void Nav_PaneOpened(Microsoft.UI.Xaml.Controls.NavigationView sender, object args)
|
private void Nav_PaneOpened(Microsoft.UI.Xaml.Controls.NavigationView sender, object args)
|
||||||
{
|
{
|
||||||
AppTitle.Visibility = Visibility.Visible;
|
AppTitle.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
if (sender.DisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Expanded && sender.IsPaneOpen)
|
|
||||||
AppTitleBar.Margin = new Thickness(40, 0, 0, 0);
|
|
||||||
else
|
|
||||||
AppTitleBar.Margin = new Thickness();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
xmlns:local="using:FoxTube.Pages"
|
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"
|
||||||
xmlns:foxtube="using:FoxTube"
|
|
||||||
xmlns:controls="using:FoxTube.Controls"
|
xmlns:controls="using:FoxTube.Controls"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
@@ -40,19 +39,19 @@
|
|||||||
<RowDefinition Height="auto"/>
|
<RowDefinition Height="auto"/>
|
||||||
<RowDefinition/>
|
<RowDefinition/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<StackPanel Grid.Row="0" Margin="20" Grid.Column="1" x:Name="cover" HorizontalAlignment="Left">
|
<StackPanel Grid.Row="0" Margin="10" Grid.Column="1" x:Name="cover" HorizontalAlignment="Left">
|
||||||
<Image Source="/Assets/videoThumbSample.png" Name="thumbnail"/>
|
<Image Source="/Assets/videoThumbSample.png" Name="thumbnail"/>
|
||||||
<TextBlock FontSize="20" Text="[Title]" TextWrapping="WrapWholeWords" Name="title"/>
|
<TextBlock FontSize="20" Text="[Title]" TextWrapping="WrapWholeWords" Name="title"/>
|
||||||
<TextBlock Foreground="Gray" Text="# videos | # views | Updated at: ##-##-## ##:##:##" TextWrapping="WrapWholeWords" Name="info"/>
|
<TextBlock Foreground="Gray" Text="# videos | # views | Updated at: ##-##-## ##:##:##" TextWrapping="WrapWholeWords" Name="info"/>
|
||||||
<TextBlock Foreground="Gray" Text="description" TextWrapping="WrapWholeWords" Name="description"/>
|
<TextBlock Foreground="Gray" Text="description" TextWrapping="WrapWholeWords" Name="description"/>
|
||||||
<Button Margin="0,10,0,0" Background="Transparent" Name="toChannel" Click="toChannel_Click">
|
<Button Margin="10" Background="Transparent" Name="toChannel" Click="toChannel_Click">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
<ColumnDefinition/>
|
<ColumnDefinition/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<PersonPicture Height="50" Name="avatar"/>
|
<PersonPicture Height="50" Name="avatar"/>
|
||||||
<TextBlock Grid.Column="1" Text="Channel name" FontSize="18" VerticalAlignment="Center" Margin="10,0,0,0" TextWrapping="WrapWholeWords" Name="channelName"/>
|
<TextBlock Grid.Column="1" Text="Channel name" FontSize="18" VerticalAlignment="Center" Margin="10,0" TextWrapping="WrapWholeWords" Name="channelName"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Button>
|
</Button>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
@@ -89,7 +88,5 @@
|
|||||||
<AppBarButton x:Uid="/Playlist/refresh" Icon="Refresh" Label="Refresh" Name="refresh" Click="refresh_Click"/>
|
<AppBarButton x:Uid="/Playlist/refresh" Icon="Refresh" Label="Refresh" Name="refresh" Click="refresh_Click"/>
|
||||||
<AppBarButton x:Uid="/Playlist/share" Icon="Share" Label="Share" Name="share" Click="share_Click"/>
|
<AppBarButton x:Uid="/Playlist/share" Icon="Share" Label="Share" Name="share" Click="share_Click"/>
|
||||||
</CommandBar>
|
</CommandBar>
|
||||||
|
|
||||||
<foxtube:LoadingPage Grid.RowSpan="2" Visibility="Collapsed" RefreshPage="refresh_Click" x:Name="loading"/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace FoxTube.Pages
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Playlist page
|
/// Playlist page
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class PlaylistPage : Page, NavigationPage
|
public sealed partial class PlaylistPage : Page, INavigationPage
|
||||||
{
|
{
|
||||||
public object Parameter { get; set; } = null;
|
public object Parameter { get; set; } = null;
|
||||||
public string playlistId;
|
public string playlistId;
|
||||||
@@ -32,17 +32,14 @@ namespace FoxTube.Pages
|
|||||||
public PlaylistPage()
|
public PlaylistPage()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
DataTransferManager.GetForCurrentView().DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(Share);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnNavigatedTo(e);
|
base.OnNavigatedTo(e);
|
||||||
Parameter = e.Parameter;
|
Parameter = e.Parameter;
|
||||||
if (e.Parameter == null)
|
|
||||||
loading.Error("NullReferenceException", "Unable to initialize page. Playlist ID is not stated.");
|
if (e.Parameter as string == "WL")
|
||||||
else if (e.Parameter as string == "WL")
|
|
||||||
LoadWL();
|
LoadWL();
|
||||||
else
|
else
|
||||||
Initialize(e.Parameter as string);
|
Initialize(e.Parameter as string);
|
||||||
@@ -50,8 +47,6 @@ namespace FoxTube.Pages
|
|||||||
|
|
||||||
public async void Initialize(string id)
|
public async void Initialize(string id)
|
||||||
{
|
{
|
||||||
loading.Refresh();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
playlistId = id;
|
playlistId = id;
|
||||||
@@ -66,16 +61,10 @@ namespace FoxTube.Pages
|
|||||||
info.Text = $"{item.ContentDetails.ItemCount} {ResourceLoader.GetForCurrentView("Playlist").GetString("/Playlist/videos")}";
|
info.Text = $"{item.ContentDetails.ItemCount} {ResourceLoader.GetForCurrentView("Playlist").GetString("/Playlist/videos")}";
|
||||||
description.Text = item.Snippet.Localized.Description;
|
description.Text = item.Snippet.Localized.Description;
|
||||||
|
|
||||||
channelName.Text = item.Snippet.ChannelTitle;
|
channelName.Text = Methods.GuardFromNull(item.Snippet.ChannelTitle);
|
||||||
|
|
||||||
ChannelsResource.ListRequest channelRequest = SecretsVault.Service.Channels.List("snippet");
|
avatar.ProfilePicture = new BitmapImage((await new YoutubeExplode.YoutubeClient().GetChannelAsync(item.Snippet.ChannelId)).LogoUrl.ToUri()) { DecodePixelWidth = 50, DecodePixelHeight = 50 };
|
||||||
channelRequest.Id = item.Snippet.ChannelId;
|
thumbnail.Source = new BitmapImage(item.Snippet.Thumbnails.Medium.Url.ToUri());
|
||||||
Channel channel = (await channelRequest.ExecuteAsync()).Items[0];
|
|
||||||
|
|
||||||
try { avatar.ProfilePicture = new BitmapImage(channel.Snippet.Thumbnails.Medium.Url.ToUri()) { DecodePixelWidth = 50, DecodePixelHeight = 50 }; }
|
|
||||||
catch { }
|
|
||||||
try { thumbnail.Source = new BitmapImage(item.Snippet.Thumbnails.Medium.Url.ToUri()); }
|
|
||||||
catch { }
|
|
||||||
|
|
||||||
request = SecretsVault.Service.PlaylistItems.List("contentDetails");
|
request = SecretsVault.Service.PlaylistItems.List("contentDetails");
|
||||||
request.PlaylistId = id;
|
request.PlaylistId = id;
|
||||||
@@ -89,15 +78,15 @@ namespace FoxTube.Pages
|
|||||||
foreach (PlaylistItem i in response.Items)
|
foreach (PlaylistItem i in response.Items)
|
||||||
list.Add(new VideoCard(i.ContentDetails.VideoId, playlistId));
|
list.Add(new VideoCard(i.ContentDetails.VideoId, playlistId));
|
||||||
|
|
||||||
loading.Close();
|
Methods.MainPage.PageContent.LoadingPage.Close();
|
||||||
}
|
}
|
||||||
catch (System.Net.Http.HttpRequestException)
|
catch (System.Net.Http.HttpRequestException)
|
||||||
{
|
{
|
||||||
loading.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
Methods.MainPage.PageContent.LoadingPage.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
loading.Error(e.GetType().ToString(), e.Message);
|
Methods.MainPage.PageContent.LoadingPage.Error(e.GetType().ToString(), e.Message);
|
||||||
Analytics.TrackEvent("Playlist loading error", new Dictionary<string, string>()
|
Analytics.TrackEvent("Playlist loading error", new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "Exception", e.GetType().ToString() },
|
{ "Exception", e.GetType().ToString() },
|
||||||
@@ -109,8 +98,6 @@ namespace FoxTube.Pages
|
|||||||
|
|
||||||
public async void LoadWL()
|
public async void LoadWL()
|
||||||
{
|
{
|
||||||
loading.Refresh();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
playlistId = "WL";
|
playlistId = "WL";
|
||||||
@@ -125,10 +112,8 @@ namespace FoxTube.Pages
|
|||||||
|
|
||||||
channelName.Text = SecretsVault.UserChannel.Snippet.Title;
|
channelName.Text = SecretsVault.UserChannel.Snippet.Title;
|
||||||
|
|
||||||
try { avatar.ProfilePicture = new BitmapImage(SecretsVault.UserChannel.Snippet.Thumbnails.Medium.Url.ToUri()) { DecodePixelWidth = 50, DecodePixelHeight = 50 }; }
|
avatar.ProfilePicture = new BitmapImage(SecretsVault.UserChannel.Snippet.Thumbnails.Medium.Url.ToUri()) { DecodePixelWidth = 50, DecodePixelHeight = 50 };
|
||||||
catch { }
|
thumbnail.Source = new BitmapImage((await new YoutubeExplode.YoutubeClient().GetVideoAsync(SecretsVault.WatchLater.First())).Thumbnails.HighResUrl.ToUri());
|
||||||
try { thumbnail.Source = new BitmapImage((await new YoutubeExplode.YoutubeClient().GetVideoAsync(SecretsVault.WatchLater.First())).Thumbnails.HighResUrl.ToUri()); }
|
|
||||||
catch { }
|
|
||||||
|
|
||||||
for (int k = 0; k < 25 && k < SecretsVault.WatchLater.Count; k++)
|
for (int k = 0; k < 25 && k < SecretsVault.WatchLater.Count; k++)
|
||||||
list.Add(new VideoCard(SecretsVault.WatchLater[k], "WL"));
|
list.Add(new VideoCard(SecretsVault.WatchLater[k], "WL"));
|
||||||
@@ -136,11 +121,11 @@ namespace FoxTube.Pages
|
|||||||
if (list.Count >= SecretsVault.WatchLater.Count)
|
if (list.Count >= SecretsVault.WatchLater.Count)
|
||||||
more.Visibility = Visibility.Collapsed;
|
more.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
loading.Close();
|
Methods.MainPage.PageContent.LoadingPage.Close();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
loading.Error(e.GetType().ToString(), e.Message);
|
Methods.MainPage.PageContent.LoadingPage.Error(e.GetType().ToString(), e.Message);
|
||||||
Analytics.TrackEvent("WL playlist loading error", new Dictionary<string, string>()
|
Analytics.TrackEvent("WL playlist loading error", new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "Exception", e.GetType().ToString() },
|
{ "Exception", e.GetType().ToString() },
|
||||||
@@ -161,11 +146,12 @@ namespace FoxTube.Pages
|
|||||||
|
|
||||||
private void refresh_Click(object sender, RoutedEventArgs e)
|
private void refresh_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Methods.MainPage.GoToPlaylist(playlistId);
|
Methods.MainPage.VideoContent.Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void share_Click(object sender, RoutedEventArgs e)
|
private void share_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
DataTransferManager.GetForCurrentView().DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(Share);
|
||||||
DataTransferManager.ShowShareUI();
|
DataTransferManager.ShowShareUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,5 @@
|
|||||||
<AppBarButton Label="Open in browser" Icon="Globe" Name="inBrowser" Click="InBrowser_Click"/>
|
<AppBarButton Label="Open in browser" Icon="Globe" Name="inBrowser" Click="InBrowser_Click"/>
|
||||||
<AppBarButton Label="Refresh" Icon="Refresh" Click="AppBarButton_Click"/>
|
<AppBarButton Label="Refresh" Icon="Refresh" Click="AppBarButton_Click"/>
|
||||||
</CommandBar>
|
</CommandBar>
|
||||||
|
|
||||||
<local:LoadingPage x:Name="loading" Grid.RowSpan="2" Visibility="Collapsed" RefreshPage="AppBarButton_Click"/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
@@ -16,11 +16,12 @@ namespace FoxTube
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Search page
|
/// Search page
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class Search : Page, NavigationPage
|
public sealed partial class Search : Page, INavigationPage
|
||||||
{
|
{
|
||||||
public object Parameter { get; set; } = null;
|
public object Parameter { get; set; } = null;
|
||||||
readonly ResourceLoader resources = ResourceLoader.GetForCurrentView("Search");
|
readonly ResourceLoader resources = ResourceLoader.GetForCurrentView("Search");
|
||||||
|
|
||||||
|
ContentFrame frame;
|
||||||
public SearchParameters Parameters;
|
public SearchParameters Parameters;
|
||||||
SearchResource.ListRequest request;
|
SearchResource.ListRequest request;
|
||||||
string nextToken;
|
string nextToken;
|
||||||
@@ -65,21 +66,13 @@ namespace FoxTube
|
|||||||
{
|
{
|
||||||
base.OnNavigatedTo(e);
|
base.OnNavigatedTo(e);
|
||||||
Parameter = e.Parameter;
|
Parameter = e.Parameter;
|
||||||
if (e.Parameter == null)
|
|
||||||
loading.Error("NullReferenceException", "Unable to initialize search. Search term is not stated.");
|
frame = ((object[])e.Parameter)[1] as ContentFrame;
|
||||||
else
|
Initialize(((object[])e.Parameter)[0] as SearchParameters);
|
||||||
{
|
|
||||||
if (e.Parameter is SearchParameters)
|
|
||||||
Initialize(e.Parameter as SearchParameters);
|
|
||||||
else
|
|
||||||
loading.Error("ArgumentException", "Wrong parameter");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void Initialize(SearchParameters arg)
|
public async void Initialize(SearchParameters arg)
|
||||||
{
|
{
|
||||||
loading.Refresh();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Parameters = arg;
|
Parameters = arg;
|
||||||
@@ -129,6 +122,7 @@ namespace FoxTube
|
|||||||
SearchListResponse response = await request.ExecuteAsync();
|
SearchListResponse response = await request.ExecuteAsync();
|
||||||
searchTerm.Text = $"{resources.GetString("/Search/header")} '{Parameters.Term}'";
|
searchTerm.Text = $"{resources.GetString("/Search/header")} '{Parameters.Term}'";
|
||||||
resultsCount.Text = $"{resources.GetString("/Search/found")}: {SetResults(response.PageInfo.TotalResults)} {resources.GetString("/Search/items")}";
|
resultsCount.Text = $"{resources.GetString("/Search/found")}: {SetResults(response.PageInfo.TotalResults)} {resources.GetString("/Search/items")}";
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(response.NextPageToken))
|
if (!string.IsNullOrWhiteSpace(response.NextPageToken))
|
||||||
nextToken = response.NextPageToken;
|
nextToken = response.NextPageToken;
|
||||||
else
|
else
|
||||||
@@ -138,15 +132,15 @@ namespace FoxTube
|
|||||||
foreach (SearchResult item in response.Items)
|
foreach (SearchResult item in response.Items)
|
||||||
AddItem(item);
|
AddItem(item);
|
||||||
|
|
||||||
loading.Close();
|
frame.LoadingPage.Close();
|
||||||
}
|
}
|
||||||
catch (System.Net.Http.HttpRequestException)
|
catch (System.Net.Http.HttpRequestException)
|
||||||
{
|
{
|
||||||
loading.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
frame.LoadingPage.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
loading.Error(e.GetType().ToString(), e.Message);
|
frame.LoadingPage.Error(e.GetType().ToString(), e.Message);
|
||||||
Analytics.TrackEvent("Search loading error", new Dictionary<string, string>()
|
Analytics.TrackEvent("Search loading error", new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "Exception", e.GetType().ToString() },
|
{ "Exception", e.GetType().ToString() },
|
||||||
@@ -172,7 +166,7 @@ namespace FoxTube
|
|||||||
|
|
||||||
private void AppBarButton_Click(object sender, RoutedEventArgs e)
|
private void AppBarButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Methods.MainPage.GoToSearch(Parameters);
|
frame.Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void More_Clicked()
|
private async void More_Clicked()
|
||||||
|
|||||||
@@ -9,19 +9,19 @@
|
|||||||
|
|
||||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
<Pivot SelectedIndex="0" Name="pivot" IsHeaderItemsCarouselEnabled="False" SelectionChanged="Pivot_SelectionChanged">
|
<Pivot SelectedIndex="0" Name="pivot" IsHeaderItemsCarouselEnabled="False" SelectionChanged="Pivot_SelectionChanged">
|
||||||
<PivotItem Header="General" x:Uid="/Settings/general">
|
<PivotItem Name="generalTab" Header="General" x:Uid="/Settings/general">
|
||||||
<ScrollViewer>
|
<ScrollViewer>
|
||||||
<settingspages:General/>
|
<settingspages:General/>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</PivotItem>
|
</PivotItem>
|
||||||
<PivotItem Header="About us" x:Uid="/Settings/about">
|
<PivotItem Name="aboutTab" Header="About us" x:Uid="/Settings/about">
|
||||||
<ScrollViewer>
|
<ScrollViewer>
|
||||||
<settingspages:About/>
|
<settingspages:About/>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</PivotItem>
|
</PivotItem>
|
||||||
<PivotItem Header="Inbox" x:Uid="/Settings/inbox">
|
<PivotItem Name="inboxTab" Header="Inbox" x:Uid="/Settings/inbox">
|
||||||
<ScrollViewer>
|
<ScrollViewer>
|
||||||
<settingspages:Inbox/>
|
<settingspages:Inbox x:Name="inbox"/>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</PivotItem>
|
</PivotItem>
|
||||||
</Pivot>
|
</Pivot>
|
||||||
|
|||||||
@@ -7,9 +7,10 @@ namespace FoxTube
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Settings tabs placeholder
|
/// Settings tabs placeholder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class Settings : Page, NavigationPage
|
public sealed partial class Settings : Page, INavigationPage
|
||||||
{
|
{
|
||||||
public object Parameter { get; set; } = null;
|
public object Parameter { get; set; } = null;
|
||||||
|
|
||||||
bool inboxLoaded = false;
|
bool inboxLoaded = false;
|
||||||
string inboxId = null;
|
string inboxId = null;
|
||||||
public Settings()
|
public Settings()
|
||||||
@@ -21,25 +22,30 @@ namespace FoxTube
|
|||||||
{
|
{
|
||||||
base.OnNavigatedTo(e);
|
base.OnNavigatedTo(e);
|
||||||
Parameter = e.Parameter;
|
Parameter = e.Parameter;
|
||||||
if (!string.IsNullOrWhiteSpace(e.Parameter as string))
|
|
||||||
|
if(!string.IsNullOrWhiteSpace((string)e.Parameter))
|
||||||
|
switch((string)e.Parameter)
|
||||||
{
|
{
|
||||||
inboxId = e.Parameter as string;
|
case "about":
|
||||||
pivot.SelectedIndex = 2;
|
pivot.SelectedItem = aboutTab;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
inboxId = (string)e.Parameter;
|
||||||
|
pivot.SelectedItem = inboxTab;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Methods.MainPage.PageContent.LoadingPage.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (pivot.SelectedIndex == 2 && !inboxLoaded)
|
if (pivot.SelectedItem == inboxTab && !inboxLoaded)
|
||||||
{
|
{
|
||||||
(((pivot.Items[2] as PivotItem).Content as ScrollViewer).Content as Inbox).LoadItems();
|
inbox.LoadItems(inboxId);
|
||||||
inboxLoaded = true;
|
inboxLoaded = true;
|
||||||
if(inboxId != null)
|
|
||||||
{
|
|
||||||
(((pivot.Items[2] as PivotItem).Content as ScrollViewer).Content as Inbox).Open(inboxId as string);
|
|
||||||
inboxId = null;
|
inboxId = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -7,48 +7,27 @@
|
|||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
|
|
||||||
<Grid Name="grid">
|
|
||||||
<VisualStateManager.VisualStateGroups>
|
|
||||||
<VisualStateGroup>
|
|
||||||
<VisualState>
|
|
||||||
<VisualState.StateTriggers>
|
|
||||||
<AdaptiveTrigger MinWindowWidth="600"/>
|
|
||||||
</VisualState.StateTriggers>
|
|
||||||
|
|
||||||
<VisualState.Setters>
|
|
||||||
<Setter Target="grid.ColumnDefinitions[1].Width" Value="auto"/>
|
|
||||||
</VisualState.Setters>
|
|
||||||
</VisualState>
|
|
||||||
</VisualStateGroup>
|
|
||||||
</VisualStateManager.VisualStateGroups>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition/>
|
|
||||||
<ColumnDefinition Width="0"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
|
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<TextBlock Text="FoxTube" FontSize="28"/>
|
<TextBlock Text="FoxTube" FontSize="28"/>
|
||||||
<TextBlock Name="version" Text="[currentVersion]" FontSize="14" Foreground="Gray" Margin="0,-5,0,10"/>
|
<TextBlock Name="version" Text="[currentVersion]" FontSize="14" Foreground="Gray" Margin="0,-5,0,0"/>
|
||||||
|
|
||||||
<TextBlock x:Uid="/About/developed" TextWrapping="WrapWholeWords" Text="Developed by Michael Gordeev (also known as XFox)" Margin="0,0,0,10"/>
|
<TextBlock x:Uid="/About/developed" TextWrapping="WrapWholeWords" Text="Developed by Michael "XFox" Gordeev" Margin="0,10,0,0"/>
|
||||||
<TextBlock TextWrapping="WrapWholeWords" Visibility="Collapsed" Text="Special thanks to contributors for motivating me, testers and translators for making this app better everyday and you for using this app;)" Margin="0,0,0,10"/>
|
<TextBlock TextWrapping="WrapWholeWords" Visibility="Collapsed" Text="Special thanks to contributors for motivating me, testers and translators for making this app better everyday and you for using this app;)" Margin="0,10,0,0"/>
|
||||||
|
|
||||||
<TextBlock x:Uid="/About/contacts" Text="Contacts" FontSize="22" FontWeight="SemiBold"/>
|
<TextBlock x:Uid="/About/contacts" Text="Contacts" FontSize="22" FontWeight="SemiBold" Margin="0,10,0,0"/>
|
||||||
<TextBlock><Run x:Uid="/About/twitter">Twitter:</Run> <Hyperlink NavigateUri="https://twitter.com/XFox_Mike">@XFox_Mike</Hyperlink></TextBlock>
|
<TextBlock><Run x:Uid="/About/twitter">Twitter:</Run> <Hyperlink NavigateUri="https://twitter.com/xfox111">@xfox111</Hyperlink></TextBlock>
|
||||||
<TextBlock><Run x:Uid="/About/vk">Vkontakte:</Run> <Hyperlink NavigateUri="https://vk.com/XFox.Mike">@XFox.Mike</Hyperlink></TextBlock>
|
<TextBlock><Run x:Uid="/About/vk">Vkontakte:</Run> <Hyperlink NavigateUri="https://vk.com/XFox.Mike">@XFox.Mike</Hyperlink></TextBlock>
|
||||||
<TextBlock Visibility="Collapsed">YouTube: <Hyperlink NavigateUri="https://youtube.com/c/FoxGameStudioChannel">@FoxGameStudioChannel</Hyperlink></TextBlock>
|
<TextBlock Visibility="Collapsed">YouTube: <Hyperlink NavigateUri="https://youtube.com/c/FoxGameStudioChannel">@xfox</Hyperlink></TextBlock>
|
||||||
<TextBlock>E-mail: <Hyperlink NavigateUri="mailto:michael.xfox@outlook.com">michael.xfox@outlook.com</Hyperlink></TextBlock>
|
<TextBlock>E-mail: <Hyperlink NavigateUri="mailto:michael.xfox@outlook.com">michael.xfox@outlook.com</Hyperlink></TextBlock>
|
||||||
<TextBlock Visibility="Collapsed" Margin="0,0,0,10"> <Run x:Uid="/About/myBlog">My blog (Russian language only):</Run> <Hyperlink NavigateUri="https://michael-xfox.com">https://michael-xfox.com</Hyperlink></TextBlock>
|
<TextBlock Visibility="Collapsed"><Run x:Uid="/About/myBlog">My website:</Run> <Hyperlink NavigateUri="https://michael-xfox.com">https://michael-xfox.com</Hyperlink></TextBlock>
|
||||||
|
|
||||||
<TextBlock x:Uid="/About/legal" Text="Legal stuff" FontSize="22" FontWeight="SemiBold"/>
|
<TextBlock x:Uid="/About/legal" Text="Legal stuff" FontSize="22" FontWeight="SemiBold" Margin="0,10,0,0"/>
|
||||||
<HyperlinkButton x:Uid="/About/ourPrivacy" Content="Our Privacy Policy" NavigateUri="https://foxgame-studio.000webhostapp.com/FoxTubeAssets/PrivacyPolicy.txt" Padding="0,5,0,0"/>
|
<HyperlinkButton x:Uid="/About/ourPrivacy" Content="Our Privacy Policy" NavigateUri="https://foxgame-studio.000webhostapp.com/FoxTubeAssets/PrivacyPolicy.txt" Padding="0"/>
|
||||||
<HyperlinkButton x:Uid="/About/ytPrivacy" Content="YouTube Privacy Policy" NavigateUri="https://youtube.com/t/privacy" Padding="0"/>
|
<HyperlinkButton x:Uid="/About/ytPrivacy" Content="YouTube Privacy Policy" NavigateUri="https://youtube.com/t/privacy" Padding="0"/>
|
||||||
<HyperlinkButton x:Uid="/About/terms" Content="YouTube Terms of use" NavigateUri="https://youtube.com/t/terms" Padding="0"/>
|
<HyperlinkButton x:Uid="/About/terms" Content="YouTube Terms of use" NavigateUri="https://youtube.com/t/terms" Padding="0"/>
|
||||||
<HyperlinkButton x:Uid="/About/guides" Content="YouTube Community Guidelines" NavigateUri="https://youtube.com/t/community_guidelines" Padding="0,0,0,10"/>
|
<HyperlinkButton x:Uid="/About/guides" Content="YouTube Community Guidelines" NavigateUri="https://youtube.com/t/community_guidelines" Padding="0,0,0,10"/>
|
||||||
<TextBlock x:Uid="/About/crMe" Text="© 2018 Michael Gordeev"/>
|
<TextBlock Name="crMe" x:Uid="/About/crMe" Text="© Michael Gordeev"/>
|
||||||
<TextBlock x:Uid="/About/crYt" Text="© 2018 YouTube, LLC"/>
|
<TextBlock Name="crYt" x:Uid="/About/crYt" Text="© YouTube, LLC"/>
|
||||||
<Button Name="feedback" x:Uid="/About/feedback" Content="Leave feedback" Margin="0,5" Click="Button_Click" Visibility="Collapsed"/>
|
<Button Name="feedback" x:Uid="/About/feedback" Content="Leave feedback" Margin="0,10" Click="Button_Click" Visibility="Collapsed"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<Image Grid.Column="1" Source="/Assets/LogoAvatar.png" VerticalAlignment="Top" Width="128"/>
|
|
||||||
</Grid>
|
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ namespace FoxTube.Pages.SettingsPages
|
|||||||
PackageVersion ver = Package.Current.Id.Version;
|
PackageVersion ver = Package.Current.Id.Version;
|
||||||
version.Text = $"{ver.Major}.{ver.Minor}.{ver.Build}";
|
version.Text = $"{ver.Major}.{ver.Minor}.{ver.Build}";
|
||||||
|
|
||||||
|
crMe.Text = crMe.Text.Insert(1, " " + DateTime.Now.Year);
|
||||||
|
crYt.Text = crYt.Text.Insert(1, " " + DateTime.Now.Year);
|
||||||
|
|
||||||
if (StoreServicesFeedbackLauncher.IsSupported())
|
if (StoreServicesFeedbackLauncher.IsSupported())
|
||||||
feedback.Visibility = Visibility.Visible;
|
feedback.Visibility = Visibility.Visible;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ namespace FoxTube.Pages.SettingsPages
|
|||||||
foreach (VideoQuality i in Enum.GetValues(typeof(VideoQuality)).ToReversedList())
|
foreach (VideoQuality i in Enum.GetValues(typeof(VideoQuality)).ToReversedList())
|
||||||
quality.Items.Add(new ComboBoxItem() { Tag = i.GetVideoQualityLabel(), Content = i.GetVideoQualityLabel() });
|
quality.Items.Add(new ComboBoxItem() { Tag = i.GetVideoQualityLabel(), Content = i.GetVideoQualityLabel() });
|
||||||
quality.SelectedItem = quality.Items.ToList().Find(i => ((ComboBoxItem)i).Tag.ToString() == SettingsStorage.VideoQuality);
|
quality.SelectedItem = quality.Items.ToList().Find(i => ((ComboBoxItem)i).Tag.ToString() == SettingsStorage.VideoQuality);
|
||||||
|
|
||||||
mobileWarning.IsOn = SettingsStorage.CheckConnection;
|
mobileWarning.IsOn = SettingsStorage.CheckConnection;
|
||||||
autoplay.IsOn = SettingsStorage.Autoplay;
|
autoplay.IsOn = SettingsStorage.Autoplay;
|
||||||
|
|
||||||
@@ -50,34 +51,34 @@ namespace FoxTube.Pages.SettingsPages
|
|||||||
|
|
||||||
async void InitializeRegions()
|
async void InitializeRegions()
|
||||||
{
|
{
|
||||||
|
//Initialize regions
|
||||||
I18nRegionsResource.ListRequest regRequest = SecretsVault.Service.I18nRegions.List("snippet");
|
I18nRegionsResource.ListRequest regRequest = SecretsVault.Service.I18nRegions.List("snippet");
|
||||||
regRequest.Hl = SettingsStorage.Language;
|
regRequest.Hl = SettingsStorage.Language;
|
||||||
I18nRegionListResponse regResponse = await regRequest.ExecuteAsync();
|
I18nRegionListResponse regResponse = await regRequest.ExecuteAsync();
|
||||||
|
|
||||||
regResponse.Items.ForEach(i => region.Items.Add(new ComboBoxItem
|
regResponse.Items.ForEach(i => region.Items.Add(new ComboBoxItem
|
||||||
{
|
{
|
||||||
Content = i.Snippet.Name,
|
Content = i.Snippet.Name,
|
||||||
Tag = i.Snippet.Gl
|
Tag = i.Snippet.Gl
|
||||||
}));
|
}));
|
||||||
region.SelectedItem = region.Items.Find(i => ((ComboBoxItem)i).Tag as string == SettingsStorage.Region) ?? region.Items.Find(i => ((ComboBoxItem)i).Tag as string == SettingsStorage.Language.Remove(0, 3));
|
region.SelectedItem = region.Items.Find(i => ((ComboBoxItem)i).Tag as string == SettingsStorage.Region);
|
||||||
|
|
||||||
|
//Initialize relevance language
|
||||||
I18nLanguagesResource.ListRequest langRequest = SecretsVault.Service.I18nLanguages.List("snippet");
|
I18nLanguagesResource.ListRequest langRequest = SecretsVault.Service.I18nLanguages.List("snippet");
|
||||||
langRequest.Hl = SettingsStorage.Language;
|
langRequest.Hl = SettingsStorage.Language;
|
||||||
I18nLanguageListResponse langResponse = await langRequest.ExecuteAsync();
|
I18nLanguageListResponse langResponse = await langRequest.ExecuteAsync();
|
||||||
foreach(I18nLanguage i in langResponse.Items)
|
|
||||||
{
|
langResponse.Items.ForEach(i => relLanguage.Items.Add(new ComboBoxItem
|
||||||
relLanguage.Items.Add(new ComboBoxItem
|
|
||||||
{
|
{
|
||||||
Content = i.Snippet.Name,
|
Content = i.Snippet.Name,
|
||||||
Tag = i.Snippet.Hl
|
Tag = i.Snippet.Hl
|
||||||
});
|
}));
|
||||||
if (SettingsStorage.RelevanceLanguage == i.Snippet.Hl)
|
relLanguage.SelectedItem = relLanguage.Items.Find(i => ((ComboBoxItem)i).Tag as string == SettingsStorage.RelevanceLanguage);
|
||||||
relLanguage.SelectedItem = relLanguage.Items.Last();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void language_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void language_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (SettingsStorage.Language == (language.SelectedItem as ComboBoxItem).Tag.ToString())
|
if ((language.SelectedItem as ComboBoxItem).Tag.ToString() == SettingsStorage.Language)
|
||||||
return;
|
return;
|
||||||
ApplicationLanguages.PrimaryLanguageOverride = (language.SelectedItem as ComboBoxItem).Tag.ToString();
|
ApplicationLanguages.PrimaryLanguageOverride = (language.SelectedItem as ComboBoxItem).Tag.ToString();
|
||||||
SettingsStorage.Language = (language.SelectedItem as ComboBoxItem).Tag.ToString();
|
SettingsStorage.Language = (language.SelectedItem as ComboBoxItem).Tag.ToString();
|
||||||
@@ -104,6 +105,11 @@ namespace FoxTube.Pages.SettingsPages
|
|||||||
SettingsStorage.VideoNotifications = newVideo.IsOn;
|
SettingsStorage.VideoNotifications = newVideo.IsOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void devNews_Toggled(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
SettingsStorage.DevNotifications = devNews.IsOn;
|
||||||
|
}
|
||||||
|
|
||||||
private void RelLanguage_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void RelLanguage_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
SettingsStorage.RelevanceLanguage = ((ComboBoxItem)relLanguage.SelectedItem).Tag.ToString();
|
SettingsStorage.RelevanceLanguage = ((ComboBoxItem)relLanguage.SelectedItem).Tag.ToString();
|
||||||
@@ -121,17 +127,17 @@ namespace FoxTube.Pages.SettingsPages
|
|||||||
|
|
||||||
private void RadioButton_Checked(object sender, RoutedEventArgs e)
|
private void RadioButton_Checked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (sender == light && SettingsStorage.Theme != 0)
|
if (sender == light)
|
||||||
{
|
{
|
||||||
SettingsStorage.Theme = 0;
|
SettingsStorage.Theme = 0;
|
||||||
Methods.MainPage.RequestedTheme = ElementTheme.Light;
|
Methods.MainPage.RequestedTheme = ElementTheme.Light;
|
||||||
}
|
}
|
||||||
else if (sender == dark && SettingsStorage.Theme != 1)
|
else if (sender == dark)
|
||||||
{
|
{
|
||||||
SettingsStorage.Theme = 1;
|
SettingsStorage.Theme = 1;
|
||||||
Methods.MainPage.RequestedTheme = ElementTheme.Dark;
|
Methods.MainPage.RequestedTheme = ElementTheme.Dark;
|
||||||
}
|
}
|
||||||
else if (sender == system && SettingsStorage.Theme != 2)
|
else if (sender == system)
|
||||||
{
|
{
|
||||||
SettingsStorage.Theme = 2;
|
SettingsStorage.Theme = 2;
|
||||||
if (new Windows.UI.ViewManagement.UISettings().GetColorValue(Windows.UI.ViewManagement.UIColorType.Background) == Colors.Black)
|
if (new Windows.UI.ViewManagement.UISettings().GetColorValue(Windows.UI.ViewManagement.UIColorType.Background) == Colors.Black)
|
||||||
@@ -146,10 +152,5 @@ namespace FoxTube.Pages.SettingsPages
|
|||||||
{
|
{
|
||||||
CoreApplication.Exit();
|
CoreApplication.Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void devNews_Toggled(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
SettingsStorage.DevNotifications = devNews.IsOn;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<Grid Name="grid">
|
<Grid Name="grid">
|
||||||
<VisualStateManager.VisualStateGroups>
|
<VisualStateManager.VisualStateGroups>
|
||||||
<VisualStateGroup>
|
<VisualStateGroup CurrentStateChanged="VisualStateGroup_CurrentStateChanged">
|
||||||
<VisualState>
|
<VisualState>
|
||||||
<VisualState.StateTriggers>
|
<VisualState.StateTriggers>
|
||||||
<AdaptiveTrigger MinWindowWidth="1500"/>
|
<AdaptiveTrigger MinWindowWidth="1500"/>
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
<Setter Target="grid.ColumnDefinitions[0].Width" Value="*"/>
|
<Setter Target="grid.ColumnDefinitions[0].Width" Value="*"/>
|
||||||
<Setter Target="grid.ColumnDefinitions[1].Width" Value="3*"/>
|
<Setter Target="grid.ColumnDefinitions[1].Width" Value="3*"/>
|
||||||
<Setter Target="close.Visibility" Value="Collapsed"/>
|
<Setter Target="close.Visibility" Value="Collapsed"/>
|
||||||
|
<Setter Target="selector.Background" Value="{StaticResource SystemControlBackgroundChromeMediumLowBrush}"/>
|
||||||
</VisualState.Setters>
|
</VisualState.Setters>
|
||||||
</VisualState>
|
</VisualState>
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@
|
|||||||
<Setter Target="grid.ColumnDefinitions[0].Width" Value="*"/>
|
<Setter Target="grid.ColumnDefinitions[0].Width" Value="*"/>
|
||||||
<Setter Target="grid.ColumnDefinitions[1].Width" Value="2*"/>
|
<Setter Target="grid.ColumnDefinitions[1].Width" Value="2*"/>
|
||||||
<Setter Target="close.Visibility" Value="Collapsed"/>
|
<Setter Target="close.Visibility" Value="Collapsed"/>
|
||||||
|
<Setter Target="selector.Background" Value="{StaticResource SystemControlBackgroundChromeMediumLowBrush}"/>
|
||||||
</VisualState.Setters>
|
</VisualState.Setters>
|
||||||
</VisualState>
|
</VisualState>
|
||||||
|
|
||||||
@@ -44,6 +46,7 @@
|
|||||||
<Setter Target="grid.ColumnDefinitions[0].Width" Value="*"/>
|
<Setter Target="grid.ColumnDefinitions[0].Width" Value="*"/>
|
||||||
<Setter Target="grid.ColumnDefinitions[1].Width" Value="*"/>
|
<Setter Target="grid.ColumnDefinitions[1].Width" Value="*"/>
|
||||||
<Setter Target="close.Visibility" Value="Collapsed"/>
|
<Setter Target="close.Visibility" Value="Collapsed"/>
|
||||||
|
<Setter Target="selector.Background" Value="{StaticResource SystemControlBackgroundChromeMediumLowBrush}"/>
|
||||||
</VisualState.Setters>
|
</VisualState.Setters>
|
||||||
</VisualState>
|
</VisualState>
|
||||||
</VisualStateGroup>
|
</VisualStateGroup>
|
||||||
@@ -53,7 +56,7 @@
|
|||||||
<ColumnDefinition Width="0"/>
|
<ColumnDefinition Width="0"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<StackPanel VerticalAlignment="Stretch" Background="{StaticResource SystemControlBackgroundChromeMediumLowBrush}">
|
<StackPanel VerticalAlignment="Stretch" Name="selector">
|
||||||
<ComboBox x:Uid="/Inbox/filter" Header="Filter" Margin="10" HorizontalAlignment="Stretch" SelectedIndex="0" Name="filter" SelectionChanged="filter_SelectionChanged">
|
<ComboBox x:Uid="/Inbox/filter" Header="Filter" Margin="10" HorizontalAlignment="Stretch" SelectedIndex="0" Name="filter" SelectionChanged="filter_SelectionChanged">
|
||||||
<ComboBoxItem x:Uid="/Inbox/all" Content="All"/>
|
<ComboBoxItem x:Uid="/Inbox/all" Content="All"/>
|
||||||
<ComboBoxItem x:Uid="/Inbox/messages" Content="Messages"/>
|
<ComboBoxItem x:Uid="/Inbox/messages" Content="Messages"/>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using Windows.UI.Xaml.Controls;
|
|||||||
using FoxTube.Classes;
|
using FoxTube.Classes;
|
||||||
using Windows.Storage;
|
using Windows.Storage;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
using Microsoft.AppCenter.Analytics;
|
||||||
|
|
||||||
namespace FoxTube.Pages.SettingsPages
|
namespace FoxTube.Pages.SettingsPages
|
||||||
{
|
{
|
||||||
@@ -15,27 +16,26 @@ namespace FoxTube.Pages.SettingsPages
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class Inbox : Page
|
public sealed partial class Inbox : Page
|
||||||
{
|
{
|
||||||
List<InboxItem> items = new List<InboxItem>();
|
readonly List<InboxItem> items = new List<InboxItem>();
|
||||||
|
|
||||||
string open;
|
|
||||||
public Inbox()
|
public Inbox()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void LoadItems()
|
public async void LoadItems(string id = null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
XmlDocument doc = new XmlDocument();
|
XmlDocument doc = new XmlDocument();
|
||||||
|
|
||||||
StorageFile file = await (await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync(@"Assets\Data")).GetFileAsync("Patchnotes.xml");
|
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync("ms-appx:///Assets/Data/Patchnotes.xml".ToUri());
|
||||||
doc.Load(await file.OpenStreamForReadAsync());
|
doc.Load(await file.OpenStreamForReadAsync());
|
||||||
foreach (XmlElement e in doc["items"].ChildNodes)
|
foreach (XmlElement e in doc["items"].ChildNodes)
|
||||||
items.Add(new InboxItem(
|
items.Add(new InboxItem(
|
||||||
e.GetAttribute("version"),
|
e.GetAttribute("version"),
|
||||||
e["content"][SettingsStorage.Language].InnerText,
|
e["content"][SettingsStorage.Language].InnerText,
|
||||||
e.GetAttribute("time")));
|
DateTime.Parse(e.GetAttribute("time"))));
|
||||||
|
|
||||||
doc.Load("http://foxgame-studio.000webhostapp.com/foxtube-messages.xml");
|
doc.Load("http://foxgame-studio.000webhostapp.com/foxtube-messages.xml");
|
||||||
foreach (XmlElement e in doc["posts"].ChildNodes)
|
foreach (XmlElement e in doc["posts"].ChildNodes)
|
||||||
@@ -43,25 +43,29 @@ namespace FoxTube.Pages.SettingsPages
|
|||||||
e["header"][SettingsStorage.Language].InnerText,
|
e["header"][SettingsStorage.Language].InnerText,
|
||||||
e["content"][SettingsStorage.Language].InnerText,
|
e["content"][SettingsStorage.Language].InnerText,
|
||||||
DateTime.Parse(e.GetAttribute("time")),
|
DateTime.Parse(e.GetAttribute("time")),
|
||||||
e["id"].InnerText
|
e["id"].InnerText));
|
||||||
));
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Analytics.TrackEvent("Failed to load inbox", new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "Exception", e.GetType().ToString() },
|
||||||
|
{ "Message", e.Message }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
items.OrderBy(item => item.TimeStamp);
|
items.OrderBy(item => item.TimeStamp);
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
|
|
||||||
items.ForEach(i => list.Items.Add(i));
|
items.ForEach(i => list.Items.Add(i));
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(open))
|
if (!string.IsNullOrWhiteSpace(id))
|
||||||
Open(open);
|
list.SelectedItem = items.Find(i => i.Id == id);
|
||||||
|
|
||||||
open = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void filter_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void filter_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
if (list == null)
|
||||||
{
|
return;
|
||||||
|
|
||||||
list.Items.Clear();
|
list.Items.Clear();
|
||||||
|
|
||||||
switch (filter.SelectedIndex)
|
switch (filter.SelectedIndex)
|
||||||
@@ -81,21 +85,13 @@ namespace FoxTube.Pages.SettingsPages
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(NullReferenceException) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
private void list_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void list_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
InboxItem item = list.SelectedItem as InboxItem;
|
if (!(list.SelectedItem is InboxItem item))
|
||||||
if(list.SelectedItem != null)
|
return;
|
||||||
{
|
|
||||||
OpenView(item.Title, item.Content);
|
OpenView(item.Title, item.Content);
|
||||||
if (grid.ColumnDefinitions[1].Width.Value == 0)
|
|
||||||
{
|
|
||||||
grid.ColumnDefinitions[0].Width = new GridLength(0);
|
|
||||||
grid.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Star);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseView()
|
void CloseView()
|
||||||
@@ -104,6 +100,12 @@ namespace FoxTube.Pages.SettingsPages
|
|||||||
title.Text = "";
|
title.Text = "";
|
||||||
list.SelectedItem = null;
|
list.SelectedItem = null;
|
||||||
block.Visibility = Visibility.Visible;
|
block.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
|
if (grid.ColumnDefinitions[0].Width.Value == 0)
|
||||||
|
{
|
||||||
|
grid.ColumnDefinitions[1].Width = new GridLength(0);
|
||||||
|
grid.ColumnDefinitions[0].Width = new GridLength(1, GridUnitType.Star);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenView(string header, string body)
|
void OpenView(string header, string body)
|
||||||
@@ -111,29 +113,23 @@ namespace FoxTube.Pages.SettingsPages
|
|||||||
content.Text = body;
|
content.Text = body;
|
||||||
title.Text = header;
|
title.Text = header;
|
||||||
block.Visibility = Visibility.Collapsed;
|
block.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
|
if (grid.ColumnDefinitions[1].Width.Value == 0)
|
||||||
|
{
|
||||||
|
grid.ColumnDefinitions[0].Width = new GridLength(0);
|
||||||
|
grid.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Star);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void close_Click(object sender, RoutedEventArgs e)
|
private void close_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
CloseView();
|
CloseView();
|
||||||
if (grid.ColumnDefinitions[0].Width.Value == 0)
|
|
||||||
{
|
|
||||||
grid.ColumnDefinitions[0].Width = new GridLength(1, GridUnitType.Star);
|
|
||||||
grid.ColumnDefinitions[1].Width = new GridLength(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Open(string arg)
|
private void VisualStateGroup_CurrentStateChanged(object sender, VisualStateChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if(items.Count == 0)
|
if (e.NewState == null)
|
||||||
{
|
CloseView();
|
||||||
open = arg;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
InboxItem item = items.Find(i => i.Id == arg);
|
|
||||||
if(item != null)
|
|
||||||
list.SelectedItem = item;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,12 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
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"
|
||||||
xmlns:foxtube="using:FoxTube"
|
|
||||||
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
|
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
|
|
||||||
<Grid>
|
|
||||||
<ScrollViewer>
|
<ScrollViewer>
|
||||||
<controls:AdaptiveGridView ItemsSource="{x:Bind list}" DesiredWidth="250" Margin="5,0,0,0">
|
<controls:AdaptiveGridView ItemsSource="{x:Bind list}" DesiredWidth="250">
|
||||||
<controls:AdaptiveGridView.ItemTemplate>
|
<controls:AdaptiveGridView.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Button HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Padding="5" Tag="{Binding Path=Snippet.ResourceId.ChannelId}" Click="Button_Click">
|
<Button HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Padding="5" Tag="{Binding Path=Snippet.ResourceId.ChannelId}" Click="Button_Click">
|
||||||
@@ -32,6 +30,4 @@
|
|||||||
</controls:AdaptiveGridView.ItemTemplate>
|
</controls:AdaptiveGridView.ItemTemplate>
|
||||||
</controls:AdaptiveGridView>
|
</controls:AdaptiveGridView>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
<foxtube:LoadingPage Visibility="Collapsed"/>
|
|
||||||
</Grid>
|
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
@@ -8,13 +8,15 @@ namespace FoxTube.Pages
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// User's subscriptions page
|
/// User's subscriptions page
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class Subscriptions : Page, NavigationPage
|
public sealed partial class Subscriptions : Page, INavigationPage
|
||||||
{
|
{
|
||||||
public object Parameter { get; set; } = null;
|
public object Parameter { get; set; } = null;
|
||||||
readonly List<Subscription> list = SecretsVault.Subscriptions;
|
readonly List<Subscription> list = SecretsVault.Subscriptions;
|
||||||
public Subscriptions()
|
public Subscriptions()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
Methods.MainPage.PageContent.LoadingPage.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Button_Click(object sender, RoutedEventArgs e)
|
private void Button_Click(object sender, RoutedEventArgs e)
|
||||||
|
|||||||
@@ -4,22 +4,17 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
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"
|
||||||
|
xmlns:ui="using:Microsoft.Toolkit.Uwp.UI.Controls"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
|
||||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Name="grid" SizeChanged="Grid_SizeChanged">
|
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
<Grid.ColumnDefinitions>
|
<ui:AdaptiveGridView Name="list" DesiredWidth="400" SelectionMode="None" HorizontalContentAlignment="Left">
|
||||||
<ColumnDefinition/>
|
<ui:AdaptiveGridView.ItemContainerTransitions>
|
||||||
<ColumnDefinition Width="0"/>
|
<TransitionCollection>
|
||||||
<ColumnDefinition Width="0"/>
|
<EntranceThemeTransition IsStaggeringEnabled="True"/>
|
||||||
<ColumnDefinition Width="0"/>
|
</TransitionCollection>
|
||||||
<ColumnDefinition Width="0"/>
|
</ui:AdaptiveGridView.ItemContainerTransitions>
|
||||||
</Grid.ColumnDefinitions>
|
</ui:AdaptiveGridView>
|
||||||
<TextBlock Name="empty" Grid.ColumnSpan="5" Text="Ø" FontSize="200" Foreground="Gray" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.RowSpan="2"/>
|
<TextBlock Name="empty" Text="Ø" FontSize="200" Foreground="Gray" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.RowSpan="2"/>
|
||||||
|
|
||||||
<StackPanel Grid.Column="0" Name="col0"/>
|
|
||||||
<StackPanel Grid.Column="1" Name="col1"/>
|
|
||||||
<StackPanel Grid.Column="2" Name="col2"/>
|
|
||||||
<StackPanel Grid.Column="3" Name="col3"/>
|
|
||||||
<StackPanel Grid.Column="4" Name="col4"/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using FoxTube.Controls.Adverts;
|
using FoxTube.Controls;
|
||||||
using System.Collections.Generic;
|
using FoxTube.Controls.Adverts;
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
|
|
||||||
@@ -10,19 +10,9 @@ namespace FoxTube.Pages
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class VideoGrid : Page
|
public sealed partial class VideoGrid : Page
|
||||||
{
|
{
|
||||||
public int Columns
|
public int Count => list.Items.Count;
|
||||||
{
|
public ItemCollection Children => list.Items;
|
||||||
get { return cols; }
|
private int ItemsCount => Children.FindAll(i => i is VideoCard).Count + Children.FindAll(i => i is ChannelCard).Count + Children.FindAll(i => i is PlaylistCard).Count + Children.FindAll(i => i is CardAdvert).Count;
|
||||||
set
|
|
||||||
{
|
|
||||||
cols = value;
|
|
||||||
UpdateGrid();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private int cols = 1;
|
|
||||||
public int Count => Children.Count;
|
|
||||||
public bool IsRelatedVideos { get; set; } = false;
|
|
||||||
public List<UIElement> Children { get; } = new List<UIElement>();
|
|
||||||
|
|
||||||
public VideoGrid()
|
public VideoGrid()
|
||||||
{
|
{
|
||||||
@@ -31,60 +21,21 @@ namespace FoxTube.Pages
|
|||||||
|
|
||||||
public void Add(UIElement card)
|
public void Add(UIElement card)
|
||||||
{
|
{
|
||||||
(grid.Children[Count % cols + 1] as StackPanel).Children.Add(card);
|
list.Items.Add(card);
|
||||||
Children.Add(card);
|
if ((list.Items.Count - 5) % 25 == 0)
|
||||||
|
list.Items.Add(new CardAdvert());
|
||||||
if ((Children.Count - 5) % 25 == 0 && !SecretsVault.AdsDisabled)
|
|
||||||
{
|
|
||||||
CardAdvert advert = new CardAdvert(IsRelatedVideos);
|
|
||||||
(grid.Children[Count % cols + 1] as StackPanel).Children.Add(advert);
|
|
||||||
Children.Add(advert);
|
|
||||||
}
|
|
||||||
|
|
||||||
empty.Visibility = Visibility.Collapsed;
|
empty.Visibility = Visibility.Collapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
for (int k = 1; k <= 5; k++)
|
list.Items.Clear();
|
||||||
(grid.Children[k] as StackPanel).Children.Clear();
|
|
||||||
|
|
||||||
empty.Visibility = Visibility.Visible;
|
empty.Visibility = Visibility.Visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteItem(FrameworkElement item)
|
public void DeleteItem(FrameworkElement item)
|
||||||
{
|
{
|
||||||
Children.Remove(item);
|
Children.Remove(item);
|
||||||
UpdateGrid();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateGrid()
|
|
||||||
{
|
|
||||||
for (int k = 1; k <= 5; k++)
|
|
||||||
(grid.Children[k] as StackPanel).Children.Clear();
|
|
||||||
|
|
||||||
for (int k = 0; k < Count; k++)
|
|
||||||
(grid.Children[k % cols + 1] as StackPanel).Children.Add(Children[k]);
|
|
||||||
|
|
||||||
for (int k = 0; k < cols; k++)
|
|
||||||
grid.ColumnDefinitions[k].Width = new GridLength(1, GridUnitType.Star);
|
|
||||||
|
|
||||||
for (int k = cols; k < 5; k++)
|
|
||||||
grid.ColumnDefinitions[k].Width = new GridLength(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Grid_SizeChanged(object sender, SizeChangedEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.NewSize.Width >= 1600 && Columns != 5)
|
|
||||||
Columns = 5;
|
|
||||||
else if (e.NewSize.Width >= 1200 && e.NewSize.Width < 1600 && Columns != 4)
|
|
||||||
Columns = 4;
|
|
||||||
else if (e.NewSize.Width >= 900 && e.NewSize.Width < 1200 && Columns != 3)
|
|
||||||
Columns = 3;
|
|
||||||
else if (e.NewSize.Width >= 550 && e.NewSize.Width < 900 && Columns != 2)
|
|
||||||
Columns = 2;
|
|
||||||
else if (e.NewSize.Width < 550 && Columns != 1)
|
|
||||||
Columns = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,8 +29,8 @@
|
|||||||
<ColumnDefinition Width="400"/>
|
<ColumnDefinition Width="400"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<ScrollViewer Margin="0,0,0,50" Name="mainScroll" VerticalScrollBarVisibility="Hidden">
|
<ScrollViewer Margin="0,0,0,50" Name="mainScroll" VerticalScrollBarVisibility="Hidden">
|
||||||
<StackPanel Orientation="Vertical" Name="mainContent">
|
<StackPanel Name="mainContent">
|
||||||
<Border BorderBrush="Red" BorderThickness="5" CornerRadius="10" Margin="0,10" Name="upcoming" Visibility="Collapsed">
|
<Border BorderBrush="Red" BorderThickness="5" CornerRadius="10" Margin="10" Name="upcoming" Visibility="Collapsed">
|
||||||
<Grid Margin="10">
|
<Grid Margin="10">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="auto"/>
|
<ColumnDefinition Width="auto"/>
|
||||||
@@ -125,10 +125,10 @@
|
|||||||
</CommandBar>
|
</CommandBar>
|
||||||
|
|
||||||
<Grid Grid.Column="1" Name="tabsPlaceholder">
|
<Grid Grid.Column="1" Name="tabsPlaceholder">
|
||||||
<Pivot Grid.Row="1" Name="pivot" SelectedIndex="0" IsHeaderItemsCarouselEnabled="False">
|
<Pivot Name="pivot" SelectedIndex="0" IsHeaderItemsCarouselEnabled="False">
|
||||||
<PivotItem x:Uid="/VideoPage/related" Header="Suggestions">
|
<PivotItem x:Uid="/VideoPage/related" Header="Suggestions">
|
||||||
<ScrollViewer>
|
<ScrollViewer>
|
||||||
<pages:VideoGrid x:Name="relatedVideos" IsRelatedVideos="True"/>
|
<pages:VideoGrid x:Name="relatedVideos"/>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</PivotItem>
|
</PivotItem>
|
||||||
<PivotItem x:Uid="/VideoPage/comments" Header="Comments" Name="commentsPlaceholder">
|
<PivotItem x:Uid="/VideoPage/comments" Header="Comments" Name="commentsPlaceholder">
|
||||||
@@ -174,7 +174,5 @@
|
|||||||
</ComboBox>
|
</ComboBox>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ContentDialog>
|
</ContentDialog>
|
||||||
|
|
||||||
<local:LoadingPage Grid.ColumnSpan="2" Visibility="Collapsed" x:Name="loading" RefreshPage="refresh_Click"/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
@@ -42,11 +42,12 @@ namespace FoxTube.Pages
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Video page
|
/// Video page
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class VideoPage : Page
|
public sealed partial class VideoPage : Page, INavigationPage
|
||||||
{
|
{
|
||||||
ResourceLoader resources = ResourceLoader.GetForCurrentView("VideoPage");
|
ResourceLoader resources = ResourceLoader.GetForCurrentView("VideoPage");
|
||||||
|
|
||||||
public string videoId;
|
public object Parameter { get; set; } = null;
|
||||||
|
|
||||||
public string playlistId = null;
|
public string playlistId = null;
|
||||||
public Video item;
|
public Video item;
|
||||||
public HistoryItem history;
|
public HistoryItem history;
|
||||||
@@ -59,15 +60,12 @@ namespace FoxTube.Pages
|
|||||||
DispatcherTimer liveTimer;
|
DispatcherTimer liveTimer;
|
||||||
DispatcherTimer countdownTimer;
|
DispatcherTimer countdownTimer;
|
||||||
|
|
||||||
public LoadingPage LoadingPage => loading;
|
|
||||||
public VideoPlayer Player => player;
|
public VideoPlayer Player => player;
|
||||||
|
|
||||||
public VideoPage()
|
public VideoPage()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
DataTransferManager.GetForCurrentView().DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(Share);
|
|
||||||
|
|
||||||
if (Window.Current.Bounds.Width <= 1000)
|
if (Window.Current.Bounds.Width <= 1000)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("Correcting layout...");
|
Debug.WriteLine("Correcting layout...");
|
||||||
@@ -78,14 +76,12 @@ namespace FoxTube.Pages
|
|||||||
mainContent.Children.Add(pivot);
|
mainContent.Children.Add(pivot);
|
||||||
|
|
||||||
grid.ColumnDefinitions[1].Width = new GridLength(0);
|
grid.ColumnDefinitions[1].Width = new GridLength(0);
|
||||||
|
|
||||||
pivot.SelectedIndex = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Player_NextClicked()
|
private void Player_NextClicked()
|
||||||
{
|
{
|
||||||
if (playlistId != null)
|
if (playlistId != null && playlistList.SelectedIndex + 1 < playlistList.Items.Count)
|
||||||
playlistList.SelectedIndex++;
|
playlistList.SelectedIndex++;
|
||||||
else
|
else
|
||||||
(relatedVideos.Children[0] as VideoCard).Button_Click(this, null);
|
(relatedVideos.Children[0] as VideoCard).Button_Click(this, null);
|
||||||
@@ -94,19 +90,15 @@ namespace FoxTube.Pages
|
|||||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnNavigatedTo(e);
|
base.OnNavigatedTo(e);
|
||||||
if (e.Parameter == null)
|
Parameter = e.Parameter;
|
||||||
loading.Error("NullReferenceException", "Unable to initialize page. Video ID is not stated.");
|
|
||||||
else
|
|
||||||
Initialize(e.Parameter as object[]);
|
Initialize(e.Parameter as object[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void Initialize(object[] ids)
|
public async void Initialize(object[] ids)
|
||||||
{
|
{
|
||||||
loading.Refresh();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
videoId = ids[0] as string;
|
|
||||||
incognito = (bool)ids[2];
|
incognito = (bool)ids[2];
|
||||||
|
|
||||||
if (ids[1] != null)
|
if (ids[1] != null)
|
||||||
@@ -130,27 +122,26 @@ namespace FoxTube.Pages
|
|||||||
LoadInfo();
|
LoadInfo();
|
||||||
LoadAddTo();
|
LoadAddTo();
|
||||||
|
|
||||||
loading.Close();
|
Methods.MainPage.VideoContent.LoadingPage.Close();
|
||||||
}
|
}
|
||||||
catch (System.Net.Http.HttpRequestException)
|
catch (System.Net.Http.HttpRequestException)
|
||||||
{
|
{
|
||||||
loading.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
Methods.MainPage.VideoContent.LoadingPage.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
loading.Error(e.GetType().ToString(), e.Message);
|
Methods.MainPage.VideoContent.LoadingPage.Error(e.GetType().ToString(), e.Message);
|
||||||
Analytics.TrackEvent("Video loading error", new Dictionary<string, string>()
|
Analytics.TrackEvent("Video loading error", new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "Exception", e.GetType().ToString() },
|
{ "Exception", e.GetType().ToString() },
|
||||||
{ "Message", e.Message },
|
{ "Message", e.Message },
|
||||||
{ "Video ID", videoId }
|
{ "Video ID", item.Id }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSchedule()
|
void SetSchedule()
|
||||||
{
|
{
|
||||||
views.Visibility = Visibility.Collapsed;
|
|
||||||
upcoming.Visibility = Visibility.Visible;
|
upcoming.Visibility = Visibility.Visible;
|
||||||
if (item.LiveStreamingDetails.ScheduledEndTime.HasValue || item.LiveStreamingDetails.ScheduledStartTime.HasValue)
|
if (item.LiveStreamingDetails.ScheduledEndTime.HasValue || item.LiveStreamingDetails.ScheduledStartTime.HasValue)
|
||||||
schedule.Visibility = Visibility.Visible;
|
schedule.Visibility = Visibility.Visible;
|
||||||
@@ -208,7 +199,6 @@ namespace FoxTube.Pages
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
//Retrieving data
|
//Retrieving data
|
||||||
PlaylistsResource.ListRequest playlistRequest = SecretsVault.Service.Playlists.List("snippet,contentDetails");
|
PlaylistsResource.ListRequest playlistRequest = SecretsVault.Service.Playlists.List("snippet,contentDetails");
|
||||||
playlistRequest.Id = id;
|
playlistRequest.Id = id;
|
||||||
@@ -237,7 +227,7 @@ namespace FoxTube.Pages
|
|||||||
|
|
||||||
//Setting data
|
//Setting data
|
||||||
playlistName.Text = playlistItem.Snippet.Localized.Title;
|
playlistName.Text = playlistItem.Snippet.Localized.Title;
|
||||||
playlistChannel.Text = playlistItem.Snippet.ChannelTitle;
|
playlistChannel.Text = Methods.GuardFromNull(playlistItem.Snippet.ChannelTitle);
|
||||||
|
|
||||||
playlistCounter.Text = $"{items.IndexOf(selection) + 1}/{playlistItem.ContentDetails.ItemCount}";
|
playlistCounter.Text = $"{items.IndexOf(selection) + 1}/{playlistItem.ContentDetails.ItemCount}";
|
||||||
}
|
}
|
||||||
@@ -249,9 +239,6 @@ namespace FoxTube.Pages
|
|||||||
await Task.Delay(500);
|
await Task.Delay(500);
|
||||||
|
|
||||||
playlistScroll.ChangeView(null, playlistList.SelectedIndex * 86 + 89, null, true);
|
playlistScroll.ChangeView(null, playlistList.SelectedIndex * 86 + 89, null, true);
|
||||||
|
|
||||||
if (playlistList.SelectedIndex == playlistList.Items.Count - 1)
|
|
||||||
player.Controls.IsNextTrackButtonVisible = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async void LoadInfo()
|
async void LoadInfo()
|
||||||
@@ -259,7 +246,7 @@ namespace FoxTube.Pages
|
|||||||
//Setting meta
|
//Setting meta
|
||||||
title.Text = item.Snippet.Localized.Title;
|
title.Text = item.Snippet.Localized.Title;
|
||||||
date.Text = $"{resources.GetString("/VideoPage/publishedAt")}: {item.Snippet.PublishedAt} ({Methods.GetAgo(item.Snippet.PublishedAt.Value)})";
|
date.Text = $"{resources.GetString("/VideoPage/publishedAt")}: {item.Snippet.PublishedAt} ({Methods.GetAgo(item.Snippet.PublishedAt.Value)})";
|
||||||
Methods.FormatText(ref description, item.Snippet.Localized.Description);
|
description.FormatText(item.Snippet.Localized.Description);
|
||||||
|
|
||||||
//Setting channel button
|
//Setting channel button
|
||||||
ChannelsResource.ListRequest channelRequest = SecretsVault.Service.Channels.List("snippet, statistics");
|
ChannelsResource.ListRequest channelRequest = SecretsVault.Service.Channels.List("snippet, statistics");
|
||||||
@@ -278,29 +265,25 @@ namespace FoxTube.Pages
|
|||||||
//Setting User's rate
|
//Setting User's rate
|
||||||
if (SecretsVault.IsAuthorized)
|
if (SecretsVault.IsAuthorized)
|
||||||
{
|
{
|
||||||
VideoGetRatingResponse ratingResponse = await SecretsVault.Service.Videos.GetRating(videoId).ExecuteAsync();
|
VideoRating rating = (await SecretsVault.Service.Videos.GetRating(item.Id).ExecuteAsync()).Items[0];
|
||||||
if (ratingResponse.Items[0].Rating == "like")
|
if (rating.Rating == "like")
|
||||||
{
|
{
|
||||||
userRating = Rating.Like;
|
userRating = Rating.Like;
|
||||||
like.Foreground = new SolidColorBrush(Colors.Green);
|
like.Foreground = new SolidColorBrush(Colors.Green);
|
||||||
}
|
}
|
||||||
else if (ratingResponse.Items[0].Rating == "dislike")
|
else if (rating.Rating == "dislike")
|
||||||
{
|
{
|
||||||
userRating = Rating.Dislike;
|
userRating = Rating.Dislike;
|
||||||
dislike.Foreground = new SolidColorBrush(Colors.Red);
|
dislike.Foreground = new SolidColorBrush(Colors.Red);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Subscription s in SecretsVault.Subscriptions)
|
if(SecretsVault.Subscriptions.Exists(i => i.Snippet.ResourceId.ChannelId == item.Snippet.ChannelId))
|
||||||
{
|
|
||||||
if (s.Snippet.ResourceId.ChannelId == item.Snippet.ChannelId)
|
|
||||||
{
|
{
|
||||||
subscribe.Background = new SolidColorBrush(Colors.Transparent);
|
subscribe.Background = new SolidColorBrush(Colors.Transparent);
|
||||||
subscribe.Foreground = new SolidColorBrush(Colors.Gray);
|
subscribe.Foreground = new SolidColorBrush(Colors.Gray);
|
||||||
subscribe.Content = resources.GetString("/Cards/unsubscribe");
|
subscribe.Content = resources.GetString("/Cards/unsubscribe");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
subscribe.Visibility = Visibility.Visible;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
download.Visibility = Visibility.Collapsed;
|
download.Visibility = Visibility.Collapsed;
|
||||||
@@ -308,9 +291,9 @@ namespace FoxTube.Pages
|
|||||||
subscribe.Visibility = Visibility.Collapsed;
|
subscribe.Visibility = Visibility.Collapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(HistorySet.Items.Exists(i => i.Id == videoId) && HistorySet.Items.Find(i => i.Id == videoId).LeftOn.TotalSeconds >= 30 && Methods.GetDuration(item.ContentDetails.Duration).TotalSeconds - HistorySet.Items.Find(i => i.Id == videoId).LeftOn.TotalSeconds >= 30)
|
|
||||||
|
if ((history = HistorySet.Items.Find(i => i.Id == item.Id)) != null && history.LeftOn.TotalSeconds >= 30 && Methods.GetDuration(item.ContentDetails.Duration).TotalSeconds - history.LeftOn.TotalSeconds >= 30)
|
||||||
{
|
{
|
||||||
history = HistorySet.Items.Find(i => i.Id == videoId);
|
|
||||||
left.Visibility = Visibility.Visible;
|
left.Visibility = Visibility.Visible;
|
||||||
left.Content = $"\xE122 {resources.GetString("/VideoPage/continue")}: {history.LeftOn.ToString(@"hh\:mm\:ss")}";
|
left.Content = $"\xE122 {resources.GetString("/VideoPage/continue")}: {history.LeftOn.ToString(@"hh\:mm\:ss")}";
|
||||||
}
|
}
|
||||||
@@ -342,7 +325,7 @@ namespace FoxTube.Pages
|
|||||||
private async void LiveStatsUpdate(object sender = null, object e = null)
|
private async void LiveStatsUpdate(object sender = null, object e = null)
|
||||||
{
|
{
|
||||||
VideosResource.ListRequest request = SecretsVault.Service.Videos.List("liveStreamingDetails");
|
VideosResource.ListRequest request = SecretsVault.Service.Videos.List("liveStreamingDetails");
|
||||||
request.Id = videoId;
|
request.Id = item.Id;
|
||||||
|
|
||||||
views.Text = $"{(await request.ExecuteAsync()).Items[0].LiveStreamingDetails.ConcurrentViewers} {resources.GetString("/Cards/viewers")}";
|
views.Text = $"{(await request.ExecuteAsync()).Items[0].LiveStreamingDetails.ConcurrentViewers} {resources.GetString("/Cards/viewers")}";
|
||||||
}
|
}
|
||||||
@@ -359,7 +342,7 @@ namespace FoxTube.Pages
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MediaStreamInfoSet infoSet = await new YoutubeClient().GetVideoMediaStreamInfosAsync(videoId);
|
MediaStreamInfoSet infoSet = await new YoutubeClient().GetVideoMediaStreamInfosAsync(item.Id);
|
||||||
foreach (MuxedStreamInfo i in infoSet.Muxed)
|
foreach (MuxedStreamInfo i in infoSet.Muxed)
|
||||||
{
|
{
|
||||||
MenuFlyoutItem menuItem = new MenuFlyoutItem()
|
MenuFlyoutItem menuItem = new MenuFlyoutItem()
|
||||||
@@ -395,7 +378,7 @@ namespace FoxTube.Pages
|
|||||||
SearchResource.ListRequest request = SecretsVault.Service.Search.List("snippet");
|
SearchResource.ListRequest request = SecretsVault.Service.Search.List("snippet");
|
||||||
request.RegionCode = SettingsStorage.Region;
|
request.RegionCode = SettingsStorage.Region;
|
||||||
request.RelevanceLanguage = SettingsStorage.RelevanceLanguage;
|
request.RelevanceLanguage = SettingsStorage.RelevanceLanguage;
|
||||||
request.RelatedToVideoId = videoId;
|
request.RelatedToVideoId = item.Id;
|
||||||
request.SafeSearch = (SearchResource.ListRequest.SafeSearchEnum)SettingsStorage.SafeSearch;
|
request.SafeSearch = (SearchResource.ListRequest.SafeSearchEnum)SettingsStorage.SafeSearch;
|
||||||
request.MaxResults = 20;
|
request.MaxResults = 20;
|
||||||
request.Type = "video";
|
request.Type = "video";
|
||||||
@@ -408,9 +391,6 @@ namespace FoxTube.Pages
|
|||||||
|
|
||||||
private void Player_Minimize(object sender, params object[] e)
|
private void Player_Minimize(object sender, params object[] e)
|
||||||
{
|
{
|
||||||
if (isExtended == (bool)e[0])
|
|
||||||
return;
|
|
||||||
|
|
||||||
isExtended = (bool)e[0];
|
isExtended = (bool)e[0];
|
||||||
if(isExtended)
|
if(isExtended)
|
||||||
{
|
{
|
||||||
@@ -447,12 +427,12 @@ namespace FoxTube.Pages
|
|||||||
string timecode = player.Player.Position.TotalSeconds > 10 ?
|
string timecode = player.Player.Position.TotalSeconds > 10 ?
|
||||||
"&t=" + (int)player.Player.Position.TotalSeconds + "s" : string.Empty;
|
"&t=" + (int)player.Player.Position.TotalSeconds + "s" : string.Empty;
|
||||||
|
|
||||||
await Launcher.LaunchUriAsync($"https://www.youtube.com/watch?v={videoId}{timecode}".ToUri());
|
await Launcher.LaunchUriAsync($"https://www.youtube.com/watch?v={item.Id}{timecode}".ToUri());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refresh_Click(object sender, RoutedEventArgs e)
|
public void refresh_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Methods.MainPage.GoToVideo(videoId, playlistId);
|
Methods.MainPage.VideoContent.Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CloseVideo()
|
public void CloseVideo()
|
||||||
@@ -497,12 +477,13 @@ namespace FoxTube.Pages
|
|||||||
Methods.Share(args,
|
Methods.Share(args,
|
||||||
item.Snippet.Thumbnails.Medium.Url,
|
item.Snippet.Thumbnails.Medium.Url,
|
||||||
item.Snippet.Title,
|
item.Snippet.Title,
|
||||||
$"https://www.youtube.com/watch?v={videoId}",
|
$"https://www.youtube.com/watch?v={item.Id}",
|
||||||
resources.GetString("/Cards/videoShare"));
|
resources.GetString("/Cards/videoShare"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void share_Click(object sender, RoutedEventArgs e)
|
private void share_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
DataTransferManager.GetForCurrentView().DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(Share);
|
||||||
DataTransferManager.ShowShareUI();
|
DataTransferManager.ShowShareUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,7 +499,7 @@ namespace FoxTube.Pages
|
|||||||
dislike.Foreground = new SolidColorBrush(Colors.Red);
|
dislike.Foreground = new SolidColorBrush(Colors.Red);
|
||||||
dislikes.Text = (int.Parse(dislikes.Text, NumberStyles.AllowThousands) + 1).ToString("0,0");
|
dislikes.Text = (int.Parse(dislikes.Text, NumberStyles.AllowThousands) + 1).ToString("0,0");
|
||||||
rating.Value--;
|
rating.Value--;
|
||||||
await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.Dislike).ExecuteAsync();
|
await SecretsVault.Service.Videos.Rate(item.Id, VideosResource.RateRequest.RatingEnum.Dislike).ExecuteAsync();
|
||||||
|
|
||||||
userRating = Rating.Dislike;
|
userRating = Rating.Dislike;
|
||||||
break;
|
break;
|
||||||
@@ -527,7 +508,7 @@ namespace FoxTube.Pages
|
|||||||
dislike.Foreground = new SolidColorBrush(Colors.Red);
|
dislike.Foreground = new SolidColorBrush(Colors.Red);
|
||||||
dislikes.Text = (int.Parse(dislikes.Text, NumberStyles.AllowThousands) + 1).ToString("0,0");
|
dislikes.Text = (int.Parse(dislikes.Text, NumberStyles.AllowThousands) + 1).ToString("0,0");
|
||||||
rating.Maximum++;
|
rating.Maximum++;
|
||||||
await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.Dislike).ExecuteAsync();
|
await SecretsVault.Service.Videos.Rate(item.Id, VideosResource.RateRequest.RatingEnum.Dislike).ExecuteAsync();
|
||||||
|
|
||||||
userRating = Rating.Dislike;
|
userRating = Rating.Dislike;
|
||||||
break;
|
break;
|
||||||
@@ -536,7 +517,7 @@ namespace FoxTube.Pages
|
|||||||
dislike.Foreground = new SolidColorBrush(Colors.Gray);
|
dislike.Foreground = new SolidColorBrush(Colors.Gray);
|
||||||
dislikes.Text = (int.Parse(dislikes.Text, NumberStyles.AllowThousands) - 1).ToString("0,0");
|
dislikes.Text = (int.Parse(dislikes.Text, NumberStyles.AllowThousands) - 1).ToString("0,0");
|
||||||
rating.Maximum--;
|
rating.Maximum--;
|
||||||
await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.None).ExecuteAsync();
|
await SecretsVault.Service.Videos.Rate(item.Id, VideosResource.RateRequest.RatingEnum.None).ExecuteAsync();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -553,7 +534,7 @@ namespace FoxTube.Pages
|
|||||||
like.Foreground = new SolidColorBrush(Colors.Green);
|
like.Foreground = new SolidColorBrush(Colors.Green);
|
||||||
likes.Text = (int.Parse(likes.Text, NumberStyles.AllowThousands) + 1).ToString("0,0");
|
likes.Text = (int.Parse(likes.Text, NumberStyles.AllowThousands) + 1).ToString("0,0");
|
||||||
rating.Value++;
|
rating.Value++;
|
||||||
await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.Like).ExecuteAsync();
|
await SecretsVault.Service.Videos.Rate(item.Id, VideosResource.RateRequest.RatingEnum.Like).ExecuteAsync();
|
||||||
|
|
||||||
userRating = Rating.Like;
|
userRating = Rating.Like;
|
||||||
break;
|
break;
|
||||||
@@ -563,7 +544,7 @@ namespace FoxTube.Pages
|
|||||||
likes.Text = (int.Parse(likes.Text, NumberStyles.AllowThousands) + 1).ToString("0,0");
|
likes.Text = (int.Parse(likes.Text, NumberStyles.AllowThousands) + 1).ToString("0,0");
|
||||||
rating.Maximum++;
|
rating.Maximum++;
|
||||||
rating.Value++;
|
rating.Value++;
|
||||||
await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.Like).ExecuteAsync();
|
await SecretsVault.Service.Videos.Rate(item.Id, VideosResource.RateRequest.RatingEnum.Like).ExecuteAsync();
|
||||||
|
|
||||||
userRating = Rating.Like;
|
userRating = Rating.Like;
|
||||||
break;
|
break;
|
||||||
@@ -573,7 +554,7 @@ namespace FoxTube.Pages
|
|||||||
likes.Text = (int.Parse(likes.Text, NumberStyles.AllowThousands) - 1).ToString("0,0");
|
likes.Text = (int.Parse(likes.Text, NumberStyles.AllowThousands) - 1).ToString("0,0");
|
||||||
rating.Maximum--;
|
rating.Maximum--;
|
||||||
rating.Value--;
|
rating.Value--;
|
||||||
await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.None).ExecuteAsync();
|
await SecretsVault.Service.Videos.Rate(item.Id, VideosResource.RateRequest.RatingEnum.None).ExecuteAsync();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -582,7 +563,7 @@ namespace FoxTube.Pages
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if ((e.AddedItems[0] as VideoPlaylistItem).Id != videoId)
|
if ((e.AddedItems[0] as VideoPlaylistItem).Id != item.Id)
|
||||||
Methods.MainPage.GoToVideo((e.AddedItems[0] as VideoPlaylistItem).Id, playlistId);
|
Methods.MainPage.GoToVideo((e.AddedItems[0] as VideoPlaylistItem).Id, playlistId);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
@@ -605,6 +586,8 @@ namespace FoxTube.Pages
|
|||||||
}
|
}
|
||||||
|
|
||||||
async void LoadAddTo()
|
async void LoadAddTo()
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (SecretsVault.UserChannel == null)
|
if (SecretsVault.UserChannel == null)
|
||||||
{
|
{
|
||||||
@@ -641,6 +624,11 @@ namespace FoxTube.Pages
|
|||||||
addList.Items.Add(menuItem);
|
addList.Items.Add(menuItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
addTo.Visibility = Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async void Item_Click(object sender, RoutedEventArgs e)
|
private async void Item_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -124,10 +124,10 @@
|
|||||||
<value>Contacts</value>
|
<value>Contacts</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="crMe.Text" xml:space="preserve">
|
<data name="crMe.Text" xml:space="preserve">
|
||||||
<value>© 2018 Michael Gordeev</value>
|
<value>© Michael Gordeev</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="crYt.Text" xml:space="preserve">
|
<data name="crYt.Text" xml:space="preserve">
|
||||||
<value>© 2018 YouTube, LLC</value>
|
<value>© YouTube, LLC</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="developed.Text" xml:space="preserve">
|
<data name="developed.Text" xml:space="preserve">
|
||||||
<value>Developed by Michael Gordeev (also known as XFox)</value>
|
<value>Developed by Michael Gordeev (also known as XFox)</value>
|
||||||
@@ -142,7 +142,7 @@
|
|||||||
<value>Legal stuff</value>
|
<value>Legal stuff</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="myBlog.Text" xml:space="preserve">
|
<data name="myBlog.Text" xml:space="preserve">
|
||||||
<value>My blog (Russian language only)</value>
|
<value>My website</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ourPrivacy.Content" xml:space="preserve">
|
<data name="ourPrivacy.Content" xml:space="preserve">
|
||||||
<value>Our Privacy Policy</value>
|
<value>Our Privacy Policy</value>
|
||||||
|
|||||||
@@ -139,7 +139,7 @@
|
|||||||
<value>Windows color settings</value>
|
<value>Windows color settings</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="en.Content" xml:space="preserve">
|
<data name="en.Content" xml:space="preserve">
|
||||||
<value>English (United States of America)</value>
|
<value>English (United States)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="interfaceLang.Header" xml:space="preserve">
|
<data name="interfaceLang.Header" xml:space="preserve">
|
||||||
<value>App interface language</value>
|
<value>App interface language</value>
|
||||||
@@ -187,7 +187,7 @@
|
|||||||
<value>Reopen the app to apply changes (otherwise some elements may not be displayed correctly)</value>
|
<value>Reopen the app to apply changes (otherwise some elements may not be displayed correctly)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ru.Content" xml:space="preserve">
|
<data name="ru.Content" xml:space="preserve">
|
||||||
<value>Russian (Russian Federation)</value>
|
<value>Russian (Russia)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="safeSearch.Header" xml:space="preserve">
|
<data name="safeSearch.Header" xml:space="preserve">
|
||||||
<value>SafeSearch</value>
|
<value>SafeSearch</value>
|
||||||
|
|||||||
@@ -124,10 +124,10 @@
|
|||||||
<value>Контакты</value>
|
<value>Контакты</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="crMe.Text" xml:space="preserve">
|
<data name="crMe.Text" xml:space="preserve">
|
||||||
<value>© 2018 Михаил Гордеев</value>
|
<value>© Михаил Гордеев</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="crYt.Text" xml:space="preserve">
|
<data name="crYt.Text" xml:space="preserve">
|
||||||
<value>© 2018 YouTube, LLC</value>
|
<value>© YouTube, LLC</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="developed.Text" xml:space="preserve">
|
<data name="developed.Text" xml:space="preserve">
|
||||||
<value>Разработано Михаилом Гордеевым (также известным как XFox)</value>
|
<value>Разработано Михаилом Гордеевым (также известным как XFox)</value>
|
||||||
@@ -142,7 +142,7 @@
|
|||||||
<value>Юридический материал</value>
|
<value>Юридический материал</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="myBlog.Text" xml:space="preserve">
|
<data name="myBlog.Text" xml:space="preserve">
|
||||||
<value>Мой блог</value>
|
<value>Мой веб-сайт</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ourPrivacy.Content" xml:space="preserve">
|
<data name="ourPrivacy.Content" xml:space="preserve">
|
||||||
<value>Наша политика конфиденциальности</value>
|
<value>Наша политика конфиденциальности</value>
|
||||||
|
|||||||
@@ -139,7 +139,7 @@
|
|||||||
<value>Цветовые настройки Windows</value>
|
<value>Цветовые настройки Windows</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="en.Content" xml:space="preserve">
|
<data name="en.Content" xml:space="preserve">
|
||||||
<value>Английский (Соединенные Штаты Америки)</value>
|
<value>Английский (США)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="interfaceLang.Header" xml:space="preserve">
|
<data name="interfaceLang.Header" xml:space="preserve">
|
||||||
<value>Язык интерфейса</value>
|
<value>Язык интерфейса</value>
|
||||||
@@ -187,7 +187,7 @@
|
|||||||
<value>Перезапустите приложение, чтобы применить настройки (в противном случае некоторые элементы могут неправильно отображаться)</value>
|
<value>Перезапустите приложение, чтобы применить настройки (в противном случае некоторые элементы могут неправильно отображаться)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ru.Content" xml:space="preserve">
|
<data name="ru.Content" xml:space="preserve">
|
||||||
<value>Русский (Российская Федерация)</value>
|
<value>Русский (Россия)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="safeSearch.Header" xml:space="preserve">
|
<data name="safeSearch.Header" xml:space="preserve">
|
||||||
<value>Безопасный поиск</value>
|
<value>Безопасный поиск</value>
|
||||||
|
|||||||
@@ -41,6 +41,6 @@
|
|||||||
<Style TargetType="ui:NavigationViewItemHeader">
|
<Style TargetType="ui:NavigationViewItemHeader">
|
||||||
<Setter Property="FontSize" Value="14"/>
|
<Setter Property="FontSize" Value="14"/>
|
||||||
</Style>
|
</Style>
|
||||||
<Duration x:Key="CardOpacityDuration">0:0:0.5</Duration>
|
<Duration x:Key="CardOpacityDuration">0:0:0.3</Duration>
|
||||||
|
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
|
|||||||
Reference in New Issue
Block a user