Merged PR 21: Version 0.2.1901-2
- Added ability to delete comments. Fixes Related Work Items: #228, #234 - Refactored Video page Related Work Items: #183, #186 - Player refactoring - Chat Related Work Items: #183, #185 - New Logo draft - Improving thumbnails quality - Seek slider fixes Related Work Items: #235, #237 - Regions and languagaes improved. Video cards duration display fixed. Added settings updating system Related Work Items: #236 - Items cards' context menu. Fixed duplicating authors' name on comments replies. Another version of logo Related Work Items: #226 - Context menu for cards done Related Work Items: #226 - Live stats update done Related Work Items: #183, #186 - Settings recovery system improvements - Missync fixed. New logo. Supporting all existing qualities Related Work Items: #207 - Added support of livestreams. Chat messages avatars added. Formatting live chat messages added. Few player fixes Related Work Items: #183, #184 - Refactored player. Refactored changelog system. Players isn't localized Related Work Items: #161, #211, #238 - Player fixes. Localization updates. Tiles updated Related Work Items: #161 - Menu render fix Related Work Items: #239 - Fullscreen mode fixes Related Work Items: #240 - Manifest changes - Ads development - Video cards fixes. Localization fixes. CardAdvert created Related Work Items: #244, #245 - Localization fixed. Player fixes. Menu fixes Related Work Items: #243, #245 - Menu displaying fixes - Fixes Related Work Items: #241, #242, #249, #250 - SafeSearch filter fixed - Video page fixes Related Work Items: #249 - Patchnote updated - Version updated
@@ -131,14 +131,13 @@
|
||||
<Version>6.1.5</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Net.WebClient">
|
||||
<HintPath>..\..\..\..\..\..\Program Files (x86)\Microsoft SDKs\UWPNuGetPackages\microsoft.netcore.universalwindowsplatform\6.1.5\ref\uap10.0.15138\System.Net.WebClient.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>false</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
@@ -1,10 +1,39 @@
|
||||
using Windows.Data.Xml.Dom;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using Windows.Data.Xml.Dom;
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Notifications;
|
||||
|
||||
namespace FoxTube.Background
|
||||
{
|
||||
public static class Notification
|
||||
{
|
||||
private static Dictionary<string, string> languagePack = LoadPack();
|
||||
|
||||
private static Dictionary<string, string> LoadPack()
|
||||
{
|
||||
object[] saved = JsonConvert.DeserializeObject<object[]>(ApplicationData.Current.RoamingSettings.Values["settings"] as string);
|
||||
if (saved[7] as string == "ru-RU")
|
||||
return new Dictionary<string, string>()
|
||||
{
|
||||
{ "addLater", "Посмотреть позже" },
|
||||
{ "changelog", "Список изменений" },
|
||||
{ "changelogHeader", "Что нового в версии" },
|
||||
{ "videoContent", "загрузил новое видео" },
|
||||
{ "goChannel", "Открыть канал" }
|
||||
};
|
||||
else
|
||||
return new Dictionary<string, string>()
|
||||
{
|
||||
{ "addLater", "Add to Watch later" },
|
||||
{ "changelog", "Changelog" },
|
||||
{ "changelogHeader", "What's new in version" },
|
||||
{ "videoContent", "uploaded a new video" },
|
||||
{ "goChannel", "Go to channel" }
|
||||
};
|
||||
}
|
||||
|
||||
public static ToastNotification GetChangelogToast(string version)
|
||||
{
|
||||
XmlDocument template = new XmlDocument();
|
||||
@@ -14,8 +43,8 @@ namespace FoxTube.Background
|
||||
<binding template='ToastGeneric'>
|
||||
<image placement='hero' src='http://foxgame-studio.000webhostapp.com/FoxTubeAssets/WhatsNewThumb.png'/>
|
||||
<image placement='appLogoOverride' hint-crop='circle' src='http://foxgame-studio.000webhostapp.com/FoxTubeAssets/NewsAvatar.png'/>
|
||||
<text>Changelog</text>
|
||||
<text>See what's new in version {version}</text>
|
||||
<text>{languagePack["changelog"]}</text>
|
||||
<text>{languagePack["changelogHeader"]} {version}</text>
|
||||
</binding>
|
||||
</visual>
|
||||
</toast>");
|
||||
@@ -33,13 +62,13 @@ namespace FoxTube.Background
|
||||
<image placement='hero' src='{thumbnail.Replace("&", "%26")}'/>
|
||||
<image placement='appLogoOverride' hint-crop='circle' src='{avatar.Replace("&", "%26") ?? "http://foxgame-studio.000webhostapp.com/FoxTubeAssets/LogoAvatar.png"}'/>
|
||||
<text>{title}</text>
|
||||
<text>{channel} uploaded a new video</text>
|
||||
<text>{channel} {languagePack["videoContent"]}</text>
|
||||
</binding>
|
||||
</visual>
|
||||
|
||||
<actions>
|
||||
<action content='Add to Watch later' activationType='background' arguments='later|{id}'/>
|
||||
<action content='Go to channel' activationType='foreground' arguments='channel|{channelId}'/>
|
||||
<action content='{languagePack["addLater"]}' activationType='background' arguments='later|{id}'/>
|
||||
<action content='{languagePack["goChannel"]}' activationType='foreground' arguments='channel|{channelId}'/>
|
||||
</actions>
|
||||
</toast>");
|
||||
|
||||
|
||||
@@ -1,9 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<items>
|
||||
<item time="2018-07-29T23:00:00-03" version="1.0.1">
|
||||
<content>Announcement body (beware of special characters)</content>
|
||||
<item time="2019-01-05" version="0.2.19012">
|
||||
<content>
|
||||
<en-US>### What's new:
|
||||
|
||||
- 'Live' button fixed in the player
|
||||
- Long channel names on crads fixed
|
||||
- Fixed video description disappearing on window resizing
|
||||
- Player seek is fixed
|
||||
- Added video buffering progress indicatior
|
||||
- Small fixes
|
||||
|
||||
### Known issues:
|
||||
|
||||
- Recommended and subscriptions pages aren't implemented
|
||||
- History isn't implemented
|
||||
- Playlists management isn't implemented
|
||||
- Ads aren't implemented
|
||||
</en-US>
|
||||
<ru-RU>### Что нового:
|
||||
|
||||
- Кнопка перехода к прямому эфиру на стримах теперь работает
|
||||
- Исправлен баг с длинными именами каналов на карточках
|
||||
- Исправлено исчезание описания видео при изменении размеров окна
|
||||
- Исправлен ползунок перемотки видео
|
||||
- Добавлен индикатор буферизации видео
|
||||
- Мелкие исправления
|
||||
|
||||
### Что по-прежнему не работает:
|
||||
|
||||
- Страница рекомендованных видео и страница видео с подписок
|
||||
- История
|
||||
- Работа с плейлистами
|
||||
- Нет карточек рекламы
|
||||
</ru-RU>
|
||||
</content>
|
||||
</item>
|
||||
</items>
|
||||
<!--<item time="YYYY-MM-DDThh:mm:ss-03" version="1.0.1">
|
||||
<content>Announcement body (beware of special characters)</content>
|
||||
</item>-->
|
||||
|
||||
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 961 B After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 394 B After Width: | Height: | Size: 610 B |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 699 B After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1020 B After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 785 B After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 934 B After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 343 B After Width: | Height: | Size: 461 B |
|
Before Width: | Height: | Size: 475 B After Width: | Height: | Size: 723 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 595 B After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 831 B After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 55 KiB |
@@ -1,33 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FoxTube.Classes
|
||||
{
|
||||
public class Caption
|
||||
{
|
||||
public TimeSpan Start { get; private set; }
|
||||
public TimeSpan Duration { get; private set; }
|
||||
public TimeSpan End
|
||||
{
|
||||
get { return Start + Duration; }
|
||||
}
|
||||
public string Text { get; private set; }
|
||||
|
||||
public Caption(int startTime, int duration, string text)
|
||||
{
|
||||
Start = TimeSpan.FromMilliseconds(startTime);
|
||||
Duration = TimeSpan.FromMilliseconds(duration);
|
||||
Text = text;
|
||||
}
|
||||
|
||||
public Caption(double startTime, double duration, string text)
|
||||
{
|
||||
Start = TimeSpan.FromSeconds(startTime);
|
||||
Duration = TimeSpan.FromSeconds(duration);
|
||||
Text = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
|
||||
namespace FoxTube.Classes
|
||||
{
|
||||
@@ -14,6 +15,8 @@ namespace FoxTube.Classes
|
||||
public string Content { get; set; }
|
||||
public string Id { get; set; }
|
||||
|
||||
private ResourceLoader resources = ResourceLoader.GetForCurrentView("Inbox");
|
||||
|
||||
public string Icon
|
||||
{
|
||||
get
|
||||
@@ -29,9 +32,9 @@ namespace FoxTube.Classes
|
||||
get
|
||||
{
|
||||
if (Type == InboxItemType.PatchNote)
|
||||
return "Patch note";
|
||||
return resources.GetString("changelog");
|
||||
else
|
||||
return "Developer's message";
|
||||
return resources.GetString("dev");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +43,7 @@ namespace FoxTube.Classes
|
||||
get
|
||||
{
|
||||
if (Type == InboxItemType.PatchNote)
|
||||
return $"What's new in v{Id}";
|
||||
return $"{resources.GetString("whatsnew")}{Id}";
|
||||
else
|
||||
return Subject;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using Google.Apis.YouTube.v3;
|
||||
using FoxTube.Controls.Adverts;
|
||||
using FoxTube.Pages;
|
||||
using Google.Apis.YouTube.v3;
|
||||
using Microsoft.Advertising.WinRT.UI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@@ -6,8 +9,10 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using System.Xml;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using Windows.Storage;
|
||||
using Windows.Storage.Streams;
|
||||
using Windows.System;
|
||||
@@ -16,11 +21,15 @@ using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Documents;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using YoutubeExplode.Models.MediaStreams;
|
||||
|
||||
namespace FoxTube
|
||||
{
|
||||
public static class Methods
|
||||
{
|
||||
private static ResourceLoader resources = ResourceLoader.GetForCurrentView("Methods");
|
||||
public static CommentsPage CommentsPage { get; set; }
|
||||
|
||||
public static bool NeedToResponse { get; set; } = false;
|
||||
public static MainPage MainPage
|
||||
{
|
||||
@@ -37,6 +46,30 @@ namespace FoxTube
|
||||
return new Uri(url);
|
||||
}
|
||||
|
||||
public static string GetChars(this string str, int count)
|
||||
{
|
||||
try
|
||||
{
|
||||
string s = "";
|
||||
for (int i = 0; i < count; i++)
|
||||
s += str[i];
|
||||
return s;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static List<object> ToReversedList(this Array array)
|
||||
{
|
||||
List<object> list = new List<object>();
|
||||
foreach (object i in array)
|
||||
list.Add(i);
|
||||
list.Reverse();
|
||||
return list;
|
||||
}
|
||||
|
||||
public static void ForEach<T>(this IEnumerable<T> array, Action<T> action)
|
||||
{
|
||||
array.ToList().ForEach(action);
|
||||
@@ -64,36 +97,56 @@ namespace FoxTube
|
||||
return arr[arr.Length - 1];
|
||||
}
|
||||
|
||||
public static TimeSpan GetDuration(this string str)
|
||||
{
|
||||
try
|
||||
{
|
||||
return XmlConvert.ToTimeSpan(str);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
TimeSpan time = XmlConvert.ToTimeSpan("PT" + str.Split('T')[1]);
|
||||
TimeSpan date = TimeSpan.FromDays(int.Parse(str.Split('W')[0].Replace("P", "")) * 7);
|
||||
date.Add(time);
|
||||
|
||||
return date;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return TimeSpan.FromMilliseconds(0);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetAgo(DateTime dateTime)
|
||||
{
|
||||
TimeSpan span = DateTime.Now - dateTime;
|
||||
|
||||
if (span.TotalMinutes < 1)
|
||||
return "Just now";
|
||||
return resources.GetString("/Methods/now");
|
||||
else if (Math.Round(span.TotalMinutes) == 1)
|
||||
return "1 minute ago";
|
||||
return resources.GetString("/Methods/oneMinute");
|
||||
else if (span.TotalMinutes < 60)
|
||||
return Math.Round(span.TotalMinutes) + " minutes ago";
|
||||
return Math.Round(span.TotalMinutes) + " " + resources.GetString("/Methods/minutes");
|
||||
else if (Math.Round(span.TotalHours) == 1)
|
||||
return "1 hour ago";
|
||||
return resources.GetString("/Methods/oneHr");
|
||||
else if (span.TotalHours < 24)
|
||||
return Math.Round(span.TotalHours) + " hours ago";
|
||||
return Math.Round(span.TotalHours) + " " + resources.GetString("/Methods/hrs");
|
||||
else if (Math.Round(span.TotalDays) == 1)
|
||||
return "1 day ago";
|
||||
return resources.GetString("/Methods/oneDay");
|
||||
else if (span.TotalDays < 7)
|
||||
return Math.Round(span.TotalDays) + " days ago";
|
||||
return Math.Round(span.TotalDays) + " " + resources.GetString("/Methods/days");
|
||||
else if (Math.Round(span.TotalDays) == 7)
|
||||
return "1 week ago";
|
||||
return resources.GetString("/Methods/oneWeek");
|
||||
else if (span.TotalDays < 30)
|
||||
return Math.Round(span.TotalDays / 7) + " weeks ago";
|
||||
return Math.Round(span.TotalDays / 7) + " " + resources.GetString("/Methods/weeks");
|
||||
else if (Math.Round(span.TotalDays) == 30)
|
||||
return "1 month ago";
|
||||
return resources.GetString("/Methods/oneMonth");
|
||||
else if (Math.Round(span.TotalDays) < 365)
|
||||
return Math.Round(span.TotalDays / 30) + " months ago";
|
||||
return Math.Round(span.TotalDays / 30) + " " + resources.GetString("/Methods/months");
|
||||
else if (Math.Round(span.TotalDays / 365) == 365)
|
||||
return "1 year ago";
|
||||
return resources.GetString("/Methods/oneYear");
|
||||
else
|
||||
return Math.Round(span.TotalDays / 365) + " years ago";
|
||||
return Math.Round(span.TotalDays / 365) + " " + resources.GetString("/Methods/years");
|
||||
}
|
||||
|
||||
public static void FormatText(ref TextBlock block, string text)
|
||||
@@ -139,6 +192,37 @@ namespace FoxTube
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetVideoQualityLabel(this VideoQuality quality)
|
||||
{
|
||||
switch (quality)
|
||||
{
|
||||
case VideoQuality.High1080:
|
||||
return "1080p";
|
||||
case VideoQuality.High1440:
|
||||
return "1440p";
|
||||
case VideoQuality.High2160:
|
||||
return "2160p";
|
||||
case VideoQuality.High2880:
|
||||
return "2880p";
|
||||
case VideoQuality.High3072:
|
||||
return "3072p";
|
||||
case VideoQuality.High4320:
|
||||
return "4320p";
|
||||
case VideoQuality.High720:
|
||||
return "720p";
|
||||
case VideoQuality.Low144:
|
||||
return "144p";
|
||||
case VideoQuality.Low240:
|
||||
return "240p";
|
||||
case VideoQuality.Medium360:
|
||||
return "360p";
|
||||
case VideoQuality.Medium480:
|
||||
return "480p";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
/*public static string QualityToString(YouTubeQuality quality)
|
||||
{
|
||||
switch(quality)
|
||||
@@ -242,7 +326,7 @@ namespace FoxTube
|
||||
{
|
||||
DataRequest request = args.Request;
|
||||
request.Data.Properties.Title = title;
|
||||
request.Data.Properties.Description = $"Sharing a {type}";
|
||||
request.Data.Properties.Description = $"{resources.GetString("/Methods/sharing")} {type}";
|
||||
|
||||
request.Data.SetText(title + "\n" + "#YouTube #FoxTube #SharedWithFoxTube");
|
||||
request.Data.SetWebLink(url.ToUri());
|
||||
|
||||
@@ -8,6 +8,7 @@ using Google.Apis.YouTube.v3;
|
||||
using Google.Apis.YouTube.v3.Data;
|
||||
using Newtonsoft.Json;
|
||||
using Windows.Storage;
|
||||
using Windows.Services.Store;
|
||||
|
||||
namespace FoxTube
|
||||
{
|
||||
@@ -17,7 +18,7 @@ namespace FoxTube
|
||||
//Events
|
||||
public static event ObjectEventHandler AuthorizationStateChanged;
|
||||
public static event ObjectEventHandler SubscriptionsChanged;
|
||||
public static event Event NotPurchased; //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
|
||||
private static ClientSecrets Secrets => new ClientSecrets()
|
||||
@@ -36,6 +37,8 @@ namespace FoxTube
|
||||
ApplicationName = "FoxTube"
|
||||
};
|
||||
public static YouTubeService Service => IsAuthorized ? new YouTubeService(Initializer) : NoAuthService;
|
||||
public static string AppId => true ? "d25517cb-12d4-4699-8bdc-52040c712cab" : "9ncqqxjtdlfh";
|
||||
public static string AdUnitId => true ? "test" : "1100037769";
|
||||
public static bool AdsDisabled { get; private set; } = true;
|
||||
|
||||
//User info
|
||||
@@ -193,15 +196,38 @@ namespace FoxTube
|
||||
/// <summary>
|
||||
/// Connects to MS Store and checks if user has bought ad-free
|
||||
/// </summary>
|
||||
public static void CheckAddons()
|
||||
public static async void CheckAddons()
|
||||
{
|
||||
//TODO: Check addons list
|
||||
bool purchased = true;
|
||||
try
|
||||
{
|
||||
StoreContext store = StoreContext.GetDefault();
|
||||
StoreProductQueryResult requset = await store.GetAssociatedStoreProductsAsync(new[] { "Consumable", "Durable", "UnmanagedConsumable" });
|
||||
|
||||
if(!purchased)
|
||||
if (!requset.Products["foxtube-adsremove"].IsInUserCollection)
|
||||
{
|
||||
AdsDisabled = false;
|
||||
NotPurchased?.Invoke();
|
||||
Purchased?.Invoke(args:false);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
public static async void GetAdblock()
|
||||
{
|
||||
StoreContext store = StoreContext.GetDefault();
|
||||
StorePurchaseResult request = await store.RequestPurchaseAsync("foxtube-adsremove");
|
||||
|
||||
switch (request.Status)
|
||||
{
|
||||
case StorePurchaseStatus.AlreadyPurchased:
|
||||
Purchased?.Invoke(args: true);
|
||||
AdsDisabled = true;
|
||||
break;
|
||||
|
||||
case StorePurchaseStatus.Succeeded:
|
||||
Purchased?.Invoke(args: true);
|
||||
AdsDisabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -7,6 +7,8 @@ using Windows.Storage;
|
||||
|
||||
namespace FoxTube
|
||||
{
|
||||
public enum MatureState { Blocked, Allowed, AllowedOnce }
|
||||
|
||||
public static class SettingsStorage
|
||||
{
|
||||
public static string VideoQuality
|
||||
@@ -84,7 +86,7 @@ namespace FoxTube
|
||||
SaveData();
|
||||
}
|
||||
}
|
||||
public static string Region
|
||||
public static string RelevanceLanguage
|
||||
{
|
||||
get { return (string)settings[8]; }
|
||||
set
|
||||
@@ -93,17 +95,16 @@ namespace FoxTube
|
||||
SaveData();
|
||||
}
|
||||
}
|
||||
public static int SafeSearch
|
||||
public static string Region
|
||||
{
|
||||
get { return Convert.ToInt32(settings[9]); }
|
||||
get { return (string)settings[9]; }
|
||||
set
|
||||
{
|
||||
settings[9] = value;
|
||||
SaveData();
|
||||
}
|
||||
}
|
||||
|
||||
public static int Theme
|
||||
public static int SafeSearch
|
||||
{
|
||||
get { return Convert.ToInt32(settings[10]); }
|
||||
set
|
||||
@@ -112,15 +113,25 @@ namespace FoxTube
|
||||
SaveData();
|
||||
}
|
||||
}
|
||||
public static bool HasAccount
|
||||
|
||||
public static int Theme
|
||||
{
|
||||
get { return (bool)settings[11]; }
|
||||
get { return Convert.ToInt32(settings[11]); }
|
||||
set
|
||||
{
|
||||
settings[11] = value;
|
||||
SaveData();
|
||||
}
|
||||
}
|
||||
public static bool HasAccount
|
||||
{
|
||||
get { return (bool)settings[12]; }
|
||||
set
|
||||
{
|
||||
settings[12] = value;
|
||||
SaveData();
|
||||
}
|
||||
}
|
||||
|
||||
public static string Version
|
||||
{
|
||||
@@ -139,9 +150,25 @@ namespace FoxTube
|
||||
storage.Values["version"] = value;
|
||||
}
|
||||
}
|
||||
public static MatureState Mature
|
||||
{
|
||||
get
|
||||
{
|
||||
if (storage.Values["mature"] == null)
|
||||
{
|
||||
storage.Values["mature"] = MatureState.Blocked;
|
||||
return MatureState.Blocked;
|
||||
}
|
||||
else return (MatureState)storage.Values["mature"];
|
||||
}
|
||||
set
|
||||
{
|
||||
storage.Values["mature"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
//Settings storage
|
||||
private static readonly ApplicationDataContainer storage = ApplicationData.Current.LocalSettings;
|
||||
private static readonly ApplicationDataContainer storage = ApplicationData.Current.RoamingSettings;
|
||||
|
||||
//Predefined preferences
|
||||
private static object[] settings = new object[]
|
||||
@@ -157,7 +184,8 @@ namespace FoxTube
|
||||
100,
|
||||
|
||||
(new[] { "ua", "ru", "by", "kz", "kg", "md", "lv", "ee" }).Contains(CultureInfo.InstalledUICulture.TwoLetterISOLanguageName) ? "ru-RU" : "en-US",
|
||||
CultureInfo.CurrentCulture.Name,
|
||||
(new[] { "ua", "ru", "by", "kz", "kg", "md", "lv", "ee" }).Contains(CultureInfo.InstalledUICulture.TwoLetterISOLanguageName) ? "ru" : "en",
|
||||
(new[] { "ua", "ru", "by", "kz", "kg", "md", "lv", "ee" }).Contains(CultureInfo.InstalledUICulture.TwoLetterISOLanguageName) ? "ru" : "US",
|
||||
0,
|
||||
|
||||
2,
|
||||
@@ -166,14 +194,53 @@ namespace FoxTube
|
||||
|
||||
public static void LoadData()
|
||||
{
|
||||
/*if(true && (storage.Values["forceUpdate"] == null || storage.Values["forceUpdate"].ToString() != Version))
|
||||
{
|
||||
SaveData();
|
||||
storage.Values["forceUpdate"] = Version;
|
||||
return;
|
||||
}*/
|
||||
|
||||
try
|
||||
{
|
||||
settings = JsonConvert.DeserializeObject<object[]>(storage.Values["settings"] as string);
|
||||
object[] saved = JsonConvert.DeserializeObject<object[]>(storage.Values["settings"] as string);
|
||||
if (settings.Length > saved.Length)
|
||||
{
|
||||
if (saved[0] is string)
|
||||
settings[0] = saved;
|
||||
if (saved[1] is string)
|
||||
settings[1] = saved;
|
||||
if (saved[2] is bool)
|
||||
settings[2] = saved;
|
||||
if (saved[3] is bool)
|
||||
settings[3] = saved;
|
||||
if (saved[4] is bool)
|
||||
settings[4] = saved;
|
||||
if (saved[5] is bool)
|
||||
settings[5] = saved;
|
||||
if (saved[6] is int)
|
||||
settings[6] = saved;
|
||||
if (saved[7] is string)
|
||||
settings[7] = saved;
|
||||
if (saved[8] is string)
|
||||
settings[8] = saved;
|
||||
if (saved[9] is string)
|
||||
settings[9] = saved;
|
||||
if (saved[10] is int)
|
||||
settings[10] = saved;
|
||||
if (saved[11] is int)
|
||||
settings[11] = saved;
|
||||
if (saved[12] is bool)
|
||||
settings[12] = saved;
|
||||
|
||||
SaveData();
|
||||
}
|
||||
else settings = saved;
|
||||
}
|
||||
catch (ArgumentNullException) { }
|
||||
}
|
||||
|
||||
public static async void SaveData()
|
||||
public static void SaveData()
|
||||
{
|
||||
storage.Values["settings"] = JsonConvert.SerializeObject(settings);
|
||||
ExportSettings();
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace FoxTube.Controls
|
||||
Visibility = Visibility.Visible;
|
||||
else
|
||||
Visibility = Visibility.Collapsed;
|
||||
SecretsVault.NotPurchased += () => Visibility = Visibility.Visible;
|
||||
SecretsVault.Purchased += (s, e) => Visibility = (bool)e[0] ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
|
||||
private void Grid_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<UserControl
|
||||
x:Class="FoxTube.Controls.Adverts.CardAdvert"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
SizeChanged="UserControl_SizeChanged"
|
||||
d:DesignHeight="290"
|
||||
d:DesignWidth="384">
|
||||
|
||||
<Button Padding="0" Background="Transparent" Name="btn">
|
||||
<Grid Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="75"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Image Name="image" Source="/Assets/videoThumbSample.png" Stretch="Fill"/>
|
||||
<StackPanel Margin="0,0,5,5" Background="Orange" VerticalAlignment="Bottom" BorderBrush="OrangeRed" BorderThickness="1" HorizontalAlignment="Right" Padding="5,2,5,3">
|
||||
<TextBlock Name="info" Text="SPONSORED CONTENT" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Gray" FontSize="12"/>
|
||||
</StackPanel>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="20"/>
|
||||
<RowDefinition Height="55"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Name="contentGrid">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="60"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Ellipse Grid.Column="0" Height="50" Width="50" Margin="5,-30,5,10" Fill="{ThemeResource SystemControlBackgroundChromeMediumBrush}"/>
|
||||
<PersonPicture Name="icon" Grid.Column="0" Height="46" Margin="5,-30,5,0" BorderBrush="White" BorderThickness="10"/>
|
||||
|
||||
<TextBlock Name="sponsor" HorizontalAlignment="Left" Grid.Column="1" Text="[Sponsored by]" TextTrimming="CharacterEllipsis" Foreground="Gray" Margin="0,2,0,0" FontSize="12"/>
|
||||
<TextBlock Grid.Column="1" Name="desc" Text="[Description]" HorizontalAlignment="Right" Foreground="Gray" Margin="0,2,2,0" FontSize="12"/>
|
||||
</Grid>
|
||||
<TextBlock Grid.Row="1" Name="title" Text="[Title]" TextWrapping="WrapWholeWords" Margin="5" MaxLines="2" TextTrimming="CharacterEllipsis"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Button>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,62 @@
|
||||
using System.Linq;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Microsoft.Advertising.WinRT.UI;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
|
||||
namespace FoxTube.Controls.Adverts
|
||||
{
|
||||
/// <summary>
|
||||
/// Advert which is looks similar to video cards
|
||||
/// </summary>
|
||||
public sealed partial class CardAdvert : UserControl
|
||||
{
|
||||
NativeAdsManagerV2 manager = new NativeAdsManagerV2(SecretsVault.AppId, SecretsVault.AdUnitId);
|
||||
public NativeAdV2 advert;
|
||||
public CardAdvert()
|
||||
{
|
||||
InitializeComponent();
|
||||
manager.AdReady += AdReady;
|
||||
manager.RequestAd();
|
||||
}
|
||||
|
||||
private void AdReady(object sender, NativeAdReadyEventArgs e)
|
||||
{
|
||||
advert = e.NativeAd;
|
||||
Initialize();
|
||||
e.NativeAd.RegisterAdContainer(this);
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
title.Text = advert.Title;
|
||||
image.Source = new BitmapImage(advert.MainImages.First().Url.ToUri());
|
||||
if (advert.AdIcon == null)
|
||||
contentGrid.ColumnDefinitions[0].Width = new GridLength(0);
|
||||
else
|
||||
icon.ProfilePicture = advert.AdIcon.Source;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(advert.SponsoredBy))
|
||||
sponsor.Visibility = Visibility.Collapsed;
|
||||
else
|
||||
sponsor.Text = advert.SponsoredBy;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(advert.Rating))
|
||||
info.Text += $" {advert.Rating}";
|
||||
|
||||
if (string.IsNullOrWhiteSpace(advert.CallToActionText) && string.IsNullOrWhiteSpace(advert.Price))
|
||||
desc.Visibility = Visibility.Collapsed;
|
||||
else if (!string.IsNullOrWhiteSpace(advert.CallToActionText))
|
||||
desc.Text = advert.CallToActionText;
|
||||
else
|
||||
desc.Text = advert.Price;
|
||||
|
||||
Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
Height = e.NewSize.Width * 0.75;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
<Image Name="cover" Source="/Assets/ChannelCoverTemplate.png" Stretch="UniformToFill" VerticalAlignment="Center"/>
|
||||
<StackPanel Name="liveTag" Margin="5" Background="Red" BorderBrush="White" BorderThickness="1" VerticalAlignment="Bottom" HorizontalAlignment="Right" Padding="5,2,5,3" Orientation="Horizontal" Visibility="Collapsed">
|
||||
<TextBlock Text=" " VerticalAlignment="Center" Foreground="White" FontSize="12" FontFamily="Segoe MDL2 Assets" FontWeight="Black"/>
|
||||
<TextBlock Text="LIVE" VerticalAlignment="Center" Foreground="White" FontSize="12" FontWeight="Bold"/>
|
||||
<TextBlock x:Uid="/Cards/live" Text="LIVE" VerticalAlignment="Center" Foreground="White" FontSize="12" FontWeight="Bold"/>
|
||||
</StackPanel>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.RowDefinitions>
|
||||
@@ -36,20 +36,29 @@
|
||||
<Ellipse Height="80" Width="80" Margin="0,-45,0,0" VerticalAlignment="Bottom" Fill="{ThemeResource SystemControlBackgroundChromeMediumBrush}"/>
|
||||
<PersonPicture Name="avatar" Grid.Column="0" Height="74" Margin="3,-45,3,3" VerticalAlignment="Bottom" BorderBrush="White" BorderThickness="10"/>
|
||||
|
||||
<TextBlock Name="title" Grid.Column="1" Text="[Channel name]" Margin="5" TextWrapping="WrapWholeWords" MaxLines="2"/>
|
||||
<TextBlock Name="title" Grid.Column="1" Text="[Channel name]" Margin="5" TextWrapping="WrapWholeWords" MaxLines="2" TextTrimming="CharacterEllipsis"/>
|
||||
<StackPanel Grid.Column="2" Margin="5">
|
||||
<TextBlock Name="subs" Text="[Subscribers counter]" Foreground="Gray"/>
|
||||
<TextBlock Name="uploads" Text="[Uploads counter]" Foreground="Gray"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<TextBlock Grid.Row="1" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Height="50" Margin="10" TextAlignment="Center" Padding="0,16,0,0" Foreground="Gray">
|
||||
<Hyperlink Click="Hyperlink_Click">Log in</Hyperlink> to manage your subscriptions
|
||||
<Hyperlink Click="Hyperlink_Click"><Run x:Uid="/Cards/login">Log in</Run></Hyperlink> <Run x:Uid="/Cards/tomanage">to manage your subscriptions</Run>
|
||||
</TextBlock>
|
||||
<Grid Visibility="Collapsed" Grid.Row="1" VerticalAlignment="Bottom" Margin="10" Name="subscriptionPane" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}">
|
||||
<Button 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" 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"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Button>
|
||||
<UserControl.ContextFlyout>
|
||||
<MenuFlyout>
|
||||
<MenuFlyoutItem x:Uid="/Cards/channel" Icon="Contact" Text="View channel" Click="Button_Click"/>
|
||||
<MenuFlyoutSeparator/>
|
||||
<MenuFlyoutItem x:Uid="/Cards/getLink" Icon="Link" Text="Copy link" Name="getLink" Click="GetLink_Click"/>
|
||||
<MenuFlyoutItem x:Uid="/Cards/openWeb" Icon="Globe" Text="Open in browser" Name="inBrowser" Click="InBrowser_Click"/>
|
||||
<MenuFlyoutItem x:Uid="/Cards/share" Icon="Share" Text="Share" Name="share" Visibility="Collapsed"/>
|
||||
</MenuFlyout>
|
||||
</UserControl.ContextFlyout>
|
||||
</UserControl>
|
||||
|
||||
@@ -1,34 +1,30 @@
|
||||
using Google.Apis.YouTube.v3;
|
||||
using Google.Apis.YouTube.v3.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using Windows.System;
|
||||
using Windows.UI;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
|
||||
|
||||
namespace FoxTube.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// Channel item card
|
||||
/// </summary>
|
||||
public sealed partial class ChannelCard : UserControl
|
||||
{
|
||||
ResourceLoader resources = ResourceLoader.GetForCurrentView("Cards");
|
||||
|
||||
string channelId;
|
||||
Channel item;
|
||||
|
||||
public ChannelCard(string id, string live = "null")
|
||||
{
|
||||
this.InitializeComponent();
|
||||
InitializeComponent();
|
||||
Initialize(id, live);
|
||||
}
|
||||
|
||||
@@ -48,8 +44,8 @@ namespace FoxTube.Controls
|
||||
|
||||
title.Text = item.Snippet.Title;
|
||||
|
||||
subs.Text = $"{item.Statistics.SubscriberCount:0,0} subscribers";
|
||||
uploads.Text = $"{item.Statistics.VideoCount:0,0} videos";
|
||||
subs.Text = $"{item.Statistics.SubscriberCount:0,0} {resources.GetString("/Cards/subscribers")}";
|
||||
uploads.Text = $"{item.Statistics.VideoCount:0,0} {resources.GetString("/Cards/videos")}";
|
||||
|
||||
if (live == "live")
|
||||
liveTag.Visibility = Visibility.Visible;
|
||||
@@ -62,7 +58,7 @@ namespace FoxTube.Controls
|
||||
{
|
||||
subscribe.Background = new SolidColorBrush(Colors.Transparent);
|
||||
subscribe.Foreground = new SolidColorBrush(Colors.Gray);
|
||||
subscribe.Content = "Subscribed";
|
||||
subscribe.Content = resources.GetString("/Cards/unsubscribe");
|
||||
}
|
||||
}
|
||||
subscriptionPane.Visibility = Visibility.Visible;
|
||||
@@ -74,7 +70,7 @@ namespace FoxTube.Controls
|
||||
{
|
||||
if (item.BrandingSettings.Image.BannerImageUrl.Contains("default"))
|
||||
throw new Exception("Default channel cover detected");
|
||||
cover.Source = new BitmapImage(new Uri(item.BrandingSettings.Image.BannerTvLowImageUrl));
|
||||
cover.Source = new BitmapImage((item.BrandingSettings.Image.BannerTvHighImageUrl ?? item.BrandingSettings.Image.BannerTvImageUrl).ToUri());
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
@@ -95,14 +91,26 @@ namespace FoxTube.Controls
|
||||
{
|
||||
subscribe.Background = new SolidColorBrush(Colors.Transparent);
|
||||
subscribe.Foreground = new SolidColorBrush(Colors.Gray);
|
||||
subscribe.Content = "Subscribed";
|
||||
subscribe.Content = resources.GetString("/Cards/unsubscribe");
|
||||
}
|
||||
else
|
||||
{
|
||||
subscribe.Background = new SolidColorBrush(Colors.Red);
|
||||
subscribe.Foreground = new SolidColorBrush(Colors.White);
|
||||
subscribe.Content = "Subscribe";
|
||||
}
|
||||
subscribe.Content = resources.GetString("/Cards/subscribe/Content");
|
||||
}
|
||||
}
|
||||
|
||||
private void GetLink_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DataPackage data = new DataPackage();
|
||||
data.SetText(string.IsNullOrWhiteSpace(item.Snippet.CustomUrl) ? $"https://www.youtube.com/channel/{item.Id}" : $"https://www.youtube.com/user/{item.Snippet.CustomUrl}");
|
||||
Clipboard.SetContent(data);
|
||||
}
|
||||
|
||||
private async void InBrowser_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await Launcher.LaunchUriAsync((string.IsNullOrWhiteSpace(item.Snippet.CustomUrl) ? $"https://www.youtube.com/channel/{item.Id}" : $"https://www.youtube.com/user/{item.Snippet.CustomUrl}").ToUri());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
<UserControl
|
||||
x:Class="FoxTube.Controls.Chat"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="600"
|
||||
d:DesignWidth="400">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Name="inputField">
|
||||
<TextBox x:Uid="/Chat/box" Margin="5,5,42,5" PlaceholderText="Send a message" Name="newMessage" VerticalAlignment="Center" MinHeight="32" TextWrapping="Wrap" AcceptsReturn="True"/>
|
||||
<Button HorizontalAlignment="Right" Name="send" Click="send_Click" VerticalAlignment="Top"
|
||||
Height="32" Width="32"
|
||||
Margin="0,5,5,0" Padding="0"
|
||||
Background="Transparent"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
Content="" FontSize="30"/>
|
||||
</Grid>
|
||||
|
||||
<ScrollViewer Grid.Row="1">
|
||||
<ListView Name="list" SelectionMode="None">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border BorderBrush="Red" BorderThickness="{Binding Path=BorderThickness}" CornerRadius="5" HorizontalAlignment="Stretch" Background="{Binding Path=Background}" Margin="0,2">
|
||||
<Grid Margin="0,5,5,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" Margin="5,0">
|
||||
<PersonPicture Height="20" ProfilePicture="{Binding Path=Avatar}"/>
|
||||
<FontIcon Glyph="" Margin="2,0" Visibility="{Binding Path=IsVerified}">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/Chat/verified"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</FontIcon>
|
||||
<FontIcon Glyph="" Margin="2,0" Visibility="{Binding Path=IsModerator}">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/Chat/moder"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</FontIcon>
|
||||
<FontIcon Glyph="" Margin="2,0" Visibility="{Binding Path=IsOwner}">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/Chat/owner"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</FontIcon>
|
||||
<FontIcon Glyph="" Margin="2,0" Visibility="{Binding Path=IsSponsor}">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/Chat/sponsor"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</FontIcon>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Grid.Column="1" VerticalAlignment="Top" Margin="0,0,5,0">
|
||||
<HyperlinkButton Content="{Binding Path=Author}" Tag="{Binding Path=ChannelId}" Grid.Column="1" Margin="0,-6,0,0" FontWeight="Bold" Click="HyperlinkButton_Click"/>
|
||||
<TextBlock Text=":"/>
|
||||
</StackPanel>
|
||||
<GroupItem Content="{Binding Path=Message}" Grid.Column="2"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
<ListViewItem>
|
||||
<TextBlock x:Uid="/Chat/welcome" Text="Welcome to the chat room" Foreground="Gray"/>
|
||||
</ListViewItem>
|
||||
</ListView>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,141 @@
|
||||
using System;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Google.Apis.YouTube.v3.Data;
|
||||
using Google.Apis.YouTube.v3;
|
||||
using Windows.UI;
|
||||
|
||||
namespace FoxTube.Controls
|
||||
{
|
||||
public class ChatMessage
|
||||
{
|
||||
public string Author => message.AuthorDetails.DisplayName;
|
||||
public TextBlock Message
|
||||
{
|
||||
get
|
||||
{
|
||||
TextBlock block = new TextBlock()
|
||||
{
|
||||
IsTextSelectionEnabled = true,
|
||||
VerticalAlignment = VerticalAlignment.Top,
|
||||
TextWrapping = TextWrapping.WrapWholeWords
|
||||
};
|
||||
Methods.FormatText(ref block, message.Snippet.DisplayMessage);
|
||||
return block;
|
||||
}
|
||||
}
|
||||
public string ChannelId => message.AuthorDetails.ChannelId;
|
||||
public string Avatar => message.AuthorDetails.ProfileImageUrl;
|
||||
|
||||
public Visibility IsVerified => message.AuthorDetails.IsVerified.Value ? Visibility.Visible : Visibility.Collapsed;
|
||||
public Visibility IsOwner => message.AuthorDetails.IsChatOwner.Value ? Visibility.Visible : Visibility.Collapsed;
|
||||
public Visibility IsSponsor => message.AuthorDetails.IsChatSponsor.Value ? Visibility.Visible : Visibility.Collapsed;
|
||||
public Visibility IsModerator => message.AuthorDetails.IsChatModerator.Value ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
public Brush Background
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsVerified == Visibility.Visible || IsOwner == Visibility.Visible || IsSponsor == Visibility.Visible || IsModerator == Visibility.Visible)
|
||||
return new SolidColorBrush() { Color = Colors.Red, Opacity = .2 };
|
||||
else
|
||||
return new SolidColorBrush();
|
||||
}
|
||||
}
|
||||
public Thickness BorderThickness
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsVerified == Visibility.Visible || IsOwner == Visibility.Visible || IsSponsor == Visibility.Visible || IsModerator == Visibility.Visible)
|
||||
return new Thickness(2);
|
||||
else
|
||||
return new Thickness(0);
|
||||
}
|
||||
}
|
||||
|
||||
private LiveChatMessage message;
|
||||
|
||||
public ChatMessage(LiveChatMessage item)
|
||||
{
|
||||
message = item;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed partial class Chat : UserControl
|
||||
{
|
||||
string chatId;
|
||||
DateTime lastInsert;
|
||||
DispatcherTimer timer = new DispatcherTimer()
|
||||
{
|
||||
Interval = TimeSpan.FromSeconds(1)
|
||||
};
|
||||
|
||||
public Chat(string id)
|
||||
{
|
||||
InitializeComponent();
|
||||
if (!SecretsVault.IsAuthorized)
|
||||
inputField.Visibility = Visibility.Collapsed;
|
||||
|
||||
chatId = id;
|
||||
timer.Tick += Update;
|
||||
timer.Start();
|
||||
}
|
||||
|
||||
public async void Update(object sender, object e)
|
||||
{
|
||||
LiveChatMessagesResource.ListRequest request = SecretsVault.Service.LiveChatMessages.List(chatId, "snippet,authorDetails");
|
||||
LiveChatMessageListResponse response = await request.ExecuteAsync();
|
||||
foreach (LiveChatMessage i in response.Items)
|
||||
if(i.Snippet.PublishedAt >= lastInsert)
|
||||
list.Items.Insert(0, new ChatMessage(i));
|
||||
lastInsert = DateTime.Now;
|
||||
timer.Interval = TimeSpan.FromMilliseconds(response.PollingIntervalMillis.Value);
|
||||
timer.Start();
|
||||
}
|
||||
|
||||
private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Methods.MainPage.GoToChannel(((HyperlinkButton)sender).Tag as string);
|
||||
}
|
||||
|
||||
private async void send_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
newMessage.IsEnabled = false;
|
||||
send.IsEnabled = false;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(newMessage.Text))
|
||||
return;
|
||||
|
||||
LiveChatMessage message = new LiveChatMessage()
|
||||
{
|
||||
Snippet = new LiveChatMessageSnippet()
|
||||
{
|
||||
Type = "textMessageEvent",
|
||||
LiveChatId = chatId,
|
||||
TextMessageDetails = new LiveChatTextMessageDetails()
|
||||
{
|
||||
MessageText = newMessage.Text
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
LiveChatMessagesResource.InsertRequest request = SecretsVault.Service.LiveChatMessages.Insert(message, "snippet,authorDetails");
|
||||
LiveChatMessage response = await request.ExecuteAsync();
|
||||
|
||||
if(response != null)
|
||||
{
|
||||
newMessage.Text = string.Empty;
|
||||
list.Items.Add(new ChatMessage(response));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
newMessage.IsEnabled = true;
|
||||
send.IsEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,8 @@
|
||||
x:Class="FoxTube.Controls.CommentCard"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:FoxTube.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignWidth="400">
|
||||
|
||||
@@ -38,8 +36,9 @@
|
||||
<StackPanel Grid.Row="2" Name="editor" Visibility="Collapsed">
|
||||
<TextBox Name="editorText" Text="[Content]" AcceptsReturn="True" TextWrapping="Wrap" TextChanged="editorText_TextChanged"/>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,5,0,5">
|
||||
<Button Name="editorClose" Content="Cancel" Click="editorClose_Click"/>
|
||||
<Button Name="editorSend" Content="Submit" Margin="5,0,0,0" Click="editorSend_Click"/>
|
||||
<Button x:Uid="/CommentsPage/editorDelete" Content="Delete comment" Background="Red" Name="deleteComment" Click="DeleteComment_Click"/>
|
||||
<Button x:Uid="/CommentsPage/editorCancel" Name="editorClose" Content="Cancel" Click="editorClose_Click" Margin="5, 0"/>
|
||||
<Button x:Uid="/CommentsPage/editorSubmit" Name="editorSend" Content="Submit" Click="editorSend_Click"/>
|
||||
</StackPanel>
|
||||
<ProgressBar Name="editorSending" Foreground="Red" IsIndeterminate="True" Visibility="Collapsed"/>
|
||||
</StackPanel>
|
||||
@@ -69,7 +68,7 @@
|
||||
Height="35">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock FontFamily="Segoe MDL2 Assets" Text="" FontSize="20"/>
|
||||
<TextBlock Text="Reply"/>
|
||||
<TextBlock x:Uid="/CommentsPage/reply" Text="Reply"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
@@ -78,7 +77,7 @@
|
||||
Height="35">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock FontFamily="Segoe MDL2 Assets" Text="" FontSize="20"/>
|
||||
<TextBlock Text="Edit"/>
|
||||
<TextBlock x:Uid="/CommentsPage/edit" Text="Edit"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
@@ -86,7 +85,7 @@
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<TextBox Grid.Row="1" Name="reply" TextChanged="reply_TextChanged" TextWrapping="Wrap" BorderThickness="0" Background="{ThemeResource SystemControlBackgroundChromeMediumLowBrush}" AcceptsReturn="True" MaxLength="500"
|
||||
<TextBox x:Uid="/CommentsPage/replyBox" Grid.Row="1" Name="reply" TextChanged="reply_TextChanged" TextWrapping="Wrap" BorderThickness="0" Background="{ThemeResource SystemControlBackgroundChromeMediumLowBrush}" AcceptsReturn="True" MaxLength="500"
|
||||
Padding="5" Margin="0,0,32,0"
|
||||
PlaceholderText="Enter your reply..."/>
|
||||
<Button Grid.Row="1" Name="send" Click="send_Click" IsEnabled="False" HorizontalAlignment="Right" VerticalAlignment="Top"
|
||||
|
||||
@@ -1,31 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
using Google.Apis.YouTube.v3;
|
||||
using Google.Apis.YouTube.v3.Data;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
using Windows.System;
|
||||
using Windows.UI.Popups;
|
||||
|
||||
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
|
||||
using Windows.ApplicationModel.Resources;
|
||||
|
||||
namespace FoxTube.Controls
|
||||
{
|
||||
public enum CommentType { TopLevel, Reply }
|
||||
/// <summary>
|
||||
/// Control represents video comment entity
|
||||
/// </summary>
|
||||
public sealed partial class CommentCard : UserControl
|
||||
{
|
||||
ResourceLoader resources = ResourceLoader.GetForCurrentView("CommentsPage");
|
||||
|
||||
Comment item;
|
||||
CommentThread thread;
|
||||
bool repliesLoaded = false;
|
||||
@@ -33,7 +28,7 @@ namespace FoxTube.Controls
|
||||
|
||||
public CommentCard(CommentThread comment)
|
||||
{
|
||||
this.InitializeComponent();
|
||||
InitializeComponent();
|
||||
Initialize(comment);
|
||||
}
|
||||
|
||||
@@ -72,7 +67,7 @@ namespace FoxTube.Controls
|
||||
else
|
||||
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 ? "(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);
|
||||
|
||||
try { avatar.ProfilePicture = new BitmapImage(new Uri(comment.Snippet.TopLevelComment.Snippet.AuthorProfileImageUrl)); }
|
||||
@@ -118,7 +113,7 @@ namespace FoxTube.Controls
|
||||
else
|
||||
author.Text = comment.Snippet.AuthorDisplayName;
|
||||
|
||||
meta.Text = string.Format("{0} {1}", comment.Snippet.AuthorDisplayName, Methods.GetAgo(comment.Snippet.PublishedAt.Value), comment.Snippet.UpdatedAt.Value != comment.Snippet.PublishedAt.Value ? "(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);
|
||||
|
||||
try { avatar.ProfilePicture = new BitmapImage(new Uri(comment.Snippet.AuthorProfileImageUrl)); }
|
||||
@@ -209,7 +204,7 @@ namespace FoxTube.Controls
|
||||
}
|
||||
catch
|
||||
{
|
||||
await new MessageDialog("Failed to send your reply. Please, try again later.", "Failed to send your reply").ShowAsync();
|
||||
await new MessageDialog(resources.GetString("/CommentsPage/failedReply")).ShowAsync();
|
||||
}
|
||||
send.IsEnabled = true;
|
||||
reply.IsEnabled = true;
|
||||
@@ -251,7 +246,7 @@ namespace FoxTube.Controls
|
||||
}
|
||||
catch
|
||||
{
|
||||
await new MessageDialog("Failed to edit your commentary. Please, try again later.", "Failed to edit your commentary").ShowAsync();
|
||||
await new MessageDialog(resources.GetString("/CommentsPage/failedEdit")).ShowAsync();
|
||||
}
|
||||
|
||||
editorText.IsEnabled = true;
|
||||
@@ -274,5 +269,26 @@ namespace FoxTube.Controls
|
||||
editorText.Text = text.Text;
|
||||
editor.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
private async void DeleteComment_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
MessageDialog dialog = new MessageDialog(resources.GetString("/CommentsPage/deleteContent"), resources.GetString("/CommentsPage/deleteHeader"));
|
||||
|
||||
dialog.Commands.Add(new UICommand(resources.GetString("/CommentsPage/yes"), async (command) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await SecretsVault.Service.Comments.Delete(item.Id).ExecuteAsync();
|
||||
Methods.CommentsPage.RemoveComment(this);
|
||||
}
|
||||
catch { }
|
||||
}));
|
||||
dialog.Commands.Add(new UICommand(resources.GetString("/CommentsPage/no")));
|
||||
|
||||
dialog.CancelCommandIndex = 1;
|
||||
dialog.DefaultCommandIndex = 0;
|
||||
|
||||
await dialog.ShowAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@
|
||||
<Button Name="open" Click="open_Click" Width="80" Height="80" Padding="0" Background="Transparent">
|
||||
<StackPanel>
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="30" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="Open" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center"/>
|
||||
<TextBlock x:Uid="/Downloads/openFile" Text="Open" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Name="gotoOriginal" Click="gotoOriginal_Click" Width="80" Height="80" Padding="0" Background="Transparent">
|
||||
<StackPanel>
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="30" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="Go to original" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center" HorizontalAlignment="Center"/>
|
||||
<TextBlock x:Uid="/Downloads/gotoOrign" Text="Go to original" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
@@ -47,7 +47,7 @@
|
||||
<TextBlock Name="status" Text="Downloading..." HorizontalAlignment="Left"/>
|
||||
<ProgressBar Name="progressBar" Width="200" Maximum="1" IsIndeterminate="True" Foreground="Red"/>
|
||||
<TextBlock Name="perc" Text="--%"/>
|
||||
<Button Content="Cancel" Name="cancel" Click="CancelPrompt" HorizontalAlignment="Right"/>
|
||||
<Button x:Uid="/Downloads/cancel" Content="Cancel" Name="cancel" Click="CancelPrompt" HorizontalAlignment="Right"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -15,11 +15,14 @@ using Windows.UI.Popups;
|
||||
using Windows.UI.Notifications;
|
||||
using Microsoft.Toolkit.Uwp.Notifications;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
|
||||
namespace FoxTube.Controls
|
||||
{
|
||||
public sealed partial class DownloadItem : UserControl
|
||||
{
|
||||
ResourceLoader resources = ResourceLoader.GetForCurrentView("Downloads");
|
||||
|
||||
public DownloadItemContainer Container { get; private set; }
|
||||
public StorageFile file;
|
||||
public bool InProgress { get; set; } = false;
|
||||
@@ -62,10 +65,10 @@ namespace FoxTube.Controls
|
||||
title.Text = Container.Title;
|
||||
path.Text = file.Name;
|
||||
thumbnail.Source = new BitmapImage(Container.Thumbnail);
|
||||
quality.Text = $"Quality: {Container.Quality}";
|
||||
duration.Text = $"Duration: {Container.Duration}";
|
||||
channel.Text = $"Author: {Container.Channel}";
|
||||
ext.Text = $"Extension: {Container.Extension}";
|
||||
quality.Text = $"{resources.GetString("/Downloads/quality")}: {Container.Quality}";
|
||||
duration.Text = $"{resources.GetString("/Downloads/duration")}: {Container.Duration}";
|
||||
channel.Text = $"{resources.GetString("/Downloads/author")}: {Container.Channel}";
|
||||
ext.Text = $"{resources.GetString("/Downloads/ext")}: {Container.Extension}";
|
||||
|
||||
progressPanel.Visibility = Visibility.Collapsed;
|
||||
donePanel.Visibility = Visibility.Visible;
|
||||
@@ -93,11 +96,11 @@ namespace FoxTube.Controls
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new AdaptiveText() { Text = "Downloading a video" },
|
||||
new AdaptiveText() { Text = resources.GetString("/Downloads/toastStartHeader") },
|
||||
new AdaptiveProgressBar()
|
||||
{
|
||||
Title = meta.Snippet.Title,
|
||||
Status = "Downloading...",
|
||||
Status = resources.GetString("/Downloads/downloading/Text"),
|
||||
Value = new BindableProgressBarValue("value")
|
||||
}
|
||||
}
|
||||
@@ -108,7 +111,7 @@ namespace FoxTube.Controls
|
||||
{
|
||||
Buttons =
|
||||
{
|
||||
new ToastButton("Cancel", $"dcancel|{Container.Id}")
|
||||
new ToastButton(resources.GetString("/Downloads/cancel/Content"), $"dcancel|{Container.Id}")
|
||||
{
|
||||
ActivationType = ToastActivationType.Background
|
||||
}
|
||||
@@ -131,10 +134,10 @@ namespace FoxTube.Controls
|
||||
|
||||
thumbnail.Source = new BitmapImage(new Uri(meta.Snippet.Thumbnails.Medium.Url));
|
||||
title.Text = meta.Snippet.Title;
|
||||
ext.Text = $"Extension: {info.Container.GetFileExtension()}";
|
||||
quality.Text = $"Quality: {q}";
|
||||
duration.Text = $"Duration: {XmlConvert.ToTimeSpan(meta.ContentDetails.Duration)}";
|
||||
channel.Text = $"Author: {meta.Snippet.ChannelTitle}";
|
||||
ext.Text = $"{resources.GetString("/Downloads/ext")}: {info.Container.GetFileExtension()}";
|
||||
quality.Text = $"{resources.GetString("/Downloads/quality")}: {q}";
|
||||
duration.Text = $"{resources.GetString("/Downloads/duration")}: {XmlConvert.ToTimeSpan(meta.ContentDetails.Duration)}";
|
||||
channel.Text = $"{resources.GetString("/Downloads/author")}: {meta.Snippet.ChannelTitle}";
|
||||
path.Text = file.Name;
|
||||
|
||||
progressPanel.Visibility = Visibility.Visible;
|
||||
@@ -170,13 +173,13 @@ namespace FoxTube.Controls
|
||||
template.LoadXml($@"<toast activationType='background' launch='download|{file.Path}'>
|
||||
<visual>
|
||||
<binding template='ToastGeneric'>
|
||||
<text>Download complete</text>
|
||||
<text>{resources.GetString("/Downloads/toastCompleteHeader")}</text>
|
||||
<text>{Container.Title}</text>
|
||||
</binding>
|
||||
</visual>
|
||||
|
||||
<actions>
|
||||
<action content='Go to original'
|
||||
<action content='{resources.GetString("/Downloads/gotoOrign/Text")}'
|
||||
activationType='foreground'
|
||||
arguments='video|{Container.Id}'/>
|
||||
</actions>
|
||||
@@ -196,7 +199,7 @@ namespace FoxTube.Controls
|
||||
|
||||
public async void Cancel()
|
||||
{
|
||||
status.Text = "Cancelling...";
|
||||
status.Text = resources.GetString("/Downloads/cancelling");
|
||||
progressBar.IsIndeterminate = true;
|
||||
cancel.IsEnabled = false;
|
||||
cts.Cancel();
|
||||
@@ -210,7 +213,7 @@ namespace FoxTube.Controls
|
||||
template.LoadXml($@"<toast activationType='foreground' launch='download'>
|
||||
<visual>
|
||||
<binding template='ToastGeneric'>
|
||||
<text>Download canceled</text>
|
||||
<text>{resources.GetString("/Downloads/toastCanceledHeader")}</text>
|
||||
<text>{Container.Title}</text>
|
||||
</binding>
|
||||
</visual>
|
||||
@@ -224,10 +227,10 @@ namespace FoxTube.Controls
|
||||
{
|
||||
if(InProgress)
|
||||
{
|
||||
MessageDialog dialog = new MessageDialog("Are you sure?", "Cancelling download");
|
||||
MessageDialog dialog = new MessageDialog(resources.GetString("/Downloads/prompt"), resources.GetString("/Downloads/cancellingHeader"));
|
||||
|
||||
dialog.Commands.Add(new UICommand("Yes", (command) => Cancel()));
|
||||
dialog.Commands.Add(new UICommand("No"));
|
||||
dialog.Commands.Add(new UICommand(resources.GetString("/Downloads/yes"), (command) => Cancel()));
|
||||
dialog.Commands.Add(new UICommand(resources.GetString("/Downloads/no")));
|
||||
|
||||
dialog.DefaultCommandIndex = 1;
|
||||
await dialog.ShowAsync();
|
||||
|
||||
@@ -1,36 +1,32 @@
|
||||
using FoxTube.Classes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using System;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
using System.Xml;
|
||||
using System.Diagnostics;
|
||||
|
||||
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
|
||||
using Windows.Media;
|
||||
using YoutubeExplode.Models.ClosedCaptions;
|
||||
|
||||
namespace FoxTube.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// Control for displaying closed captions
|
||||
/// </summary>
|
||||
public sealed partial class LiveCaptions : UserControl
|
||||
{
|
||||
public MediaElement Player { get; set; }
|
||||
public double Size
|
||||
{
|
||||
get => text.FontSize;
|
||||
set => text.FontSize = value;
|
||||
}
|
||||
|
||||
public MediaTimelineController Player { get; set; }
|
||||
private bool isClosed = false;
|
||||
DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(10) };
|
||||
List<Caption> captions = new List<Caption>();
|
||||
Caption currentCaption = null;
|
||||
ClosedCaption currentCaption = null;
|
||||
|
||||
ClosedCaptionTrack track = null;
|
||||
|
||||
public LiveCaptions()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
InitializeComponent();
|
||||
timer.Tick += UpdateCaption;
|
||||
}
|
||||
|
||||
@@ -40,11 +36,11 @@ namespace FoxTube.Controls
|
||||
|
||||
bool found = false;
|
||||
if(!isClosed)
|
||||
captions.ForEach((x) =>
|
||||
track.Captions.ForEach(i =>
|
||||
{
|
||||
if (Player.Position >= x.Start && Player.Position <= x.End)
|
||||
if (Player.Position >= i.Offset && Player.Position <= i.Offset + i.Duration)
|
||||
{
|
||||
currentCaption = x;
|
||||
currentCaption = i;
|
||||
text.Text = currentCaption.Text;
|
||||
Visibility = Visibility.Visible;
|
||||
found = true;
|
||||
@@ -58,24 +54,15 @@ namespace FoxTube.Controls
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialize(string source, bool isAutoGenerated = false)
|
||||
public async void Initialize(ClosedCaptionTrackInfo info)
|
||||
{
|
||||
captions.Clear();
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(source);
|
||||
track = await new YoutubeExplode.YoutubeClient().GetClosedCaptionTrackAsync(info);
|
||||
|
||||
if (!isAutoGenerated)
|
||||
foreach (XmlElement i in doc["timedtext"]["body"].ChildNodes)
|
||||
captions.Add(new Caption(int.Parse(i.GetAttribute("t")), int.Parse(i.GetAttribute("d")), i.InnerText));
|
||||
else
|
||||
foreach (XmlElement i in doc["transcript"].ChildNodes)
|
||||
captions.Add(new Caption(double.Parse(i.GetAttribute("start")), double.Parse(i.GetAttribute("dur")), i.InnerText.Replace("<font color=\"#E5E5E5\">", "").Replace("<font color=\"#CCCCCC\">", "").Replace("</font>", "").Replace("'", "'")));
|
||||
|
||||
captions.ForEach((x) =>
|
||||
track.Captions.ForEach(i =>
|
||||
{
|
||||
if (Player.Position > x.Start && Player.Position < x.End)
|
||||
if (Player.Position > i.Offset && Player.Position < i.Offset + i.Duration)
|
||||
{
|
||||
currentCaption = x;
|
||||
currentCaption = i;
|
||||
text.Text = currentCaption.Text;
|
||||
Visibility = Visibility.Visible;
|
||||
}
|
||||
@@ -86,7 +73,7 @@ namespace FoxTube.Controls
|
||||
|
||||
public void Close()
|
||||
{
|
||||
captions.Clear();
|
||||
track = null;
|
||||
currentCaption = null;
|
||||
Visibility = Visibility.Collapsed;
|
||||
timer.Stop();
|
||||
|
||||
@@ -41,11 +41,21 @@
|
||||
<Ellipse Grid.Column="0" Height="50" Width="50" Margin="5,-30,5,10" Fill="{ThemeResource SystemControlBackgroundChromeMediumBrush}"/>
|
||||
<PersonPicture Name="avatar" Grid.Column="0" Height="46" Margin="5,-30,5,0" BorderBrush="White" BorderThickness="10"/>
|
||||
|
||||
<TextBlock Name="channelName" Grid.Column="1" Text="[Channel name]" Foreground="Gray" Margin="0,2,0,0" FontSize="12"/>
|
||||
<TextBlock HorizontalAlignment="Left" MaxWidth="200" TextTrimming="CharacterEllipsis" Name="channelName" Grid.Column="1" Text="[Channel name]" Foreground="Gray" Margin="0,2,0,0" FontSize="12"/>
|
||||
<TextBlock Grid.Column="1" Name="date" Text="[Published at]" HorizontalAlignment="Right" Foreground="Gray" Margin="0,2,2,0" FontSize="12"/>
|
||||
</Grid>
|
||||
<TextBlock Grid.Row="1" Name="title" Text="[Title]" TextWrapping="WrapWholeWords" Margin="5" MaxLines="2"/>
|
||||
<TextBlock Grid.Row="1" Name="title" Text="[Title]" TextWrapping="WrapWholeWords" TextTrimming="CharacterEllipsis" Margin="5" MaxLines="2"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Button>
|
||||
<UserControl.ContextFlyout>
|
||||
<MenuFlyout>
|
||||
<MenuFlyoutItem x:Uid="/Cards/playlist" Icon="List" Text="View playlist" Click="Button_Click"/>
|
||||
<MenuFlyoutItem x:Uid="/Cards/channel" Icon="Contact" Text="View channel" Name="openChannel" Click="OpenChannel_Click"/>
|
||||
<MenuFlyoutSeparator/>
|
||||
<MenuFlyoutItem x:Uid="/Cards/getLink" Icon="Link" Text="Copy link" Name="getLink" Click="GetLink_Click"/>
|
||||
<MenuFlyoutItem x:Uid="/Cards/openWeb" Icon="Globe" Text="Open in browser" Name="inBrowser" Click="InBrowser_Click"/>
|
||||
<MenuFlyoutItem x:Uid="/Cards/share" Icon="Share" Text="Share" Name="share" Visibility="Collapsed"/>
|
||||
</MenuFlyout>
|
||||
</UserControl.ContextFlyout>
|
||||
</Page>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Google.Apis.YouTube.v3;
|
||||
using Google.Apis.YouTube.v3.Data;
|
||||
using System;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using Windows.System;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
@@ -40,7 +42,7 @@ namespace FoxTube.Controls
|
||||
|
||||
try
|
||||
{
|
||||
thumbnail.Source = new BitmapImage(new Uri(item.Snippet.Thumbnails.Medium.Url));
|
||||
thumbnail.Source = new BitmapImage((item.Snippet.Thumbnails.Maxres ?? item.Snippet.Thumbnails.Medium).Url.ToUri());
|
||||
avatar.ProfilePicture = new BitmapImage(new Uri((await r.ExecuteAsync()).Items[0].Snippet.Thumbnails.Medium.Url));
|
||||
} catch { }
|
||||
}
|
||||
@@ -54,5 +56,22 @@ namespace FoxTube.Controls
|
||||
{
|
||||
Methods.MainPage.GoToPlaylist(item.Id);
|
||||
}
|
||||
|
||||
private void OpenChannel_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Methods.MainPage.GoToChannel(item.Snippet.ChannelId);
|
||||
}
|
||||
|
||||
private void GetLink_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DataPackage data = new DataPackage();
|
||||
data.SetText($"https://www.youtube.com/playlist?list={playlistId}");
|
||||
Clipboard.SetContent(data);
|
||||
}
|
||||
|
||||
private async void InBrowser_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await Launcher.LaunchUriAsync($"https://www.youtube.com/playlist?list={playlistId}".ToUri());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<HyperlinkButton Foreground="Red" HorizontalAlignment="Center" Content="Show more" Name="btn" Click="btn_Click"/>
|
||||
<HyperlinkButton x:Uid="/Cards/more" Foreground="Red" HorizontalAlignment="Center" Content="Show more" Name="btn" Click="btn_Click"/>
|
||||
<ProgressBar Name="bar" IsIndeterminate="True" Foreground="Red" Visibility="Collapsed"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<Image Name="thumbnail" Source="/Assets/videoThumbSample.png" Stretch="Fill"/>
|
||||
<Grid Background="#7F000000" Name="watched" Visibility="Collapsed">
|
||||
<StackPanel Margin="5" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" VerticalAlignment="Top" HorizontalAlignment="Left" Padding="5,2,5,2" BorderBrush="Gray" BorderThickness="1">
|
||||
<TextBlock Text="Watched" Foreground="Gray" FontSize="12"/>
|
||||
<TextBlock x:Uid="/Cards/watched" Text="Watched" Foreground="Gray" FontSize="12"/>
|
||||
</StackPanel>
|
||||
<ProgressBar VerticalAlignment="Bottom" Margin="54,0,0,0" Foreground="Red" Name="leftOn"/>
|
||||
</Grid>
|
||||
@@ -29,7 +29,7 @@
|
||||
</StackPanel>
|
||||
<StackPanel Name="liveTag" Margin="0,0,5,30" Background="Red" BorderBrush="White" BorderThickness="1" VerticalAlignment="Bottom" HorizontalAlignment="Right" Padding="5,2,5,3" Orientation="Horizontal" Visibility="Collapsed">
|
||||
<TextBlock Text=" " VerticalAlignment="Center" Foreground="White" FontSize="12" FontFamily="Segoe MDL2 Assets" FontWeight="Black"/>
|
||||
<TextBlock Name="liveContent" Text="LIVE" VerticalAlignment="Center" Foreground="White" FontSize="12" FontWeight="Bold"/>
|
||||
<TextBlock x:Uid="/Cards/live" Name="liveContent" Text="LIVE" VerticalAlignment="Center" Foreground="White" FontSize="12" FontWeight="Bold"/>
|
||||
</StackPanel>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.RowDefinitions>
|
||||
@@ -44,22 +44,28 @@
|
||||
<Ellipse Grid.Column="0" Height="50" Width="50" Margin="5,-30,5,10" Fill="{ThemeResource SystemControlBackgroundChromeMediumBrush}"/>
|
||||
<PersonPicture Name="avatar" Grid.Column="0" Height="46" Margin="5,-30,5,0" BorderBrush="White" BorderThickness="10"/>
|
||||
|
||||
<TextBlock Name="channelName" Grid.Column="1" Text="[Channel name]" Foreground="Gray" Margin="0,2,0,0" FontSize="12"/>
|
||||
<TextBlock MaxWidth="200" Name="channelName" HorizontalAlignment="Left" Grid.Column="1" Text="[Channel name]" TextTrimming="CharacterEllipsis" Foreground="Gray" Margin="0,2,0,0" FontSize="12"/>
|
||||
<TextBlock Grid.Column="1" Name="views" Text="[Views]" HorizontalAlignment="Right" Foreground="Gray" Margin="0,2,2,0" FontSize="12"/>
|
||||
</Grid>
|
||||
<TextBlock Grid.Row="1" Name="title" Text="[Title]" TextWrapping="WrapWholeWords" Margin="5" MaxLines="2"/>
|
||||
<TextBlock Grid.Row="1" Name="title" Text="[Title]" TextWrapping="WrapWholeWords" Margin="5" MaxLines="2" TextTrimming="CharacterEllipsis"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Button>
|
||||
<UserControl.ContextFlyout>
|
||||
<MenuFlyout>
|
||||
<MenuFlyoutItem Icon="Play" Text="Play"/>
|
||||
<MenuFlyoutItem Icon="Contact" Text="View channel"/>
|
||||
<MenuFlyoutItem x:Uid="/Cards/play" Icon="Play" Text="Play" Name="play" Click="Button_Click"/>
|
||||
<MenuFlyoutItem x:Uid="/Cards/incognitoPlay" Text="Play incognito" Visibility="Collapsed">
|
||||
<MenuFlyoutItem.Icon>
|
||||
<FontIcon Glyph=""/>
|
||||
</MenuFlyoutItem.Icon>
|
||||
</MenuFlyoutItem>
|
||||
<MenuFlyoutItem x:Uid="/Cards/channel" Icon="Contact" Text="View channel" Name="viewChannel" Click="ViewChannel_Click"/>
|
||||
<MenuFlyoutSeparator/>
|
||||
<MenuFlyoutItem Icon="Link" Text="Copy link"/>
|
||||
<MenuFlyoutItem Icon="Share" Text="Share"/>
|
||||
<MenuFlyoutSeparator/>
|
||||
<MenuFlyoutItem Icon="Download" Text="Download"/>
|
||||
<MenuFlyoutItem x:Uid="/Cards/getLink" Icon="Link" Text="Copy link" Name="getLink" Click="GetLink_Click"/>
|
||||
<MenuFlyoutItem x:Uid="/Cards/openWeb" Icon="Globe" Text="Open in browser" Name="inBrowser" Click="InBrowser_Click"/>
|
||||
<MenuFlyoutItem x:Uid="/Cards/share" Icon="Share" Text="Share" Name="share" Visibility="Collapsed"/>
|
||||
<MenuFlyoutSeparator Visibility="Collapsed"/>
|
||||
<MenuFlyoutItem Icon="Download" Text="Download" Visibility="Collapsed"/>
|
||||
</MenuFlyout>
|
||||
</UserControl.ContextFlyout>
|
||||
</UserControl>
|
||||
|
||||
@@ -4,22 +4,26 @@ using Windows.UI.Xaml.Controls;
|
||||
using Google.Apis.YouTube.v3;
|
||||
using Google.Apis.YouTube.v3.Data;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
using System.Xml;
|
||||
using Windows.System;
|
||||
using Windows.UI.Popups;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
|
||||
namespace FoxTube.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// Video item card
|
||||
/// </summary>
|
||||
public sealed partial class VideoCard : UserControl
|
||||
{
|
||||
ResourceLoader resources = ResourceLoader.GetForCurrentView("Cards");
|
||||
|
||||
public string playlistId;
|
||||
public string videoId;
|
||||
Video item;
|
||||
|
||||
bool embed = true;
|
||||
public VideoCard(string id, string playlist = null)
|
||||
{
|
||||
this.InitializeComponent();
|
||||
InitializeComponent();
|
||||
Initialize(id, playlist);
|
||||
}
|
||||
|
||||
@@ -42,7 +46,7 @@ namespace FoxTube.Controls
|
||||
channelName.Text = item.Snippet.ChannelTitle;
|
||||
if (item.Snippet.LiveBroadcastContent == "live")
|
||||
{
|
||||
views.Text = $"{item.LiveStreamingDetails.ConcurrentViewers:0,0} viewers";
|
||||
views.Text = $"{item.LiveStreamingDetails.ConcurrentViewers:0,0} {resources.GetString("/Cards/viewers")}";
|
||||
if (item.LiveStreamingDetails.ScheduledStartTime.HasValue && item.LiveStreamingDetails.ScheduledEndTime.HasValue)
|
||||
info.Text = $"{item.LiveStreamingDetails.ScheduledEndTime - item.LiveStreamingDetails.ScheduledStartTime} | {Methods.GetAgo(item.LiveStreamingDetails.ActualStartTime.Value)}";
|
||||
else
|
||||
@@ -59,14 +63,13 @@ namespace FoxTube.Controls
|
||||
liveTag.Visibility = Visibility.Visible;
|
||||
|
||||
if (item.LiveStreamingDetails.ScheduledStartTime.HasValue && (item.LiveStreamingDetails.ScheduledStartTime - DateTime.Now).Value.TotalMilliseconds > 0)
|
||||
liveContent.Text = $"Goes live in {item.LiveStreamingDetails.ScheduledStartTime}";
|
||||
else liveContent.Text = "Upcoming";
|
||||
liveContent.Text = $"{resources.GetString("/Cards/goesLive")} {item.LiveStreamingDetails.ScheduledStartTime}";
|
||||
else liveContent.Text = resources.GetString("/Cards/upcoming");
|
||||
}
|
||||
else
|
||||
{
|
||||
views.Text = $"{item.Statistics.ViewCount:0,0} views";
|
||||
info.Text = $"{XmlConvert.ToTimeSpan(item.ContentDetails.Duration)} | {Methods.GetAgo(item.Snippet.PublishedAt.Value)}";
|
||||
embed = false;
|
||||
views.Text = $"{item.Statistics.ViewCount:0,0} {resources.GetString("/Cards/views")}";
|
||||
info.Text = $"{item.ContentDetails.Duration.GetDuration()} | {Methods.GetAgo(item.Snippet.PublishedAt.Value)}";
|
||||
}
|
||||
|
||||
var request1 = SecretsVault.Service.Channels.List("snippet");
|
||||
@@ -76,7 +79,7 @@ namespace FoxTube.Controls
|
||||
try
|
||||
{
|
||||
avatar.ProfilePicture = new BitmapImage(new Uri(response1.Items[0].Snippet.Thumbnails.Medium.Url));
|
||||
thumbnail.Source = new BitmapImage(new Uri(item.Snippet.Thumbnails.Medium.Url));
|
||||
thumbnail.Source = new BitmapImage(new Uri((item.Snippet.Thumbnails.Maxres ?? item.Snippet.Thumbnails.Medium).Url));
|
||||
}
|
||||
catch { }
|
||||
|
||||
@@ -87,23 +90,26 @@ namespace FoxTube.Controls
|
||||
}*/
|
||||
}
|
||||
|
||||
public async void Button_Click(object sender, RoutedEventArgs e)
|
||||
public void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (embed)
|
||||
{
|
||||
MessageDialog dialog = new MessageDialog("Unfortunately, at this stage of application development we don't support live steams. This issue will be fixed in the next update. Sorry. Would you like us to open this stream in browser?", "Open in browser");
|
||||
|
||||
dialog.Commands.Add(new UICommand("Yes", async (command) =>
|
||||
{
|
||||
await Launcher.LaunchUriAsync(new Uri($"https://www.youtube.com/watch?v={videoId}"));
|
||||
}));
|
||||
dialog.Commands.Add(new UICommand("No"));
|
||||
dialog.DefaultCommandIndex = 0;
|
||||
dialog.CancelCommandIndex = 1;
|
||||
await dialog.ShowAsync();
|
||||
}
|
||||
else
|
||||
Methods.MainPage.GoToVideo(videoId, playlistId);
|
||||
}
|
||||
|
||||
private void ViewChannel_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Methods.MainPage.GoToChannel(item.Snippet.ChannelId);
|
||||
}
|
||||
|
||||
private void GetLink_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DataPackage data = new DataPackage();
|
||||
data.SetText($"https://www.youtube.com/watch?v={videoId}");
|
||||
Clipboard.SetContent(data);
|
||||
}
|
||||
|
||||
private async void InBrowser_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await Launcher.LaunchUriAsync($"https://www.youtube.com/watch?v={videoId}".ToUri());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,8 @@
|
||||
x:Class="FoxTube.VideoPlayer"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:FoxTube"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
|
||||
xmlns:controls1="using:FoxTube.Controls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="1080"
|
||||
@@ -16,10 +14,9 @@
|
||||
PointerEntered="UserControl_PointerEntered">
|
||||
|
||||
<Grid Background="White" Name="grid" Tapped="UserControl_Tapped">
|
||||
<MediaElement Width="0" Height="0" VerticalAlignment="Top" HorizontalAlignment="Right" Name="audioSource" MediaOpened="videoSource_Opened" BufferingProgressChanged="videoSource_BufferingProgressChanged"/>
|
||||
<MediaElement IsDoubleTapEnabled="False" CurrentStateChanged="videoSource_CurrentStateChanged" AutoPlay="False" MediaOpened="videoSource_Opened" BufferingProgressChanged="videoSource_BufferingProgressChanged" Volume="0" Name="videoSource" AreTransportControlsEnabled="False" PosterSource="ms-appx:///Assets/videoThumbSample.png"/>
|
||||
|
||||
<controls1:LiveCaptions Player="{x:Bind videoSource}" Visibility="Collapsed"/>
|
||||
<MediaPlayerElement IsDoubleTapEnabled="False" Name="videoSource" AreTransportControlsEnabled="False" PosterSource="ms-appx:///Assets/videoThumbSample.png"/>
|
||||
<MediaPlayerElement Name="audioSource" Width="0" Height="0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
|
||||
<controls1:LiveCaptions Player="{x:Bind controller}" Visibility="Collapsed"/>
|
||||
|
||||
<Grid Name="controls" Visibility="Visible">
|
||||
<Grid.RowDefinitions>
|
||||
@@ -27,21 +24,37 @@
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0" Name="header" Height="50" Background="#7F000000">
|
||||
<Grid Name="header" Height="50" Background="#7F000000">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Click="minimize_Click" Name="minimize" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Minimize"/>
|
||||
<Button Click="minimize_Click" Name="minimize" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/minimize"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
<StackPanel Grid.Column="1" Margin="10,0,10,0" VerticalAlignment="Center">
|
||||
<TextBlock Name="title" Text="[Title]" Foreground="White" VerticalAlignment="Center" TextWrapping="WrapWholeWords" FontSize="20" MaxLines="1" ToolTipService.ToolTip="Title"/>
|
||||
<TextBlock Name="title" Text="[Title]" Foreground="White" VerticalAlignment="Center" TextWrapping="WrapWholeWords" FontSize="20" MaxLines="1"/>
|
||||
<TextBlock Foreground="LightGray" Text="[Channel name]" Name="channelName" FontStyle="Italic"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="2" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Name="closeHeader" Click="close_Click" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Close video"/>
|
||||
<Button Name="cast" Click="cast_Click" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Cast to device"/>
|
||||
<Button Name="miniViewBtn" Click="miniView_Click" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Compact view mode" HorizontalAlignment="Center" Margin="0,0,0,0" VerticalAlignment="Center"/>
|
||||
<Button Name="closeHeader" Click="close_Click" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/close"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
<Button Name="cast" Click="cast_Click" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/cast"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
<Button Name="miniViewBtn" Click="miniView_Click" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" HorizontalAlignment="Center" Margin="0,0,0,0" VerticalAlignment="Center">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/miniview"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -53,27 +66,43 @@
|
||||
<Button VerticalAlignment="Center" Content="" FontFamily="Segoe MDL2 Assets" Background="Transparent" FontSize="100" Foreground="WhiteSmoke" Name="touchPlay" Click="play_Click"/>
|
||||
<Button VerticalAlignment="Center" Content="" FontFamily="Segoe MDL2 Assets" Background="Transparent" FontSize="40" Foreground="WhiteSmoke" Name="touchFwd30" Click="fwd30_Click"/>
|
||||
</StackPanel>
|
||||
<Button Visibility="Collapsed" Margin="0,32,0,0" VerticalAlignment="Top" HorizontalAlignment="Right" Name="miniViewExit" Grid.Row="1" Click="miniView_Click" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="45" Height="45" FontSize="25" ToolTipService.ToolTip="Exit compact view mode"/>
|
||||
<Button Visibility="Collapsed" VerticalAlignment="Top" HorizontalAlignment="Right" Name="close" Click="close_Click" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="45" Height="45" FontSize="25" ToolTipService.ToolTip="Close video"/>
|
||||
<Button Visibility="Collapsed" Margin="0,32,0,0" VerticalAlignment="Top" HorizontalAlignment="Right" Name="miniViewExit" Grid.Row="1" Click="miniView_Click" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="45" Height="45" FontSize="25">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/exitminiview"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
<Button Visibility="Collapsed" VerticalAlignment="Top" HorizontalAlignment="Right" Name="close" Click="close_Click" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="45" Height="45" FontSize="25">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/close"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
<Button Visibility="Collapsed"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Left"
|
||||
Name="maximize" Click="maximize_Click"
|
||||
Background="Transparent" FontFamily="Segoe MDL2 Assets" Foreground="White" FontSize="25"
|
||||
Content=""
|
||||
Width="45" Height="45"
|
||||
ToolTipService.ToolTip="Maximize"/>
|
||||
Width="45" Height="45">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/maximize"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
<ProgressBar VerticalAlignment="Bottom" Foreground="Red" Name="seekIndicator" Visibility="Collapsed"/>
|
||||
</Grid>
|
||||
|
||||
<Button Name="skipAd" Visibility="Collapsed" Margin="0,0,0,25" Grid.Row="1" HorizontalAlignment="Right" Foreground="White" VerticalAlignment="Bottom" Padding="10" BorderBrush="Black" BorderThickness="2" Background="#7E000000">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="30" Margin="0,0,10,0" Text="" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="Skip ad" FontSize="30" TextWrapping="WrapWholeWords" MaxWidth="250"/>
|
||||
<StackPanel Name="schedulePanel" Visibility="Collapsed" VerticalAlignment="Bottom" HorizontalAlignment="Right" Grid.Row="1" BorderBrush="Black" BorderThickness="2" Background="#7E000000" Padding="10" Margin="0,25" Orientation="Horizontal">
|
||||
<FontIcon Glyph="" FontSize="30" Margin="0,0,10,0" VerticalAlignment="Top"/>
|
||||
<StackPanel>
|
||||
<TextBlock FontWeight="Bold" Text="Stream hasn't started yet"/>
|
||||
<TextBlock Name="scheduleHeader" Visibility="Collapsed" Text="Stream schedule:"/>
|
||||
<TextBlock Name="scheduleStart" Visibility="Collapsed" Text="Start time: "/>
|
||||
<TextBlock Name="scheduleEnd" Visibility="Collapsed" Text="End time:"/>
|
||||
|
||||
<TextBlock Name="countdownHeader" Visibility="Collapsed" FontWeight="Bold" Text="Stream will be started in:" Margin="0,10,0,0"/>
|
||||
<TextBlock Name="countdown" Visibility="Collapsed" FontWeight="SemiBold" FontSize="20" Text="1:00:00:00"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<Grid Grid.Row="2" Height="50" Name="mainControls" Background="#7F000000">
|
||||
<ProgressBar Name="bufferingBar" VerticalAlignment="Top" Margin="0,-4,0,0" IsIndeterminate="True" Visibility="Visible"/>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
@@ -81,53 +110,102 @@
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Click="play_Click" Name="play" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Play"/>
|
||||
<Button Name="next" Click="next_Click" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Next video"/>
|
||||
<Button Name="openVolume" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Volume">
|
||||
<Button Click="play_Click" Name="play" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/play"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
<Button Name="next" Click="next_Click" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/next"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
<Button Name="openVolume" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/volume"/>
|
||||
</ToolTipService.ToolTip>
|
||||
<Button.Flyout>
|
||||
<Flyout>
|
||||
<StackPanel Orientation="Horizontal" Margin="-10">
|
||||
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Mute" Name="muteBtn" Click="muteBtn_Click"/>
|
||||
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" Name="muteBtn" Click="muteBtn_Click">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/mute"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
<Slider Orientation="Horizontal" Width="150" Margin="10,5,10,0" VerticalAlignment="Center" Name="volume" ValueChanged="volume_ValueChanged"/>
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
<Button Name="gotoLive" Visibility="Collapsed" Click="GotoLive_Click" Background="Transparent" Foreground="White" Height="50" FontSize="25">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/goLive"/>
|
||||
</ToolTipService.ToolTip>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon Glyph="" Foreground="Red"/>
|
||||
<TextBlock Text="Live" Margin="5,0,0,0" FontSize="15" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<Grid Grid.Column="1">
|
||||
<TextBlock Name="elapsedTime" Foreground="White" Text="[Elapsed]" VerticalAlignment="Bottom" HorizontalAlignment="Left" ToolTipService.ToolTip="Time elapsed"/>
|
||||
<TextBlock Name="remainingTime" Foreground="White" Text="[Remaining]" VerticalAlignment="Bottom" HorizontalAlignment="Right" ToolTipService.ToolTip="Time remaining"/>
|
||||
<Grid Grid.Column="1" Name="seekPanel">
|
||||
<TextBlock Name="elapsedTime" Foreground="White" Text="[Elapsed]" VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
|
||||
<TextBlock Name="remainingTime" Foreground="White" Text="[Remaining]" VerticalAlignment="Bottom" HorizontalAlignment="Right"/>
|
||||
<Grid VerticalAlignment="Top" Margin="0,15,0,0" Height="2">
|
||||
<ProgressBar Background="#66FFFFFF" Foreground="LightGray" Name="bufferingLevel"/>
|
||||
</Grid>
|
||||
<Slider PointerCaptureLost="seek_PointerCaptureLost" ValueChanged="seek_ValueChanged" Name="seek" VerticalAlignment="Top" ToolTipService.ToolTip="Seek" IsThumbToolTipEnabled="False" Background="Transparent" HorizontalAlignment="Stretch"/>
|
||||
<Slider PointerCaptureLost="seek_PointerCaptureLost" ManipulationStarted="Seek_PointerCaptured" ManipulationMode="TranslateRailsX" ValueChanged="seek_ValueChanged" Name="seek" VerticalAlignment="Top" IsThumbToolTipEnabled="False" Background="Transparent" HorizontalAlignment="Stretch"/>
|
||||
</Grid>
|
||||
|
||||
<StackPanel Grid.Column="2" Orientation="Horizontal">
|
||||
<Button Click="back10_Click" Name="back10" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Skip back for 10 seconds"/>
|
||||
<Button Click="fwd30_Click" Name="fwd30" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Skip forward for 30 seconds"/>
|
||||
<TextBlock Text="1:12:32" Name="liveElapsed" Visibility="Collapsed" Margin="10,0" FontSize="20" VerticalAlignment="Center">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/streamElapsed"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</TextBlock>
|
||||
<StackPanel Orientation="Horizontal" Name="rewindPanel">
|
||||
<Button Click="back10_Click" Name="back10" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/back"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
<Button Click="fwd30_Click" Name="fwd30" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/fwd"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<Line Stroke="White" StrokeThickness="2" Y1="5" Y2="45"/>
|
||||
|
||||
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Subtitles" Name="captionsBtn">
|
||||
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" Name="captionsBtn">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/subs"/>
|
||||
</ToolTipService.ToolTip>
|
||||
<Button.Flyout>
|
||||
<Flyout>
|
||||
<StackPanel Width="225">
|
||||
<ToggleSwitch Name="subsSwitch" Toggled="subsSwitch_Toggled" OnContent="Subtitles" OffContent="Subtitles"/>
|
||||
<ComboBox Name="subsLang" Header="Language" PlaceholderText="No subtitles are available" Visibility="Collapsed" HorizontalAlignment="Stretch" SelectionChanged="subsLang_SelectionChanged"/>
|
||||
<ToggleSwitch x:Uid="/VideoPage/subsSwitch" Name="subsSwitch" Toggled="subsSwitch_Toggled" OnContent="Subtitles" OffContent="Subtitles"/>
|
||||
<ComboBox x:Uid="/VideoPage/subsSelector" Name="subsLang" Header="Language" PlaceholderText="No subtitles are available" Visibility="Collapsed" HorizontalAlignment="Stretch" SelectionChanged="subsLang_SelectionChanged"/>
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Video quality">
|
||||
<Button Name="qualityBtn" Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/quality"/>
|
||||
</ToolTipService.ToolTip>
|
||||
<Button.Flyout>
|
||||
<Flyout>
|
||||
<ComboBox Width="225" Header="Quality" Name="quality" SelectionChanged="quality_SelectionChanged"/>
|
||||
<ComboBox x:Uid="/VideoPage/qualitySelector" Width="225" Header="Quality" Name="quality" SelectionChanged="quality_SelectionChanged"/>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" ToolTipService.ToolTip="Full screen" Name="fullscreen" Click="fullscreen_Click"/>
|
||||
<Button Background="Transparent" FontFamily="Segoe MDL2 Assets" Content="" Foreground="White" Width="50" Height="50" FontSize="25" Name="fullscreen" Click="fullscreen_Click">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="/VideoPage/fullscreen"/>
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
@@ -168,13 +246,5 @@
|
||||
<Button Name="signin" Click="signin_Click" Content="Sign in now" Foreground="White" Background="Gray" HorizontalAlignment="Right" Grid.Column="1" Margin="0,0,10,0"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid Background="#E5000000" Visibility="Collapsed">
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Name="errorPlate">
|
||||
<TextBlock Text="Something went wrong..." HorizontalAlignment="Center" FontSize="20"/>
|
||||
<TextBlock Text="Video ID: " HorizontalAlignment="Center" IsTextSelectionEnabled="True" FontSize="20"/>
|
||||
<TextBlock Text="Error type: " HorizontalAlignment="Center" IsTextSelectionEnabled="True" FontSize="20"/>
|
||||
<TextBlock Text="Message: " HorizontalAlignment="Center" IsTextSelectionEnabled="True" FontSize="20"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WindowsXamlEnableOverview>true</WindowsXamlEnableOverview>
|
||||
<PackageCertificateKeyFile>FoxTube_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
<PackageCertificateThumbprint>E33236F6F6066A373DFA92A7B7C1467B1EF0BA81</PackageCertificateThumbprint>
|
||||
<PackageCertificateKeyFile>
|
||||
</PackageCertificateKeyFile>
|
||||
<PackageCertificateThumbprint>E888C12EC9A02B902D03CDA4515BDBE9F5E71F1F</PackageCertificateThumbprint>
|
||||
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
|
||||
<AppxAutoIncrementPackageRevision>False</AppxAutoIncrementPackageRevision>
|
||||
<AppxPackageDir>C:\Users\Michael Gordeev\Downloads\FoxTube dists\0.2.1812-2\</AppxPackageDir>
|
||||
<AppxPackageDir>C:\Users\Michael Gordeev\Downloads\FoxTube dists\0.2.1901-1\</AppxPackageDir>
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
<AppxBundlePlatforms>x86|x64|arm</AppxBundlePlatforms>
|
||||
<AppInstallerUpdateFrequency>1</AppInstallerUpdateFrequency>
|
||||
@@ -103,7 +104,6 @@
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Classes\Caption.cs" />
|
||||
<Compile Include="Classes\DownloadItemContainer.cs" />
|
||||
<Compile Include="Classes\InboxItem.cs" />
|
||||
<Compile Include="Classes\Methods.cs" />
|
||||
@@ -112,9 +112,15 @@
|
||||
<Compile Include="Controls\Advert.xaml.cs">
|
||||
<DependentUpon>Advert.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\Adverts\CardAdvert.xaml.cs">
|
||||
<DependentUpon>CardAdvert.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\ChannelCard.xaml.cs">
|
||||
<DependentUpon>ChannelCard.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\Chat.xaml.cs">
|
||||
<DependentUpon>Chat.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\CommentCard.xaml.cs">
|
||||
<DependentUpon>CommentCard.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@@ -280,10 +286,18 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Controls\Adverts\CardAdvert.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Controls\ChannelCard.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Controls\Chat.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Controls\CommentCard.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
@@ -403,7 +417,7 @@
|
||||
<Version>6.1.9</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications">
|
||||
<Version>4.0.0</Version>
|
||||
<Version>5.0.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls">
|
||||
<Version>4.0.0</Version>
|
||||
@@ -412,7 +426,7 @@
|
||||
<Version>4.3.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="YoutubeExplode">
|
||||
<Version>4.5.1</Version>
|
||||
<Version>4.6.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="YoutubeExtractor">
|
||||
<Version>0.10.11</Version>
|
||||
@@ -420,6 +434,25 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="FoxTube_TemporaryKey.pfx" />
|
||||
<PRIResource Include="Strings\ru-RU\VideoPage.resw" />
|
||||
<PRIResource Include="Strings\en-US\VideoPage.resw" />
|
||||
<PRIResource Include="Strings\ru-RU\Channel.resw" />
|
||||
<PRIResource Include="Strings\en-US\Channel.resw" />
|
||||
<PRIResource Include="Strings\ru-RU\Chat.resw" />
|
||||
<PRIResource Include="Strings\en-US\Chat.resw" />
|
||||
<PRIResource Include="Strings\ru-RU\Cards.resw" />
|
||||
<PRIResource Include="Strings\en-US\Cards.resw" />
|
||||
<PRIResource Include="Strings\ru-RU\Methods.resw" />
|
||||
<PRIResource Include="Strings\en-US\Methods.resw" />
|
||||
<PRIResource Include="Strings\ru-RU\Search.resw" />
|
||||
<PRIResource Include="Strings\en-US\Search.resw" />
|
||||
<PRIResource Include="Strings\ru-RU\Playlist.resw" />
|
||||
<PRIResource Include="Strings\en-US\Playlist.resw" />
|
||||
<PRIResource Include="Strings\ru-RU\Downloads.resw" />
|
||||
<PRIResource Include="Strings\ru-RU\CommentsPage.resw" />
|
||||
<PRIResource Include="Strings\en-US\Downloads.resw" />
|
||||
<PRIResource Include="Strings\ru-RU\Home.resw" />
|
||||
<PRIResource Include="Strings\en-US\Home.resw" />
|
||||
<PRIResource Include="Strings\en-US\CommentsPage.resw" />
|
||||
<PRIResource Include="Strings\ru-RU\LoadingPage.resw" />
|
||||
<PRIResource Include="Strings\en-US\LoadingPage.resw" />
|
||||
@@ -427,7 +460,6 @@
|
||||
<PRIResource Include="Strings\ru-RU\General.resw" />
|
||||
<PRIResource Include="Strings\ru-RU\About.resw" />
|
||||
<PRIResource Include="Strings\ru-RU\Settings.resw" />
|
||||
<PRIResource Include="Strings\en-US\Translate.resw" />
|
||||
<PRIResource Include="Strings\en-US\Inbox.resw" />
|
||||
<PRIResource Include="Strings\en-US\About.resw" />
|
||||
<PRIResource Include="Strings\en-US\General.resw" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?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">
|
||||
<Identity Name="foxtube-5d1cba1f-d7d5-472b-acb7-beb360bab268" Publisher="CN=Michael Gordeev" Version="0.2.18122.0" />
|
||||
<Identity Name="foxtube-5d1cba1f-d7d5-472b-acb7-beb360bab268" Publisher="CN=Michael Gordeev" Version="0.2.19012.0" />
|
||||
<mp:PhoneIdentity PhoneProductId="5d1cba1f-d7d5-472b-acb7-beb360bab268" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||
<Properties>
|
||||
<DisplayName>FoxTube</DisplayName>
|
||||
@@ -15,7 +15,7 @@
|
||||
</Resources>
|
||||
<Applications>
|
||||
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="FoxTube.App" ResourceGroup="foxtube">
|
||||
<uap:VisualElements DisplayName="FoxTube" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="YouTube Client" BackgroundColor="red">
|
||||
<uap:VisualElements DisplayName="FoxTube" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="YouTube Client" BackgroundColor="skyBlue">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" ShortName="FoxTube" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png">
|
||||
<uap:ShowNameOnTiles>
|
||||
<uap:ShowOn Tile="square150x150Logo" />
|
||||
@@ -23,7 +23,7 @@
|
||||
<uap:ShowOn Tile="square310x310Logo" />
|
||||
</uap:ShowNameOnTiles>
|
||||
</uap:DefaultTile>
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" BackgroundColor="red" />
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" BackgroundColor="#282828" />
|
||||
</uap:VisualElements>
|
||||
<Extensions>
|
||||
<Extension Category="windows.backgroundTasks" EntryPoint="FoxTube.Background.BackgroundProcessor">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Pivot SelectedIndex="0" Name="content" IsHeaderItemsCarouselEnabled="False" SelectionChanged="content_SelectionChanged">
|
||||
<PivotItem Header="Videos">
|
||||
<PivotItem x:Uid="/Channel/videos" Header="Videos">
|
||||
<ScrollViewer>
|
||||
<StackPanel Name="videos">
|
||||
<Image Name="channelCover" Stretch="Uniform" Source="/Assets/ChannelCoverTemplate.png"/>
|
||||
@@ -35,11 +35,11 @@
|
||||
<TextBlock Name="videosCount" Foreground="Gray" Text="563,000 videos"/>
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="2" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Height="50" Margin="10" TextAlignment="Center" Padding="0,16,0,0" Foreground="Gray">
|
||||
<Hyperlink Click="Hyperlink_Click">Log in</Hyperlink> to manage your subscriptions
|
||||
<Hyperlink Click="Hyperlink_Click"><Run x:Uid="/Cards/login">Log in</Run></Hyperlink> <Run x:Uid="/Cards/tomanage">to manage your subscriptions</Run>
|
||||
</TextBlock>
|
||||
|
||||
<Grid Visibility="Collapsed" Grid.Column="2" VerticalAlignment="Bottom" Margin="10" Name="subscriptionPane" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<Button Click="subscribe_Click" Name="subscribe" Width="250" Height="50" Background="Red" Foreground="White" FontSize="18" FontWeight="SemiBold" Content="Subscirbe"/>
|
||||
<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>
|
||||
<pages:VideoGrid/>
|
||||
@@ -47,11 +47,11 @@
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</PivotItem>
|
||||
<PivotItem Header="Playlists">
|
||||
<PivotItem x:Uid="/Channel/playlists" Header="Playlists">
|
||||
<ScrollViewer>
|
||||
<Grid Name="playlists">
|
||||
<StackPanel Margin="10" Visibility="Visible">
|
||||
<TextBlock FontSize="28" Text="Playlists"/>
|
||||
<TextBlock x:Uid="/Channel/playlistTitle" FontSize="28" Text="Playlists"/>
|
||||
<pages:VideoGrid/>
|
||||
<controls:ShowMore Clicked="showMorePlaylists_Click"/>
|
||||
</StackPanel>
|
||||
@@ -59,10 +59,10 @@
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</PivotItem>
|
||||
<PivotItem Header="About channel">
|
||||
<PivotItem x:Uid="/Channel/about" Header="About channel">
|
||||
<ScrollViewer>
|
||||
<StackPanel Margin="10">
|
||||
<TextBlock FontSize="28" Text="About this channel"/>
|
||||
<TextBlock x:Uid="/Channel/aboutTitle" FontSize="28" Text="About this channel"/>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
@@ -70,7 +70,7 @@
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock FontSize="24" Text="Description"/>
|
||||
<TextBlock x:Uid="/Channel/desc" FontSize="24" Text="Description"/>
|
||||
<TextBlock Name="description" Margin="0,10,0,0" TextWrapping="WrapWholeWords" IsTextSelectionEnabled="True"/>
|
||||
</StackPanel>
|
||||
|
||||
@@ -85,12 +85,12 @@
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock FontSize="24" Text="Statistics"/>
|
||||
<TextBlock x:Uid="/Channel/stats" FontSize="24" Text="Statistics"/>
|
||||
|
||||
<TextBlock Text="Registration date:" Grid.Row="1"/>
|
||||
<TextBlock x:Uid="/Channel/regDate" Text="Registration date:" Grid.Row="1"/>
|
||||
<TextBlock Grid.Row="1" Grid.Column="2" Name="registration" Text="13-May-18" HorizontalAlignment="Right"/>
|
||||
|
||||
<TextBlock Grid.Row="2" Text="Views"/>
|
||||
<TextBlock x:Uid="/Channel/views" Grid.Row="2" Text="Views"/>
|
||||
<TextBlock Grid.Row="2" Grid.Column="2" Name="views" Text="1885510485" HorizontalAlignment="Right"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
@@ -99,14 +99,14 @@
|
||||
</PivotItem>
|
||||
|
||||
<Pivot.RightHeader>
|
||||
<AutoSuggestBox 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" Margin="8" PlaceholderText="Search on channel" QueryIcon="Find" Name="search" QuerySubmitted="AutoSuggestBox_QuerySubmitted"/>
|
||||
</Pivot.RightHeader>
|
||||
</Pivot>
|
||||
|
||||
<CommandBar Grid.Row="1" VerticalAlignment="Bottom" Name="commandBar">
|
||||
<AppBarButton Icon="Globe" Label="Open in browser" Name="inBrowser" Click="inBrowser_Click"/>
|
||||
<AppBarButton Icon="Refresh" Label="Refresh" Name="refresh" Click="refresh_Click"/>
|
||||
<AppBarButton Icon="Share" Label="Share" Name="share" Click="share_Click"/>
|
||||
<AppBarButton x:Uid="/Channel/openWeb" Icon="Globe" Label="Open in browser" Name="inBrowser" Click="inBrowser_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"/>
|
||||
</CommandBar>
|
||||
|
||||
<local:LoadingPage Grid.RowSpan="2" Visibility="Collapsed"/>
|
||||
|
||||
@@ -12,6 +12,7 @@ using FoxTube.Controls;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using Windows.System;
|
||||
using Windows.UI;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
|
||||
namespace FoxTube.Pages
|
||||
{
|
||||
@@ -20,6 +21,8 @@ namespace FoxTube.Pages
|
||||
/// </summary>
|
||||
public sealed partial class ChannelPage : Page
|
||||
{
|
||||
ResourceLoader resources = ResourceLoader.GetForCurrentView("Cards");
|
||||
|
||||
public string channelId;
|
||||
public Channel item;
|
||||
|
||||
@@ -78,8 +81,8 @@ namespace FoxTube.Pages
|
||||
item = (await request.ExecuteAsync()).Items[0];
|
||||
|
||||
title.Text = item.Snippet.Title;
|
||||
subscribers.Text = $"{item.Statistics.SubscriberCount:0,0} subscribers";
|
||||
videosCount.Text = $"{item.Statistics.VideoCount:0,0} videos";
|
||||
subscribers.Text = $"{item.Statistics.SubscriberCount:0,0} {resources.GetString("/Cards/subscribers")}";
|
||||
videosCount.Text = $"{item.Statistics.VideoCount:0,0} {resources.GetString("/Cards/videos")}";
|
||||
|
||||
try
|
||||
{
|
||||
@@ -121,7 +124,7 @@ namespace FoxTube.Pages
|
||||
{
|
||||
subscribe.Background = new SolidColorBrush(Colors.Transparent);
|
||||
subscribe.Foreground = new SolidColorBrush(Colors.Gray);
|
||||
subscribe.Content = "Subscribed";
|
||||
subscribe.Content = resources.GetString("/Cards/unsubscribe");
|
||||
}
|
||||
subscriptionPane.Visibility = Visibility.Visible;
|
||||
}
|
||||
@@ -228,13 +231,13 @@ namespace FoxTube.Pages
|
||||
{
|
||||
subscribe.Background = new SolidColorBrush(Colors.Transparent);
|
||||
subscribe.Foreground = new SolidColorBrush(Colors.Gray);
|
||||
subscribe.Content = "Subscribed";
|
||||
subscribe.Content = resources.GetString("/Cards/unsubscribe");
|
||||
}
|
||||
else
|
||||
{
|
||||
subscribe.Background = new SolidColorBrush(Colors.Red);
|
||||
subscribe.Foreground = new SolidColorBrush(Colors.White);
|
||||
subscribe.Content = "Subscribe";
|
||||
subscribe.Content = resources.GetString("/Cards/subscribe/Content");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,7 +289,7 @@ namespace FoxTube.Pages
|
||||
item.Snippet.Thumbnails.Medium.Url,
|
||||
item.Snippet.Title,
|
||||
string.IsNullOrWhiteSpace(item.Snippet.CustomUrl) ? $"https://www.youtube.com/channel/{item.Id}" : $"https://www.youtube.com/user/{item.Snippet.CustomUrl}",
|
||||
"channel");
|
||||
resources.GetString("/Cards/channelShare"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<TextBlock Name="counter" Grid.Row="1" Text="[Comments count] Comments" Margin="5,0,0,0" VerticalAlignment="Center" FontWeight="SemiBold"/>
|
||||
<StackPanel Padding="0" Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,0,10,0">
|
||||
<TextBlock x:Uid="/CommentsPage/sortBy" Text="Sort by: " VerticalAlignment="Center" Margin="0,0,5,0"/>
|
||||
<Button Name="orderBtn" Background="Transparent" Content="Relevance" Foreground="Red" Padding="0" VerticalAlignment="Center">
|
||||
<Button Name="orderBtn" Background="Transparent" Content="Relevance" Foreground="Red" Padding="0" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,3">
|
||||
|
||||
<Button.Flyout>
|
||||
<MenuFlyout>
|
||||
@@ -44,7 +44,7 @@
|
||||
<ScrollViewer Grid.Row="1" Name="scroll">
|
||||
<StackPanel>
|
||||
<StackPanel Name="placeholder"/>
|
||||
<HyperlinkButton Visibility="Collapsed" Name="more" Click="more_Click" HorizontalAlignment="Center" Foreground="Red" Content="Show more"/>
|
||||
<HyperlinkButton x:Uid="/CommentsPage/more" Visibility="Collapsed" Name="more" Click="more_Click" HorizontalAlignment="Center" Foreground="Red" Content="Show more"/>
|
||||
<ProgressBar Name="moreLoading" Visibility="Collapsed" IsIndeterminate="True" Foreground="Red"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
using System;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
using Google.Apis.YouTube.v3;
|
||||
using Google.Apis.YouTube.v3.Data;
|
||||
using FoxTube.Controls;
|
||||
using Windows.UI.Popups;
|
||||
|
||||
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
|
||||
using Windows.ApplicationModel.Resources;
|
||||
|
||||
namespace FoxTube.Pages
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// Comments placeholder
|
||||
/// </summary>
|
||||
public sealed partial class CommentsPage : Page
|
||||
{
|
||||
ResourceLoader resources = ResourceLoader.GetForCurrentView("CommentsPage");
|
||||
|
||||
string threadId;
|
||||
string nextPageToken;
|
||||
|
||||
@@ -29,13 +29,15 @@ namespace FoxTube.Pages
|
||||
public async void Initialize(Video video)
|
||||
{
|
||||
threadId = video.Id;
|
||||
Methods.CommentsPage = this;
|
||||
|
||||
if (!SecretsVault.IsAuthorized)
|
||||
grid.RowDefinitions[0].Height = new GridLength(0);
|
||||
else
|
||||
grid.RowDefinitions[0].Height = GridLength.Auto;
|
||||
|
||||
counter.Text = string.Format("{0:0,0} Comments", video.Statistics.CommentCount);
|
||||
counter.Text = $"{video.Statistics.CommentCount:0,0} {resources.GetString("/CommentsPage/comments")}";
|
||||
orderBtn.Content = resources.GetString("/CommentsPage/relevance/Text");
|
||||
|
||||
var request = SecretsVault.Service.CommentThreads.List("snippet,replies");
|
||||
request.Order = order;
|
||||
@@ -53,6 +55,11 @@ namespace FoxTube.Pages
|
||||
placeholder.Children.Add(new CommentCard(comment));
|
||||
}
|
||||
|
||||
public void RemoveComment(CommentCard commentCard)
|
||||
{
|
||||
placeholder.Children.Remove(commentCard);
|
||||
}
|
||||
|
||||
private async void more_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
more.Visibility = Visibility.Collapsed;
|
||||
@@ -84,7 +91,7 @@ namespace FoxTube.Pages
|
||||
moreLoading.Visibility = Visibility.Visible;
|
||||
|
||||
order = CommentThreadsResource.ListRequest.OrderEnum.Relevance;
|
||||
orderBtn.Content = "Relevance";
|
||||
orderBtn.Content = resources.GetString("/CommentsPage/relevance/Text");
|
||||
|
||||
placeholder.Children.Clear();
|
||||
|
||||
@@ -111,7 +118,7 @@ namespace FoxTube.Pages
|
||||
moreLoading.Visibility = Visibility.Visible;
|
||||
|
||||
order = CommentThreadsResource.ListRequest.OrderEnum.Time;
|
||||
orderBtn.Content = "Publish date";
|
||||
orderBtn.Content = resources.GetString("/CommentsPage/publish");
|
||||
|
||||
placeholder.Children.Clear();
|
||||
|
||||
|
||||
@@ -21,17 +21,17 @@
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Name="path" IsTextSelectionEnabled="True" TextWrapping="WrapWholeWords"/>
|
||||
<Button Grid.Column="1" 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>
|
||||
|
||||
<ScrollViewer Grid.Row="1">
|
||||
<StackPanel Name="stack"/>
|
||||
</ScrollViewer>
|
||||
|
||||
<TextBlock 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"/>
|
||||
|
||||
<CommandBar DefaultLabelPosition="Right" Grid.Row="2">
|
||||
<AppBarButton Label="Refresh" Icon="Refresh" Click="Refresh"/>
|
||||
<AppBarButton x:Uid="/Downloads/refresh" Label="Refresh" Icon="Refresh" Click="Refresh"/>
|
||||
</CommandBar>
|
||||
</Grid>
|
||||
</Page>
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Pivot Name="pivot" SelectionChanged="pivot_SelectionChanged">
|
||||
<PivotItem Header="Recommended" Name="recommended">
|
||||
<PivotItem x:Uid="/Home/recommended" Header="Recommended" Name="recommended">
|
||||
<ScrollViewer>
|
||||
<StackPanel/>
|
||||
</ScrollViewer>
|
||||
</PivotItem>
|
||||
<PivotItem Header="Trending" Name="trending">
|
||||
<PivotItem x:Uid="/Home/trending" Header="Trending" Name="trending">
|
||||
<ScrollViewer>
|
||||
<StackPanel>
|
||||
<pages:VideoGrid/>
|
||||
@@ -29,7 +29,7 @@
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</PivotItem>
|
||||
<PivotItem Header="Subscriptions" Name="subscriptions">
|
||||
<PivotItem x:Uid="/Home/subs" Header="Subscriptions" Name="subscriptions">
|
||||
<ScrollViewer>
|
||||
<StackPanel/>
|
||||
</ScrollViewer>
|
||||
@@ -37,7 +37,7 @@
|
||||
</Pivot>
|
||||
|
||||
<CommandBar Grid.Row="1">
|
||||
<AppBarButton Icon="Refresh" Label="Refresh page" Name="refresh" Click="refreshPage"/>
|
||||
<AppBarButton x:Uid="/Home/refresh" Icon="Refresh" Label="Refresh page" Name="refresh" Click="refreshPage"/>
|
||||
</CommandBar>
|
||||
<local:LoadingPage Grid.RowSpan="2" Margin="0,50,0,0" Visibility="Visible" RefreshPage="refreshPage"/>
|
||||
</Grid>
|
||||
|
||||
@@ -25,12 +25,10 @@ namespace FoxTube
|
||||
|
||||
string trendToken;
|
||||
Dictionary<string, string> subsTokens = new Dictionary<string, string>();
|
||||
string reg;
|
||||
|
||||
public Home()
|
||||
{
|
||||
InitializeComponent();
|
||||
reg = CultureInfo.GetCultures(CultureTypes.AllCultures).Find(i => i.IetfLanguageTag == SettingsStorage.Region).IetfLanguageTag.Remove(0, 3);
|
||||
|
||||
trendGrid = ((trending.Content as ScrollViewer).Content as StackPanel).Children[0] as VideoGrid;
|
||||
trendMore = ((trending.Content as ScrollViewer).Content as StackPanel).Children[1] as ShowMore;
|
||||
@@ -54,7 +52,7 @@ namespace FoxTube
|
||||
request.PageToken = trendToken;
|
||||
|
||||
request.Chart = VideosResource.ListRequest.ChartEnum.MostPopular;
|
||||
request.RegionCode = reg;
|
||||
request.RegionCode = SettingsStorage.Region;
|
||||
VideoListResponse response = await request.ExecuteAsync();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(response.NextPageToken))
|
||||
@@ -108,7 +106,7 @@ namespace FoxTube
|
||||
request.MaxResults = 48;
|
||||
|
||||
request.Chart = VideosResource.ListRequest.ChartEnum.MostPopular;
|
||||
request.RegionCode = reg;
|
||||
request.RegionCode = SettingsStorage.Region;
|
||||
VideoListResponse response = await request.ExecuteAsync();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(response.NextPageToken))
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
x:Class="FoxTube.LoadingPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:FoxTube"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
@@ -12,28 +11,28 @@
|
||||
|
||||
<StackPanel Name="wifiTrouble" Visibility="Collapsed" VerticalAlignment="Center">
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="" FontSize="100" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="Check your internet connection" FontSize="48" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="Please, make sure you are connected to the internet and try again." HorizontalAlignment="Center"/>
|
||||
<TextBlock x:Uid="/LoadingPage/checkConnection" Text="Check your internet connection" TextWrapping="WrapWholeWords" FontSize="48" HorizontalAlignment="Center" HorizontalTextAlignment="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"/>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<Button Content="Open network settings" Margin="5" Name="openWifi" Click="openWifi_Click"/>
|
||||
<Button Content="Open troubleshooter" Background="Red" Foreground="White" Margin="5" Name="openTroubleshoot" Click="openTroubleshoot_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"/>
|
||||
</StackPanel>
|
||||
<TextBlock Text="OR" FontSize="20" HorizontalAlignment="Center"/>
|
||||
<Button Name="wifiRefresh" Click="wifiRefresh_Click" Content="Refresh page" HorizontalAlignment="Center" Background="Red" Foreground="White" Margin="5"/>
|
||||
<TextBlock x:Uid="/LoadingPage/or" Text="OR" FontSize="20" HorizontalAlignment="Center"/>
|
||||
<Button x:Uid="/LoadingPage/refresh" Name="wifiRefresh" Click="wifiRefresh_Click" Content="Refresh page" HorizontalAlignment="Center" Background="Red" Foreground="White" Margin="5"/>
|
||||
<TextBlock Name="wifiException" Foreground="Gray" Text="Exception:" HorizontalAlignment="Center" IsTextSelectionEnabled="True"/>
|
||||
<TextBlock Name="wifiMessage" Foreground="Gray" Text="Message:" HorizontalAlignment="Center" IsTextSelectionEnabled="True"/>
|
||||
<TextBlock Name="wifiMessage" Foreground="Gray" Text="Message:" HorizontalAlignment="Center" IsTextSelectionEnabled="True" TextWrapping="WrapWholeWords"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Name="trouble" Visibility="Collapsed" VerticalAlignment="Center">
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="" FontSize="100" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="We are unable to display the page" FontSize="48" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="It could be caused by YouTube internal server error or by application's bug. Please, try again later" 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/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"/>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<Button Name="refresh" Click="wifiRefresh_Click" Content="Refresh page" Margin="5"/>
|
||||
<Button Content="Leave feedback" Background="Red" Foreground="White" Margin="5" Name="feedback" Click="feedback_Click"/>
|
||||
<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"/>
|
||||
</StackPanel>
|
||||
<TextBlock Name="exception" Foreground="Gray" Text="Exception:" HorizontalAlignment="Center" IsTextSelectionEnabled="True"/>
|
||||
<TextBlock Name="message" Foreground="Gray" Text="Message:" HorizontalAlignment="Center" IsTextSelectionEnabled="True"/>
|
||||
<TextBlock Name="message" Foreground="Gray" Text="Message:" HorizontalAlignment="Center" IsTextSelectionEnabled="True" TextWrapping="WrapWholeWords"/>
|
||||
</StackPanel>
|
||||
|
||||
<FontIcon Name="blockIcon" Visibility="Collapsed" Glyph="" FontSize="100" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="Gray"/>
|
||||
|
||||
@@ -1,35 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
|
||||
|
||||
namespace FoxTube
|
||||
{
|
||||
public enum LoadingState { Loadnig, Loaded, Error, Blocked }
|
||||
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// Loading sreen. Represents loading ring or error
|
||||
/// </summary>
|
||||
public sealed partial class LoadingPage : Page
|
||||
{
|
||||
ResourceLoader resources = ResourceLoader.GetForCurrentView("LoadingPage");
|
||||
|
||||
public event RoutedEventHandler RefreshPage;
|
||||
public LoadingState State { get; private set; } = LoadingState.Loadnig;
|
||||
|
||||
public LoadingPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void Error(string exceptionId = "Unknown", string details = "N/A", bool isWifiTrouble = false)
|
||||
@@ -41,15 +31,15 @@ namespace FoxTube
|
||||
|
||||
if (isWifiTrouble)
|
||||
{
|
||||
wifiException.Text = $"ID: {exceptionId}";
|
||||
wifiMessage.Text = $"Details: {details}";
|
||||
wifiException.Text = $"{resources.GetString("/LoadingPage/ex")}: {exceptionId}";
|
||||
wifiMessage.Text = $"{resources.GetString("/LoadingPage/details")}: {details}";
|
||||
|
||||
wifiTrouble.Visibility = Visibility.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
exception.Text = $"ID: {exceptionId}";
|
||||
message.Text = $"Details: {details}";
|
||||
exception.Text = $"{resources.GetString("/LoadingPage/ex")}: {exceptionId}";
|
||||
message.Text = $"{resources.GetString("/LoadingPage/details")}: {details}";
|
||||
|
||||
trouble.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
</NavigationViewItem.Icon>
|
||||
</NavigationViewItem>
|
||||
|
||||
<NavigationViewItem x:Uid="/Main/adsFree" Content="Remove ads" Visibility="Collapsed" Name="removeAds">
|
||||
<NavigationViewItem x:Uid="/Main/adsFree" Content="Remove ads" Visibility="Collapsed" Tapped="RemoveAds_Tapped" Name="removeAds">
|
||||
<NavigationViewItem.Icon>
|
||||
<FontIcon Glyph=""/>
|
||||
</NavigationViewItem.Icon>
|
||||
|
||||
@@ -21,8 +21,9 @@ using System.Net;
|
||||
using Windows.UI.Popups;
|
||||
using Windows.Networking.Connectivity;
|
||||
using Windows.UI.Core;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using Windows.Storage;
|
||||
using System.IO;
|
||||
|
||||
namespace FoxTube
|
||||
{
|
||||
@@ -34,18 +35,39 @@ namespace FoxTube
|
||||
public sealed partial class MainPage : Page
|
||||
{
|
||||
Sender s = Sender.None;
|
||||
ResourceLoader resources = ResourceLoader.GetForCurrentView("Main");
|
||||
public MainPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
//Comparing current version with last recorded version. If doesn't match, poping up changelog notification
|
||||
CheckVersion();
|
||||
|
||||
SecretsVault.AuthorizationStateChanged += AuthorizationStateChanged;
|
||||
SecretsVault.SubscriptionsChanged += SecretsVault_SubscriptionsChanged;
|
||||
SecretsVault.Purchased += (sender, e) =>
|
||||
{
|
||||
removeAds.Visibility = (e[0] as bool?).Value ? Visibility.Collapsed : Visibility.Visible;
|
||||
content.Navigate(typeof(Home));
|
||||
};
|
||||
SecretsVault.CheckAuthorization();
|
||||
SecretsVault.CheckAddons();
|
||||
|
||||
SetTitleBar();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Comparing current version with last recorded version. If doesn't match, poping up changelog notification
|
||||
/// </summary>
|
||||
public async void CheckVersion()
|
||||
{
|
||||
PackageVersion ver = Package.Current.Id.Version;
|
||||
if (SettingsStorage.Version != $"{ver.Major}.{ver.Minor}")
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlDocument changelog = new XmlDocument();
|
||||
changelog.Load("http://foxgame-studio.000webhostapp.com/foxtube-changelog.xml");
|
||||
StorageFile file = await (await Package.Current.InstalledLocation.GetFolderAsync(@"Assets\Data")).GetFileAsync("Patchnotes.xml");
|
||||
changelog.Load(await file.OpenStreamForReadAsync());
|
||||
XmlElement e = changelog["items"].ChildNodes[0] as XmlElement;
|
||||
|
||||
ToastNotificationManager.CreateToastNotifier().Show(FoxTube.Background.Notification.GetChangelogToast(e.GetAttribute("version")));
|
||||
@@ -57,14 +79,6 @@ namespace FoxTube
|
||||
Debug.WriteLine("Unable to retrieve changelog");
|
||||
}
|
||||
}
|
||||
|
||||
SecretsVault.AuthorizationStateChanged += AuthorizationStateChanged;
|
||||
SecretsVault.SubscriptionsChanged += SecretsVault_SubscriptionsChanged;
|
||||
SecretsVault.NotPurchased += () => removeAds.Visibility = Visibility.Visible;
|
||||
SecretsVault.CheckAuthorization();
|
||||
SecretsVault.CheckAddons();
|
||||
|
||||
SetTitleBar();
|
||||
}
|
||||
|
||||
public Video GetCurrentItem()
|
||||
@@ -73,6 +87,12 @@ namespace FoxTube
|
||||
catch { return null; }
|
||||
}
|
||||
|
||||
public string GetPlaylist()
|
||||
{
|
||||
try { return (videoPlaceholder.Content as VideoPage).playlistId; }
|
||||
catch { return null; }
|
||||
}
|
||||
|
||||
public void SetTitleBar()
|
||||
{
|
||||
var titleBar = ApplicationView.GetForCurrentView().TitleBar;
|
||||
@@ -200,6 +220,9 @@ namespace FoxTube
|
||||
}
|
||||
else if (e[0] as bool? == false)
|
||||
{
|
||||
for (int k = nav.MenuItems.Count - 1; k > 8; k--)
|
||||
nav.MenuItems.RemoveAt(k);
|
||||
|
||||
account.Visibility = Visibility.Visible;
|
||||
avatar.Visibility = Visibility.Collapsed;
|
||||
|
||||
@@ -212,18 +235,16 @@ namespace FoxTube
|
||||
subsHeader.Visibility = Visibility.Collapsed;
|
||||
|
||||
subsHeader.Visibility = Visibility.Collapsed;
|
||||
for(int k = 9; k < nav.MenuItems.Count; k++)
|
||||
nav.MenuItems.RemoveAt(k);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageDialog dialog = new MessageDialog("We were unabled to retrieve your account information due to weak internet connection or Google servers' problems. PLease, try again later", "Failed to connect");
|
||||
MessageDialog dialog = new MessageDialog(resources.GetString("/Main/connectErrContent"), resources.GetString("/Main/connectErrHeader"));
|
||||
|
||||
dialog.Commands.Add(new UICommand("Try again", (command) =>
|
||||
dialog.Commands.Add(new UICommand(resources.GetString("/Main/tryAgain"), (command) =>
|
||||
{
|
||||
SecretsVault.Authorize();
|
||||
}));
|
||||
dialog.Commands.Add(new UICommand("Quit", (command) =>
|
||||
dialog.Commands.Add(new UICommand(resources.GetString("/Main/quit"), (command) =>
|
||||
{
|
||||
Methods.CloseApp();
|
||||
}));
|
||||
@@ -292,15 +313,15 @@ namespace FoxTube
|
||||
var connection = NetworkInformation.GetInternetConnectionProfile().GetConnectionCost();
|
||||
if (SettingsStorage.CheckConnection && (connection.NetworkCostType == NetworkCostType.Fixed || connection.NetworkCostType == NetworkCostType.Variable))
|
||||
{
|
||||
MessageDialog dialog = new MessageDialog("You are on metered connection now. Additional charges may apply. Do you want to continue?")
|
||||
MessageDialog dialog = new MessageDialog(resources.GetString("/Main/metered"))
|
||||
{
|
||||
DefaultCommandIndex = 2,
|
||||
CancelCommandIndex = 1
|
||||
};
|
||||
dialog.Commands.Add(new UICommand("Yes"));
|
||||
dialog.Commands.Add(new UICommand("No", (command) => cancel = true));
|
||||
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("Add to 'Watch later' playlist", (command) =>
|
||||
dialog.Commands.Add(new UICommand(resources.GetString("/Main/addLater"), (command) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -333,6 +354,9 @@ namespace FoxTube
|
||||
if (cancel)
|
||||
return;
|
||||
|
||||
if (videoPlaceholder.Content != null)
|
||||
(videoPlaceholder.Content as VideoPage).player.close_Click(this, null);
|
||||
|
||||
videoPlaceholder.Content = null;
|
||||
Fullscreen(false);
|
||||
|
||||
@@ -390,14 +414,14 @@ namespace FoxTube
|
||||
|
||||
Dictionary<Type, Action> switchCase = new Dictionary<Type, Action>()
|
||||
{
|
||||
{ typeof(Settings), () => nav.Header = "Settings" },
|
||||
{ typeof(ChannelPage), () => nav.Header = "Channel" },
|
||||
{ typeof(PlaylistPage), () => nav.Header = "Playlist" },
|
||||
{ typeof(Search), () => nav.Header = "Search" },
|
||||
{ typeof(Subscriptions), () => nav.Header = "Subscriptions" },
|
||||
{ typeof(History), () => nav.Header = "History" },
|
||||
{ typeof(Home), () => nav.Header = "Home" },
|
||||
{ typeof(Downloads), () => nav.Header = "Downloads" }
|
||||
{ typeof(Settings), () => nav.Header = resources.GetString("/Main/settings/Content") },
|
||||
{ typeof(ChannelPage), () => nav.Header = resources.GetString("/Main/channel") },
|
||||
{ typeof(PlaylistPage), () => nav.Header = resources.GetString("/Main/playlist") },
|
||||
{ typeof(Search), () => nav.Header = resources.GetString("/Main/searchPlaceholder/PlaceholderText") },
|
||||
{ typeof(Subscriptions), () => nav.Header = resources.GetString("/Main/subscriptions/Content") },
|
||||
{ typeof(History), () => nav.Header = resources.GetString("/Main/history/Content") },
|
||||
{ typeof(Home), () => nav.Header = resources.GetString("/Main/home/Content") },
|
||||
{ typeof(Downloads), () => nav.Header = resources.GetString("/Main/downloads/Content") }
|
||||
};
|
||||
|
||||
if (content.SourcePageType == typeof(Home) || content.SourcePageType == typeof(Settings) || content.SourcePageType == typeof(Subscriptions))
|
||||
@@ -425,7 +449,7 @@ namespace FoxTube
|
||||
|
||||
if (videoPlaceholder.Content != null)
|
||||
{
|
||||
nav.Header = "Video";
|
||||
nav.Header = resources.GetString("/Main/video");
|
||||
nav.ExpandedModeThresholdWidth = short.MaxValue;
|
||||
nav.IsPaneOpen = false;
|
||||
}
|
||||
@@ -437,24 +461,37 @@ namespace FoxTube
|
||||
{
|
||||
nav.CompactModeThresholdWidth = short.MaxValue;
|
||||
nav.ExpandedModeThresholdWidth = short.MaxValue;
|
||||
nav.OpenPaneLength = 0;
|
||||
try
|
||||
{
|
||||
nav.IsPaneVisible = false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
nav.CompactPaneLength = 0;
|
||||
nav.OpenPaneLength = 0;
|
||||
}
|
||||
nav.Margin = new Thickness(0, -45, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
nav.CompactModeThresholdWidth = 641;
|
||||
if(videoPlaceholder.Content == null)
|
||||
nav.ExpandedModeThresholdWidth = 1008;
|
||||
nav.Margin = new Thickness(0);
|
||||
try
|
||||
{
|
||||
nav.IsPaneVisible = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
nav.CompactPaneLength = new NavigationView().CompactPaneLength;
|
||||
nav.OpenPaneLength = new NavigationView().OpenPaneLength; ;
|
||||
}
|
||||
if (videoPlaceholder.Content != null && nav.IsPaneOpen)
|
||||
nav.IsPaneOpen = false;
|
||||
else
|
||||
{
|
||||
nav.OpenPaneLength = 300;
|
||||
nav.CompactPaneLength = 40;
|
||||
}
|
||||
SetTitleBar();
|
||||
}
|
||||
nav.UpdateLayout();
|
||||
}
|
||||
|
||||
public void CloseVideo()
|
||||
@@ -464,8 +501,8 @@ namespace FoxTube
|
||||
ApplicationView.GetForCurrentView().ExitFullScreenMode();
|
||||
Fullscreen(false);
|
||||
}
|
||||
(videoPlaceholder.Content as VideoPage).player.pointerCaptured = false;
|
||||
videoPlaceholder.Content = null;
|
||||
GC.Collect();
|
||||
Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Arrow, 0);
|
||||
MaximizeVideo();
|
||||
|
||||
@@ -544,14 +581,14 @@ namespace FoxTube
|
||||
{
|
||||
Dictionary<Type, Action> switchCase = new Dictionary<Type, Action>()
|
||||
{
|
||||
{ typeof(Settings), () => nav.Header = "Settings" },
|
||||
{ typeof(ChannelPage), () => nav.Header = "Channel" },
|
||||
{ typeof(PlaylistPage), () => nav.Header = "Playlist" },
|
||||
{ typeof(Search), () => nav.Header = "Search" },
|
||||
{ typeof(Subscriptions), () => nav.Header = "Subscriptions" },
|
||||
{ typeof(History), () => nav.Header = "History" },
|
||||
{ typeof(Home), () => nav.Header = "Home" },
|
||||
{ typeof(Downloads), () => nav.Header = "Downloads" }
|
||||
{ typeof(Settings), () => nav.Header = resources.GetString("/Main/settings/Content") },
|
||||
{ typeof(ChannelPage), () => nav.Header = resources.GetString("/Main/channel") },
|
||||
{ typeof(PlaylistPage), () => nav.Header = resources.GetString("/Main/playlist") },
|
||||
{ typeof(Search), () => nav.Header = resources.GetString("/Main/searchPlaceholder/PlaceholderText") },
|
||||
{ typeof(Subscriptions), () => nav.Header = resources.GetString("/Main/subscriptions/Content") },
|
||||
{ typeof(History), () => nav.Header = resources.GetString("/Main/history/Content") },
|
||||
{ typeof(Home), () => nav.Header = resources.GetString("/Main/home/Content") },
|
||||
{ typeof(Downloads), () => nav.Header = resources.GetString("/Main/downloads/Content") }
|
||||
};
|
||||
|
||||
try { switchCase[e.SourcePageType](); }
|
||||
@@ -724,5 +761,10 @@ namespace FoxTube
|
||||
{
|
||||
((NavigationViewItem)sender).ContextFlyout.ShowAt((NavigationViewItem)sender);
|
||||
}
|
||||
|
||||
private void RemoveAds_Tapped(object sender, TappedRoutedEventArgs e)
|
||||
{
|
||||
SecretsVault.GetAdblock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,16 +63,16 @@
|
||||
</ScrollViewer>
|
||||
|
||||
<CommandBar Grid.Row="2" Grid.ColumnSpan="2">
|
||||
<AppBarButton Icon="Globe" Label="Open in browser" Name="inBrowser" Click="inBrowser_Click"/>
|
||||
<AppBarButton Icon="Add" Label="Add to" IsEnabled="False">
|
||||
<AppBarButton x:Uid="/Playlist/openWeb" Icon="Globe" Label="Open in browser" Name="inBrowser" Click="inBrowser_Click"/>
|
||||
<AppBarButton x:Uid="/Playlist/addTo" Icon="Add" Label="Add to" IsEnabled="False">
|
||||
<AppBarButton.Flyout>
|
||||
<MenuFlyout>
|
||||
|
||||
</MenuFlyout>
|
||||
</AppBarButton.Flyout>
|
||||
</AppBarButton>
|
||||
<AppBarButton Icon="Refresh" Label="Refresh" Name="refresh" Click="refresh_Click"/>
|
||||
<AppBarButton Icon="Share" Label="Share" Name="share" Click="share_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"/>
|
||||
</CommandBar>
|
||||
|
||||
<foxtube:LoadingPage Grid.RowSpan="2" Visibility="Collapsed"/>
|
||||
|
||||
@@ -3,6 +3,7 @@ using Google.Apis.YouTube.v3;
|
||||
using Google.Apis.YouTube.v3.Data;
|
||||
using System;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using Windows.Foundation;
|
||||
using Windows.System;
|
||||
using Windows.UI.Xaml;
|
||||
@@ -57,7 +58,7 @@ namespace FoxTube.Pages
|
||||
item = (await request.ExecuteAsync()).Items[0];
|
||||
|
||||
title.Text = item.Snippet.Title;
|
||||
info.Text = $"{item.ContentDetails.ItemCount} videos";
|
||||
info.Text = $"{item.ContentDetails.ItemCount} {ResourceLoader.GetForCurrentView("Playlist").GetString("/Playlist/videos")}";
|
||||
description.Text = item.Snippet.Description;
|
||||
|
||||
channelName.Text = item.Snippet.ChannelTitle;
|
||||
@@ -129,7 +130,7 @@ namespace FoxTube.Pages
|
||||
item.Snippet.Thumbnails.Medium.Url,
|
||||
item.Snippet.Title,
|
||||
$"https://www.youtube.com/playlist?list={item.Id}",
|
||||
"playlist");
|
||||
ResourceLoader.GetForCurrentView("Cards").GetString("/Cards/playlistShare"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,52 +19,52 @@
|
||||
<TextBlock Name="searchTerm" Text="Search results for: [searchTerm]" FontSize="28"/>
|
||||
<TextBlock Name="resultsCount" Text="Found: [resultCount] item(s)" FontSize="14" Foreground="Gray"/>
|
||||
|
||||
<HyperlinkButton Name="toggleFilters" Click="toggleFilters_Click" Content="Show filters " FontFamily="Default, Segoe MDL2 Assets" Visibility="Visible"/>
|
||||
<HyperlinkButton x:Uid="/Search/filters" Name="toggleFilters" Click="toggleFilters_Click" Content="Show filters " FontFamily="Default, Segoe MDL2 Assets" Visibility="Visible"/>
|
||||
<StackPanel Name="filters" Visibility="Collapsed">
|
||||
<GridView Padding="5" SelectionMode="None">
|
||||
<ComboBox Name="order" Header="Sort by" Width="150" SelectedIndex="0">
|
||||
<ComboBoxItem Content="Relevance"/>
|
||||
<ComboBoxItem Content="Upload date"/>
|
||||
<ComboBoxItem Content="View count"/>
|
||||
<ComboBoxItem Content="Rating"/>
|
||||
<ComboBoxItem Content="Title"/>
|
||||
<ComboBox x:Uid="/Search/order" Name="order" Header="Sort by" Width="150" SelectedIndex="0">
|
||||
<ComboBoxItem x:Uid="/Search/relevance" Content="Relevance"/>
|
||||
<ComboBoxItem x:Uid="/Search/update" Content="Upload date"/>
|
||||
<ComboBoxItem x:Uid="/Search/views" Content="View count"/>
|
||||
<ComboBoxItem x:Uid="/Search/rating" Content="Rating"/>
|
||||
<ComboBoxItem x:Uid="/Search/title" Content="Title"/>
|
||||
</ComboBox>
|
||||
<ComboBox Name="type" Header="Type" Width="150" SelectedIndex="0" SelectionChanged="type_SelectionChanged">
|
||||
<ComboBoxItem Content="All"/>
|
||||
<ComboBoxItem Content="Video"/>
|
||||
<ComboBoxItem Content="Channel"/>
|
||||
<ComboBoxItem Content="Playlist"/>
|
||||
<ComboBox x:Uid="/Search/type" Name="type" Header="Type" Width="150" SelectedIndex="0" SelectionChanged="type_SelectionChanged">
|
||||
<ComboBoxItem x:Uid="/Search/all" Content="All"/>
|
||||
<ComboBoxItem x:Uid="/Search/video" Content="Video"/>
|
||||
<ComboBoxItem x:Uid="/Search/channel" Content="Channel"/>
|
||||
<ComboBoxItem x:Uid="/Search/playlist" Content="Playlist"/>
|
||||
</ComboBox>
|
||||
<ComboBox Name="date" Header="Upload date" Width="150" SelectedIndex="0">
|
||||
<ComboBoxItem Content="Anytime"/>
|
||||
<ComboBoxItem Content="Last hour"/>
|
||||
<ComboBoxItem Content="Today"/>
|
||||
<ComboBoxItem Content="This week"/>
|
||||
<ComboBoxItem Content="This month"/>
|
||||
<ComboBoxItem Content="This year"/>
|
||||
<ComboBox x:Uid="/Search/updateHeader" Name="date" Header="Upload date" Width="150" SelectedIndex="0">
|
||||
<ComboBoxItem x:Uid="/Search/anytime" Content="Anytime"/>
|
||||
<ComboBoxItem x:Uid="/Search/lasthr" Content="Last hour"/>
|
||||
<ComboBoxItem x:Uid="/Search/today" Content="Today"/>
|
||||
<ComboBoxItem x:Uid="/Search/week" Content="This week"/>
|
||||
<ComboBoxItem x:Uid="/Search/month" Content="This month"/>
|
||||
<ComboBoxItem x:Uid="/Search/year" Content="This year"/>
|
||||
</ComboBox>
|
||||
<ComboBox Visibility="Collapsed" Name="duration" Header="Duration" Width="150" SelectedIndex="0">
|
||||
<ComboBoxItem Content="Any"/>
|
||||
<ComboBoxItem Content="Long (> 20 minutes)"/>
|
||||
<ComboBoxItem Content="Medium"/>
|
||||
<ComboBoxItem Content="Short (< 4 minutes)"/>
|
||||
<ComboBox x:Uid="/Search/duration" Visibility="Collapsed" Name="duration" Header="Duration" Width="150" SelectedIndex="0">
|
||||
<ComboBoxItem x:Uid="/Search/any" Content="Any"/>
|
||||
<ComboBoxItem x:Uid="/Search/long" Content="Long (> 20 minutes)"/>
|
||||
<ComboBoxItem x:Uid="/Search/medium" Content="Medium"/>
|
||||
<ComboBoxItem x:Uid="/Search/short" Content="Short (< 4 minutes)"/>
|
||||
</ComboBox>
|
||||
</GridView>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Visibility="Collapsed" Content="Features" Name="featBtn" Margin="10,0,0,10">
|
||||
<Button x:Uid="/Search/features" Visibility="Collapsed" Content="Features" Name="featBtn" Margin="10,0,0,10">
|
||||
<Button.Flyout>
|
||||
<Flyout>
|
||||
<ListView Name="features" SelectionMode="Multiple" Header="Features">
|
||||
<ListView x:Uid="/Search/featuresHeader" Name="features" SelectionMode="Multiple" Header="Features">
|
||||
<TextBlock Text="HD"/>
|
||||
<TextBlock Text="3D"/>
|
||||
<TextBlock Text="Subtitles/CC"/>
|
||||
<TextBlock Text="Live"/>
|
||||
<TextBlock Text="Creative Commons"/>
|
||||
<TextBlock x:Uid="/Search/subs" Text="Subtitles/CC"/>
|
||||
<TextBlock x:Uid="/Search/live" Text="Live"/>
|
||||
<TextBlock x:Uid="/Search/cc" Text="Creative Commons"/>
|
||||
</ListView>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
<Button Content="Apply" Margin="10,0,0,10" Name="apply" Click="apply_Click"/>
|
||||
<Button x:Uid="/Search/apply" Content="Apply" Margin="10,0,0,10" Name="apply" Click="apply_Click"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
<pages:VideoGrid/>
|
||||
|
||||
@@ -8,7 +8,7 @@ using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
using Windows.System;
|
||||
using System.Globalization;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
|
||||
namespace FoxTube
|
||||
{
|
||||
@@ -17,6 +17,8 @@ namespace FoxTube
|
||||
/// </summary>
|
||||
public sealed partial class Search : Page
|
||||
{
|
||||
ResourceLoader resources = ResourceLoader.GetForCurrentView("Search");
|
||||
|
||||
public SearchParameters Parameters;
|
||||
SearchResource.ListRequest request;
|
||||
string nextToken;
|
||||
@@ -95,10 +97,10 @@ namespace FoxTube
|
||||
(grid.Children[1] as CommandBar).Visibility = Visibility.Collapsed;
|
||||
}
|
||||
request.Q = arg.Term;
|
||||
request.SafeSearch = (SearchResource.ListRequest.SafeSearchEnum)(int)settings.Values["safeSearch"];
|
||||
request.SafeSearch = (SearchResource.ListRequest.SafeSearchEnum)SettingsStorage.SafeSearch;
|
||||
|
||||
request.RegionCode = CultureInfo.GetCultures(CultureTypes.AllCultures).Find(i => i.IetfLanguageTag == SettingsStorage.Region).IetfLanguageTag.Remove(0, 3);
|
||||
request.RelevanceLanguage = CultureInfo.GetCultures(CultureTypes.AllCultures).Find(i => i.IetfLanguageTag == SettingsStorage.Region).TwoLetterISOLanguageName;
|
||||
request.RegionCode = SettingsStorage.Region;
|
||||
request.RelevanceLanguage = SettingsStorage.RelevanceLanguage;
|
||||
|
||||
request.MaxResults = 48;
|
||||
try
|
||||
@@ -130,8 +132,8 @@ namespace FoxTube
|
||||
features.SelectedItems.Add(features.Items[4]);
|
||||
|
||||
SearchListResponse response = await request.ExecuteAsync();
|
||||
searchTerm.Text = $"Search results for: {Parameters.Term}";
|
||||
resultsCount.Text = $"Found: {SetResults(response.PageInfo.TotalResults)} item(s)";
|
||||
searchTerm.Text = $"{resources.GetString("/Search/header")} '{Parameters.Term}'";
|
||||
resultsCount.Text = $"{resources.GetString("/Search/found")}: {SetResults(response.PageInfo.TotalResults)} {resources.GetString("/Search/items")}";
|
||||
if (!string.IsNullOrWhiteSpace(response.NextPageToken))
|
||||
nextToken = response.NextPageToken;
|
||||
else
|
||||
@@ -158,12 +160,12 @@ namespace FoxTube
|
||||
if(filters.Visibility == Visibility.Collapsed)
|
||||
{
|
||||
filters.Visibility = Visibility.Visible;
|
||||
toggleFilters.Content = "Hide filters \xE014";
|
||||
toggleFilters.Content = resources.GetString("/Search/hideFilters");
|
||||
}
|
||||
else
|
||||
{
|
||||
filters.Visibility = Visibility.Collapsed;
|
||||
toggleFilters.Content = "Show filters \xE015";
|
||||
toggleFilters.Content = resources.GetString("/Search/filters/Content");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<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 x:Uid="/About/legal" Text="Legal stuff" FontSize="22" FontWeight="SemiBold"/>
|
||||
<HyperlinkButton x:Uid="/About/ourPrivacy" Content="Our Privacy Policy" NavigateUri="https://michael-xfox.com/foxtubepp.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,5,0,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/guides" Content="YouTube Community Guidelines" NavigateUri="https://youtube.com/t/community_guidelines" Padding="0,0,0,10"/>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<TextBlock x:Uid="/General/restart" Foreground="Red" Text="Reopen the app to apply settings"/>
|
||||
<Button x:Uid="/General/closeApp" Content="Close app" Background="Red" Margin="5" Click="Button_Click"/>
|
||||
</StackPanel>
|
||||
<ComboBox Header="Search relevance language" MinWidth="250" Name="relLanguage" SelectionChanged="RelLanguage_SelectionChanged"/>
|
||||
<ComboBox x:Uid="/General/region" Header="Region" MinWidth="250" Name="region" SelectionChanged="region_SelectionChanged"/>
|
||||
<ComboBox x:Uid="/General/safeSearch" Header="SafeSearch" MinWidth="250" Name="safeSearch" SelectionChanged="safeSearch_SelectionChanged">
|
||||
<ComboBoxItem x:Uid="/General/moderate" Content="Moderate"/>
|
||||
@@ -29,20 +30,13 @@
|
||||
<TextBlock x:Uid="/General/playback" Text="Playback" FontSize="22"/>
|
||||
<ComboBox x:Uid="/General/quality" Width="250" Header="Default video playback quality" Name="quality" SelectionChanged="quality_SelectionChanged">
|
||||
<ComboBoxItem Tag="remember" x:Uid="/General/remember" Content="Remember my choice"/>
|
||||
<ComboBoxItem Tag="2160p" Content="2160p"/>
|
||||
<ComboBoxItem Tag="1080p" Content="1080p"/>
|
||||
<ComboBoxItem Tag="720p" Content="720p"/>
|
||||
<ComboBoxItem Tag="480p" Content="480p"/>
|
||||
<ComboBoxItem Tag="360p" Content="360p"/>
|
||||
<ComboBoxItem Tag="240p" Content="240p"/>
|
||||
<ComboBoxItem Tag="144p" Content="144p"/>
|
||||
</ComboBox>
|
||||
<ToggleSwitch x:Uid="/General/metered" OnContent="Notify when playing on metered connection" OffContent="Notify when playing on metered connection" Name="mobileWarning" Toggled="mobileWarning_Toggled"/>
|
||||
<ToggleSwitch x:Uid="/General/autoplay" OnContent="Play videos automatically" OffContent="Play videos automatically" Name="autoplay" Toggled="autoplay_Toggled"/>
|
||||
|
||||
<TextBlock x:Uid="/General/notifications" Text="Notifications" FontSize="22"/>
|
||||
<ToggleSwitch x:Uid="/General/newVideo" Name="newVideo" OnContent="Notify when someone of your subscriptions uploaded new video" OffContent="Notify when someone of your subscriptions uploaded new video" Toggled="notification_IsEnabledChanged"/>
|
||||
<ToggleSwitch Name="devNews" OnContent="Recieve messages from developers" OffContent="Recieve messages from developers" Toggled="devNews_Toggled"/>
|
||||
<ToggleSwitch x:Uid="/General/devNotifications" Name="devNews" OnContent="Recieve messages from developers" OffContent="Recieve messages from developers" Toggled="devNews_Toggled"/>
|
||||
|
||||
<TextBlock x:Uid="/General/color" Text="Color mode" FontSize="22"/>
|
||||
<RadioButton x:Uid="/General/colorLight" Content="Light" Name="light" GroupName="color" Checked="RadioButton_Checked"/>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.UI;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Google.Apis.YouTube.v3;
|
||||
using Google.Apis.YouTube.v3.Data;
|
||||
using YoutubeExplode.Models.MediaStreams;
|
||||
using System;
|
||||
|
||||
namespace FoxTube.Pages.SettingsPages
|
||||
{
|
||||
@@ -17,18 +20,10 @@ namespace FoxTube.Pages.SettingsPages
|
||||
InitializeComponent();
|
||||
|
||||
language.SelectedItem = language.Items.Find(i => ((ComboBoxItem)i).Tag.ToString() == SettingsStorage.Language);
|
||||
CultureInfo.GetCultures(CultureTypes.AllCultures).FindAll(i => !i.IsNeutralCulture).ForEach(i =>
|
||||
{
|
||||
region.Items.Add(new ComboBoxItem
|
||||
{
|
||||
Content = i.DisplayName,
|
||||
Tag = i.IetfLanguageTag
|
||||
});
|
||||
if (i.IetfLanguageTag == SettingsStorage.Region)
|
||||
region.SelectedItem = region.Items.Last();
|
||||
});
|
||||
safeSearch.SelectedIndex = SettingsStorage.SafeSearch;
|
||||
|
||||
foreach (VideoQuality i in Enum.GetValues(typeof(VideoQuality)).ToReversedList())
|
||||
quality.Items.Add(new ComboBoxItem() { Tag = i.GetVideoQualityLabel(), Content = i.GetVideoQualityLabel() });
|
||||
quality.SelectedItem = quality.Items.ToList().Find(i => ((ComboBoxItem)i).Tag.ToString() == SettingsStorage.VideoQuality);
|
||||
mobileWarning.IsOn = SettingsStorage.CheckConnection;
|
||||
autoplay.IsOn = SettingsStorage.Autoplay;
|
||||
@@ -48,6 +43,37 @@ namespace FoxTube.Pages.SettingsPages
|
||||
system.IsChecked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
InitializeRegions();
|
||||
}
|
||||
|
||||
async void InitializeRegions()
|
||||
{
|
||||
I18nRegionsResource.ListRequest regRequest = SecretsVault.Service.I18nRegions.List("snippet");
|
||||
I18nRegionListResponse regResponse = await regRequest.ExecuteAsync();
|
||||
foreach(I18nRegion i in regResponse.Items)
|
||||
{
|
||||
region.Items.Add(new ComboBoxItem
|
||||
{
|
||||
Content = i.Snippet.Name,
|
||||
Tag = i.Snippet.Gl
|
||||
});
|
||||
if (SettingsStorage.Region == i.Snippet.Gl)
|
||||
region.SelectedItem = region.Items.Last();
|
||||
}
|
||||
|
||||
I18nLanguagesResource.ListRequest langRequest = SecretsVault.Service.I18nLanguages.List("snippet");
|
||||
I18nLanguageListResponse langResponse = await langRequest.ExecuteAsync();
|
||||
foreach(I18nLanguage i in langResponse.Items)
|
||||
{
|
||||
relLanguage.Items.Add(new ComboBoxItem
|
||||
{
|
||||
Content = i.Snippet.Name,
|
||||
Tag = i.Snippet.Hl
|
||||
});
|
||||
if (SettingsStorage.RelevanceLanguage == i.Snippet.Hl)
|
||||
relLanguage.SelectedItem = relLanguage.Items.Last();
|
||||
}
|
||||
}
|
||||
|
||||
private void language_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
@@ -79,9 +105,14 @@ namespace FoxTube.Pages.SettingsPages
|
||||
SettingsStorage.VideoNotifications = newVideo.IsOn;
|
||||
}
|
||||
|
||||
private void RelLanguage_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
SettingsStorage.RelevanceLanguage = ((ComboBoxItem)relLanguage.SelectedItem).Tag.ToString();
|
||||
}
|
||||
|
||||
private void region_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
SettingsStorage.Region = CultureInfo.GetCultures(CultureTypes.AllCultures)[region.SelectedIndex].Name;
|
||||
SettingsStorage.Region = ((ComboBoxItem)region.SelectedItem).Tag.ToString();
|
||||
}
|
||||
|
||||
private void safeSearch_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
|
||||
@@ -2,56 +2,46 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
using FoxTube.Classes;
|
||||
using System.Xml;
|
||||
using Windows.Storage;
|
||||
using System.Diagnostics;
|
||||
using Windows.UI.Popups;
|
||||
|
||||
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
|
||||
using System.Xml;
|
||||
|
||||
namespace FoxTube.Pages.SettingsPages
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// Page with changelogs and dev messages
|
||||
/// </summary>
|
||||
public sealed partial class Inbox : Page
|
||||
{
|
||||
List<InboxItem> items = new List<InboxItem>();
|
||||
public Inbox()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void LoadItems()
|
||||
public async void LoadItems()
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
|
||||
doc.Load("http://foxgame-studio.000webhostapp.com/foxtube-changelog.xml");
|
||||
StorageFile file = await (await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync(@"Assets\Data")).GetFileAsync("Patchnotes.xml");
|
||||
doc.Load(await file.OpenStreamForReadAsync());
|
||||
foreach (XmlElement e in doc["items"].ChildNodes)
|
||||
items.Add(new InboxItem(
|
||||
e.GetAttribute("version"),
|
||||
e["content"].InnerText,
|
||||
e["content"][SettingsStorage.Language].InnerText,
|
||||
e.GetAttribute("time")));
|
||||
|
||||
doc.Load("http://foxgame-studio.000webhostapp.com/foxtube-messages.xml");
|
||||
foreach (XmlElement e in doc["posts"].ChildNodes)
|
||||
items.Add(new InboxItem(
|
||||
e["header"].InnerText,
|
||||
e["content"].InnerText,
|
||||
DateTime.Parse(e["time"].InnerText),
|
||||
e["content"][SettingsStorage.Language].InnerText,
|
||||
DateTime.Parse(e.GetAttribute("time")),
|
||||
e["id"].InnerText
|
||||
));
|
||||
|
||||
|
||||
@@ -1,39 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using FoxTube.Controls.Adverts;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
using System.Diagnostics;
|
||||
using System.Timers;
|
||||
using Windows.UI.Core;
|
||||
using Microsoft.Toolkit.Uwp.UI.Controls;
|
||||
|
||||
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
|
||||
|
||||
namespace FoxTube.Pages
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// Items cards container
|
||||
/// </summary>
|
||||
public sealed partial class VideoGrid : Page
|
||||
{
|
||||
public VideoGrid()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void Add(UIElement card)
|
||||
{
|
||||
list.Items.Add(card);
|
||||
/*if (list.Items.Count % 10 == 0)
|
||||
list.Items.Add(new CardAdvert());*/
|
||||
empty.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:pages="using:FoxTube.Pages"
|
||||
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
|
||||
xmlns:ui="using:Microsoft.Advertising.WinRT.UI"
|
||||
xmlns:controls1="using:FoxTube.Controls"
|
||||
mc:Ignorable="d">
|
||||
|
||||
@@ -37,12 +35,6 @@
|
||||
<local:VideoPlayer/>
|
||||
<PivotItem Header="Description" Name="descriptionPanel">
|
||||
<StackPanel Margin="0,10">
|
||||
<Button Visibility="Collapsed">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon Glyph="" Margin="0,0,10,0"/>
|
||||
<TextBlock Text="Continue watching from HH:MM:SS"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<TextBlock IsTextSelectionEnabled="True" Name="title" Text="[Video title]" FontSize="25" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Start"/>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
@@ -55,7 +47,7 @@
|
||||
<StackPanel Orientation="Vertical" Grid.Column="1" Padding="5" VerticalAlignment="Center">
|
||||
<TextBlock Name="channelName" Text="[Channel name]" FontSize="18"/>
|
||||
<TextBlock Name="subscribers" Text="[subscribers]" Foreground="Gray" Margin="0,0,0,5"/>
|
||||
<Button Click="subscribe_Click" Grid.Column="2" Height="30" Width="200" Background="Red" Foreground="White" FontSize="14" FontWeight="SemiBold" Content="Subscirbe" Name="subscribe"/>
|
||||
<Button x:Uid="/Cards/subscribe" Click="subscribe_Click" Grid.Column="2" Height="30" Width="200" Background="Red" Foreground="White" FontSize="14" FontWeight="SemiBold" Content="Subscirbe" Name="subscribe"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
@@ -82,38 +74,19 @@
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<TextBlock Name="description" Text="[Description]" IsTextSelectionEnabled="True" TextWrapping="WrapWholeWords"/>
|
||||
<Grid Margin="0,20,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="20"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Text="Published at: "/>
|
||||
<TextBlock Grid.Row="1" Text="Category: "/>
|
||||
<TextBlock Grid.Row="2" Text="License: "/>
|
||||
|
||||
<TextBlock Name="publishedAt" Grid.Column="2" Text="[Publishing date]"/>
|
||||
<TextBlock Name="category" Grid.Column="2" Grid.Row="1" Padding="0" Text="[Category]"/>
|
||||
<TextBlock Name="license" Grid.Column="2" Grid.Row="2" Text="[License type]"/>
|
||||
</Grid>
|
||||
<TextBlock Margin="0,20" Name="category" Text="Category: "/>
|
||||
</StackPanel>
|
||||
</PivotItem>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<CommandBar VerticalAlignment="Bottom" Name="commandbar">
|
||||
<AppBarButton Icon="Download" Label="Download video" Name="download">
|
||||
<AppBarButton x:Uid="/VideoPage/download" Icon="Download" Label="Download video" Name="download">
|
||||
<AppBarButton.Flyout>
|
||||
<MenuFlyout x:Name="downloadSelector"/>
|
||||
</AppBarButton.Flyout>
|
||||
</AppBarButton>
|
||||
<AppBarButton Name="addTo" Label="Add to" Icon="Add">
|
||||
<AppBarButton x:Uid="/VideoPage/addTo" Name="addTo" Label="Add to" Icon="Add">
|
||||
<AppBarButton.Flyout>
|
||||
<Flyout>
|
||||
<ScrollViewer Margin="-12" MaxHeight="300">
|
||||
@@ -154,14 +127,14 @@
|
||||
</Flyout>
|
||||
</AppBarButton.Flyout>
|
||||
</AppBarButton>
|
||||
<AppBarButton Name="refresh" Click="refresh_Click" Icon="Refresh" Label="Refresh page"/>
|
||||
<AppBarButton Name="share" Click="share_Click" Icon="Share" Label="Share"/>
|
||||
<AppBarButton Name="openBrowser" Click="openBrowser_Click" Icon="Globe" Label="Open in browser"/>
|
||||
<AppBarButton x:Uid="/VideoPage/refresh" Name="refresh" Click="refresh_Click" Icon="Refresh" Label="Refresh page"/>
|
||||
<AppBarButton x:Uid="/VideoPage/share" Name="share" Click="share_Click" Icon="Share" Label="Share"/>
|
||||
<AppBarButton x:Uid="/VideoPage/openWeb" Name="openBrowser" Click="openBrowser_Click" Icon="Globe" Label="Open in browser"/>
|
||||
</CommandBar>
|
||||
|
||||
<Grid Grid.Column="1" Name="tabsPlaceholder">
|
||||
<Pivot Grid.Row="1" Name="pivot" SelectedIndex="0" IsHeaderItemsCarouselEnabled="False">
|
||||
<PivotItem Header="Suggestions">
|
||||
<PivotItem x:Uid="/VideoPage/related" Header="Suggestions">
|
||||
<ScrollViewer>
|
||||
<StackPanel>
|
||||
<controls1:Advert/>
|
||||
@@ -169,10 +142,10 @@
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</PivotItem>
|
||||
<PivotItem Header="Comments" Name="commentsPlaceholder">
|
||||
<PivotItem x:Uid="/VideoPage/comments" Header="Comments" Name="commentsPlaceholder">
|
||||
<pages:CommentsPage/>
|
||||
</PivotItem>
|
||||
<PivotItem Header="Playlist" Name="playlist">
|
||||
<PivotItem x:Uid="/VideoPage/playlist" Header="Playlist" Name="playlist">
|
||||
<ScrollViewer>
|
||||
<StackPanel>
|
||||
<StackPanel Padding="8" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}">
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
using System;
|
||||
using FoxTube.Controls;
|
||||
using FoxTube.Controls.Adverts;
|
||||
using Google.Apis.YouTube.v3;
|
||||
using Google.Apis.YouTube.v3.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using Windows.Foundation;
|
||||
using Windows.Storage;
|
||||
using Windows.System;
|
||||
using Windows.UI;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
using Windows.System;
|
||||
using Google.Apis.YouTube.v3.Data;
|
||||
using Google.Apis.YouTube.v3;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
using System.Diagnostics;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using Windows.Storage;
|
||||
using Windows.UI;
|
||||
using FoxTube.Controls;
|
||||
using YoutubeExplode.Models.MediaStreams;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
using YoutubeExplode;
|
||||
using YoutubeExplode.Models.MediaStreams;
|
||||
|
||||
namespace FoxTube.Pages
|
||||
{
|
||||
@@ -42,10 +45,10 @@ namespace FoxTube.Pages
|
||||
/// </summary>
|
||||
public sealed partial class VideoPage : Page
|
||||
{
|
||||
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
|
||||
ResourceLoader resources = ResourceLoader.GetForCurrentView("VideoPage");
|
||||
|
||||
public string videoId;
|
||||
string playlistId = null;
|
||||
public string playlistId = null;
|
||||
public Video item;
|
||||
|
||||
bool wide;
|
||||
@@ -57,6 +60,8 @@ namespace FoxTube.Pages
|
||||
public CommentsPage comments;
|
||||
public LoadingPage loading;
|
||||
|
||||
DispatcherTimer liveTimer;
|
||||
|
||||
public VideoPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -84,8 +89,11 @@ namespace FoxTube.Pages
|
||||
}
|
||||
}
|
||||
|
||||
private void Player_NextClicked(object sender, params object[] e)
|
||||
private void Player_NextClicked()
|
||||
{
|
||||
if (playlistId != null)
|
||||
playlistList.SelectedIndex++;
|
||||
else
|
||||
(relatedVideos.Children[0] as VideoCard).Button_Click(this, null);
|
||||
}
|
||||
|
||||
@@ -107,21 +115,47 @@ namespace FoxTube.Pages
|
||||
videoId = ids[0];
|
||||
|
||||
if (ids[1] != null)
|
||||
LoadPlaylist(ids[1]);
|
||||
else
|
||||
pivot.Items.Remove(playlist);
|
||||
|
||||
VideosResource.ListRequest request = SecretsVault.Service.Videos.List("snippet,statistics,status,contentDetails,liveStreamingDetails");
|
||||
request.Id = ids[0];
|
||||
item = (await request.ExecuteAsync()).Items[0];
|
||||
|
||||
if (item.Snippet.LiveBroadcastContent == "none")
|
||||
LoadStats();
|
||||
else
|
||||
LoadStream();
|
||||
|
||||
LoadInfo();
|
||||
|
||||
loading.Close();
|
||||
}
|
||||
catch (System.Net.Http.HttpRequestException)
|
||||
{
|
||||
playlistId = ids[1];
|
||||
loading.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
loading.Error(e.GetType().ToString(), e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
async void LoadPlaylist(string id)
|
||||
{
|
||||
playlistId = id;
|
||||
List<VideoPlaylistItem> items = new List<VideoPlaylistItem>();
|
||||
VideoPlaylistItem selection = null;
|
||||
|
||||
//Retrieving data
|
||||
PlaylistsResource.ListRequest playlistRequest = SecretsVault.Service.Playlists.List("snippet,contentDetails");
|
||||
playlistRequest.Id = ids[1];
|
||||
playlistRequest.Id = id;
|
||||
Playlist playlistItem = (await playlistRequest.ExecuteAsync()).Items[0];
|
||||
|
||||
playlistName.Text = playlistItem.Snippet.Title;
|
||||
playlistChannel.Text = playlistItem.Snippet.ChannelTitle;
|
||||
|
||||
PlaylistItemsResource.ListRequest listRequest = SecretsVault.Service.PlaylistItems.List("snippet");
|
||||
listRequest.MaxResults = 50;
|
||||
listRequest.PlaylistId = ids[1];
|
||||
listRequest.PlaylistId = id;
|
||||
PlaylistItemListResponse listResponse = await listRequest.ExecuteAsync();
|
||||
|
||||
foreach (PlaylistItem i in listResponse.Items)
|
||||
@@ -150,39 +184,49 @@ namespace FoxTube.Pages
|
||||
for (int k = 0; k < items.Count; k++)
|
||||
items[k].Number = k + 1;
|
||||
|
||||
//Setting data
|
||||
playlistName.Text = playlistItem.Snippet.Title;
|
||||
playlistChannel.Text = playlistItem.Snippet.ChannelTitle;
|
||||
|
||||
playlistCounter.Text = $"{items.IndexOf(selection) + 1}/{playlistItem.ContentDetails.ItemCount}";
|
||||
|
||||
playlistList.ItemsSource = items;
|
||||
playlistList.SelectedItem = selection;
|
||||
pivot.SelectedItem = playlist;
|
||||
|
||||
if (playlistList.SelectedIndex == playlistList.Items.Count - 1)
|
||||
player.Next.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
else
|
||||
pivot.Items.Remove(playlist);
|
||||
|
||||
VideosResource.ListRequest request = SecretsVault.Service.Videos.List("snippet,statistics,status,contentDetails");
|
||||
request.Id = ids[0];
|
||||
item = (await request.ExecuteAsync()).Items[0];
|
||||
|
||||
async void LoadInfo()
|
||||
{
|
||||
//Setting meta
|
||||
title.Text = item.Snippet.Title;
|
||||
Methods.FormatText(ref description, item.Snippet.Description);
|
||||
|
||||
publishedAt.Text = item.Snippet.PublishedAt.ToString();
|
||||
if (item.Status.License == "youtube")
|
||||
license.Text = "Standard YouTube License";
|
||||
else license.Text = "Creative Commons Attribution license (reuse allowed)";
|
||||
//Setting channel button
|
||||
ChannelsResource.ListRequest channelRequest = SecretsVault.Service.Channels.List("snippet, statistics");
|
||||
channelRequest.Id = item.Snippet.ChannelId;
|
||||
var item1 = (await channelRequest.ExecuteAsync()).Items[0];
|
||||
|
||||
VideoCategoriesResource.ListRequest categoryRequest = SecretsVault.Service.VideoCategories.List("snippet");
|
||||
categoryRequest.Id = item.Snippet.CategoryId;
|
||||
category.Text = (await categoryRequest.ExecuteAsync()).Items[0].Snippet.Title;
|
||||
channelAvatar.ProfilePicture = new BitmapImage(new Uri(item1.Snippet.Thumbnails.Medium.Url));
|
||||
channelName.Text = item.Snippet.ChannelTitle;
|
||||
subscribers.Text = $"{item1.Statistics.SubscriberCount:0,0} {resources.GetString("/Cards/subscribers")}";
|
||||
|
||||
views.Text = $"{item.Statistics.ViewCount:0,0} views";
|
||||
//Setting ratings
|
||||
dislikes.Text = $"{item.Statistics.DislikeCount:0,0}";
|
||||
likes.Text = $"{item.Statistics.LikeCount:0,0}";
|
||||
rating.Value = (double)item.Statistics.DislikeCount / (double)(item.Statistics.DislikeCount + item.Statistics.LikeCount) * 100;
|
||||
|
||||
//Setting category
|
||||
VideoCategoriesResource.ListRequest categoryRequest = SecretsVault.Service.VideoCategories.List("snippet");
|
||||
categoryRequest.Id = item.Snippet.CategoryId;
|
||||
category.Text = (await categoryRequest.ExecuteAsync()).Items[0].Snippet.Title;
|
||||
|
||||
//Setting User's rate
|
||||
if (SecretsVault.IsAuthorized)
|
||||
{
|
||||
VideoGetRatingResponse ratingResponse = await SecretsVault.Service.Videos.GetRating(ids[0]).ExecuteAsync();
|
||||
VideoGetRatingResponse ratingResponse = await SecretsVault.Service.Videos.GetRating(videoId).ExecuteAsync();
|
||||
if (ratingResponse.Items[0].Rating == "like")
|
||||
{
|
||||
userRating = Rating.Like;
|
||||
@@ -200,7 +244,7 @@ namespace FoxTube.Pages
|
||||
{
|
||||
subscribe.Background = new SolidColorBrush(Colors.Transparent);
|
||||
subscribe.Foreground = new SolidColorBrush(Colors.Gray);
|
||||
subscribe.Content = "Subscribed";
|
||||
subscribe.Content = resources.GetString("/Cards/unsubscribe");
|
||||
}
|
||||
}
|
||||
subscribe.Visibility = Visibility.Visible;
|
||||
@@ -212,29 +256,45 @@ namespace FoxTube.Pages
|
||||
subscribe.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
ChannelsResource.ListRequest channelRequest = SecretsVault.Service.Channels.List("snippet, statistics");
|
||||
channelRequest.Id = item.Snippet.ChannelId;
|
||||
var item1 = (await channelRequest.ExecuteAsync()).Items[0];
|
||||
//Initializing player
|
||||
player.Initialize(item, item1.Snippet.Thumbnails.Medium.Url);
|
||||
|
||||
channelAvatar.ProfilePicture = new BitmapImage(new Uri(item1.Snippet.Thumbnails.Medium.Url));
|
||||
channelName.Text = item.Snippet.ChannelTitle;
|
||||
subscribers.Text = $"{item1.Statistics.SubscriberCount:0,0} subscribers";
|
||||
LoadRelatedVideos();
|
||||
}
|
||||
|
||||
void LoadStream()
|
||||
{
|
||||
liveTimer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(10) };
|
||||
liveTimer.Tick += LiveStatsUpdate;
|
||||
liveTimer.Start();
|
||||
LiveStatsUpdate();
|
||||
|
||||
if(string.IsNullOrWhiteSpace(item.LiveStreamingDetails.ActiveLiveChatId))
|
||||
pivot.Items.Remove(commentsPlaceholder);
|
||||
else
|
||||
{
|
||||
commentsPlaceholder.Header = resources.GetString("/VideoPage/chat");
|
||||
commentsPlaceholder.Content = new Chat(item.LiveStreamingDetails.ActiveLiveChatId);
|
||||
pivot.SelectedItem = commentsPlaceholder;
|
||||
}
|
||||
download.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
private async void LiveStatsUpdate(object sender = null, object e = null)
|
||||
{
|
||||
VideosResource.ListRequest request = SecretsVault.Service.Videos.List("liveStreamingDetails");
|
||||
request.Id = videoId;
|
||||
Video video = (await request.ExecuteAsync()).Items[0];
|
||||
|
||||
views.Text = $"{video.LiveStreamingDetails.ConcurrentViewers} {resources.GetString("/Cards/viewers")}";
|
||||
}
|
||||
|
||||
void LoadStats()
|
||||
{
|
||||
views.Text = $"{item.Statistics.ViewCount:0,0} {resources.GetString("/Cards/views")}";
|
||||
|
||||
comments.Initialize(item);
|
||||
player.Initialize(item, item1.Snippet.Thumbnails.Medium.Url);
|
||||
LoadRelatedVideos();
|
||||
LoadDownloads();
|
||||
|
||||
loading.Close();
|
||||
}
|
||||
catch (System.Net.Http.HttpRequestException)
|
||||
{
|
||||
loading.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
loading.Error(e.GetType().ToString(), e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
async void LoadDownloads()
|
||||
@@ -255,8 +315,8 @@ namespace FoxTube.Pages
|
||||
|
||||
MenuFlyoutItem audioItem = new MenuFlyoutItem()
|
||||
{
|
||||
Text = "Audio track",
|
||||
Tag = new object[] { infoSet.Audio[0], "Audio only" }
|
||||
Text = resources.GetString("/VideoPage/audio"),
|
||||
Tag = new object[] { infoSet.Audio[0], resources.GetString("/Cards/audioOnly") }
|
||||
};
|
||||
audioItem.Click += downloadItemSelected;
|
||||
downloadSelector.Items.Add(audioItem);
|
||||
@@ -275,8 +335,10 @@ namespace FoxTube.Pages
|
||||
async void LoadRelatedVideos()
|
||||
{
|
||||
SearchResource.ListRequest request = SecretsVault.Service.Search.List("snippet");
|
||||
request.RegionCode = SettingsStorage.Region;
|
||||
request.RelevanceLanguage = SettingsStorage.RelevanceLanguage;
|
||||
request.RelatedToVideoId = videoId;
|
||||
request.SafeSearch = (SearchResource.ListRequest.SafeSearchEnum)(int)settings.Values["safeSearch"];
|
||||
request.SafeSearch = (SearchResource.ListRequest.SafeSearchEnum)SettingsStorage.SafeSearch;
|
||||
request.MaxResults = 20;
|
||||
request.Type = "video";
|
||||
|
||||
@@ -320,10 +382,10 @@ namespace FoxTube.Pages
|
||||
private async void openBrowser_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
player.Pause();
|
||||
string timecode = player.elapsed.TotalSeconds > 10 ?
|
||||
"&t=" + (int)player.elapsed.TotalSeconds + "s" : string.Empty;
|
||||
string timecode = player.Elapsed.TotalSeconds > 10 ?
|
||||
"&t=" + (int)player.Elapsed.TotalSeconds + "s" : string.Empty;
|
||||
|
||||
await Launcher.LaunchUriAsync(new Uri($"https://www.youtube.com/watch?v={videoId}{timecode}"));
|
||||
await Launcher.LaunchUriAsync($"https://www.youtube.com/watch?v={videoId}{timecode}".ToUri());
|
||||
}
|
||||
|
||||
public void refresh_Click(object sender, RoutedEventArgs e)
|
||||
@@ -344,6 +406,8 @@ namespace FoxTube.Pages
|
||||
mainContent.Children.Remove(pivot);
|
||||
tabsPlaceholder.Children.Add(pivot);
|
||||
|
||||
pivot.SelectedItem = descriptionPanel;
|
||||
descriptionPanel.Opacity = 1;
|
||||
pivot.Items.RemoveAt(0);
|
||||
mainContent.Children.Add(descriptionPanel);
|
||||
|
||||
@@ -373,7 +437,7 @@ namespace FoxTube.Pages
|
||||
item.Snippet.Thumbnails.Medium.Url,
|
||||
item.Snippet.Title,
|
||||
$"https://www.youtube.com/watch?v={videoId}",
|
||||
"video");
|
||||
resources.GetString("/Cards/videoShare"));
|
||||
}
|
||||
|
||||
private void share_Click(object sender, RoutedEventArgs e)
|
||||
@@ -388,10 +452,10 @@ namespace FoxTube.Pages
|
||||
{
|
||||
case Rating.Like:
|
||||
like.Foreground = new SolidColorBrush(Colors.Gray);
|
||||
likes.Text = (int.Parse(likes.Text, System.Globalization.NumberStyles.AllowThousands) - 1).ToString("0,0");
|
||||
likes.Text = (int.Parse(likes.Text, NumberStyles.AllowThousands) - 1).ToString("0,0");
|
||||
|
||||
dislike.Foreground = new SolidColorBrush(Colors.Red);
|
||||
dislikes.Text = (int.Parse(dislikes.Text, System.Globalization.NumberStyles.AllowThousands) + 1).ToString("0,0");
|
||||
dislikes.Text = (int.Parse(dislikes.Text, NumberStyles.AllowThousands) + 1).ToString("0,0");
|
||||
rating.Value--;
|
||||
await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.Dislike).ExecuteAsync();
|
||||
|
||||
@@ -400,7 +464,7 @@ namespace FoxTube.Pages
|
||||
|
||||
case Rating.None:
|
||||
dislike.Foreground = new SolidColorBrush(Colors.Red);
|
||||
dislikes.Text = (int.Parse(dislikes.Text, System.Globalization.NumberStyles.AllowThousands) + 1).ToString("0,0");
|
||||
dislikes.Text = (int.Parse(dislikes.Text, NumberStyles.AllowThousands) + 1).ToString("0,0");
|
||||
rating.Maximum++;
|
||||
await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.Dislike).ExecuteAsync();
|
||||
|
||||
@@ -409,7 +473,7 @@ namespace FoxTube.Pages
|
||||
|
||||
case Rating.Dislike:
|
||||
dislike.Foreground = new SolidColorBrush(Colors.Gray);
|
||||
dislikes.Text = (int.Parse(dislikes.Text, System.Globalization.NumberStyles.AllowThousands) - 1).ToString("0,0");
|
||||
dislikes.Text = (int.Parse(dislikes.Text, NumberStyles.AllowThousands) - 1).ToString("0,0");
|
||||
rating.Maximum--;
|
||||
await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.None).ExecuteAsync();
|
||||
break;
|
||||
@@ -423,10 +487,10 @@ namespace FoxTube.Pages
|
||||
{
|
||||
case Rating.Dislike:
|
||||
dislike.Foreground = new SolidColorBrush(Colors.Gray);
|
||||
dislikes.Text = (int.Parse(dislikes.Text, System.Globalization.NumberStyles.AllowThousands) - 1).ToString("0,0");
|
||||
dislikes.Text = (int.Parse(dislikes.Text, NumberStyles.AllowThousands) - 1).ToString("0,0");
|
||||
|
||||
like.Foreground = new SolidColorBrush(Colors.Green);
|
||||
likes.Text = (int.Parse(likes.Text, System.Globalization.NumberStyles.AllowThousands) + 1).ToString("0,0");
|
||||
likes.Text = (int.Parse(likes.Text, NumberStyles.AllowThousands) + 1).ToString("0,0");
|
||||
rating.Value++;
|
||||
await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.Like).ExecuteAsync();
|
||||
|
||||
@@ -435,7 +499,7 @@ namespace FoxTube.Pages
|
||||
|
||||
case Rating.None:
|
||||
like.Foreground = new SolidColorBrush(Colors.Green);
|
||||
likes.Text = (int.Parse(likes.Text, System.Globalization.NumberStyles.AllowThousands) + 1).ToString("0,0");
|
||||
likes.Text = (int.Parse(likes.Text, NumberStyles.AllowThousands) + 1).ToString("0,0");
|
||||
rating.Maximum++;
|
||||
rating.Value++;
|
||||
await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.Like).ExecuteAsync();
|
||||
@@ -445,7 +509,7 @@ namespace FoxTube.Pages
|
||||
|
||||
case Rating.Like:
|
||||
like.Foreground = new SolidColorBrush(Colors.Gray);
|
||||
likes.Text = (int.Parse(likes.Text, System.Globalization.NumberStyles.AllowThousands) - 1).ToString("0,0");
|
||||
likes.Text = (int.Parse(likes.Text, NumberStyles.AllowThousands) - 1).ToString("0,0");
|
||||
rating.Maximum--;
|
||||
rating.Value--;
|
||||
await SecretsVault.Service.Videos.Rate(videoId, VideosResource.RateRequest.RatingEnum.None).ExecuteAsync();
|
||||
@@ -469,13 +533,13 @@ namespace FoxTube.Pages
|
||||
{
|
||||
subscribe.Background = new SolidColorBrush(Colors.Transparent);
|
||||
subscribe.Foreground = new SolidColorBrush(Colors.Gray);
|
||||
subscribe.Content = "Subscribed";
|
||||
subscribe.Content = resources.GetString("/Cards/unsubscribe");
|
||||
}
|
||||
else
|
||||
{
|
||||
subscribe.Background = new SolidColorBrush(Colors.Red);
|
||||
subscribe.Foreground = new SolidColorBrush(Colors.White);
|
||||
subscribe.Content = "Subscribe";
|
||||
subscribe.Content = resources.GetString("/Cards/subscribe/Content");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="channel.Text" xml:space="preserve">
|
||||
<value>View channel</value>
|
||||
</data>
|
||||
<data name="channelShare" xml:space="preserve">
|
||||
<value>channel</value>
|
||||
</data>
|
||||
<data name="getLink.Text" xml:space="preserve">
|
||||
<value>Copy link</value>
|
||||
</data>
|
||||
<data name="goesLive" xml:space="preserve">
|
||||
<value>Goes live in</value>
|
||||
</data>
|
||||
<data name="incognitoPlay.Text" xml:space="preserve">
|
||||
<value>Play incognito</value>
|
||||
</data>
|
||||
<data name="live.Text" xml:space="preserve">
|
||||
<value>LIVE</value>
|
||||
</data>
|
||||
<data name="login.Text" xml:space="preserve">
|
||||
<value>Log in</value>
|
||||
</data>
|
||||
<data name="more.Content" xml:space="preserve">
|
||||
<value>Show more</value>
|
||||
</data>
|
||||
<data name="openWeb.Text" xml:space="preserve">
|
||||
<value>Open in browser</value>
|
||||
</data>
|
||||
<data name="play.Text" xml:space="preserve">
|
||||
<value>Play</value>
|
||||
</data>
|
||||
<data name="playlist.Text" xml:space="preserve">
|
||||
<value>View playlist</value>
|
||||
</data>
|
||||
<data name="playlistShare" xml:space="preserve">
|
||||
<value>playlist</value>
|
||||
</data>
|
||||
<data name="share.Text" xml:space="preserve">
|
||||
<value>Share</value>
|
||||
</data>
|
||||
<data name="subscribe.Content" xml:space="preserve">
|
||||
<value>Subscribe</value>
|
||||
</data>
|
||||
<data name="subscribers" xml:space="preserve">
|
||||
<value>subscribers</value>
|
||||
</data>
|
||||
<data name="tomanage.Text" xml:space="preserve">
|
||||
<value>to manage your subscriptions</value>
|
||||
</data>
|
||||
<data name="unsubscribe" xml:space="preserve">
|
||||
<value>Subscribed</value>
|
||||
</data>
|
||||
<data name="upcoming" xml:space="preserve">
|
||||
<value>Upcoming</value>
|
||||
</data>
|
||||
<data name="videos" xml:space="preserve">
|
||||
<value>videos</value>
|
||||
</data>
|
||||
<data name="videoShare" xml:space="preserve">
|
||||
<value>video</value>
|
||||
</data>
|
||||
<data name="viewers" xml:space="preserve">
|
||||
<value>viewers</value>
|
||||
</data>
|
||||
<data name="views" xml:space="preserve">
|
||||
<value>views</value>
|
||||
</data>
|
||||
<data name="watched.Text" xml:space="preserve">
|
||||
<value>Watched</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,159 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="about.Header" xml:space="preserve">
|
||||
<value>About channel</value>
|
||||
</data>
|
||||
<data name="aboutTitle.Text" xml:space="preserve">
|
||||
<value>About this channel</value>
|
||||
</data>
|
||||
<data name="desc.Text" xml:space="preserve">
|
||||
<value>Description</value>
|
||||
</data>
|
||||
<data name="openWeb.Label" xml:space="preserve">
|
||||
<value>Open in browser</value>
|
||||
</data>
|
||||
<data name="playlists.Header" xml:space="preserve">
|
||||
<value>Playlists</value>
|
||||
</data>
|
||||
<data name="playlistTitle.Text" xml:space="preserve">
|
||||
<value>Playlists</value>
|
||||
</data>
|
||||
<data name="refresh.Label" xml:space="preserve">
|
||||
<value>Refresh</value>
|
||||
</data>
|
||||
<data name="regDate.Text" xml:space="preserve">
|
||||
<value>Registration date:</value>
|
||||
</data>
|
||||
<data name="search.PlaceholderText" xml:space="preserve">
|
||||
<value>Search on channel</value>
|
||||
</data>
|
||||
<data name="share.Label" xml:space="preserve">
|
||||
<value>Share</value>
|
||||
</data>
|
||||
<data name="stats.Text" xml:space="preserve">
|
||||
<value>Statistics</value>
|
||||
</data>
|
||||
<data name="videos.Header" xml:space="preserve">
|
||||
<value>Videos</value>
|
||||
</data>
|
||||
<data name="views.Text" xml:space="preserve">
|
||||
<value>Views:</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -117,28 +117,22 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="description" xml:space="preserve">
|
||||
<value>You can help us make this app even better by contributing to its development by translating this app. You can choose a brand new language to translate or edit mistakes in existing translations.</value>
|
||||
<data name="box.PlaceholderText" xml:space="preserve">
|
||||
<value>Send a message</value>
|
||||
</data>
|
||||
<data name="export" xml:space="preserve">
|
||||
<value>Export to PC (.zip)</value>
|
||||
<data name="moder.Text" xml:space="preserve">
|
||||
<value>Moderator</value>
|
||||
</data>
|
||||
<data name="guide0" xml:space="preserve">
|
||||
<value>It's quite simple:</value>
|
||||
<data name="owner.Text" xml:space="preserve">
|
||||
<value>Chat owner</value>
|
||||
</data>
|
||||
<data name="guide1" xml:space="preserve">
|
||||
<value>1. Choose language you you want to translate on</value>
|
||||
<data name="sponsor.Text" xml:space="preserve">
|
||||
<value>Sponsor</value>
|
||||
</data>
|
||||
<data name="guide2" xml:space="preserve">
|
||||
<value>2. Import language pack to your PC</value>
|
||||
<data name="verified.Text" xml:space="preserve">
|
||||
<value>Verified</value>
|
||||
</data>
|
||||
<data name="header" xml:space="preserve">
|
||||
<value>Help us translate this app</value>
|
||||
</data>
|
||||
<data name="langPlaceholder" xml:space="preserve">
|
||||
<value>Choose language...</value>
|
||||
</data>
|
||||
<data name="warning" xml:space="preserve">
|
||||
<value>Attention! This tool is used to help us to provide our app to more people from other countries. Please, don't send not done language packs. Thanks in advance ;)</value>
|
||||
<data name="welcome.Text" xml:space="preserve">
|
||||
<value>Welcome to the chat room</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -117,19 +117,64 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="comments" xml:space="preserve">
|
||||
<value>comments</value>
|
||||
</data>
|
||||
<data name="date.Text" xml:space="preserve">
|
||||
<value>Date</value>
|
||||
</data>
|
||||
<data name="deleteContent" xml:space="preserve">
|
||||
<value>Are you sure? This action cannot be undone</value>
|
||||
</data>
|
||||
<data name="deleteHeader" xml:space="preserve">
|
||||
<value>Delete comment</value>
|
||||
</data>
|
||||
<data name="edit.Text" xml:space="preserve">
|
||||
<value>Edit</value>
|
||||
</data>
|
||||
<data name="edited" xml:space="preserve">
|
||||
<value>(edited)</value>
|
||||
</data>
|
||||
<data name="editorCancel.Content" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="editorDelete.Content" xml:space="preserve">
|
||||
<value>Delete comment</value>
|
||||
</data>
|
||||
<data name="editorSubmin.Content" xml:space="preserve">
|
||||
<value>Submit</value>
|
||||
</data>
|
||||
<data name="failedEdit" xml:space="preserve">
|
||||
<value>Failed to edit your commentary. Please, try again later.</value>
|
||||
</data>
|
||||
<data name="failedReply" xml:space="preserve">
|
||||
<value>Failed to send your reply. Please, try again later.</value>
|
||||
</data>
|
||||
<data name="more.Content" xml:space="preserve">
|
||||
<value>Show more</value>
|
||||
</data>
|
||||
<data name="no" xml:space="preserve">
|
||||
<value>No</value>
|
||||
</data>
|
||||
<data name="publish" xml:space="preserve">
|
||||
<value>Publish date</value>
|
||||
</data>
|
||||
<data name="relevance.Text" xml:space="preserve">
|
||||
<value>Relevance</value>
|
||||
</data>
|
||||
<data name="reply.Text" xml:space="preserve">
|
||||
<value>Reply</value>
|
||||
</data>
|
||||
<data name="replyBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Enter your reply...</value>
|
||||
</data>
|
||||
<data name="sortBy.Text" xml:space="preserve">
|
||||
<value>Sort by: </value>
|
||||
</data>
|
||||
<data name="textbox.PlaceholderText" xml:space="preserve">
|
||||
<value>Add a public comment</value>
|
||||
</data>
|
||||
<data name="yes" xml:space="preserve">
|
||||
<value>Yes</value>
|
||||
</data>
|
||||
</root>
|
||||