Archived
1
0

Well, I'm depressing so no message. Just accept your faith

This commit is contained in:
Michael Gordeev
2019-03-26 12:16:56 +03:00
parent 34e33d3f0e
commit 854b0c88b1
81 changed files with 1212 additions and 178 deletions
+16 -21
View File
@@ -1,7 +1,4 @@
using Google.Apis.Services; using Newtonsoft.Json;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -11,6 +8,7 @@ using System.Xml;
using Windows.ApplicationModel.Background; using Windows.ApplicationModel.Background;
using Windows.Storage; using Windows.Storage;
using Windows.UI.Notifications; using Windows.UI.Notifications;
using YoutubeExplode.Models;
namespace FoxTube.Background namespace FoxTube.Background
{ {
@@ -19,11 +17,6 @@ namespace FoxTube.Background
private DateTime lastCheck; private DateTime lastCheck;
private readonly ApplicationDataContainer settings = ApplicationData.Current.RoamingSettings; private readonly ApplicationDataContainer settings = ApplicationData.Current.RoamingSettings;
dynamic prefs; dynamic prefs;
private readonly YouTubeService Service = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = "AIzaSyBgHrCnrlzlVmk0cJKL8RqP9Y8x6XSuk_0",
ApplicationName = "FoxTube"
});
BackgroundTaskDeferral def; BackgroundTaskDeferral def;
public async void Run(IBackgroundTaskInstance taskInstance) public async void Run(IBackgroundTaskInstance taskInstance)
@@ -60,33 +53,35 @@ namespace FoxTube.Background
{ {
Dictionary<string, string> subscriptions = JsonConvert.DeserializeObject<Dictionary<string, string>>(settings.Values["subscriptions"] as string); Dictionary<string, string> subscriptions = JsonConvert.DeserializeObject<Dictionary<string, string>>(settings.Values["subscriptions"] as string);
List<SearchResult> results = new List<SearchResult>(); List<XmlElement> results = new List<XmlElement>();
foreach (var s in subscriptions) foreach (var s in subscriptions)
{ {
SearchResource.ListRequest request = Service.Search.List("snippet"); XmlDocument doc = new XmlDocument();
request.PublishedAfter = lastCheck; doc.LoadXml(await new HttpClient().GetStringAsync($"https://www.youtube.com/feeds/videos.xml?channel_id={s.Key}"));
request.ChannelId = s.Key;
request.Type = "video";
request.MaxResults = 5;
SearchListResponse response = await request.ExecuteAsync();
foreach (SearchResult i in response.Items) List<XmlElement> items = new List<XmlElement>();
foreach (XmlElement i in doc["feed"].ChildNodes)
if (i.Name == "entry" && DateTime.Parse(i["published"].InnerText) > lastCheck.Subtract(TimeSpan.FromDays(1)))
items.Add(i);
items.OrderByDescending(i => DateTime.Parse(i["published"].InnerText));
foreach(XmlElement i in items)
{ {
results.Add(i); results.Add(i);
ToastNotificationManager.CreateToastNotifier().Show( ToastNotificationManager.CreateToastNotifier().Show(
Notification.GetVideoToast(i.Id.VideoId, i.Snippet.ChannelId, i.Snippet.Title, i.Snippet.ChannelTitle, i.Snippet.Thumbnails.Medium.Url, s.Value)); Notification.GetVideoToast(i["yt:videoId"].InnerText, s.Key, i["title"].InnerText, i["author"]["name"].InnerText, (await new YoutubeExplode.YoutubeClient().GetVideoAsync(i["yt:videoId"].InnerText)).Thumbnails.MediumResUrl, DateTime.Parse(i["published"].InnerText), s.Value));
} }
} }
results.OrderBy(i => i.Snippet.PublishedAt);
TileUpdater updater = TileUpdateManager.CreateTileUpdaterForApplication(); TileUpdater updater = TileUpdateManager.CreateTileUpdaterForApplication();
updater.EnableNotificationQueue(true); updater.EnableNotificationQueue(true);
updater.Clear(); updater.Clear();
for (int i = 0; i < 5 && i < results.Count; i++) for (int i = 0; i < 5 && i < results.Count; i++)
updater.Update(Tiles.GetTileLayout(System.Security.SecurityElement.Escape(results[i].Snippet.Title), System.Security.SecurityElement.Escape(results[i].Snippet.ChannelTitle), results[i].Snippet.Thumbnails.Medium.Url.Replace("&", "%26"), subscriptions[results[i].Snippet.ChannelId])); updater.Update(Tiles.GetTileLayout(System.Security.SecurityElement.Escape(results[i]["title"].InnerText), System.Security.SecurityElement.Escape(results[i]["author"]["name"].InnerText), (await new YoutubeExplode.YoutubeClient().GetVideoAsync(results[i]["yt:videoId"].InnerText)).Thumbnails.MediumResUrl.Replace("&", "%26"), subscriptions[results[i]["author"]["url"].InnerText.Split('/').Last()]));
} }
catch { } catch { }
} }
+8 -2
View File
@@ -128,10 +128,16 @@
<Version>1.29.2.1006</Version> <Version>1.29.2.1006</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.AppCenter.Analytics"> <PackageReference Include="Microsoft.AppCenter.Analytics">
<Version>1.13.0</Version> <Version>1.13.2</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform"> <PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.1.5</Version> <Version>6.2.8</Version>
</PackageReference>
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications">
<Version>5.1.1</Version>
</PackageReference>
<PackageReference Include="YoutubeExplode">
<Version>4.6.7</Version>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup />
+7 -4
View File
@@ -1,4 +1,7 @@
using Newtonsoft.Json; using Google.Apis.YouTube.v3.Data;
using Microsoft.Toolkit.Uwp.Notifications;
using Newtonsoft.Json;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Windows.Data.Xml.Dom; using Windows.Data.Xml.Dom;
using Windows.Storage; using Windows.Storage;
@@ -51,11 +54,11 @@ namespace FoxTube.Background
return new ToastNotification(template); return new ToastNotification(template);
} }
public static ToastNotification GetVideoToast(string id, string channelId, string title, string channel, string thumbnail, string avatar) public static ToastNotification GetVideoToast(string id, string channelId, string title, string channel, string thumbnail, DateTimeOffset timeStamp, string avatar)
{ {
XmlDocument template = new XmlDocument(); XmlDocument template = new XmlDocument();
string ts = $"{timeStamp.Year}-{timeStamp.Month:00}-{timeStamp.Day:00}T{timeStamp.Hour:00}:{timeStamp.Minute:00}:{timeStamp.Second:00}Z";
template.LoadXml($@"<toast activationType='foreground' launch='video|{id}'> template.LoadXml($@"<toast activationType='foreground' launch='video|{id}' displayTimestamp='{ts}'>
<visual> <visual>
<binding template='ToastGeneric'> <binding template='ToastGeneric'>
<image placement='hero' src='{thumbnail.Replace("&", "%26")}'/> <image placement='hero' src='{thumbnail.Replace("&", "%26")}'/>
+8
View File
@@ -10,6 +10,7 @@ using System.Xml;
using Windows.ApplicationModel; using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation; using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.Background; using Windows.ApplicationModel.Background;
using Windows.ApplicationModel.Core;
using Windows.Globalization; using Windows.Globalization;
using Windows.Storage; using Windows.Storage;
using Windows.System.Power; using Windows.System.Power;
@@ -22,6 +23,7 @@ namespace FoxTube
{ {
sealed partial class App : Application sealed partial class App : Application
{ {
Stopwatch sw = new Stopwatch();
public App() public App()
{ {
SettingsStorage.LoadData(); SettingsStorage.LoadData();
@@ -45,6 +47,8 @@ namespace FoxTube
AppCenter.Start("45774462-9ea7-438a-96fc-03982666f39e", typeof(Analytics)); AppCenter.Start("45774462-9ea7-438a-96fc-03982666f39e", typeof(Analytics));
AppCenter.SetCountryCode(SettingsStorage.Region); AppCenter.SetCountryCode(SettingsStorage.Region);
sw.Start();
} }
/// <summary> /// <summary>
@@ -257,6 +261,10 @@ namespace FoxTube
private void OnSuspending(object sender, SuspendingEventArgs e) private void OnSuspending(object sender, SuspendingEventArgs e)
{ {
var deferral = e.SuspendingOperation.GetDeferral(); var deferral = e.SuspendingOperation.GetDeferral();
sw.Stop();
SettingsStorage.Uptime += sw.Elapsed;
SettingsStorage.SaveData(); SettingsStorage.SaveData();
DownloadAgent.QuitPrompt(); DownloadAgent.QuitPrompt();
deferral.Complete(); deferral.Complete();
+4
View File
@@ -27,6 +27,10 @@ using YoutubeExplode.Models.MediaStreams;
namespace FoxTube namespace FoxTube
{ {
public interface NavigationPage
{
object Parameter { get; set; }
}
public static class Methods public static class Methods
{ {
private static ResourceLoader resources = ResourceLoader.GetForCurrentView("Methods"); private static ResourceLoader resources = ResourceLoader.GetForCurrentView("Methods");
+27 -10
View File
@@ -10,6 +10,9 @@ using Newtonsoft.Json;
using Windows.Storage; using Windows.Storage;
using Windows.Services.Store; using Windows.Services.Store;
using System.Net.Http; using System.Net.Http;
using Google.Apis.Oauth2.v2.Data;
using Google.Apis.Oauth2.v2;
using static Google.Apis.Auth.OAuth2.UwpCodeReceiver;
namespace FoxTube namespace FoxTube
{ {
@@ -49,6 +52,7 @@ namespace FoxTube
public static string AccountId => UserChannel?.Id; public static string AccountId => UserChannel?.Id;
public static Channel UserChannel { get; private set; } public static Channel UserChannel { get; private set; }
public static Userinfoplus UserInfo { get; private set; }
public static List<Subscription> Subscriptions { get; } = new List<Subscription>(); public static List<Subscription> Subscriptions { get; } = new List<Subscription>();
public static List<string> History { get; set; } = new List<string>(); public static List<string> History { get; set; } = new List<string>();
@@ -116,14 +120,15 @@ namespace FoxTube
/// <param name="retrieveSubs">Loads user's subscriptions if true</param> /// <param name="retrieveSubs">Loads user's subscriptions if true</param>
public static async void Authorize(bool retrieveSubs = true) public static async void Authorize(bool retrieveSubs = true)
{ {
#region Retrieving user's credential
try try
{ {
#region Retrieving user's credential
Credential = await GoogleWebAuthorizationBroker.AuthorizeAsync( Credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
Secrets, Secrets,
new[] new[]
{ {
Google.Apis.Oauth2.v2.Oauth2Service.Scope.UserinfoProfile, Oauth2Service.Scope.UserinfoProfile,
Oauth2Service.Scope.UserinfoEmail,
YouTubeService.Scope.YoutubeForceSsl, YouTubeService.Scope.YoutubeForceSsl,
YouTubeService.Scope.Youtube, YouTubeService.Scope.Youtube,
YouTubeService.Scope.YoutubeUpload, YouTubeService.Scope.YoutubeUpload,
@@ -132,15 +137,28 @@ namespace FoxTube
}, },
"user", "user",
CancellationToken.None); CancellationToken.None);
}
catch (AuthenticateException e)
{
if (e.Message.Contains("UserCancel"))
return;
else
throw e;
}
if (Credential == null || !retrieveSubs) if (Credential == null || !retrieveSubs)
goto InvokeEvent; return;
SettingsStorage.HasAccount = true; SettingsStorage.HasAccount = true;
HttpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Credential.Token.AccessToken); HttpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Credential.Token.AccessToken);
#endregion #endregion
try
{
#region Retrieving user's data #region Retrieving user's data
UserInfo = await new Oauth2Service(Initializer).Userinfo.Get().ExecuteAsync();
try try
{ {
WatchLater = await Methods.GetLater(); WatchLater = await Methods.GetLater();
@@ -148,10 +166,6 @@ namespace FoxTube
} }
catch { } catch { }
var request = Service.Channels.List("snippet,contentDetails");
request.Mine = true;
UserChannel = (await request.ExecuteAsync()).Items[0];
SubscriptionsResource.ListRequest subRequest = Service.Subscriptions.List("snippet"); SubscriptionsResource.ListRequest subRequest = Service.Subscriptions.List("snippet");
subRequest.Mine = true; subRequest.Mine = true;
subRequest.MaxResults = 50; subRequest.MaxResults = 50;
@@ -169,13 +183,16 @@ namespace FoxTube
nextToken = subResponse.NextPageToken; nextToken = subResponse.NextPageToken;
} while (!string.IsNullOrWhiteSpace(nextToken)); } while (!string.IsNullOrWhiteSpace(nextToken));
var request = Service.Channels.List("snippet,contentDetails");
request.Mine = true;
UserChannel = (await request.ExecuteAsync()).Items[0];
#endregion #endregion
//Saving user's subscriptions for background task //Saving user's subscriptions for background task
SaveSubscriptions(); SaveSubscriptions();
InvokeEvent: AuthorizationStateChanged?.Invoke(args: true);
AuthorizationStateChanged?.Invoke(args: IsAuthorized);
} }
catch catch
{ {
@@ -189,7 +206,7 @@ namespace FoxTube
public static void SaveSubscriptions() public static void SaveSubscriptions()
{ {
Dictionary<string, string> subs = new Dictionary<string, string>(); Dictionary<string, string> subs = new Dictionary<string, string>();
Subscriptions.ForEach(x => subs.Add(x.Snippet.ResourceId.ChannelId, x.Snippet.Thumbnails.Medium.Url)); Subscriptions.ForEach(x => subs.Add(x.Snippet.ResourceId.ChannelId, x.Snippet.Thumbnails.Default__.Url));
ApplicationData.Current.RoamingSettings.Values["subscriptions"] = JsonConvert.SerializeObject(subs); ApplicationData.Current.RoamingSettings.Values["subscriptions"] = JsonConvert.SerializeObject(subs);
} }
+34 -2
View File
@@ -19,7 +19,7 @@ namespace FoxTube
public bool checkConnection = true; public bool checkConnection = true;
public bool autoplay = true; public bool autoplay = true;
public int volume = 100; public double volume = 100;
public string language = (new[] { "ua", "ru", "by", "kz", "kg", "md", "lv", "ee" }).Contains(CultureInfo.InstalledUICulture.TwoLetterISOLanguageName) ? "ru-RU" : "en-US"; public string language = (new[] { "ua", "ru", "by", "kz", "kg", "md", "lv", "ee" }).Contains(CultureInfo.InstalledUICulture.TwoLetterISOLanguageName) ? "ru-RU" : "en-US";
public string relevanceLanguage = (new[] { "ua", "ru", "by", "kz", "kg", "md", "lv", "ee" }).Contains(CultureInfo.InstalledUICulture.TwoLetterISOLanguageName) ? "ru" : "en"; public string relevanceLanguage = (new[] { "ua", "ru", "by", "kz", "kg", "md", "lv", "ee" }).Contains(CultureInfo.InstalledUICulture.TwoLetterISOLanguageName) ? "ru" : "en";
@@ -28,6 +28,10 @@ namespace FoxTube
public bool hasAccount = false; public bool hasAccount = false;
public int theme = 2; public int theme = 2;
public TimeSpan uptime = TimeSpan.FromSeconds(0);
public bool promptReview = true;
public bool promptFeedback = true;
} }
public static class SettingsStorage public static class SettingsStorage
@@ -88,7 +92,7 @@ namespace FoxTube
SaveData(); SaveData();
} }
} }
public static int Volume public static double Volume
{ {
get { return Container.volume; } get { return Container.volume; }
set set
@@ -187,6 +191,34 @@ namespace FoxTube
} }
} }
public static TimeSpan Uptime
{
get { return Container.uptime; }
set
{
Container.uptime = value;
SaveData();
}
}
public static bool PromptReview
{
get { return Container.promptReview; }
set
{
Container.promptReview = value;
SaveData();
}
}
public static bool PromptFeedback
{
get { return Container.promptFeedback; }
set
{
Container.promptFeedback = value;
SaveData();
}
}
//Settings storage //Settings storage
private static readonly ApplicationDataContainer storage = ApplicationData.Current.RoamingSettings; private static readonly ApplicationDataContainer storage = ApplicationData.Current.RoamingSettings;
private static SettingsContainer Container; private static SettingsContainer Container;
+1 -1
View File
@@ -10,7 +10,7 @@
VerticalAlignment="Top" VerticalAlignment="Top"
d:DesignHeight="290" d:DesignHeight="290"
d:DesignWidth="384" d:DesignWidth="384"
MaxWidth="500"> Opacity="0">
<Windows10version1809:UserControl.OpacityTransition> <Windows10version1809:UserControl.OpacityTransition>
<ScalarTransition Duration="0:0:0.5"/> <ScalarTransition Duration="0:0:0.5"/>
@@ -84,6 +84,11 @@ namespace FoxTube
} }
} }
public void Minimize()
{
Minimize_Click(GetTemplateChild("minimize"), null);
}
private void ProgressSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e) private void ProgressSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{ {
(GetTemplateChild("compactSeek") as ProgressBar).Value = e.NewValue; (GetTemplateChild("compactSeek") as ProgressBar).Value = e.NewValue;
@@ -189,6 +194,8 @@ namespace FoxTube
(GetTemplateChild("maximize") as Button).Visibility = Visibility.Collapsed; (GetTemplateChild("maximize") as Button).Visibility = Visibility.Collapsed;
(GetTemplateChild("compactClose") as Button).Visibility = Visibility.Collapsed; (GetTemplateChild("compactClose") as Button).Visibility = Visibility.Collapsed;
(GetTemplateChild("dragholder") as Button).Visibility = Visibility.Visible;
(GetTemplateChild("captions") as LiveCaptions).Size = 15; (GetTemplateChild("captions") as LiveCaptions).Size = 15;
} }
@@ -237,6 +244,8 @@ namespace FoxTube
(GetTemplateChild("footer") as Grid).Visibility = Visibility.Visible; (GetTemplateChild("footer") as Grid).Visibility = Visibility.Visible;
(GetTemplateChild("captions") as LiveCaptions).Size = 24; (GetTemplateChild("captions") as LiveCaptions).Size = 24;
(GetTemplateChild("dragholder") as Button).Visibility = Visibility.Collapsed;
} }
public void SetMeta(string title, string channel) public void SetMeta(string title, string channel)
+6 -17
View File
@@ -1,32 +1,15 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Windows.Foundation;
using Windows.UI.Core; using Windows.UI.Core;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Input;
using Google.Apis.YouTube.v3.Data; using Google.Apis.YouTube.v3.Data;
using Windows.UI.Xaml.Media.Imaging; using Windows.UI.Xaml.Media.Imaging;
using Windows.Media; using Windows.Media;
using Windows.Storage.Streams; using Windows.Storage.Streams;
using Windows.UI.ViewManagement;
using System.Xml;
using Windows.ApplicationModel.Core;
using Windows.UI;
using Windows.Media.Casting;
using YoutubeExplode.Models.MediaStreams; using YoutubeExplode.Models.MediaStreams;
using YoutubeExplode; using YoutubeExplode;
using YoutubeExplode.Models.ClosedCaptions;
using System.Globalization;
using FoxTube.Controls;
using Windows.System;
using Windows.Media.Core;
using Windows.Media.Playback;
using System.Net.Http;
using System.Diagnostics; using System.Diagnostics;
using Windows.UI.Popups;
namespace FoxTube namespace FoxTube
{ {
@@ -124,6 +107,11 @@ namespace FoxTube
MiniMode?.Invoke(this, e); MiniMode?.Invoke(this, e);
} }
public void Minimize()
{
Controls.Minimize();
}
private void Controls_QualityChanged(object sender, MediaStreamInfo requestedQuality, MediaStreamInfoSet list) private void Controls_QualityChanged(object sender, MediaStreamInfo requestedQuality, MediaStreamInfoSet list)
{ {
videoSource.Pause(); videoSource.Pause();
@@ -232,6 +220,7 @@ namespace FoxTube
private void VideoSource_VolumeChanged(object sender, RoutedEventArgs e) private void VideoSource_VolumeChanged(object sender, RoutedEventArgs e)
{ {
audioSource.Volume = videoSource.Volume; audioSource.Volume = videoSource.Volume;
SettingsStorage.Volume = videoSource.Volume;
} }
} }
} }
-1
View File
@@ -10,7 +10,6 @@
VerticalAlignment="Top" VerticalAlignment="Top"
d:DesignHeight="290" d:DesignHeight="290"
d:DesignWidth="384" d:DesignWidth="384"
MaxWidth="500"
Opacity="0"> Opacity="0">
<Windows10version1809:Page.OpacityTransition> <Windows10version1809:Page.OpacityTransition>
-1
View File
@@ -10,7 +10,6 @@
VerticalAlignment="Top" VerticalAlignment="Top"
d:DesignHeight="290" d:DesignHeight="290"
d:DesignWidth="384" d:DesignWidth="384"
MaxWidth="500"
Opacity="0"> Opacity="0">
<Windows10version1809:UserControl.OpacityTransition> <Windows10version1809:UserControl.OpacityTransition>
+13 -7
View File
@@ -393,7 +393,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AdaptiveCards.Rendering.Uwp"> <PackageReference Include="AdaptiveCards.Rendering.Uwp">
<Version>1.1.0</Version> <Version>1.1.2</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Google.Apis"> <PackageReference Include="Google.Apis">
<Version>1.30.0-beta02</Version> <Version>1.30.0-beta02</Version>
@@ -414,25 +414,28 @@
<Version>10.1811.22001</Version> <Version>10.1811.22001</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.AppCenter.Analytics"> <PackageReference Include="Microsoft.AppCenter.Analytics">
<Version>1.13.0</Version> <Version>1.13.2</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform"> <PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.1.9</Version> <Version>6.2.8</Version>
</PackageReference>
<PackageReference Include="Microsoft.Services.Store.Engagement">
<Version>10.1901.28001</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications"> <PackageReference Include="Microsoft.Toolkit.Uwp.Notifications">
<Version>5.0.0</Version> <Version>5.1.1</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls"> <PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls">
<Version>5.0.0</Version> <Version>5.1.1</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.UI.Xaml"> <PackageReference Include="Microsoft.UI.Xaml">
<Version>2.0.181018003.1</Version> <Version>2.0.181018004</Version>
</PackageReference> </PackageReference>
<PackageReference Include="runtime.win10-arm64.runtime.native.System.IO.Compression"> <PackageReference Include="runtime.win10-arm64.runtime.native.System.IO.Compression">
<Version>4.3.2</Version> <Version>4.3.2</Version>
</PackageReference> </PackageReference>
<PackageReference Include="YoutubeExplode"> <PackageReference Include="YoutubeExplode">
<Version>4.6.4</Version> <Version>4.6.7</Version>
</PackageReference> </PackageReference>
<PackageReference Include="YoutubeExtractor"> <PackageReference Include="YoutubeExtractor">
<Version>0.10.11</Version> <Version>0.10.11</Version>
@@ -485,6 +488,9 @@
<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' ">
+1 -1
View File
@@ -15,7 +15,7 @@
</Resources> </Resources>
<Applications> <Applications>
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="FoxTube.App" ResourceGroup="foxtube"> <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 for Windows 10" BackgroundColor="skyBlue"> <uap:VisualElements DisplayName="FoxTube" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="YouTube Client for Windows 10" BackgroundColor="#282828">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" ShortName="FoxTube" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png"> <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" ShortName="FoxTube" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png">
<uap:ShowNameOnTiles> <uap:ShowNameOnTiles>
<uap:ShowOn Tile="square150x150Logo" /> <uap:ShowOn Tile="square150x150Logo" />
+10 -1
View File
@@ -21,8 +21,9 @@ namespace FoxTube.Pages
/// <summary> /// <summary>
/// Channel page /// Channel page
/// </summary> /// </summary>
public sealed partial class ChannelPage : Page public sealed partial class ChannelPage : Page, NavigationPage
{ {
public object Parameter { get; set; } = null;
readonly ResourceLoader resources = ResourceLoader.GetForCurrentView("Cards"); readonly ResourceLoader resources = ResourceLoader.GetForCurrentView("Cards");
public string channelId; public string channelId;
@@ -43,6 +44,7 @@ namespace FoxTube.Pages
protected override void OnNavigatedTo(NavigationEventArgs e) protected override void OnNavigatedTo(NavigationEventArgs e)
{ {
base.OnNavigatedTo(e); base.OnNavigatedTo(e);
Parameter = e.Parameter;
if ((string)e.Parameter == null) if ((string)e.Parameter == null)
loading.Error("NullReferenceException", "Unable to initialize search. Search term is not stated."); loading.Error("NullReferenceException", "Unable to initialize search. Search term is not stated.");
else else
@@ -124,6 +126,8 @@ namespace FoxTube.Pages
{ "Channel ID", channelId } { "Channel ID", channelId }
}); });
} }
ScrollViewer_ViewChanged(this, null);
} }
async void LoadPlaylist() async void LoadPlaylist()
@@ -167,6 +171,11 @@ namespace FoxTube.Pages
{ {
if (content.SelectedIndex == 1 && !playlistLoaded) if (content.SelectedIndex == 1 && !playlistLoaded)
LoadPlaylist(); LoadPlaylist();
if (content.SelectedIndex == 0)
ScrollViewer_ViewChanged(this, null);
else
ColapsedHeader.Opacity = 1;
} }
private async void ShowMorePlaylists_Click() private async void ShowMorePlaylists_Click()
+2 -1
View File
@@ -9,8 +9,9 @@ namespace FoxTube.Pages
/// <summary> /// <summary>
/// Downloads page /// Downloads page
/// </summary> /// </summary>
public sealed partial class Downloads : Page public sealed partial class Downloads : Page, NavigationPage
{ {
public object Parameter { get; set; } = null;
public Downloads() public Downloads()
{ {
InitializeComponent(); InitializeComponent();
+3 -1
View File
@@ -12,8 +12,9 @@ namespace FoxTube.Pages
/// <summary> /// <summary>
/// YouTube history page /// YouTube history page
/// </summary> /// </summary>
public sealed partial class History : Page public sealed partial class History : Page, NavigationPage
{ {
public object Parameter { get; set; } = null;
List<string> entries; List<string> entries;
int page = 1; int page = 1;
public string id = "HL"; public string id = "HL";
@@ -26,6 +27,7 @@ namespace FoxTube.Pages
protected override void OnNavigatedTo(NavigationEventArgs e) protected override void OnNavigatedTo(NavigationEventArgs e)
{ {
base.OnNavigatedTo(e); base.OnNavigatedTo(e);
Parameter = e.Parameter;
loading.RefreshPage += Refresh_Click; loading.RefreshPage += Refresh_Click;
+2 -1
View File
@@ -14,8 +14,9 @@ namespace FoxTube
/// <summary> /// <summary>
/// Home page /// Home page
/// </summary> /// </summary>
public sealed partial class Home : Page public sealed partial class Home : Page, NavigationPage
{ {
public object Parameter { get; set; } = null;
private bool trendLoaded = false, recLoaded = false, subsLoaded = false; private bool trendLoaded = false, recLoaded = false, subsLoaded = false;
List<string> homeList = new List<string>(); List<string> homeList = new List<string>();
+6 -14
View File
@@ -40,7 +40,7 @@
<NavigationView SelectedItem="toHome" Windows10version1803:BackRequested="Nav_BackRequested" Windows10version1803:PaneClosing="Nav_PaneClosing" Windows10version1803:PaneOpened="Nav_PaneOpened" OpenPaneLength="300" Name="nav" SelectionChanged="Nav_SelectionChanged"> <NavigationView SelectedItem="toHome" Windows10version1803:BackRequested="Nav_BackRequested" Windows10version1803:PaneClosing="Nav_PaneClosing" Windows10version1803:PaneOpened="Nav_PaneOpened" OpenPaneLength="300" Name="nav" SelectionChanged="Nav_SelectionChanged">
<NavigationView.Header> <NavigationView.Header>
<TextBlock Name="Title" Text="Hello, World!" Margin="0,30,0,10" Style="{StaticResource TitleTextBlockStyle}"/> <TextBlock Name="Title" Margin="0,30,0,10" Style="{StaticResource TitleTextBlockStyle}"/>
</NavigationView.Header> </NavigationView.Header>
<NavigationView.MenuItemTemplate> <NavigationView.MenuItemTemplate>
@@ -81,7 +81,7 @@
</TransitionCollection> </TransitionCollection>
</NavigationViewList.ItemContainerTransitions> </NavigationViewList.ItemContainerTransitions>
<NavigationViewItem Name="openWeb" Tapped="Web_Tapped" Icon="Globe" Content="Browser" Visibility="Collapsed"/> <NavigationViewItem Name="openWeb" Tapped="Web_Tapped" Icon="Globe" Content="Browser" Visibility="Collapsed"/>
<NavigationViewItem x:Uid="/Main/feedback" Name="feedback" Content="Give a feedback" Tapped="Feedback_Click"> <NavigationViewItem x:Uid="/Main/feedback" Name="feedback" Content="Give a feedback" Tapped="Feedback_Click" Visibility="Collapsed">
<NavigationViewItem.Icon> <NavigationViewItem.Icon>
<FontIcon Glyph="&#xED15;"/> <FontIcon Glyph="&#xED15;"/>
</NavigationViewItem.Icon> </NavigationViewItem.Icon>
@@ -93,18 +93,10 @@
</NavigationViewItem.Icon> </NavigationViewItem.Icon>
</NavigationViewItem> </NavigationViewItem>
<NavigationViewItem Name="account" Tapped="OpenContext"> <NavigationViewItem Name="account" x:Uid="/Main/signIn" Content="Add account" Tapped="SignIn_Click" Visibility="Collapsed">
<StackPanel Orientation="Horizontal"> <NavigationViewItem.Icon>
<FontIcon Glyph="&#xE8FA;" FontSize="16" Margin="0,0,16,0"/> <FontIcon Glyph="&#xE8FA;"/>
<TextBlock x:Uid="/Main/signIn" Text="Add account"/> </NavigationViewItem.Icon>
</StackPanel>
<NavigationViewItem.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem x:Uid="/Main/signEx" Text="Sign in with existing account" Name="signIn" Click="SignIn_Click"/>
<MenuFlyoutItem x:Uid="/Main/signNew" Text="Create new Google account" Name="createAccount" Click="CreateAccount_Click"/>
</MenuFlyout>
</NavigationViewItem.ContextFlyout>
</NavigationViewItem> </NavigationViewItem>
<NavigationViewItem Visibility="Collapsed" Name="avatar" Tapped="OpenContext" Padding="-5"> <NavigationViewItem Visibility="Collapsed" Name="avatar" Tapped="OpenContext" Padding="-5">
+91 -43
View File
@@ -18,31 +18,39 @@ using FoxTube.Pages;
using Windows.UI.Popups; using Windows.UI.Popups;
using Windows.Networking.Connectivity; using Windows.Networking.Connectivity;
using Windows.ApplicationModel.Resources; using Windows.ApplicationModel.Resources;
using Microsoft.Services.Store.Engagement;
using System.Linq;
namespace FoxTube namespace FoxTube
{ {
public enum Sender { Menu, Frame, None }
/// <summary> /// <summary>
/// Main app's layout /// Main app's layout
/// </summary> /// </summary>
public sealed partial class MainPage : Page public sealed partial class MainPage : Page
{ {
Sender s = Sender.None; bool wasInvoked = false;
readonly ResourceLoader resources = ResourceLoader.GetForCurrentView("Main"); readonly ResourceLoader resources = ResourceLoader.GetForCurrentView("Main");
Dictionary<Type, Action> headers; Dictionary<Type, Action> headers;
public MainPage() public MainPage()
{ {
InitializeComponent(); InitializeComponent();
Window.Current.SetTitleBar(AppTitleBar); Window.Current.SetTitleBar(AppTitleBar);
CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
CoreApplication.GetCurrentView().TitleBar.LayoutMetricsChanged += (s, e) => SetTitleBar(s); CoreApplication.GetCurrentView().TitleBar.LayoutMetricsChanged += (s, e) => SetTitleBar(s);
SecretsVault.AuthorizationStateChanged += AuthorizationStateChanged; SecretsVault.AuthorizationStateChanged += AuthorizationStateChanged;
SecretsVault.SubscriptionsChanged += SecretsVault_SubscriptionsChanged; SecretsVault.SubscriptionsChanged += SecretsVault_SubscriptionsChanged;
SecretsVault.Purchased += (sender, e) => SecretsVault.Purchased += async (sender, e) =>
{ {
//TODO: Localize strings
removeAds.Visibility = (e[0] as bool?).Value ? Visibility.Collapsed : Visibility.Visible; removeAds.Visibility = (e[0] as bool?).Value ? Visibility.Collapsed : Visibility.Visible;
content.Navigate(typeof(Home)); MessageDialog dialog = new MessageDialog("Thanks for purchasing full version of the app (^∇^) In order to complete changes we need to reopen it. But you can do it later");
dialog.Commands.Add(new UICommand("Close the app", (command) => Methods.CloseApp()));
dialog.Commands.Add(new UICommand("Later"));
dialog.CancelCommandIndex = 1;
dialog.DefaultCommandIndex = 0;
await dialog.ShowAsync();
}; };
SecretsVault.Initialize(); SecretsVault.Initialize();
@@ -63,6 +71,55 @@ namespace FoxTube
{ typeof(Home), () => Title.Text = resources.GetString("/Main/home/Content") }, { typeof(Home), () => Title.Text = resources.GetString("/Main/home/Content") },
{ typeof(Downloads), () => Title.Text = resources.GetString("/Main/downloads/Content") } { typeof(Downloads), () => Title.Text = resources.GetString("/Main/downloads/Content") }
}; };
if(StoreServicesFeedbackLauncher.IsSupported())
feedback.Visibility = Visibility.Visible;
PromptFeedback();
}
async void PromptFeedback()
{
//TODO: Localize strings
if (SettingsStorage.Uptime.TotalHours >= 12 && SettingsStorage.PromptFeedback)
{
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) => SettingsStorage.PromptFeedback = false));
dialog.Commands.Add(new UICommand("Maybe later"));
dialog.Commands.Add(new UICommand("Sure!", async (command) =>
{
SettingsStorage.PromptFeedback = false;
if (StoreServicesFeedbackLauncher.IsSupported())
await StoreServicesFeedbackLauncher.GetDefault().LaunchAsync();
else
{
MessageDialog message = new MessageDialog("Oops. Seems like you don't have a Feedback Hub app. But you can stil send your feedback to michael.xfox@outlook.com");
message.Commands.Add(new UICommand("Send an E-mail", async (c) => await Launcher.LaunchUriAsync("mailto:michael.xfox@outlook.com".ToUri())));
message.Commands.Add(new UICommand("Nevermind. Get me back"));
message.CancelCommandIndex = 1;
message.DefaultCommandIndex = 0;
await message.ShowAsync();
}
}));
dialog.DefaultCommandIndex = 2;
dialog.CancelCommandIndex = 1;
await dialog.ShowAsync();
}
if (SettingsStorage.Uptime.TotalHours >= 24 && SettingsStorage.PromptReview)
{
MessageDialog dialog = new MessageDialog("Like our app? Review it on Microsoft Store!");
dialog.Commands.Add(new UICommand("Don't ask me anymore", (command) => SettingsStorage.PromptReview = false));
dialog.Commands.Add(new UICommand("Maybe later"));
dialog.Commands.Add(new UICommand("Sure!", async (command) =>
{
SettingsStorage.PromptReview = false;
await Launcher.LaunchUriAsync("ms-windows-store://review/?ProductId=9NCQQXJTDLFH".ToUri());
}));
dialog.DefaultCommandIndex = 2;
dialog.CancelCommandIndex = 1;
await dialog.ShowAsync();
}
} }
public string GetPlaylist() public string GetPlaylist()
@@ -89,10 +146,10 @@ namespace FoxTube
titleBar.ButtonInactiveBackgroundColor = Colors.Transparent; titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
titleBar.ButtonInactiveForegroundColor = Colors.Gray; titleBar.ButtonInactiveForegroundColor = Colors.Gray;
if(Application.Current.RequestedTheme == ApplicationTheme.Dark) if(RequestedTheme == ElementTheme.Dark || (RequestedTheme == ElementTheme.Default && Application.Current.RequestedTheme == ApplicationTheme.Dark))
titleBar.ForegroundColor = Colors.White; titleBar.ButtonForegroundColor = Colors.White;
else else
titleBar.ForegroundColor = Colors.Black; titleBar.ButtonForegroundColor = Colors.Black;
} }
private void SecretsVault_SubscriptionsChanged(object sender, params object[] args) private void SecretsVault_SubscriptionsChanged(object sender, params object[] args)
@@ -100,7 +157,7 @@ namespace FoxTube
switch(args[0] as string) switch(args[0] as string)
{ {
case "add": case "add":
if (nav.MenuItems.Count >= 19) if (nav.MenuItems.Count < 19)
nav.MenuItems.Add(args[1] as Subscription); nav.MenuItems.Add(args[1] as Subscription);
break; break;
@@ -113,7 +170,6 @@ namespace FoxTube
if (SecretsVault.Subscriptions.Count >= 10) if (SecretsVault.Subscriptions.Count >= 10)
nav.MenuItems.Add(SecretsVault.Subscriptions[9]); nav.MenuItems.Add(SecretsVault.Subscriptions[9]);
break; break;
} }
} }
@@ -124,21 +180,15 @@ namespace FoxTube
{ {
case true: case true:
account.Visibility = Visibility.Collapsed; account.Visibility = Visibility.Collapsed;
try
{
Userinfoplus info = await new Oauth2Service(SecretsVault.Initializer).Userinfo.Get().ExecuteAsync();
myName.Text = myNameFlyout.Text = info.Name; myName.Text = myNameFlyout.Text = SecretsVault.UserInfo.Name;
if (string.IsNullOrWhiteSpace(info.Email)) myEmail.Text = SecretsVault.UserInfo.Email;
myEmail.Visibility = Visibility.Collapsed; avatarFlyout.ProfilePicture = new BitmapImage(SecretsVault.UserInfo.Picture.ToUri());
else
myEmail.Text = info.Email;
avatarFlyout.ProfilePicture = new BitmapImage(info.Picture.ToUri());
((avatar.Content as StackPanel).Children[0] as PersonPicture).ProfilePicture = avatarFlyout.ProfilePicture; ((avatar.Content as StackPanel).Children[0] as PersonPicture).ProfilePicture = avatarFlyout.ProfilePicture;
}
catch { }
avatar.Visibility = Visibility.Visible; avatar.Visibility = Visibility.Visible;
if(SecretsVault.UserChannel != null)
toChannel.Visibility = Visibility.Visible; toChannel.Visibility = Visibility.Visible;
toSubscriptions.Visibility = Visibility.Visible; toSubscriptions.Visibility = Visibility.Visible;
libHeader.Visibility = Visibility.Visible; libHeader.Visibility = Visibility.Visible;
@@ -152,9 +202,8 @@ namespace FoxTube
for (int k = 0; k < SecretsVault.Subscriptions.Count && k < 10; k++) for (int k = 0; k < SecretsVault.Subscriptions.Count && k < 10; k++)
nav.MenuItems.Add(SecretsVault.Subscriptions[k]); nav.MenuItems.Add(SecretsVault.Subscriptions[k]);
} }
if (SecretsVault.UserChannel == null)
toChannel.Visibility = Visibility.Collapsed;
break; break;
case false: case false:
for (int k = nav.MenuItems.Count - 1; k > 8; k--) for (int k = nav.MenuItems.Count - 1; k > 8; k--)
nav.MenuItems.RemoveAt(k); nav.MenuItems.RemoveAt(k);
@@ -172,6 +221,7 @@ namespace FoxTube
subsHeader.Visibility = Visibility.Collapsed; subsHeader.Visibility = Visibility.Collapsed;
break; break;
default: default:
MessageDialog dialog = new MessageDialog(resources.GetString("/Main/connectErrContent"), resources.GetString("/Main/connectErrHeader")); MessageDialog dialog = new MessageDialog(resources.GetString("/Main/connectErrContent"), resources.GetString("/Main/connectErrHeader"));
@@ -191,12 +241,12 @@ namespace FoxTube
break; break;
} }
if(e[0] as bool? != null) await Dispatcher.RunIdleAsync((command) => DownloadAgent.Initialize());
DownloadAgent.Initialize();
wasInvoked = false;
s = Sender.None;
if (content.Content != null) if (content.Content != null)
content.Navigate(content.SourcePageType); content.Navigate(content.CurrentSourcePageType, (content.Content as NavigationPage).Parameter);
else else
content.Navigate(typeof(Home)); content.Navigate(typeof(Home));
@@ -206,15 +256,10 @@ namespace FoxTube
private async void Feedback_Click(object sender, TappedRoutedEventArgs e) private async void Feedback_Click(object sender, TappedRoutedEventArgs e)
{ {
await Launcher.LaunchUriAsync(new Uri("feedback-hub:")); await StoreServicesFeedbackLauncher.GetDefault().LaunchAsync();
} }
private async void CreateAccount_Click(object sender, RoutedEventArgs e) private void SignIn_Click(object sender, TappedRoutedEventArgs e)
{
await Launcher.LaunchUriAsync(new Uri("https://accounts.google.com/signup/v2/webcreateaccount?ManageAccount&flowName=GlifWebSignIn&flowEntry=SignUp"));
}
private void SignIn_Click(object sender, RoutedEventArgs e)
{ {
SecretsVault.Authorize(); SecretsVault.Authorize();
} }
@@ -318,13 +363,13 @@ namespace FoxTube
public void MinimizeAsInitializer() public void MinimizeAsInitializer()
{ {
if (videoPlaceholder.Content != null) if (videoPlaceholder.Content == null)
return; return;
if ((videoPlaceholder.Content as VideoPage).LoadingPage.State != LoadingState.Loaded) if ((videoPlaceholder.Content as VideoPage).LoadingPage.State != LoadingState.Loaded)
CloseVideo(); CloseVideo();
else else
(videoPlaceholder.Content as VideoPage).Player.Controls_MiniModeChanged(this, true); (videoPlaceholder.Content as VideoPage).Player.Minimize();
try { headers[content.SourcePageType](); } try { headers[content.SourcePageType](); }
catch { } catch { }
@@ -390,6 +435,8 @@ namespace FoxTube
nav.IsBackEnabled = true; nav.IsBackEnabled = true;
else else
nav.IsBackEnabled = false; nav.IsBackEnabled = false;
SetNavigationMenu();
} }
private void Search_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args) private void Search_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
@@ -400,6 +447,7 @@ namespace FoxTube
private void Search_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args) private void Search_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{ {
//TODO: Make it run async
if (search.Text.Length > 2 && args.Reason == AutoSuggestionBoxTextChangeReason.UserInput) if (search.Text.Length > 2 && args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
{ {
try try
@@ -425,7 +473,7 @@ namespace FoxTube
if (nav.SelectedItem != item) if (nav.SelectedItem != item)
nav.SelectedItem = item; nav.SelectedItem = item;
else else
s = Sender.None; wasInvoked = false;
} }
catch { } catch { }
} }
@@ -435,9 +483,9 @@ namespace FoxTube
try { headers[e.SourcePageType](); } try { headers[e.SourcePageType](); }
catch { } catch { }
if (s == Sender.None) if (!wasInvoked)
{ {
s = Sender.Frame; wasInvoked = true;
if (e.SourcePageType == typeof(Settings)) if (e.SourcePageType == typeof(Settings))
SetNavigationItem(nav.SettingsItem); SetNavigationItem(nav.SettingsItem);
@@ -472,7 +520,7 @@ namespace FoxTube
} }
} }
else else
s = Sender.None; wasInvoked = false;
if(e.SourcePageType == typeof(History)) if(e.SourcePageType == typeof(History))
{ {
@@ -512,9 +560,9 @@ namespace FoxTube
{ {
try try
{ {
if (s == Sender.None) if (!wasInvoked)
{ {
s = Sender.Menu; wasInvoked = true;
if (args.IsSettingsSelected) if (args.IsSettingsSelected)
content.Navigate(typeof(Settings)); content.Navigate(typeof(Settings));
else else
@@ -538,7 +586,7 @@ namespace FoxTube
} }
} }
else else
s = Sender.None; wasInvoked = false;
} }
catch { } catch { }
} }
+3 -1
View File
@@ -18,8 +18,9 @@ namespace FoxTube.Pages
/// <summary> /// <summary>
/// Playlist page /// Playlist page
/// </summary> /// </summary>
public sealed partial class PlaylistPage : Page public sealed partial class PlaylistPage : Page, NavigationPage
{ {
public object Parameter { get; set; } = null;
public string playlistId; public string playlistId;
Playlist item; Playlist item;
@@ -36,6 +37,7 @@ namespace FoxTube.Pages
protected override void OnNavigatedTo(NavigationEventArgs e) protected override void OnNavigatedTo(NavigationEventArgs e)
{ {
base.OnNavigatedTo(e); base.OnNavigatedTo(e);
Parameter = e.Parameter;
if (e.Parameter == null) if (e.Parameter == null)
loading.Error("NullReferenceException", "Unable to initialize page. Playlist ID is not stated."); loading.Error("NullReferenceException", "Unable to initialize page. Playlist ID is not stated.");
else else
+3 -1
View File
@@ -16,8 +16,9 @@ namespace FoxTube
/// <summary> /// <summary>
/// Search page /// Search page
/// </summary> /// </summary>
public sealed partial class Search : Page public sealed partial class Search : Page, NavigationPage
{ {
public object Parameter { get; set; } = null;
readonly ResourceLoader resources = ResourceLoader.GetForCurrentView("Search"); readonly ResourceLoader resources = ResourceLoader.GetForCurrentView("Search");
public SearchParameters Parameters; public SearchParameters Parameters;
@@ -63,6 +64,7 @@ namespace FoxTube
protected override void OnNavigatedTo(NavigationEventArgs e) protected override void OnNavigatedTo(NavigationEventArgs e)
{ {
base.OnNavigatedTo(e); base.OnNavigatedTo(e);
Parameter = e.Parameter;
if (e.Parameter == null) if (e.Parameter == null)
loading.Error("NullReferenceException", "Unable to initialize search. Search term is not stated."); loading.Error("NullReferenceException", "Unable to initialize search. Search term is not stated.");
else else
+3 -1
View File
@@ -7,8 +7,9 @@ namespace FoxTube
/// <summary> /// <summary>
/// Settings tabs placeholder /// Settings tabs placeholder
/// </summary> /// </summary>
public sealed partial class Settings : Page public sealed partial class Settings : Page, NavigationPage
{ {
public object Parameter { get; set; } = null;
bool inboxLoaded = false; bool inboxLoaded = false;
string inboxId = null; string inboxId = null;
public Settings() public Settings()
@@ -19,6 +20,7 @@ namespace FoxTube
protected override void OnNavigatedTo(NavigationEventArgs e) protected override void OnNavigatedTo(NavigationEventArgs e)
{ {
base.OnNavigatedTo(e); base.OnNavigatedTo(e);
Parameter = e.Parameter;
if (!string.IsNullOrWhiteSpace(e.Parameter as string)) if (!string.IsNullOrWhiteSpace(e.Parameter as string))
{ {
inboxId = e.Parameter as string; inboxId = e.Parameter as string;
+1 -1
View File
@@ -47,7 +47,7 @@
<HyperlinkButton x:Uid="/About/guides" Content="YouTube Community Guidelines" NavigateUri="https://youtube.com/t/community_guidelines" Padding="0,0,0,10"/> <HyperlinkButton x:Uid="/About/guides" Content="YouTube Community Guidelines" NavigateUri="https://youtube.com/t/community_guidelines" Padding="0,0,0,10"/>
<TextBlock x:Uid="/About/crMe" Text="© 2018 Michael Gordeev"/> <TextBlock x:Uid="/About/crMe" Text="© 2018 Michael Gordeev"/>
<TextBlock x:Uid="/About/crYt" Text="© 2018 YouTube, LLC"/> <TextBlock x:Uid="/About/crYt" Text="© 2018 YouTube, LLC"/>
<Button x:Uid="/About/feedback" Content="Leave feedback" Margin="0,5" Click="Button_Click"/> <Button Name="feedback" x:Uid="/About/feedback" Content="Leave feedback" Margin="0,5" Click="Button_Click" Visibility="Collapsed"/>
</StackPanel> </StackPanel>
<Image Grid.Column="1" Source="/Assets/LogoAvatar.png" VerticalAlignment="Top" Width="128"/> <Image Grid.Column="1" Source="/Assets/LogoAvatar.png" VerticalAlignment="Top" Width="128"/>
</Grid> </Grid>
+6 -2
View File
@@ -1,4 +1,5 @@
using System; using Microsoft.Services.Store.Engagement;
using System;
using Windows.ApplicationModel; using Windows.ApplicationModel;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
@@ -15,11 +16,14 @@ namespace FoxTube.Pages.SettingsPages
InitializeComponent(); InitializeComponent();
PackageVersion ver = Package.Current.Id.Version; PackageVersion ver = Package.Current.Id.Version;
version.Text = $"{ver.Major}.{ver.Minor}.{ver.Build}"; version.Text = $"{ver.Major}.{ver.Minor}.{ver.Build}";
if (StoreServicesFeedbackLauncher.IsSupported())
feedback.Visibility = Visibility.Visible;
} }
private async void Button_Click(object sender, RoutedEventArgs e) private async void Button_Click(object sender, RoutedEventArgs e)
{ {
await Windows.System.Launcher.LaunchUriAsync(new Uri("feedback-hub:")); await StoreServicesFeedbackLauncher.GetDefault().LaunchAsync();
} }
} }
} }
+4 -4
View File
@@ -126,20 +126,20 @@ namespace FoxTube.Pages.SettingsPages
if (sender == light && SettingsStorage.Theme != 0) if (sender == light && SettingsStorage.Theme != 0)
{ {
SettingsStorage.Theme = 0; SettingsStorage.Theme = 0;
Application.Current.RequestedTheme = ApplicationTheme.Light; Methods.MainPage.RequestedTheme = ElementTheme.Light;
} }
else if (sender == dark && SettingsStorage.Theme != 1) else if (sender == dark && SettingsStorage.Theme != 1)
{ {
SettingsStorage.Theme = 1; SettingsStorage.Theme = 1;
Application.Current.RequestedTheme = ApplicationTheme.Dark; Methods.MainPage.RequestedTheme = ElementTheme.Dark;
} }
else if (sender == system && SettingsStorage.Theme != 2) else if (sender == system && SettingsStorage.Theme != 2)
{ {
SettingsStorage.Theme = 2; SettingsStorage.Theme = 2;
if (new Windows.UI.ViewManagement.UISettings().GetColorValue(Windows.UI.ViewManagement.UIColorType.Background) == Colors.Black) if (new Windows.UI.ViewManagement.UISettings().GetColorValue(Windows.UI.ViewManagement.UIColorType.Background) == Colors.Black)
Application.Current.RequestedTheme = ApplicationTheme.Dark; Methods.MainPage.RequestedTheme = ElementTheme.Dark;
else else
Application.Current.RequestedTheme = ApplicationTheme.Light; Methods.MainPage.RequestedTheme = ElementTheme.Light;
} }
Methods.MainPage.SetTitleBar(); Methods.MainPage.SetTitleBar();
} }
+2 -1
View File
@@ -8,8 +8,9 @@ namespace FoxTube.Pages
/// <summary> /// <summary>
/// User's subscriptions page /// User's subscriptions page
/// </summary> /// </summary>
public sealed partial class Subscriptions : Page public sealed partial class Subscriptions : Page, NavigationPage
{ {
public object Parameter { get; set; } = null;
readonly List<Subscription> list = SecretsVault.Subscriptions; readonly List<Subscription> list = SecretsVault.Subscriptions;
public Subscriptions() public Subscriptions()
{ {
+15 -11
View File
@@ -4,18 +4,22 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:Microsoft.Toolkit.Uwp.UI.Controls"
x:Name="root"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Name="grid" SizeChanged="Grid_SizeChanged">
<ui:AdaptiveGridView Name="list" DesiredWidth="400" SelectionMode="None" HorizontalContentAlignment="Left"> <Grid.ColumnDefinitions>
<ui:AdaptiveGridView.ItemContainerTransitions> <ColumnDefinition/>
<TransitionCollection> <ColumnDefinition Width="0"/>
<EntranceThemeTransition IsStaggeringEnabled="True"/> <ColumnDefinition Width="0"/>
</TransitionCollection> <ColumnDefinition Width="0"/>
</ui:AdaptiveGridView.ItemContainerTransitions> <ColumnDefinition Width="0"/>
</ui:AdaptiveGridView> </Grid.ColumnDefinitions>
<TextBlock Name="empty" Text="&#xD8;" FontSize="200" Foreground="Gray" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.RowSpan="2"/> <TextBlock Name="empty" Grid.ColumnSpan="5" Text="&#xD8;" FontSize="200" Foreground="Gray" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.RowSpan="2"/>
<StackPanel Grid.Column="0" Name="col0"/>
<StackPanel Grid.Column="1" Name="col1"/>
<StackPanel Grid.Column="2" Name="col2"/>
<StackPanel Grid.Column="3" Name="col3"/>
<StackPanel Grid.Column="4" Name="col4"/>
</Grid> </Grid>
</Page> </Page>
+47 -7
View File
@@ -1,6 +1,4 @@
using FoxTube.Controls; using System.Collections.Generic;
using System;
using System.Collections.Generic;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
@@ -11,8 +9,18 @@ namespace FoxTube.Pages
/// </summary> /// </summary>
public sealed partial class VideoGrid : Page public sealed partial class VideoGrid : Page
{ {
public int Count => list.Items.Count; public int Columns
public ItemCollection Children => list.Items; {
get { return cols; }
set
{
cols = value;
UpdateGrid();
}
}
private int cols = 1;
public int Count => Children.Count;
public List<UIElement> Children { get; } = new List<UIElement>();
public VideoGrid() public VideoGrid()
{ {
@@ -21,7 +29,8 @@ namespace FoxTube.Pages
public void Add(UIElement card) public void Add(UIElement card)
{ {
list.Items.Add(card); (grid.Children[Count % cols + 1] as StackPanel).Children.Add(card);
Children.Add(card);
/*if (list.Items.Count % 10 == 0) /*if (list.Items.Count % 10 == 0)
list.Items.Add(new CardAdvert());*/ list.Items.Add(new CardAdvert());*/
empty.Visibility = Visibility.Collapsed; empty.Visibility = Visibility.Collapsed;
@@ -29,8 +38,39 @@ namespace FoxTube.Pages
public void Clear() public void Clear()
{ {
list.Items.Clear(); for (int k = 1; k <= 5; k++)
(grid.Children[k] as StackPanel).Children.Clear();
empty.Visibility = Visibility.Visible; empty.Visibility = Visibility.Visible;
} }
void UpdateGrid()
{
for (int k = 1; k <= 5; k++)
(grid.Children[k] as StackPanel).Children.Clear();
for (int k = 0; k < Count; k++)
(grid.Children[k % cols + 1] as StackPanel).Children.Add(Children[k]);
for (int k = 0; k < cols; k++)
grid.ColumnDefinitions[k].Width = new GridLength(1, GridUnitType.Star);
for (int k = cols; k < 5; k++)
grid.ColumnDefinitions[k].Width = new GridLength(0);
}
private void Grid_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (e.NewSize.Width >= 1600 && Columns != 5)
Columns = 5;
else if (e.NewSize.Width >= 1200 && e.NewSize.Width < 1600 && Columns != 4)
Columns = 4;
else if (e.NewSize.Width >= 900 && e.NewSize.Width < 1200 && Columns != 3)
Columns = 3;
else if (e.NewSize.Width >= 550 && e.NewSize.Width < 900 && Columns != 2)
Columns = 2;
else if (e.NewSize.Width < 550 && Columns != 1)
Columns = 1;
}
} }
} }
+1 -1
View File
@@ -9,7 +9,6 @@
xmlns:controls1="using:FoxTube.Controls" xmlns:controls1="using:FoxTube.Controls"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid Name="grid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" SizeChanged="grid_SizeChanged"> <Grid Name="grid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" SizeChanged="grid_SizeChanged">
<VisualStateManager.VisualStateGroups> <VisualStateManager.VisualStateGroups>
<VisualStateGroup> <VisualStateGroup>
@@ -61,6 +60,7 @@
<PivotItem Header="Description" Name="descriptionPanel"> <PivotItem Header="Description" Name="descriptionPanel">
<StackPanel Margin="0,10"> <StackPanel Margin="0,10">
<TextBlock IsTextSelectionEnabled="True" Name="title" Text="[Video title]" FontSize="25" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Start"/> <TextBlock IsTextSelectionEnabled="True" Name="title" Text="[Video title]" FontSize="25" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Start"/>
<TextBlock Text="Published at: " Name="date"/>
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
+2 -2
View File
@@ -53,7 +53,6 @@ namespace FoxTube.Pages
public Video item; public Video item;
bool isExtended = false; bool isExtended = false;
bool playlistLoaded = false;
Rating userRating = Rating.None; Rating userRating = Rating.None;
@@ -229,6 +228,7 @@ namespace FoxTube.Pages
{ {
//Setting meta //Setting meta
title.Text = item.Snippet.Title; title.Text = item.Snippet.Title;
date.Text = $"{resources.GetString("/VideoPage/publishedAt")}: {item.Snippet.PublishedAt} ({Methods.GetAgo(item.Snippet.PublishedAt.Value)})";
Methods.FormatText(ref description, item.Snippet.Description); Methods.FormatText(ref description, item.Snippet.Description);
//Setting channel button //Setting channel button
@@ -366,7 +366,7 @@ namespace FoxTube.Pages
SearchListResponse response = await request.ExecuteAsync(); SearchListResponse response = await request.ExecuteAsync();
foreach (SearchResult video in response.Items) foreach (SearchResult video in response.Items)
relatedVideos.Children.Add(new VideoCard(video.Id.VideoId)); relatedVideos.Add(new VideoCard(video.Id.VideoId));
} }
private void Player_Minimize(object sender, params object[] e) private void Player_Minimize(object sender, params object[] e)
+1 -1
View File
@@ -180,7 +180,7 @@
<data name="signEx.Text" xml:space="preserve"> <data name="signEx.Text" xml:space="preserve">
<value>Sign in with existing account</value> <value>Sign in with existing account</value>
</data> </data>
<data name="signIn.Text" xml:space="preserve"> <data name="signIn.Content" xml:space="preserve">
<value>Add account</value> <value>Add account</value>
</data> </data>
<data name="signNew.Text" xml:space="preserve"> <data name="signNew.Text" xml:space="preserve">
+3
View File
@@ -261,4 +261,7 @@
<data name="yes" xml:space="preserve"> <data name="yes" xml:space="preserve">
<value>Yes</value> <value>Yes</value>
</data> </data>
<data name="publishedAt" xml:space="preserve">
<value>Published at</value>
</data>
</root> </root>
+1 -1
View File
@@ -180,7 +180,7 @@
<data name="signEx.Text" xml:space="preserve"> <data name="signEx.Text" xml:space="preserve">
<value>Войти с помощью существующего аккаунта Google</value> <value>Войти с помощью существующего аккаунта Google</value>
</data> </data>
<data name="signIn.Text" xml:space="preserve"> <data name="signIn.Content" xml:space="preserve">
<value>Войти в аккаунт</value> <value>Войти в аккаунт</value>
</data> </data>
<data name="signNew.Text" xml:space="preserve"> <data name="signNew.Text" xml:space="preserve">
+3
View File
@@ -261,4 +261,7 @@
<data name="yes" xml:space="preserve"> <data name="yes" xml:space="preserve">
<value>Да</value> <value>Да</value>
</data> </data>
<data name="publishedAt" xml:space="preserve">
<value>Опубликовано</value>
</data>
</root> </root>
+2 -1
View File
@@ -533,6 +533,7 @@
<Button x:Name="compactClose" VerticalAlignment="Top" HorizontalAlignment="Right"> <Button x:Name="compactClose" VerticalAlignment="Top" HorizontalAlignment="Right">
<FontIcon Glyph="&#xE106;"/> <FontIcon Glyph="&#xE106;"/>
</Button> </Button>
<Button Height="32" Width="50" Margin="0,0,48,0" VerticalAlignment="Top" HorizontalAlignment="Right" FontFamily="Segoe MDL2 Assets" Content="&#xE700;" IsHitTestVisible="False" x:Name="dragholder"/>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center" x:Name="centralStack"/> <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center" x:Name="centralStack"/>
@@ -578,7 +579,7 @@
<Grid Grid.Column="1" Margin="10,5"> <Grid Grid.Column="1" Margin="10,5">
<TextBlock VerticalAlignment="Bottom" HorizontalAlignment="Left" x:Name="TimeElapsedElement" Text="00:00"/> <TextBlock VerticalAlignment="Bottom" HorizontalAlignment="Left" x:Name="TimeElapsedElement" Text="00:00"/>
<TextBlock VerticalAlignment="Bottom" HorizontalAlignment="Right" x:Name="TimeRemainingElement" Text="00:00"/> <TextBlock VerticalAlignment="Bottom" HorizontalAlignment="Right" x:Name="TimeRemainingElement" Text="00:00"/>
<Grid VerticalAlignment="Top" Height="3" Margin="0,15,0,0"> <Grid VerticalAlignment="Top" Height="4" Margin="0,15,0,0">
<ProgressBar Background="#66FFFFFF" Foreground="#66FFFFFF" x:Name="BufferingProgressBar"/> <ProgressBar Background="#66FFFFFF" Foreground="#66FFFFFF" x:Name="BufferingProgressBar"/>
</Grid> </Grid>
<Slider x:Name="ProgressSlider" Style="{StaticResource PlayerSeek}" IsThumbToolTipEnabled="False" Background="Transparent" HorizontalAlignment="Stretch" VerticalAlignment="Top"/> <Slider x:Name="ProgressSlider" Style="{StaticResource PlayerSeek}" IsThumbToolTipEnabled="False" Background="Transparent" HorizontalAlignment="Stretch" VerticalAlignment="Top"/>
+51
View File
@@ -0,0 +1,51 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28705.295
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoxTubeDevPortal", "FoxTubeDevPortal\FoxTubeDevPortal.csproj", "{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Debug|ARM.ActiveCfg = Debug|ARM
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Debug|ARM.Build.0 = Debug|ARM
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Debug|ARM.Deploy.0 = Debug|ARM
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Debug|ARM64.ActiveCfg = Debug|ARM64
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Debug|ARM64.Build.0 = Debug|ARM64
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Debug|ARM64.Deploy.0 = Debug|ARM64
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Debug|x64.ActiveCfg = Debug|x64
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Debug|x64.Build.0 = Debug|x64
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Debug|x64.Deploy.0 = Debug|x64
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Debug|x86.ActiveCfg = Debug|x86
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Debug|x86.Build.0 = Debug|x86
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Debug|x86.Deploy.0 = Debug|x86
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Release|ARM.ActiveCfg = Release|ARM
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Release|ARM.Build.0 = Release|ARM
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Release|ARM.Deploy.0 = Release|ARM
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Release|ARM64.ActiveCfg = Release|ARM64
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Release|ARM64.Build.0 = Release|ARM64
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Release|ARM64.Deploy.0 = Release|ARM64
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Release|x64.ActiveCfg = Release|x64
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Release|x64.Build.0 = Release|x64
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Release|x64.Deploy.0 = Release|x64
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Release|x86.ActiveCfg = Release|x86
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Release|x86.Build.0 = Release|x86
{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2CCDEED5-E131-470C-AAC6-8798DF866019}
EndGlobalSection
EndGlobal
@@ -0,0 +1,7 @@
<Application
x:Class="FoxTubeDevPortal.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FoxTubeDevPortal">
</Application>
@@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
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;
namespace FoxTubeDevPortal
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
sealed partial class App : Application
{
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (e.PrelaunchActivated == false)
{
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
// Ensure the current window is active
Window.Current.Activate();
}
}
/// <summary>
/// Invoked when Navigation to a certain page fails
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
//TODO: Save application state and stop any background activity
deferral.Complete();
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

@@ -0,0 +1,34 @@
<Page
x:Class="FoxTubeDevPortal.Browser"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FoxTubeDevPortal"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal">
<Button Content="&#xE0A6;" Height="32" FontFamily="Segoe MDL2 Assets" Name="back" Click="Back_Click"/>
<Button Content="&#xE0AB;" Height="32" FontFamily="Segoe MDL2 Assets" Name="forward" Click="Forward_Click"/>
<Button Content="&#xE117;" Height="32" FontFamily="Segoe MDL2 Assets" Name="refresh" Click="Refresh_Click"/>
<Button Content="&#xE143;" Height="32" FontFamily="Segoe MDL2 Assets" Name="go" Click="Go_Click"/>
</StackPanel>
<TextBox Grid.Column="1" Name="sitebar"/>
</Grid>
<WebView Name="view" Grid.Row="1" NavigationStarting="View_NavigationStarting"/>
</Grid>
</Page>
@@ -0,0 +1,47 @@
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace FoxTubeDevPortal
{
public sealed partial class Browser : Page
{
public bool IsAppCenter { get; set; } = false;
public Browser()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
view.Navigate(new System.Uri(IsAppCenter ? "https://appcenter.ms/users/XFox/apps/FoxTube/" : "https://partner.microsoft.com/en-us/dashboard/windows/overview"));
}
private void View_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
{
back.IsEnabled = view.CanGoBack;
forward.IsEnabled = view.CanGoForward;
sitebar.Text = view.Source.AbsoluteUri;
}
private void Go_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
view.Navigate(new System.Uri(sitebar.Text));
}
private void Refresh_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
view.Refresh();
}
private void Forward_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
view.GoForward();
}
private void Back_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
view.GoBack();
}
}
}
@@ -0,0 +1,194 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{E8208BA2-CBE5-47D8-8BCB-75E0FF90EC11}</ProjectGuid>
<OutputType>AppContainerExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>FoxTubeDevPortal</RootNamespace>
<AssemblyName>FoxTubeDevPortal</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.17763.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WindowsXamlEnableOverview>true</WindowsXamlEnableOverview>
<PackageCertificateKeyFile>FoxTubeDevPortal_TemporaryKey.pfx</PackageCertificateKeyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\ARM\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
<OutputPath>bin\ARM\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\ARM64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>ARM64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM64'">
<OutputPath>bin\ARM64\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>ARM64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup>
<ItemGroup>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="Browser.xaml.cs">
<DependentUpon>Browser.xaml</DependentUpon>
</Compile>
<Compile Include="MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Include="Message.cs" />
<Compile Include="Messages.xaml.cs">
<DependentUpon>Messages.xaml</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Settings.xaml.cs">
<DependentUpon>Settings.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
<None Include="FoxTubeDevPortal_TemporaryKey.pfx" />
</ItemGroup>
<ItemGroup>
<Content Include="Properties\Default.rd.xml" />
<Content Include="Assets\LockScreenLogo.scale-200.png" />
<Content Include="Assets\SplashScreen.scale-200.png" />
<Content Include="Assets\Square150x150Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Assets\StoreLogo.png" />
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="Browser.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="MainPage.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Messages.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Settings.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.2.8</Version>
</PackageReference>
<PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls">
<Version>5.1.1</Version>
</PackageReference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
</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.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
@@ -0,0 +1,47 @@
<Page
x:Class="FoxTubeDevPortal.MainPage"
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:foxtubedevportal="using:FoxTubeDevPortal"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Border x:Name="AppTitleBar"
IsHitTestVisible="True"
VerticalAlignment="Top"
Background="Transparent"
Canvas.ZIndex="1">
<TextBlock x:Name="AppTitle"
Text="FoxTube"
VerticalAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}" />
</Border>
<NavigationView PaneTitle="Menu" PaneDisplayMode="Top" AlwaysShowHeader="False" SelectionChanged="NavigationView_SelectionChanged" SelectedItem="{x:Bind messages}">
<NavigationView.MenuItems>
<NavigationViewItem Icon="Message" Content="Messages" x:Name="messages"/>
<NavigationViewItem Icon="Flag" Content="Partner center" x:Name="partner"/>
<NavigationViewItem Icon="Admin" Content="App center" x:Name="app"/>
</NavigationView.MenuItems>
<Pivot Padding="0,-48,0,0" Name="pivot">
<PivotItem Margin="0">
<foxtubedevportal:Messages/>
</PivotItem>
<PivotItem Margin="0">
<foxtubedevportal:Browser/>
</PivotItem>
<PivotItem Margin="0">
<foxtubedevportal:Browser IsAppCenter="True"/>
</PivotItem>
<PivotItem Margin="0">
<foxtubedevportal:Settings/>
</PivotItem>
</Pivot>
</NavigationView>
</Grid>
</Page>
@@ -0,0 +1,55 @@
using Windows.ApplicationModel.Core;
using Windows.UI;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace FoxTubeDevPortal
{
public sealed partial class MainPage : Page
{
public MainPage()
{
InitializeComponent();
Window.Current.SetTitleBar(AppTitleBar);
CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
CoreApplication.GetCurrentView().TitleBar.LayoutMetricsChanged += (s, e) => SetTitleBar(s);
}
public void SetTitleBar(CoreApplicationViewTitleBar coreTitleBar = null)
{
if (coreTitleBar != null)
{
bool full = ApplicationView.GetForCurrentView().IsFullScreenMode;
double left = 12 + (full ? 0 : coreTitleBar.SystemOverlayLeftInset);
AppTitle.Margin = new Thickness(left, 8, 0, 0);
AppTitleBar.Height = coreTitleBar.Height;
}
var titleBar = ApplicationView.GetForCurrentView().TitleBar;
titleBar.ButtonBackgroundColor = Colors.Transparent;
titleBar.ButtonHoverBackgroundColor = Colors.IndianRed;
titleBar.ButtonPressedBackgroundColor = Colors.DarkRed;
titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
titleBar.ButtonInactiveForegroundColor = Colors.Gray;
if (Application.Current.RequestedTheme == ApplicationTheme.Dark)
titleBar.ForegroundColor = Colors.White;
else
titleBar.ForegroundColor = Colors.Black;
}
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
if (args.IsSettingsSelected)
pivot.SelectedIndex = 3;
else if (args.SelectedItem == messages)
pivot.SelectedIndex = 0;
else if (args.SelectedItem == partner)
pivot.SelectedIndex = 1;
else if (args.SelectedItem == app)
pivot.SelectedIndex = 2;
}
}
}
@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FoxTubeDevPortal
{
public class Message
{
public string Id;
public List<string> Languages;
public Dictionary<string, string> Header;
public Dictionary<string, string> Content;
public DateTime Date;
public string Thumbnail;
public string Avatar;
public string GetSourceCode()
{
string headers = string.Empty;
foreach (var i in Header)
headers += $@" <{i.Key}>{i.Value}</{i.Key}>
";
string contents = string.Empty;
foreach (var i in Content)
contents += $@" <{i.Key}>{i.Value}</{i.Key}>
";
return $@"<post time='2/14/2019 01:30:00 AM'>
<id>{Id}</id>
<header>
{headers}</header>
<content>
{contents}</content>
<thumbnail>{Thumbnail}</thumbnail>
<avatar>{Avatar}</avatar>
</post>";
}
}
}
@@ -0,0 +1,87 @@
<Page
x:Class="FoxTubeDevPortal.Messages"
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.Toolkit.Uwp.UI.Controls"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<NavigationView IsSettingsVisible="False" IsBackButtonVisible="Collapsed" PaneTitle="Messages list">
<NavigationView.MenuItems>
<NavigationViewItem Icon="Message" HorizontalContentAlignment="Stretch" Content="Hello, World!"/>
<NavigationViewItem Icon="Message" HorizontalContentAlignment="Stretch" Content="Hello, World!"/>
<NavigationViewItem Icon="Message" HorizontalContentAlignment="Stretch" Content="Hello, World!"/>
<NavigationViewItem Icon="Message" HorizontalContentAlignment="Stretch" Content="Hello, World!"/>
</NavigationView.MenuItems>
<NavigationView.PaneFooter>
<NavigationViewItem Icon="Add" Content="New message"/>
</NavigationView.PaneFooter>
<Pivot>
<PivotItem Header="Preview">
<ScrollViewer Grid.Column="1">
<StackPanel Margin="10">
<Grid>
<TextBlock FontWeight="Bold" Text="Hello, World!" FontSize="26" Name="title"/>
<ComboBox Width="150" HorizontalAlignment="Right">
<ComboBoxItem Content="Russian"/>
<ComboBoxItem Content="English"/>
</ComboBox>
</Grid>
<controls:MarkdownTextBlock IsTextSelectionEnabled="True" Text="Content" Name="content"/><!--Replace with MarkdownTextBlock-->
</StackPanel>
</ScrollViewer>
</PivotItem>
<PivotItem Header="Info">
<StackPanel>
<TextBlock Text="Supported languages:" FontWeight="Bold"/>
<TextBlock Text=" ru-RU, en-US"/>
<TextBlock Text="Title:" FontWeight="Bold"/>
<TextBlock Text=" [Title]"/>
<TextBlock Text=" [Title]"/>
<TextBlock Text="Content:" FontWeight="Bold"/>
<TextBlock Text=" [Text]"/>
<TextBlock Text=" [Text]"/>
<TextBlock Text="Publish date:" FontWeight="Bold"/>
<TextBlock Text=" 3/9/2019 9:43:00 PM"/>
<TextBlock Text="Thumbnail:" FontWeight="Bold"/>
<HyperlinkButton Content="Open"/>
<TextBlock Text="Avatar:" FontWeight="Bold"/>
<HyperlinkButton Content="Open"/>
<TextBlock Text="Source code:" FontWeight="Bold"/>
<Border CornerRadius="5" Background="DimGray" Padding="10">
<TextBlock Text="Code"/>
</Border>
</StackPanel>
</PivotItem>
<PivotItem Header="Editor">
<StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<HyperlinkButton Content="Markdown cheatsheet" Margin="10,0"/>
<ComboBox Width="150" HorizontalAlignment="Right">
<ComboBoxItem Content="Russian"/>
<ComboBoxItem Content="English"/>
</ComboBox>
</StackPanel>
<TextBox Header="Language 4-letter code"/>
<TextBox Header="Title"/>
<TextBox Header="Content" AcceptsReturn="True" Height="auto"/>
<DatePicker Header="Publish at"/>
<TimePicker Margin="0,10"/>
<TextBox Header="Thumbnail URL"/>
<Button Content="Attach file"/>
<TextBox Header="Avatar URL"/>
<Button Content="Attach file"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="Delete" Foreground="Red" Margin="10,0"/>
<Button Content="Submit"/>
</StackPanel>
</StackPanel>
</PivotItem>
</Pivot>
</NavigationView>
</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 FoxTubeDevPortal
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class Messages : Page
{
public Messages()
{
this.InitializeComponent();
}
}
}
@@ -0,0 +1,49 @@
<?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"
IgnorableNamespaces="uap mp">
<Identity
Name="eea8fbb3-4240-4bd2-b1ae-fee9efe8c823"
Publisher="CN=XFox"
Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="eea8fbb3-4240-4bd2-b1ae-fee9efe8c823" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>FoxTubeDevPortal</DisplayName>
<PublisherDisplayName>XFox</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="FoxTubeDevPortal.App">
<uap:VisualElements
DisplayName="FoxTubeDevPortal"
Square150x150Logo="Assets\Square150x150Logo.png"
Square44x44Logo="Assets\Square44x44Logo.png"
Description="FoxTubeDevPortal"
BackgroundColor="transparent">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"/>
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
</Capabilities>
</Package>
@@ -0,0 +1,29 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("FoxTubeDevPortal")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FoxTubeDevPortal")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]
@@ -0,0 +1,31 @@
<!--
This file contains Runtime Directives used by .NET Native. The defaults here are suitable for most
developers. However, you can modify these parameters to modify the behavior of the .NET Native
optimizer.
Runtime Directives are documented at https://go.microsoft.com/fwlink/?LinkID=391919
To fully enable reflection for App1.MyClass and all of its public/private members
<Type Name="App1.MyClass" Dynamic="Required All"/>
To enable dynamic creation of the specific instantiation of AppClass<T> over System.Int32
<TypeInstantiation Name="App1.AppClass" Arguments="System.Int32" Activate="Required Public" />
Using the Namespace directive to apply reflection policy to all the types in a particular namespace
<Namespace Name="DataClasses.ViewModels" Serialize="All" />
-->
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<!--
An Assembly element with Name="*Application*" applies to all assemblies in
the application package. The asterisks are not wildcards.
-->
<Assembly Name="*Application*" Dynamic="Required All" />
<!-- Add your application specific runtime directives here. -->
</Application>
</Directives>
@@ -0,0 +1,18 @@
<Page
x:Class="FoxTubeDevPortal.Settings"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FoxTubeDevPortal"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<TextBox Header="Domain name"/>
<TextBox Header="Username"/>
<TextBox Header="Password"/>
<Button Content="Check"/>
<HyperlinkButton Content="Open messages in browser"/>
</StackPanel>
</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 FoxTubeDevPortal
{
/// <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();
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1023 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1010 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 818 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 340 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 391 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 KiB