Archived
1
0

Anyway, I am the only one who reads this, right?

This commit is contained in:
Michael Gordeev
2019-12-02 16:52:49 +03:00
parent acd63a948e
commit bfc8689136
40 changed files with 8722 additions and 178 deletions
+1 -25
View File
@@ -111,32 +111,8 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Google.Apis">
<Version>1.30.0-beta02</Version>
</PackageReference>
<PackageReference Include="Google.Apis.Auth">
<Version>1.30.0-beta02</Version>
</PackageReference>
<PackageReference Include="Google.Apis.Core">
<Version>1.30.0-beta02</Version>
</PackageReference>
<PackageReference Include="Google.Apis.Oauth2.v2">
<Version>1.29.2.994</Version>
</PackageReference>
<PackageReference Include="Google.Apis.YouTube.v3">
<Version>1.29.2.1006</Version>
</PackageReference>
<PackageReference Include="Microsoft.AppCenter.Analytics">
<Version>2.1.1</Version>
</PackageReference>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform"> <PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.2.8</Version> <Version>6.2.9</Version>
</PackageReference>
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications">
<Version>5.1.1</Version>
</PackageReference>
<PackageReference Include="YoutubeExplode">
<Version>4.7.6</Version>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup />
+46 -7
View File
@@ -4,8 +4,8 @@
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{797951D8-BF28-4659-BDF4-C17A583E64CD}</ProjectGuid> <ProjectGuid>{29C01E10-76E7-4527-984F-B0EEF7E1AC64}</ProjectGuid>
<OutputType>winmdobj</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>FoxTube.Core</RootNamespace> <RootNamespace>FoxTube.Core</RootNamespace>
<AssemblyName>FoxTube.Core</AssemblyName> <AssemblyName>FoxTube.Core</AssemblyName>
@@ -16,7 +16,6 @@
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion> <MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<AllowCrossPlatformRetargeting>false</AllowCrossPlatformRetargeting>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
@@ -27,6 +26,7 @@
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants> <DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<LangVersion>8.0</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
@@ -36,6 +36,7 @@
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants> <DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<LangVersion>8.0</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<PlatformTarget>x86</PlatformTarget> <PlatformTarget>x86</PlatformTarget>
@@ -46,6 +47,7 @@
<DebugType>full</DebugType> <DebugType>full</DebugType>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<LangVersion>8.0</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<PlatformTarget>x86</PlatformTarget> <PlatformTarget>x86</PlatformTarget>
@@ -56,6 +58,7 @@
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<LangVersion>8.0</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
<PlatformTarget>ARM</PlatformTarget> <PlatformTarget>ARM</PlatformTarget>
@@ -66,6 +69,7 @@
<DebugType>full</DebugType> <DebugType>full</DebugType>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<LangVersion>8.0</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
<PlatformTarget>ARM</PlatformTarget> <PlatformTarget>ARM</PlatformTarget>
@@ -76,6 +80,7 @@
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<LangVersion>8.0</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM64'">
<PlatformTarget>ARM64</PlatformTarget> <PlatformTarget>ARM64</PlatformTarget>
@@ -86,6 +91,7 @@
<DebugType>full</DebugType> <DebugType>full</DebugType>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<LangVersion>8.0</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM64'">
<PlatformTarget>ARM64</PlatformTarget> <PlatformTarget>ARM64</PlatformTarget>
@@ -96,6 +102,7 @@
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<LangVersion>8.0</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<PlatformTarget>x64</PlatformTarget> <PlatformTarget>x64</PlatformTarget>
@@ -106,6 +113,7 @@
<DebugType>full</DebugType> <DebugType>full</DebugType>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<LangVersion>8.0</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<PlatformTarget>x64</PlatformTarget> <PlatformTarget>x64</PlatformTarget>
@@ -116,23 +124,54 @@
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<LangVersion>8.0</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle> <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Class1.cs" /> <Compile Include="Helpers\Extensions.cs" />
<Compile Include="Controllers\StoreInterop.cs" /> <Compile Include="Helpers\Feedback.cs" />
<Compile Include="Helpers.cs" /> <Compile Include="Helpers\Inbox.cs" />
<Compile Include="Helpers\Metrics.cs" />
<Compile Include="Helpers\Settings.cs" />
<Compile Include="Helpers\StoreInterop.cs" />
<Compile Include="Helpers\Utils.cs" />
<Compile Include="Models\Inbox\Changelog.cs" />
<Compile Include="Models\Inbox\DeveloperMessage.cs" />
<Compile Include="Models\Inbox\InboxItem.cs" />
<Compile Include="Models\IRefreshable.cs" />
<Compile Include="Models\Notifications.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Properties\FoxTube.Core.rd.xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AngleSharp">
<Version>0.13.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.AppCenter.Analytics">
<Version>2.6.1</Version>
</PackageReference>
<PackageReference Include="Microsoft.AppCenter.Crashes">
<Version>2.6.1</Version>
</PackageReference>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform"> <PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.2.9</Version> <Version>6.2.9</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Services.Store.Engagement">
<Version>10.1901.28001</Version>
</PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Models\" /> <WCFMetadata Include="Connected Services\" />
</ItemGroup>
<ItemGroup>
<SDKReference Include="Microsoft.Services.Store.Engagement, Version=10.0">
<Name>Microsoft Engagement Framework</Name>
</SDKReference>
<SDKReference Include="Microsoft.VCLibs, Version=14.0">
<Name>Visual C++ 2015 Runtime for Universal Windows Platform Apps</Name>
</SDKReference>
</ItemGroup> </ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' "> <PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion> <VisualStudioVersion>14.0</VisualStudioVersion>
-14
View File
@@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FoxTube.Core
{
public static class Helpers
{
public static Uri ToUri(this string str) =>
string.IsNullOrWhiteSpace(str) ? null : new Uri(str);
}
}
+49
View File
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Windows.Data.Xml.Dom;
using Windows.UI;
namespace FoxTube
{
public static class Extensions
{
public static Uri ToUri(this string url)
{
try { return new Uri(url); }
catch { return null; }
}
public static XmlDocument ToXml(this string text)
{
XmlDocument doc = new XmlDocument();
try
{
doc.LoadXml(text);
return doc;
}
catch { return null; }
}
public static bool Belongs<T>(this T obj, params T[] args) =>
args.Contains(obj);
public static string ToHex(this Color color) =>
$"#{color.R:X}{color.G:X}{color.B:X}";
public static Color FromHex(this Color parent, string hex)
{
hex = hex.Replace("#", "");
List<byte> values = new List<byte>();
for(int k = 0; k < hex.Length; k++)
values.Add(byte.Parse(string.Join("", hex[k], hex[++k]), System.Globalization.NumberStyles.HexNumber));
return hex.Length switch
{
6 => Color.FromArgb(255, values[0], values[1], values[2]),
8 => Color.FromArgb(values[0], values[1], values[2], values[3]),
_ => Colors.Black
};
}
}
}
+52
View File
@@ -0,0 +1,52 @@
using System;
using Microsoft.Services.Store.Engagement;
using Windows.UI.Popups;
namespace FoxTube.Core.Helpers
{
public static class Feedback
{
public static bool HasFeedbackHub => StoreServicesFeedbackLauncher.IsSupported();
public static async void OpenFeedbackHub()
{
if (HasFeedbackHub)
await StoreServicesFeedbackLauncher.GetDefault().LaunchAsync();
}
public static async void PromptFeedback()
{
if (!HasFeedbackHub)
{
Settings.PromptFeedback = false;
return;
}
MessageDialog dialog = new MessageDialog("Have some thoughts to share about the app or any suggestions? Leave feedback!");
dialog.Commands.Add(new UICommand("Don't ask me anymore", (command) => Settings.PromptFeedback = false));
dialog.Commands.Add(new UICommand("Maybe later"));
dialog.Commands.Add(new UICommand("Sure!", (command) =>
{
Settings.PromptFeedback = false;
OpenFeedbackHub();
}));
dialog.DefaultCommandIndex = 2;
dialog.CancelCommandIndex = 1;
await dialog.ShowAsync();
}
public static async void PromptReview()
{
MessageDialog dialog = new MessageDialog("Like our app? Review it on Microsoft Store!");
dialog.Commands.Add(new UICommand("Don't ask me anymore", (command) => Settings.PromptReview = false));
dialog.Commands.Add(new UICommand("Maybe later"));
dialog.Commands.Add(new UICommand("Sure!", (command) =>
{
StoreInterop.RequestReview();
Settings.PromptReview = false;
}));
dialog.DefaultCommandIndex = 2;
dialog.CancelCommandIndex = 1;
await dialog.ShowAsync();
}
}
}
+137
View File
@@ -0,0 +1,137 @@
using FoxTube.Core.Models;
using FoxTube.Core.Models.Inbox;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Windows.Data.Xml.Dom;
using Windows.Storage;
using Windows.UI.Notifications;
namespace FoxTube.Core.Helpers
{
public static class Inbox
{
static HttpClient client = new HttpClient();
static ApplicationDataContainer storage = ApplicationData.Current.RoamingSettings;
public static async Task<List<InboxItem>>GetInbox()
{
List<InboxItem> list = new List<InboxItem>();
list.AddRange(await GetMessages());
list.AddRange(await GetChangelogs());
list.OrderByDescending(i => i.TimeStamp);
return list;
}
public static async void PushNew()
{
try
{
// TODO: Add backend
HttpResponseMessage response = await client.GetAsync("https://xfox111.net/FoxTube/Messages?toast=true&publishedAfter=" + storage.Values["Inbox.lastCheck"] + "&lang=" + Settings.Language);
if (response.StatusCode == System.Net.HttpStatusCode.NoContent)
return;
XmlDocument doc = new XmlDocument();
doc.LoadXml(await response.Content.ReadAsStringAsync());
foreach (IXmlNode toast in doc.LastChild.ChildNodes)
ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification(toast.GetXml().ToXml()));
storage.Values["Inbox.lastCheck"] = DateTime.Now;
}
catch (Exception e)
{
Metrics.AddEvent("Unable to retrieve developers' messages",
("Exception", e.GetType().ToString()),
("Message", e.Message),
("App version", Metrics.CurrentVersion),
("StackTrace", e.StackTrace));
}
}
static async Task<List<Changelog>>GetChangelogs()
{
List<Changelog> list = new List<Changelog>();
try
{
// TODO: Add backend
HttpResponseMessage response = await client.GetAsync("https://xfox111.net/FoxTube/Changelogs?lang=" + Settings.Language);
if (response.StatusCode == System.Net.HttpStatusCode.NoContent)
return list;
dynamic responseObj = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
foreach (var item in responseObj)
list.Add(new Changelog(item.Version, item.Content, item.Description, item.TimeStamp));
}
catch (Exception e)
{
Metrics.AddEvent("Unable to retrieve changelogs",
("Exception", e.GetType().ToString()),
("Message", e.Message),
("App version", Metrics.CurrentVersion),
("StackTrace", e.StackTrace));
}
return list;
}
static async Task<List<DeveloperMessage>>GetMessages()
{
List<DeveloperMessage> list = new List<DeveloperMessage>();
try
{
// TODO: Add backend
HttpResponseMessage response = await client.GetAsync("https://xfox111.net/FoxTube/Messages?lang=" + Settings.Language);
if (response.StatusCode == System.Net.HttpStatusCode.NoContent)
return list;
dynamic responseObj = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
foreach (var item in responseObj)
list.Add(new DeveloperMessage(item.Id, item.Title, item.Content, item.TimeStamp, item.Avatar));
}
catch (Exception e)
{
Metrics.AddEvent("Unable to retrieve developers' messages",
("Exception", e.GetType().ToString()),
("Message", e.Message),
("App version", Metrics.CurrentVersion),
("StackTrace", e.StackTrace));
}
return list;
}
/// <summary>
/// Fires toast notification with the last changelog content
/// </summary>
public static async void PushChangelog()
{
try
{
// TODO: Add backend
Settings.LastReviewedVersion = Metrics.CurrentVersion;
HttpResponseMessage response = await client.GetAsync("https://xfox111.net/FoxTube/Changelogs?toast=true&lang=" + Settings.Language + "&version=" + Metrics.CurrentVersion);
if (response.StatusCode == System.Net.HttpStatusCode.NoContent)
return;
ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification((await response.Content.ReadAsStringAsync()).ToXml()));
}
catch (Exception e)
{
Metrics.AddEvent("Unable to retrieve changelog",
("Exception", e.GetType().ToString()),
("Message", e.Message),
("App version", Metrics.CurrentVersion),
("StackTrace", e.StackTrace));
}
}
}
}
+76
View File
@@ -0,0 +1,76 @@
using Microsoft.AppCenter;
using Microsoft.AppCenter.Analytics;
using Microsoft.AppCenter.Crashes;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.Storage;
namespace FoxTube
{
public static class Metrics
{
static readonly ApplicationDataContainer storage = ApplicationData.Current.RoamingSettings;
static readonly Stopwatch sw = new Stopwatch();
public static TimeSpan Uptime
{
get => (TimeSpan?)storage.Values["Metrics.SpentTime"] ?? TimeSpan.FromSeconds(0);
set => storage.Values["Metrics.SpentTime"] = value;
}
public static string CurrentVersion
{
get
{
PackageVersion v = Package.Current.Id.Version;
return $"{v.Major}.{v.Minor}.{v.Revision}.{v.Build}";
}
}
public static void StartSession()
{
sw.Start();
AppCenter.Start("45774462-9ea7-438a-96fc-03982666f39e", typeof(Analytics), typeof(Crashes));
AppCenter.SetCountryCode(Settings.Region);
}
public static void EndSession()
{
sw.Stop();
Uptime += sw.Elapsed;
AddEvent("Session closed",
("Duration", sw.Elapsed.ToString()),
("Spend time total", Uptime.ToString()));
}
public static void AddEvent(string eventName, params (string key, string value)[] details)
{
Dictionary<string, string> parameters = new Dictionary<string, string>();
foreach (var (key, value) in details)
parameters.Add(key, value);
Analytics.TrackEvent(eventName, parameters.Count > 0 ? parameters : null);
}
public static async Task<string> SendExtendedData(string packageTitle, string content)
{
// TODO: Add backend
using(HttpClient client = new HttpClient())
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://xfox111.net/FoxTube/AddMetrics");
Dictionary<string, string> body = new Dictionary<string, string>
{
{ "Title", packageTitle },
{ "Content", content },
{ "Version", CurrentVersion }
};
request.Content = new FormUrlEncodedContent(body);
HttpResponseMessage response = await client.SendAsync(request);
return await response.Content.ReadAsStringAsync();
}
}
}
}
+118
View File
@@ -0,0 +1,118 @@
using System.Globalization;
using Windows.Storage;
namespace FoxTube
{
public static class Settings
{
static readonly ApplicationDataContainer settings = ApplicationData.Current.RoamingSettings;
public static string DesiredVideoQuality
{
get => (string)settings.Values["DesiredVideoQuality"] ?? "auto";
set => settings.Values["DesiredVideoQuality"] = value;
}
public static string RememberedQuality
{
get => (string)settings.Values["RememberedVideoQuality"] ?? "1080p";
set => settings.Values["RememberedVideoQuality"] = value;
}
public static bool VideoNotifications
{
get => (bool?)settings.Values["NewVideosNotificationsAll"] ?? true;
set => settings.Values["NewVideosNotificationsAll"] = value;
}
public static bool DevNotifications
{
get => (bool?)settings.Values["DevelopersNewsNotifications"] ?? true;
set => settings.Values["DevelopersNewsNotifications"] = value;
}
public static bool CheckConnection
{
get => (bool?)settings.Values["WarnIfOnMeteredConnection"] ?? false;
set => settings.Values["WarnIfOnMeteredConnection"] = value;
}
public static bool Autoplay
{
get => (bool?)settings.Values["VideoAutoplay"] ?? true;
set => settings.Values["VideoAutoplay"] = value;
}
public static double Volume
{
get => (double?)settings.Values["Volume"] ?? 1;
set => settings.Values["Volume"] = value;
}
public static string Language
{
get => (string)settings.Values["InterfaceLanguage"] ?? GetDefaultLanguage();
set => settings.Values["InterfaceLanguage"] = value;
}
public static string RelevanceLanguage
{
get => (string)settings.Values["DesiredContentLanguage"] ?? CultureInfo.InstalledUICulture.TwoLetterISOLanguageName;
set => settings.Values["DesiredContentLanguage"] = value;
}
public static string Region
{
get => (string)settings.Values["Region"] ?? CultureInfo.InstalledUICulture.Name.Split('-')[1];
set => settings.Values["Region"] = value;
}
public static int SafeSearch
{
get => (int?)settings.Values["SafeSearch"] ?? 0; //Moderate
set => settings.Values["SafeSearch"] = value;
}
public static bool BlockExplicitContent
{
get => (bool?)settings.Values["BlockExplicitContent"] ?? true;
set => settings.Values["BlockExplicitContent"] = value;
}
public static bool HasAccount
{
get => (bool?)settings.Values["HasAccount"] ?? false;
set => settings.Values["HasAccount"] = value;
}
public static int Theme
{
get => (int?)settings.Values["PreferedUITheme"] ?? 2; //System
set => settings.Values["PreferedUITheme"] = value;
}
public static bool PromptReview
{
get => (bool?)settings.Values["PromptReview"] ?? Metrics.Uptime.TotalHours > 24;
set => settings.Values["PromptReview"] = value;
}
public static bool PromptFeedback
{
get => (bool?)settings.Values["PromptFeedback"] ?? Metrics.Uptime.TotalHours > 12;
set => settings.Values["PromptFeedback"] = value;
}
public static bool ProcessClipboard
{
get => (bool?)settings.Values["ProcessClipboardEntry"] ?? true;
set => settings.Values["ProcessClipboardEntry"] = value;
}
public static string LastReviewedVersion
{
get
{
if (settings.Values["LastReviewedVersion"] == null)
settings.Values["LastReviewedVersion"] = Metrics.CurrentVersion;
return (string)settings.Values["LastReviewedVersion"];
}
set => settings.Values["LastReviewedVersion"] = value;
}
static string GetDefaultLanguage()
{
if (CultureInfo.InstalledUICulture.TwoLetterISOLanguageName.Belongs("ua", "ru", "by", "kz", "kg", "md", "lv", "ee")) //Languages for Russian-speaking countries
return "ru-RU";
else
return "en-US";
}
public static void ResetSettings() =>
settings.Values.Clear();
}
}
@@ -2,7 +2,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Windows.Services.Store; using Windows.Services.Store;
namespace FoxTube.Core.Controllers namespace FoxTube.Core.Helpers
{ {
public static class StoreInterop public static class StoreInterop
{ {
@@ -34,5 +34,15 @@ namespace FoxTube.Core.Controllers
return false; return false;
} }
} }
public static async void RequestReview()
{
StoreRateAndReviewResult result = await StoreContext.GetDefault().RequestRateAndReviewAppAsync();
string attachedPackageId = result.Status == StoreRateAndReviewStatus.Error ? await Metrics.SendExtendedData("StoreReviewRequestError", result.ExtendedJsonData) : "Success";
Metrics.AddEvent("Store review request has been recieved",
("Result", result.Status.ToString()),
("ErrorData", attachedPackageId));
}
} }
} }
+36
View File
@@ -0,0 +1,36 @@
using System;
using System.Net.Http;
using Windows.ApplicationModel.Core;
using Windows.UI.Notifications;
namespace FoxTube.Core.Helpers
{
public static class Utils
{
/// <summary>
/// Terminates current application session
/// </summary>
public static void CloseApp() =>
CoreApplication.Exit();
/// <summary>
/// Restarts application
/// </summary>
public static void RestartApp() =>
RestartApp(null);
/// <summary>
/// Restarts application with specified parameters
/// </summary>
/// <param name="args">Parameters which will be provided to new application instance</param>
public static async void RestartApp(string args) =>
await CoreApplication.RequestRestartAsync(args);
public static void InitializeFailsafeProtocol()
{
Metrics.AddEvent("Failsafe protocol initiated");
Settings.ResetSettings();
RestartApp();
}
}
}
@@ -4,9 +4,10 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace FoxTube.Core namespace FoxTube.Core.Models
{ {
public sealed class Class1 public interface IRefreshable
{ {
void RefreshPage();
} }
} }
+19
View File
@@ -0,0 +1,19 @@
using System;
namespace FoxTube.Core.Models.Inbox
{
public class Changelog : InboxItem
{
public override string DefaultIcon => "\xE728";
public override string Title => "What's new in version " + Id;
public override string Type => "Changelog";
public Changelog(string version, string content, string description, DateTime timeStamp)
{
Id = version;
Content = content;
Description = description;
TimeStamp = timeStamp;
}
}
}
@@ -0,0 +1,22 @@
using System;
namespace FoxTube.Core.Models.Inbox
{
public class DeveloperMessage : InboxItem
{
public override string DefaultIcon => "\xE119";
public override string Title => _title;
string _title;
public override string Type => "Message from developers";
public DeveloperMessage(string id, string title, string content, DateTime timeStamp, string avatar)
{
Id = id;
_title = title;
Content = content;
Description = content;
TimeStamp = timeStamp;
Avatar = avatar;
}
}
}
+17
View File
@@ -0,0 +1,17 @@
using System;
namespace FoxTube.Core.Models
{
public abstract class InboxItem
{
public string Id { get; set; }
public abstract string DefaultIcon { get; }
public string Avatar { get; set; }
public abstract string Title { get; }
public string Description { get; set; }
public string Content { get; set; }
public DateTime TimeStamp { get; set; }
public abstract string Type { get; }
}
}
+27
View File
@@ -0,0 +1,27 @@
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
namespace FoxTube.Core.Models
{
public static class Notifications
{
public static ToastNotification GetChangelogToast(string version)
{
XmlDocument template = new XmlDocument();
// TODO: Add backend
template.LoadXml($@"<toast activationType='foreground' launch='changelog|{version}'>
<visual>
<binding template='ToastGeneric'>
<image placement='hero' src='https://xfox111.net/FoxTube/Thumbnails/Changelog?ver={version}'/>
<image placement='appLogoOverride' hint-crop='circle' src='https://xfox111.net/FoxTube/Avatars/Changelog'/>
<text>Changelog</text>
<text>See what's new in {version}</text>
</binding>
</visual>
</toast>");
return new ToastNotification(template);
}
}
}
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file contains Runtime Directives, specifications about types your application accesses
through reflection and other dynamic code patterns. Runtime Directives are used to control the
.NET Native optimizer and ensure that it does not remove code accessed by your library. If your
library does not do any reflection, then you generally do not need to edit this file. However,
if your library reflects over types, especially types passed to it or derived from its types,
then you should write Runtime Directives.
The most common use of reflection in libraries is to discover information about types passed
to the library. Runtime Directives have three ways to express requirements on types passed to
your library.
1. Parameter, GenericParameter, TypeParameter, TypeEnumerableParameter
Use these directives to reflect over types passed as a parameter.
2. SubTypes
Use a SubTypes directive to reflect over types derived from another type.
3. AttributeImplies
Use an AttributeImplies directive to indicate that your library needs to reflect over
types or methods decorated with an attribute.
For more information on writing Runtime Directives for libraries, please visit
https://go.microsoft.com/fwlink/?LinkID=391919
-->
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Library Name="FoxTube.Core">
<!-- add directives for your library here -->
</Library>
</Directives>
+21 -21
View File
@@ -9,7 +9,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoxTube.Background", "FoxTu
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoxTube.Tests", "FoxTube.Tests\FoxTube.Tests.csproj", "{3D864717-2D87-4E54-BFC0-755FC2FCA2A7}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoxTube.Tests", "FoxTube.Tests\FoxTube.Tests.csproj", "{3D864717-2D87-4E54-BFC0-755FC2FCA2A7}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoxTube.Core", "FoxTube.Core\FoxTube.Core.csproj", "{797951D8-BF28-4659-BDF4-C17A583E64CD}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoxTube.Core", "FoxTube.Core\FoxTube.Core.csproj", "{29C01E10-76E7-4527-984F-B0EEF7E1AC64}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -93,26 +93,26 @@ Global
{3D864717-2D87-4E54-BFC0-755FC2FCA2A7}.Release|x86.ActiveCfg = Release|x86 {3D864717-2D87-4E54-BFC0-755FC2FCA2A7}.Release|x86.ActiveCfg = Release|x86
{3D864717-2D87-4E54-BFC0-755FC2FCA2A7}.Release|x86.Build.0 = Release|x86 {3D864717-2D87-4E54-BFC0-755FC2FCA2A7}.Release|x86.Build.0 = Release|x86
{3D864717-2D87-4E54-BFC0-755FC2FCA2A7}.Release|x86.Deploy.0 = Release|x86 {3D864717-2D87-4E54-BFC0-755FC2FCA2A7}.Release|x86.Deploy.0 = Release|x86
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Debug|Any CPU.Build.0 = Debug|Any CPU {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Debug|Any CPU.Build.0 = Debug|Any CPU
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Debug|ARM.ActiveCfg = Debug|ARM {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Debug|ARM.ActiveCfg = Debug|ARM
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Debug|ARM.Build.0 = Debug|ARM {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Debug|ARM.Build.0 = Debug|ARM
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Debug|ARM64.ActiveCfg = Debug|ARM64 {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Debug|ARM64.ActiveCfg = Debug|ARM64
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Debug|ARM64.Build.0 = Debug|ARM64 {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Debug|ARM64.Build.0 = Debug|ARM64
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Debug|x64.ActiveCfg = Debug|x64 {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Debug|x64.ActiveCfg = Debug|x64
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Debug|x64.Build.0 = Debug|x64 {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Debug|x64.Build.0 = Debug|x64
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Debug|x86.ActiveCfg = Debug|x86 {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Debug|x86.ActiveCfg = Debug|x86
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Debug|x86.Build.0 = Debug|x86 {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Debug|x86.Build.0 = Debug|x86
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Release|Any CPU.ActiveCfg = Release|Any CPU {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Release|Any CPU.ActiveCfg = Release|Any CPU
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Release|Any CPU.Build.0 = Release|Any CPU {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Release|Any CPU.Build.0 = Release|Any CPU
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Release|ARM.ActiveCfg = Release|ARM {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Release|ARM.ActiveCfg = Release|ARM
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Release|ARM.Build.0 = Release|ARM {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Release|ARM.Build.0 = Release|ARM
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Release|ARM64.ActiveCfg = Release|ARM64 {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Release|ARM64.ActiveCfg = Release|ARM64
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Release|ARM64.Build.0 = Release|ARM64 {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Release|ARM64.Build.0 = Release|ARM64
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Release|x64.ActiveCfg = Release|x64 {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Release|x64.ActiveCfg = Release|x64
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Release|x64.Build.0 = Release|x64 {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Release|x64.Build.0 = Release|x64
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Release|x86.ActiveCfg = Release|x86 {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Release|x86.ActiveCfg = Release|x86
{797951D8-BF28-4659-BDF4-C17A583E64CD}.Release|x86.Build.0 = Release|x86 {29C01E10-76E7-4527-984F-B0EEF7E1AC64}.Release|x86.Build.0 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
+21 -1
View File
@@ -6,9 +6,29 @@
<Application.Resources> <Application.Resources>
<ResourceDictionary> <ResourceDictionary>
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes/Resources.xml"/>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls"/> <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls"/>
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
<Color x:Key="SystemAccentColor">Red</Color>
<Style x:Key="HeaderButton" TargetType="Button" BasedOn="{StaticResource ButtonRevealStyle}">
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Height" Value="32"/>
<Setter Property="Width" Value="32"/>
</Style>
<Style TargetType="StackPanel">
<Setter Property="ChildrenTransitions">
<Setter.Value>
<TransitionCollection>
<EntranceThemeTransition/>
</TransitionCollection>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="Button" BasedOn="{StaticResource ButtonRevealStyle}"/>
<Style TargetType="PivotItem">
<Setter Property="Margin" Value="0"/>
</Style>
</ResourceDictionary> </ResourceDictionary>
</Application.Resources> </Application.Resources>
</Application> </Application>
+39 -2
View File
@@ -1,17 +1,29 @@
using FoxTube.Core.Controllers; using System;
using FoxTube.Core.Helpers;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation; using Windows.ApplicationModel.Activation;
using Windows.UI;
using Windows.UI.Popups;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml; using Windows.UI.Xaml;
namespace FoxTube namespace FoxTube
{ {
sealed partial class App : Application sealed partial class App : Application
{ {
public App() => public App()
{
InitializeComponent(); InitializeComponent();
Suspending += OnSuspending;
UnhandledException += ErrorOccured;
Metrics.StartSession();
}
protected override async void OnLaunched(LaunchActivatedEventArgs e) protected override async void OnLaunched(LaunchActivatedEventArgs e)
{ {
await StoreInterop.UpdateStoreState(); await StoreInterop.UpdateStoreState();
if (Settings.LastReviewedVersion != Metrics.CurrentVersion)
Inbox.PushChangelog();
if (!e.PrelaunchActivated && Window.Current.Content == null) if (!e.PrelaunchActivated && Window.Current.Content == null)
Window.Current.Content = new MainPage(); Window.Current.Content = new MainPage();
@@ -34,5 +46,30 @@ namespace FoxTube
Window.Current.Content = new MainPage(); Window.Current.Content = new MainPage();
Window.Current.Activate(); Window.Current.Activate();
} }
void OnSuspending(object sender, SuspendingEventArgs e)
{
Metrics.EndSession();
}
async void ErrorOccured(object sender, Windows.UI.Xaml.UnhandledExceptionEventArgs e)
{
Metrics.AddEvent("Application chrashed",
("Exception", e.Exception.GetType().ToString()),
("Message", e.Message),
("StackTrace", e.Exception.StackTrace));
e.Handled = true;
MessageDialog alert = new MessageDialog($"Exception: {e.Exception.GetType().ToString()}\nMessage: {e.Message}\n\nIf this happens again try to reset your app settings or report the problem",
"Unhandled error occured");
alert.Commands.Add(new UICommand("Reset application", (command) => Utils.InitializeFailsafeProtocol()));
if(Feedback.HasFeedbackHub)
alert.Commands.Add(new UICommand("Report the problem", (command) => Feedback.OpenFeedbackHub()));
alert.Commands.Add(new UICommand("Close"));
alert.DefaultCommandIndex = 0;
alert.CancelCommandIndex = 2;
await alert.ShowAsync();
}
} }
} }
+2 -3
View File
@@ -1,5 +1,4 @@
using FoxTube.Controls.Cards; using FoxTube.Controls.Cards;
using FoxTube.Core.Controllers;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
@@ -17,8 +16,8 @@ namespace FoxTube.Controls
{ {
empty.Opacity = 0; empty.Opacity = 0;
if (!StoreInterop.AdsDisabled && ItemsCount % 5 == 0 && ItemsCount > 0) //if (!StoreInterop.AdsDisabled && ItemsCount % 5 == 0 && ItemsCount > 0)
Items.Add(new AdvertCard()); // Items.Add(new AdvertCard());
Items.Add(item); Items.Add(item);
} }
+35 -44
View File
@@ -123,7 +123,6 @@
<Compile Include="Controls\ItemsGrid.xaml.cs"> <Compile Include="Controls\ItemsGrid.xaml.cs">
<DependentUpon>ItemsGrid.xaml</DependentUpon> <DependentUpon>ItemsGrid.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Helpers\Utils.cs" />
<Compile Include="MainPage.xaml.cs"> <Compile Include="MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon> <DependentUpon>MainPage.xaml</DependentUpon>
</Compile> </Compile>
@@ -131,6 +130,21 @@
<Compile Include="Views\Home.xaml.cs"> <Compile Include="Views\Home.xaml.cs">
<DependentUpon>Home.xaml</DependentUpon> <DependentUpon>Home.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\Settings.xaml.cs">
<DependentUpon>Settings.xaml</DependentUpon>
</Compile>
<Compile Include="Views\SettingsSections\About.xaml.cs">
<DependentUpon>About.xaml</DependentUpon>
</Compile>
<Compile Include="Views\SettingsSections\General.xaml.cs">
<DependentUpon>General.xaml</DependentUpon>
</Compile>
<Compile Include="Views\SettingsSections\Inbox.xaml.cs">
<DependentUpon>Inbox.xaml</DependentUpon>
</Compile>
<Compile Include="Views\SettingsSections\Translate.xaml.cs">
<DependentUpon>Translate.xaml</DependentUpon>
</Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<AppxManifest Include="Package.appxmanifest"> <AppxManifest Include="Package.appxmanifest">
@@ -228,64 +242,44 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Themes\Resources.xaml"> <Page Include="Views\Home.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Views\Home.xaml"> <Page Include="Views\Settings.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\SettingsSections\About.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\SettingsSections\General.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\SettingsSections\Inbox.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\SettingsSections\Translate.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AngleSharp">
<Version>0.13.0</Version>
</PackageReference>
<PackageReference Include="Google.Apis">
<Version>1.40.3</Version>
</PackageReference>
<PackageReference Include="Google.Apis.Auth">
<Version>1.40.3</Version>
</PackageReference>
<PackageReference Include="Google.Apis.Core">
<Version>1.40.3</Version>
</PackageReference>
<PackageReference Include="Google.Apis.Oauth2.v2">
<Version>1.40.3.1602</Version>
</PackageReference>
<PackageReference Include="Google.Apis.YouTube.v3">
<Version>1.40.3.1663</Version>
</PackageReference>
<PackageReference Include="Microsoft.Advertising.XAML"> <PackageReference Include="Microsoft.Advertising.XAML">
<Version>10.1811.22001</Version> <Version>10.1811.22001</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.AppCenter.Analytics">
<Version>2.5.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform"> <PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.2.9</Version> <Version>6.2.9</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Services.Store.Engagement">
<Version>10.1901.28001</Version>
</PackageReference>
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications">
<Version>5.1.1</Version>
</PackageReference>
<PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls"> <PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls">
<Version>5.1.1</Version> <Version>6.0.0</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.UI.Xaml"> <PackageReference Include="Microsoft.UI.Xaml">
<Version>2.2.190917002</Version> <Version>2.2.190917002</Version>
</PackageReference> </PackageReference>
<PackageReference Include="runtime.win10-arm64.runtime.native.System.IO.Compression">
<Version>4.3.2</Version>
</PackageReference>
<PackageReference Include="System.IO.Compression.ZipFile">
<Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="YoutubeExplode">
<Version>4.7.10</Version>
</PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\FoxTube.Background\FoxTube.Background.csproj"> <ProjectReference Include="..\FoxTube.Background\FoxTube.Background.csproj">
@@ -293,7 +287,7 @@
<Name>FoxTube.Background</Name> <Name>FoxTube.Background</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\FoxTube.Core\FoxTube.Core.csproj"> <ProjectReference Include="..\FoxTube.Core\FoxTube.Core.csproj">
<Project>{797951d8-bf28-4659-bdf4-c17a583e64cd}</Project> <Project>{29c01e10-76e7-4527-984f-b0eef7e1ac64}</Project>
<Name>FoxTube.Core</Name> <Name>FoxTube.Core</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
@@ -301,9 +295,6 @@
<SDKReference Include="Microsoft.Advertising.Xaml, Version=10.0"> <SDKReference Include="Microsoft.Advertising.Xaml, Version=10.0">
<Name>Microsoft Advertising SDK for XAML</Name> <Name>Microsoft Advertising SDK for XAML</Name>
</SDKReference> </SDKReference>
<SDKReference Include="Microsoft.Services.Store.Engagement, Version=10.0">
<Name>Microsoft Engagement Framework</Name>
</SDKReference>
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup />
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' "> <PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
-23
View File
@@ -1,23 +0,0 @@
using Microsoft.Services.Store.Engagement;
using System;
using Windows.ApplicationModel.Core;
namespace FoxTube.Helpers
{
public static class Utils
{
public static bool HasFeedbackHub => StoreServicesFeedbackLauncher.IsSupported();
public static async void OpenFeedbackHub()
{
if(HasFeedbackHub)
await StoreServicesFeedbackLauncher.GetDefault().LaunchAsync();
}
public static void CloseApp() =>
CoreApplication.Exit();
public static async void RestartApp(string args = "") =>
await CoreApplication.RequestRestartAsync(args);
}
}
+7 -2
View File
@@ -9,7 +9,7 @@
xmlns:controls="using:FoxTube.Controls" xmlns:controls="using:FoxTube.Controls"
xmlns:toolkit="using:Microsoft.Toolkit.Uwp.UI.Controls"> xmlns:toolkit="using:Microsoft.Toolkit.Uwp.UI.Controls">
<Page.Background> <Page.Background>
<AcrylicBrush BackgroundSource="HostBackdrop" TintColor="{ThemeResource SystemColorBackgroundColor}" TintOpacity=".5"/> <AcrylicBrush BackgroundSource="HostBackdrop" TintColor="{ThemeResource SystemAltHighColor}" TintOpacity=".5"/>
</Page.Background> </Page.Background>
<Grid> <Grid>
@@ -81,11 +81,16 @@
<FontIcon Glyph="&#xED15;" Margin="0,0,-10,0"/> <FontIcon Glyph="&#xED15;" Margin="0,0,-10,0"/>
</AppBarButton.Icon> </AppBarButton.Icon>
</AppBarButton> </AppBarButton>
<AppBarButton x:Name="refresh" Click="Refresh_Click" Visibility="Collapsed">
<AppBarButton.Icon>
<SymbolIcon Symbol="Refresh" Margin="0,0,-10,0"/>
</AppBarButton.Icon>
</AppBarButton>
<controls:AccountManager x:Name="AccountsSelector"/> <controls:AccountManager x:Name="AccountsSelector"/>
</CommandBar> </CommandBar>
</Grid> </Grid>
<Frame x:Name="content" Grid.Row="1"/> <Frame x:Name="content" Grid.Row="1" Navigated="Content_Navigated"/>
<Frame x:Name="video" Grid.Row="1" Visibility="Collapsed"/> <Frame x:Name="video" Grid.Row="1" Visibility="Collapsed"/>
<toolkit:Loading IsLoading="False" x:Name="loading" VerticalContentAlignment="Center" Grid.RowSpan="2"> <toolkit:Loading IsLoading="False" x:Name="loading" VerticalContentAlignment="Center" Grid.RowSpan="2">
+35 -11
View File
@@ -1,5 +1,5 @@
using FoxTube.Core.Controllers; using FoxTube.Core.Helpers;
using FoxTube.Helpers; using FoxTube.Core.Models;
using FoxTube.Views; using FoxTube.Views;
using System; using System;
using Windows.ApplicationModel.Core; using Windows.ApplicationModel.Core;
@@ -9,19 +9,25 @@ using Windows.UI.Popups;
using Windows.UI.ViewManagement; using Windows.UI.ViewManagement;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace FoxTube namespace FoxTube
{ {
public sealed partial class MainPage : Page public sealed partial class MainPage : Page
{ {
static MainPage Current { get; set; } public static MainPage Current { get; set; }
public MainPage() public MainPage()
{ {
Current = this; Current = this;
InitializeComponent(); InitializeComponent();
if (Settings.Theme == 0)
RequestedTheme = ElementTheme.Light;
else if (Settings.Theme == 1)
RequestedTheme = ElementTheme.Dark;
// TODO: Remove this // TODO: Remove this
content.Navigate(typeof(Home)); content.Navigate(typeof(Views.Settings));
Window.Current.SetTitleBar(AppTitleBar); Window.Current.SetTitleBar(AppTitleBar);
@@ -29,20 +35,27 @@ namespace FoxTube
ApplicationViewTitleBar titleBar = ApplicationView.GetForCurrentView().TitleBar; ApplicationViewTitleBar titleBar = ApplicationView.GetForCurrentView().TitleBar;
titleBar.ButtonBackgroundColor = Colors.Transparent; titleBar.ButtonBackgroundColor = Colors.Transparent;
titleBar.ButtonHoverForegroundColor = Colors.White;
titleBar.ButtonPressedForegroundColor = Colors.White;
titleBar.ButtonHoverBackgroundColor = Color.FromArgb(50, 255, 255, 255); titleBar.ButtonHoverBackgroundColor = Color.FromArgb(50, 255, 255, 255);
titleBar.ButtonPressedBackgroundColor = Color.FromArgb(20, 255, 255, 255); titleBar.ButtonPressedBackgroundColor = Color.FromArgb(20, 255, 255, 255);
if (Application.Current.RequestedTheme == ApplicationTheme.Dark) if (RequestedTheme == ElementTheme.Default)
titleBar.ButtonForegroundColor = Colors.White; titleBar.ButtonForegroundColor =
titleBar.ButtonHoverForegroundColor =
titleBar.ButtonPressedForegroundColor = Application.Current.RequestedTheme == ApplicationTheme.Dark ? Colors.White : Colors.Black;
else else
titleBar.ForegroundColor = Colors.Black; titleBar.ButtonForegroundColor =
titleBar.ButtonHoverForegroundColor =
titleBar.ButtonPressedForegroundColor = RequestedTheme == ElementTheme.Dark ? Colors.White : Colors.Black;
LeaveFeedback.Visibility = Utils.HasFeedbackHub ? Visibility.Visible : Visibility.Collapsed; LeaveFeedback.Visibility = Feedback.HasFeedbackHub ? Visibility.Visible : Visibility.Collapsed;
RemoveAds.Visibility = StoreInterop.AdsDisabled ? Visibility.Collapsed : Visibility.Visible; RemoveAds.Visibility = StoreInterop.AdsDisabled ? Visibility.Collapsed : Visibility.Visible;
if (!StoreInterop.AdsDisabled) if (!StoreInterop.AdsDisabled)
RemoveAds.Content += $" ({StoreInterop.Price})"; RemoveAds.Content += $" ({StoreInterop.Price})";
if (Settings.PromptReview)
Feedback.PromptReview();
if (Settings.PromptFeedback)
Feedback.PromptFeedback();
} }
void NavigationView_DisplayModeChanged(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewDisplayModeChangedEventArgs args) void NavigationView_DisplayModeChanged(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewDisplayModeChangedEventArgs args)
@@ -87,7 +100,7 @@ namespace FoxTube
} }
void LeaveFeedback_Click(object sender, RoutedEventArgs e) => void LeaveFeedback_Click(object sender, RoutedEventArgs e) =>
Utils.OpenFeedbackHub(); Feedback.OpenFeedbackHub();
async void RemoveAds_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e) async void RemoveAds_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
{ {
@@ -107,5 +120,16 @@ namespace FoxTube
{ {
} }
void Content_Navigated(object sender, NavigationEventArgs e) =>
refresh.Visibility = (e.Content is IRefreshable) ? Visibility.Visible : Visibility.Collapsed;
void Refresh_Click(object sender, RoutedEventArgs e)
{
if (video.Content != null)
(video.Content as IRefreshable)?.RefreshPage();
else
(content.Content as IRefreshable)?.RefreshPage();
}
} }
} }
-18
View File
@@ -1,18 +0,0 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Color x:Key="SystemAccentColor">Red</Color>
<Style x:Key="HeaderButton" TargetType="Button" BasedOn="{StaticResource ButtonRevealStyle}">
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Height" Value="32"/>
<Setter Property="Width" Value="32"/>
</Style>
<Style TargetType="Button" BasedOn="{StaticResource ButtonRevealStyle}"/>
<Style TargetType="PivotItem">
<Setter Property="Margin" Value="0"/>
</Style>
</ResourceDictionary>
+3 -3
View File
@@ -10,7 +10,7 @@
mc:Ignorable="d"> mc:Ignorable="d">
<Pivot> <Pivot>
<PivotItem Header="Recommended" Margin="0"> <PivotItem Header="Recommended">
<Grid> <Grid>
<RefreshContainer> <RefreshContainer>
<ScrollViewer Padding="5,0"> <ScrollViewer Padding="5,0">
@@ -25,7 +25,7 @@
</toolkit:Loading> </toolkit:Loading>
</Grid> </Grid>
</PivotItem> </PivotItem>
<PivotItem Header="Trending" Margin="0"> <PivotItem Header="Trending">
<Grid> <Grid>
<RefreshContainer> <RefreshContainer>
<ScrollViewer Padding="5,0"> <ScrollViewer Padding="5,0">
@@ -40,7 +40,7 @@
</toolkit:Loading> </toolkit:Loading>
</Grid> </Grid>
</PivotItem> </PivotItem>
<PivotItem Header="Subscriptions" Margin="0"> <PivotItem Header="Subscriptions">
<Grid> <Grid>
<RefreshContainer> <RefreshContainer>
<ScrollViewer Padding="5,0"> <ScrollViewer Padding="5,0">
+7 -1
View File
@@ -1,4 +1,5 @@
using FoxTube.Controls.Cards; using FoxTube.Controls.Cards;
using FoxTube.Core.Models;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation; using Windows.UI.Xaml.Navigation;
@@ -9,11 +10,16 @@ namespace FoxTube.Views
/// <summary> /// <summary>
/// An empty page that can be used on its own or navigated to within a Frame. /// An empty page that can be used on its own or navigated to within a Frame.
/// </summary> /// </summary>
public sealed partial class Home : Page public sealed partial class Home : Page, IRefreshable
{ {
public Home() => public Home() =>
InitializeComponent(); InitializeComponent();
public void RefreshPage()
{
throw new System.NotImplementedException();
}
protected override void OnNavigatedTo(NavigationEventArgs e) protected override void OnNavigatedTo(NavigationEventArgs e)
{ {
base.OnNavigatedTo(e); base.OnNavigatedTo(e);
+38
View File
@@ -0,0 +1,38 @@
<Page
x:Class="FoxTube.Views.Settings"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:settingssections="using:FoxTube.Views.SettingsSections"
mc:Ignorable="d">
<Page.Resources>
<Style TargetType="ScrollViewer">
<Setter Property="Padding" Value="10,0"/>
</Style>
</Page.Resources>
<Pivot SelectedIndex="0" Name="pivot" IsHeaderItemsCarouselEnabled="False" SelectionChanged="Pivot_SelectionChanged">
<PivotItem Name="generalTab" Header="General">
<ScrollViewer>
<settingssections:General/>
</ScrollViewer>
</PivotItem>
<PivotItem Name="aboutTab" Header="About us">
<ScrollViewer>
<settingssections:About/>
</ScrollViewer>
</PivotItem>
<PivotItem Name="translateTab" Header="Help us translate this app">
<ScrollViewer>
<settingssections:Translate/>
</ScrollViewer>
</PivotItem>
<PivotItem Name="inboxTab" Header="Inbox">
<ScrollViewer>
<settingssections:Inbox x:Name="inbox"/>
</ScrollViewer>
</PivotItem>
</Pivot>
</Page>
+35
View File
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
namespace FoxTube.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class Settings : Page
{
public Settings()
{
this.InitializeComponent();
}
void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
}
}
+62
View File
@@ -0,0 +1,62 @@
<Page
x:Class="FoxTube.Views.SettingsSections.About"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<controls:DropShadowPanel Grid.Column="1" VerticalAlignment="Top" OffsetX="5" OffsetY="5">
<Image Source="/Assets/StoreLogo.scale-400.png" Width="150"/>
</controls:DropShadowPanel>
<StackPanel>
<TextBlock Text="FoxTube" Style="{StaticResource SubheaderTextBlockStyle}"/>
<TextBlock Name="version" Text="[currentVersion]" Style="{StaticResource CaptionTextBlockStyle}" FontStyle="Italic" Margin="0,-5,0,0"/>
<TextBlock TextWrapping="WrapWholeWords" Text="Developed by Michael &#x22;XFox&#x22; Gordeev" Margin="0,10,0,0"/>
<StackPanel Margin="0,10,0,0">
<TextBlock Text="Special thanks to:" Style="{StaticResource TitleTextBlockStyle}"/>
<TextBlock>
<Hyperlink NavigateUri="https://github.com/Tyrrrz">@Tyrrrz</Hyperlink> for his awesome library
<LineBreak/><Hyperlink NavigateUri="https://vk.com/msreviewnet">@msreviewnet</Hyperlink> for warm welcome and first feedback
<LineBreak/><Hyperlink>You</Hyperlink> for using my app :)
</TextBlock>
</StackPanel>
<StackPanel Margin="0,10,0,0">
<TextBlock Text="Contacts" Style="{StaticResource TitleTextBlockStyle}"/>
<TextBlock>
Twitter: <Hyperlink NavigateUri="https://twitter.com/xfox111">@xfox111</Hyperlink>
<LineBreak/>Vkontakte: <Hyperlink NavigateUri="https://vk.com/XFox.Mike">@XFox.Mike</Hyperlink>
<!--<LineBreak/>YouTube: <Hyperlink NavigateUri="https://youtube.com/c/FoxGameStudioChannel">@xfox</Hyperlink>-->
<LineBreak/>E-mail: <Hyperlink NavigateUri="mailto:michael.xfox@outlook.com">michael.xfox@outlook.com</Hyperlink>
<LineBreak/>My website: <Hyperlink NavigateUri="https://michael-xfox.com">https://xfox111.net</Hyperlink>
</TextBlock>
</StackPanel>
<StackPanel Margin="0,10,0,0">
<TextBlock Text="Legal stuff" Style="{StaticResource TitleTextBlockStyle}"/>
<TextBlock>
<Hyperlink NavigateUri="https://xfox111.net/Projects/FoxTube/PrivacyPolicy.txt">Our Privacy Policy</Hyperlink>
<LineBreak/><Hyperlink NavigateUri="https://youtube.com/t/privacy">YouTube Privacy Policy</Hyperlink>
<LineBreak/><Hyperlink NavigateUri="https://youtube.com/t/terms">YouTube Terms of use</Hyperlink>
<LineBreak/><Hyperlink NavigateUri="https://youtube.com/t/community_guidelines">YouTube Community Guidelines</Hyperlink>
</TextBlock>
</StackPanel>
<TextBlock Name="copyrights" Margin="0,10,0,0">
©[year] Michael Gordeev
<LineBreak/>©[year] YouTube, LLC
</TextBlock>
<Button Name="feedback" Content="Leave feedback" Margin="0,10" Visibility="Collapsed" Click="OpenFeedbackHub"/>
</StackPanel>
</Grid>
</Page>
@@ -0,0 +1,27 @@
using FoxTube.Core.Helpers;
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace FoxTube.Views.SettingsSections
{
/// <summary>
/// About page
/// </summary>
public sealed partial class About : Page
{
public About()
{
InitializeComponent();
version.Text = Metrics.CurrentVersion;
copyrights.Text = copyrights.Text.Replace("[year]", DateTime.Today.Year.ToString());
if (Feedback.HasFeedbackHub)
feedback.Visibility = Visibility.Visible;
}
void OpenFeedbackHub(object sender, RoutedEventArgs e) =>
Feedback.OpenFeedbackHub();
}
}
@@ -0,0 +1,64 @@
<Page
x:Class="FoxTube.Views.SettingsSections.General"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
<StackPanel Orientation="Vertical">
<TextBlock Text="Preferences" Style="{StaticResource SubheaderTextBlockStyle}"/>
<StackPanel Margin="0,0,0,10">
<StackPanel.ChildrenTransitions>
<TransitionCollection>
<AddDeleteThemeTransition/>
</TransitionCollection>
</StackPanel.ChildrenTransitions>
<TextBlock Text="Region &#x26; search" Style="{StaticResource TitleTextBlockStyle}"/>
<ComboBox Header="App interface language" Width="250" Name="language" SelectionChanged="LanguageChanged">
<ComboBoxItem Content="English (United States)" Tag="en-US"/>
<ComboBoxItem Content="Russian (Russia)" Tag="ru-RU"/>
</ComboBox>
<Button Content="Restart application" x:Name="restart" Visibility="Collapsed" Foreground="White" Background="Red" Margin="5" Click="Restart"/>
<ComboBox Header="Search relevance language" Width="250" Name="relevanceLanguage" SelectionChanged="RelevanceLanguageChanged" Loaded="LoadRelevaneLanguageList"/>
<ComboBox Header="Region" Width="250" Name="region" SelectionChanged="RegionChanged" Loaded="LoadRegionList"/>
<ComboBox Header="SafeSearch" Width="250" Name="safeSearch" SelectionChanged="SafeSearchChanged">
<ComboBoxItem Content="Moderate"/>
<ComboBoxItem Content="None"/>
<ComboBoxItem Content="Strict"/>
</ComboBox>
</StackPanel>
<StackPanel Margin="0,0,0,10">
<TextBlock Text="Playback" Style="{StaticResource TitleTextBlockStyle}"/>
<ComboBox Width="250" Header="Default video playback quality" Name="quality" SelectionChanged="QualityChanged" Loaded="LoadQualitiesList">
<ComboBoxItem Tag="remember" Content="Remember my choice"/>
<ComboBoxItem Tag="auto" Content="Auto"/>
</ComboBox>
<ToggleSwitch OnContent="Notify when playing on metered connection" OffContent="Notify when playing on metered connection" Name="meteredWarning" Toggled="MeteredWarningChanged"/>
<ToggleSwitch OnContent="Play videos automatically" OffContent="Play videos automatically" Name="autoplay" Toggled="AutoplayChanged"/>
<ToggleSwitch OnContent="Notify before playing explicit content" OffContent="Notify before playing explicit content" Name="explicitWarning" Toggled="ExplicitWarningChanged"/>
</StackPanel>
<StackPanel Margin="0,0,0,10">
<TextBlock Text="Notifications" Style="{StaticResource TitleTextBlockStyle}"/>
<ToggleSwitch OnContent="Notify when someone of your subscriptions uploaded new video" OffContent="Notify when someone of your subscriptions uploaded new video" Name="channelNotifications" Toggled="ChannelNotificationsChanged"/>
<ToggleSwitch OnContent="Notify if I have any YouTube link on my clipboard" OffContent="Notify if I have any YouTube link on my clipboard" x:Name="clipboardProcessing" Toggled="ClipboardProcessingChanged"/>
<ToggleSwitch OnContent="Recieve messages from developers" OffContent="Recieve messages from developers" Name="developersNews" Toggled="DevelopersNotificationsChanged"/>
</StackPanel>
<StackPanel Margin="0,0,0,10">
<TextBlock Text="Theme" Style="{StaticResource TitleTextBlockStyle}"/>
<StackPanel>
<TextBlock Text="Color mode" Style="{StaticResource SubtitleTextBlockStyle}"/>
<RadioButton Content="Light" Name="light" Tag="0" GroupName="theme" Checked="ThemeChanged"/>
<RadioButton Content="Dark" Name="dark" Tag="1" GroupName="theme" Checked="ThemeChanged"/>
<RadioButton Content="Windows default" Tag="2" Name="system" GroupName="theme" Checked="ThemeChanged"/>
</StackPanel>
<HyperlinkButton Content="Windows color settings" NavigateUri="ms-settings:colors"/>
</StackPanel>
</StackPanel>
</Page>
@@ -0,0 +1,137 @@
using FoxTube.Core.Helpers;
using System.Linq;
using Windows.Globalization;
using Windows.UI;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace FoxTube.Views.SettingsSections
{
/// <summary>
/// Preferences page
/// </summary>
public sealed partial class General : Page
{
public General()
{
InitializeComponent();
language.SelectedItem = language.Items.FirstOrDefault(i => ((ComboBoxItem)i).Tag.ToString() == FoxTube.Settings.Language);
safeSearch.SelectedIndex = FoxTube.Settings.SafeSearch;
meteredWarning.IsOn = FoxTube.Settings.CheckConnection;
autoplay.IsOn = FoxTube.Settings.Autoplay;
explicitWarning.IsOn = FoxTube.Settings.BlockExplicitContent;
channelNotifications.IsOn = FoxTube.Settings.VideoNotifications;
developersNews.IsOn = FoxTube.Settings.DevNotifications;
clipboardProcessing.IsOn = FoxTube.Settings.ProcessClipboard;
switch (FoxTube.Settings.Theme)
{
case 0:
light.IsChecked = true;
break;
case 1:
dark.IsChecked = true;
break;
case 2:
system.IsChecked = true;
break;
}
}
void LoadRelevaneLanguageList(object sender, RoutedEventArgs e)
{
// TODO: Add list loading
}
void LoadRegionList(object sender, RoutedEventArgs e)
{
// TODO: Add list loading
}
void LoadQualitiesList(object sender, RoutedEventArgs e)
{
// TODO: Add qualities loading
quality.SelectedItem = quality.Items.FirstOrDefault(i => ((ComboBoxItem)i).Tag.ToString() == FoxTube.Settings.DesiredVideoQuality);
}
void LanguageChanged(object sender, SelectionChangedEventArgs e)
{
if ((language.SelectedItem as ComboBoxItem).Tag.ToString() == FoxTube.Settings.Language)
return;
ApplicationLanguages.PrimaryLanguageOverride = (language.SelectedItem as ComboBoxItem).Tag.ToString();
FoxTube.Settings.Language = (language.SelectedItem as ComboBoxItem).Tag.ToString();
restart.Visibility = Visibility.Visible;
}
void Restart(object sender, RoutedEventArgs e) =>
Utils.RestartApp();
void RelevanceLanguageChanged(object sender, SelectionChangedEventArgs e) =>
FoxTube.Settings.RelevanceLanguage = ((ComboBoxItem)relevanceLanguage.SelectedItem).Tag.ToString();
void RegionChanged(object sender, SelectionChangedEventArgs e) =>
FoxTube.Settings.Region = ((ComboBoxItem)region.SelectedItem).Tag.ToString();
void SafeSearchChanged(object sender, SelectionChangedEventArgs e) =>
FoxTube.Settings.SafeSearch = safeSearch.SelectedIndex;
void QualityChanged(object sender, SelectionChangedEventArgs e) =>
FoxTube.Settings.DesiredVideoQuality = (quality.SelectedItem as ComboBoxItem).Tag as string;
void MeteredWarningChanged(object sender, RoutedEventArgs e) =>
FoxTube.Settings.CheckConnection = meteredWarning.IsOn;
void AutoplayChanged(object sender, RoutedEventArgs e) =>
FoxTube.Settings.Autoplay = autoplay.IsOn;
void ExplicitWarningChanged(object sender, RoutedEventArgs e) =>
FoxTube.Settings.BlockExplicitContent = explicitWarning.IsOn;
void ChannelNotificationsChanged(object sender, RoutedEventArgs e) =>
FoxTube.Settings.VideoNotifications = channelNotifications.IsOn;
void ClipboardProcessingChanged(object sender, RoutedEventArgs e) =>
FoxTube.Settings.ProcessClipboard = clipboardProcessing.IsOn;
void DevelopersNotificationsChanged(object sender, RoutedEventArgs e) =>
FoxTube.Settings.DevNotifications = developersNews.IsOn;
void ThemeChanged(object sender, RoutedEventArgs e)
{
if (FoxTube.Settings.Theme.ToString() == (string)(sender as RadioButton).Tag)
return;
switch((sender as RadioButton).Name)
{
case "light":
FoxTube.Settings.Theme = 0;
MainPage.Current.RequestedTheme = ElementTheme.Light;
break;
case "dark":
FoxTube.Settings.Theme = 1;
MainPage.Current.RequestedTheme = ElementTheme.Dark;
break;
default:
FoxTube.Settings.Theme = 2;
MainPage.Current.RequestedTheme = ElementTheme.Default;
break;
}
ApplicationViewTitleBar titleBar = ApplicationView.GetForCurrentView().TitleBar;
if (MainPage.Current.RequestedTheme == ElementTheme.Default)
titleBar.ButtonForegroundColor =
titleBar.ButtonHoverForegroundColor =
titleBar.ButtonPressedForegroundColor = Application.Current.RequestedTheme == ApplicationTheme.Dark ? Colors.White : Colors.Black;
else
titleBar.ButtonForegroundColor =
titleBar.ButtonHoverForegroundColor =
titleBar.ButtonPressedForegroundColor = MainPage.Current.RequestedTheme == ElementTheme.Dark ? Colors.White : Colors.Black;
}
}
}
+78
View File
@@ -0,0 +1,78 @@
<Page
x:Class="FoxTube.Views.SettingsSections.Inbox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:models="using:FoxTube.Core.Models"
mc:Ignorable="d"
Loaded="Page_Loaded">
<Page.Resources>
<Style TargetType="controls:DropShadowPanel">
<Setter Property="OffsetX" Value="5"/>
<Setter Property="OffsetY" Value="5"/>
</Style>
</Page.Resources>
<controls:MasterDetailsView Background="Transparent" MasterPaneWidth="400" CompactModeThresholdWidth="850" x:Name="masterDetailsView">
<controls:MasterDetailsView.MasterHeader>
<StackPanel>
<ProgressBar IsIndeterminate="True" x:Name="progressBar"/>
<ComboBox Header="Filter" HorizontalAlignment="Stretch" x:Name="filter" SelectionChanged="FilterChanged" IsEnabled="False">
<ComboBoxItem Content="All"/>
<ComboBoxItem Content="Changelogs"/>
<ComboBoxItem Content="Messages"/>
</ComboBox>
</StackPanel>
</controls:MasterDetailsView.MasterHeader>
<controls:MasterDetailsView.NoSelectionContent>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<controls:DropShadowPanel>
<TextBlock FontFamily="Segoe MDL2 Assets" Text="&#xE0A6;" FontSize="50" Margin="20,0"/>
</controls:DropShadowPanel>
<controls:DropShadowPanel>
<TextBlock Text="Select an item to view" VerticalAlignment="Center" Style="{StaticResource SubheaderTextBlockStyle}"/>
</controls:DropShadowPanel>
</StackPanel>
</controls:MasterDetailsView.NoSelectionContent>
<controls:MasterDetailsView.ItemTemplate>
<DataTemplate x:DataType="models:InboxItem">
<RelativePanel>
<RelativePanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
<Setter Property="MaxLines" Value="1"/>
<Setter Property="TextWrapping" Value="WrapWholeWords"/>
</Style>
</RelativePanel.Resources>
<PersonPicture Width="50" Margin="10,0" x:Name="icon" ProfilePicture="{Binding Avatar}" Initials="{Binding DefaultIcon}" FontFamily="Segoe MDL2 Assets" Foreground="White" Background="Red"/>
<StackPanel RelativePanel.RightOf="icon">
<TextBlock Text="{Binding Title}" Style="{StaticResource SubtitleTextBlockStyle}"/>
<TextBlock Text="{Binding Description}" FontSize="18" MaxLines="2"/>
<TextBlock Text="{Binding Type}"/>
<TextBlock Text="{Binding TimeStamp.ToShortDateString}" FontStyle="Italic" Style="{StaticResource CaptionTextBlockStyle}"/>
</StackPanel>
</RelativePanel>
</DataTemplate>
</controls:MasterDetailsView.ItemTemplate>
<controls:MasterDetailsView.DetailsTemplate>
<DataTemplate x:DataType="models:InboxItem">
<ScrollViewer>
<RelativePanel Margin="10">
<PersonPicture x:Name="avatar" Background="Red" Foreground="White" FontFamily="Segoe MDL2 Assets" Initials="{Binding DefaultIcon}" ProfilePicture="{Binding Avatar}"/>
<StackPanel RelativePanel.RightOf="avatar">
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="{Binding Title}"/>
<TextBlock Text="{Binding TimeStamp.ToLongTimeString}"/>
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" FontStyle="Italic" Text="{Binding Type}"/>
</StackPanel>
<controls:MarkdownTextBlock RelativePanel.Below="avatar" Text="{Binding Content}"/>
</RelativePanel>
</ScrollViewer>
</DataTemplate>
</controls:MasterDetailsView.DetailsTemplate>
</controls:MasterDetailsView>
</Page>
@@ -0,0 +1,42 @@
using FoxTube.Core.Models;
using FoxTube.Core.Models.Inbox;
using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace FoxTube.Views.SettingsSections
{
/// <summary>
/// Inbox view
/// </summary>
public sealed partial class Inbox : Page
{
List<InboxItem> items;
public Inbox() =>
InitializeComponent();
async void Page_Loaded(object sender, RoutedEventArgs e)
{
items = await Core.Helpers.Inbox.GetInbox();
filter.SelectedIndex = 0;
progressBar.Visibility = Visibility.Collapsed;
filter.IsEnabled = true;
}
void FilterChanged(object sender, SelectionChangedEventArgs e)
{
List<InboxItem> filtered = new List<InboxItem>();
filtered.AddRange(filter.SelectedIndex switch
{
1 => items.FindAll(i => i is Changelog),
2 => items.FindAll(i => i is DeveloperMessage),
_ => items
});
masterDetailsView.ItemsSource = filtered;
}
}
}
@@ -0,0 +1,13 @@
<Page
x:Class="FoxTube.Views.SettingsSections.Translate"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FoxTube.Views.SettingsSections"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
</Grid>
</Page>
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
namespace FoxTube.Views.SettingsSections
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class Translate : Page
{
public Translate()
{
this.InitializeComponent();
}
}
}
+31
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+7347
View File
File diff suppressed because it is too large Load Diff