Archived
1
0

App UI development

Updated and enchanced MainPage
Updated Core
This commit is contained in:
Michael Gordeev
2020-05-12 01:32:41 +03:00
parent f89bf80018
commit a792132428
54 changed files with 2684 additions and 1479 deletions
+16
View File
@@ -6,7 +6,9 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Xml; using System.Xml;
using Windows.Devices.PointOfService;
using Windows.UI; using Windows.UI;
using Windows.UI.Xaml.Media.Imaging;
namespace FoxTube namespace FoxTube
{ {
@@ -39,6 +41,9 @@ namespace FoxTube
public static bool Belongs<T>(this T obj, params T[] args) => public static bool Belongs<T>(this T obj, params T[] args) =>
args.Contains(obj); args.Contains(obj);
public static bool Belongs(this int number, int lowerLimit, int upperLimit) =>
number >= lowerLimit && number <= upperLimit;
public static string ToHex(this Color color) => public static string ToHex(this Color color) =>
$"#{color.R:X}{color.G:X}{color.B:X}"; $"#{color.R:X}{color.G:X}{color.B:X}";
@@ -57,6 +62,17 @@ namespace FoxTube
}; };
} }
public static BitmapImage LoadImage (this BitmapImage image, string source, int? height = null, int? width = null)
{
image.UriSource = source.ToUri();
if (height.HasValue)
image.DecodePixelHeight = height.Value;
if (width.HasValue)
image.DecodePixelWidth = width.Value;
return image;
}
public static TimeSpan GetDuration(this string rawDuration) public static TimeSpan GetDuration(this string rawDuration)
{ {
try try
+1 -10
View File
@@ -167,9 +167,6 @@
<PackageReference Include="Google.Apis.YouTube.v3"> <PackageReference Include="Google.Apis.YouTube.v3">
<Version>1.45.0.1929</Version> <Version>1.45.0.1929</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Advertising.XAML">
<Version>10.1811.22001</Version>
</PackageReference>
<PackageReference Include="Microsoft.AppCenter.Analytics"> <PackageReference Include="Microsoft.AppCenter.Analytics">
<Version>3.2.1</Version> <Version>3.2.1</Version>
</PackageReference> </PackageReference>
@@ -186,22 +183,16 @@
<Version>2.4.0</Version> <Version>2.4.0</Version>
</PackageReference> </PackageReference>
<PackageReference Include="YoutubeExplode"> <PackageReference Include="YoutubeExplode">
<Version>5.0.3</Version> <Version>5.0.4</Version>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<WCFMetadata Include="Connected Services\" /> <WCFMetadata Include="Connected Services\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<SDKReference Include="Microsoft.Advertising.Xaml, Version=10.0">
<Name>Microsoft Advertising SDK for XAML</Name>
</SDKReference>
<SDKReference Include="Microsoft.Services.Store.Engagement, Version=10.0"> <SDKReference Include="Microsoft.Services.Store.Engagement, Version=10.0">
<Name>Microsoft Engagement Framework</Name> <Name>Microsoft Engagement Framework</Name>
</SDKReference> </SDKReference>
<SDKReference Include="Microsoft.VCLibs, Version=14.0">
<Name>Visual C++ 2015 Runtime for Universal Windows Platform Apps</Name>
</SDKReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="ValueConverters\" /> <Folder Include="ValueConverters\" />
+4 -1
View File
@@ -133,7 +133,10 @@ namespace FoxTube
return "en-US"; return "en-US";
} }
public static void ResetSettings() => public static void ResetSettings()
{
settings.Values.Clear(); settings.Values.Clear();
ApplicationData.Current.LocalSettings.Values.Clear();
}
} }
} }
+25 -16
View File
@@ -22,7 +22,7 @@ namespace FoxTube
{ {
public static class UserManagement public static class UserManagement
{ {
public const int MaxUsersCount = 2; public const int MaxUsersCount = 1;
#region Private members #region Private members
private static readonly ApplicationDataContainer storage = ApplicationData.Current.LocalSettings; private static readonly ApplicationDataContainer storage = ApplicationData.Current.LocalSettings;
@@ -48,16 +48,13 @@ namespace FoxTube
{ {
ClientId = "349735264870-2ekqlm0a4mkg3mmrfcv90s3qp3o15dq0.apps.googleusercontent.com", ClientId = "349735264870-2ekqlm0a4mkg3mmrfcv90s3qp3o15dq0.apps.googleusercontent.com",
ClientSecret = "BkVZOAaCU2Zclf0Zlicg6y2_" ClientSecret = "BkVZOAaCU2Zclf0Zlicg6y2_"
},
new ClientSecrets // DISABLED
{
ClientId = "1096685398208-u95rcpkqb4e1ijfmb8jdq3jsg37l8igv.apps.googleusercontent.com",
ClientSecret = "IU5bbdjwvmx8ttJoXQ7e6JWd"
} }
}; };
#endregion #endregion
public static Userinfoplus[] Users { get; private set; } = new Userinfoplus[MaxUsersCount]; public static Userinfoplus[] Users { get; private set; } = new Userinfoplus[MaxUsersCount];
public static bool CanAddAccounts => Users.Any(i => i == null);
public static User CurrentUser { get; set; } public static User CurrentUser { get; set; }
public static bool Authorized => CurrentUser != null; public static bool Authorized => CurrentUser != null;
public static ExtendedYouTubeService Service => CurrentUser?.Service ?? _defaultService; public static ExtendedYouTubeService Service => CurrentUser?.Service ?? _defaultService;
@@ -108,7 +105,7 @@ namespace FoxTube
public static async Task Initialize() public static async Task Initialize()
{ {
Users = JsonConvert.DeserializeObject<Userinfoplus[]>(storage.Values["UserManagement.Users"] as string); Users = JsonConvert.DeserializeObject<Userinfoplus[]>(storage.Values["UserManagement.Users"] as string ?? "") ?? new Userinfoplus[MaxUsersCount];
int? lastUserIndex = storage.Values["UserManagement.LastUser"] as int?; int? lastUserIndex = storage.Values["UserManagement.LastUser"] as int?;
if (lastUserIndex.HasValue && Users[lastUserIndex.Value] != null || if (lastUserIndex.HasValue && Users[lastUserIndex.Value] != null ||
@@ -126,8 +123,12 @@ namespace FoxTube
string userId = CurrentUser.UserInfo.Id; string userId = CurrentUser.UserInfo.Id;
PasswordVault passwordVault = new PasswordVault(); PasswordVault passwordVault = new PasswordVault();
try
{
PasswordCredential credential = passwordVault.Retrieve("foxtube", userId); PasswordCredential credential = passwordVault.Retrieve("foxtube", userId);
passwordVault.Remove(credential); passwordVault.Remove(credential);
}
catch { }
await CurrentUser.Credential.RevokeTokenAsync(CancellationToken.None); await CurrentUser.Credential.RevokeTokenAsync(CancellationToken.None);
@@ -159,20 +160,27 @@ namespace FoxTube
} }
} }
public static async Task SwitchUser(int userIndex) public static async Task<bool> SwitchUser(int userIndex)
{ {
Userinfoplus userInfo = Users[userIndex]; Userinfoplus userInfo = Users[userIndex];
PasswordVault valut = new PasswordVault(); PasswordVault valut = new PasswordVault();
try
{
PasswordCredential vaultCredential = valut.Retrieve("foxtube", userInfo.Id); PasswordCredential vaultCredential = valut.Retrieve("foxtube", userInfo.Id);
if (vaultCredential == null)
throw new NullReferenceException("No user found to switch on");
vaultCredential.RetrievePassword(); vaultCredential.RetrievePassword();
string token = vaultCredential.Password; string token = vaultCredential.Password;
YouTube.Authorization.UserCredential credential = await AuthorizationHelpers.RestoreUser(ClientSecrets[userIndex], token); YouTube.Authorization.UserCredential credential = await AuthorizationHelpers.RestoreUser(ClientSecrets[userIndex], token);
await LoadUser(credential, userIndex); await LoadUser(credential, userIndex);
return true;
}
catch
{
return false;
}
} }
private static async Task LoadUser(YouTube.Authorization.UserCredential credential, int userIndex) private static async Task LoadUser(YouTube.Authorization.UserCredential credential, int userIndex)
@@ -192,15 +200,16 @@ namespace FoxTube
private static void UpdateToken(string id, string refreshToken) private static void UpdateToken(string id, string refreshToken)
{ {
PasswordVault passwordVault = new PasswordVault(); PasswordVault passwordVault = new PasswordVault();
PasswordCredential vaultCredential = passwordVault.Retrieve("foxtube", id); try
if (vaultCredential == null)
{ {
vaultCredential = new PasswordCredential("foxtube", CurrentUser.UserInfo.Id, refreshToken); PasswordCredential vaultCredential = passwordVault.Retrieve("foxtube", id);
vaultCredential.Password = refreshToken;
}
catch
{
PasswordCredential vaultCredential = new PasswordCredential("foxtube", CurrentUser.UserInfo.Id, refreshToken);
passwordVault.Add(vaultCredential); passwordVault.Add(vaultCredential);
} }
else
vaultCredential.Password = refreshToken;
} }
internal static void SubscriptionsChangedInvoker(User sender, Subscription subscription) => internal static void SubscriptionsChangedInvoker(User sender, Subscription subscription) =>
+3 -6
View File
@@ -1,5 +1,4 @@
using Microsoft.Advertising.WinRT.UI; using Microsoft.AppCenter.Crashes;
using Microsoft.AppCenter.Crashes;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Windows.Services.Store; using Windows.Services.Store;
@@ -14,12 +13,10 @@ namespace FoxTube.Utils
private static bool UseTestAds => true; private static bool UseTestAds => true;
private static string ApplicationId => UseTestAds ? "d25517cb-12d4-4699-8bdc-52040c712cab" : "9ncqqxjtdlfh"; public static string ApplicationId => UseTestAds ? "d25517cb-12d4-4699-8bdc-52040c712cab" : "9ncqqxjtdlfh";
private static string AdsId => UseTestAds ? "test" : "1100044398"; public static string AdsId => UseTestAds ? "test" : "1100044398";
private static string ProProductId => "9NP1QK556625"; private static string ProProductId => "9NP1QK556625";
public static NativeAdsManagerV2 AdsManager => new NativeAdsManagerV2(ApplicationId, AdsId);
public static async Task UpdateStoreState() public static async Task UpdateStoreState()
{ {
StoreProductQueryResult requset = await StoreContext.GetDefault().GetAssociatedStoreProductsAsync(new[] { "Durable" }); StoreProductQueryResult requset = await StoreContext.GetDefault().GetAssociatedStoreProductsAsync(new[] { "Durable" });
+21 -1
View File
@@ -37,10 +37,30 @@
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Style> </Style>
<Style TargetType="Button" BasedOn="{StaticResource ButtonRevealStyle}"/> <Style TargetType="Button" BasedOn="{StaticResource ButtonRevealStyle}">
<Setter Property="Height" Value="32"/>
</Style>
<Style TargetType="PivotItem"> <Style TargetType="PivotItem">
<Setter Property="Margin" Value="0"/> <Setter Property="Margin" Value="0"/>
</Style> </Style>
<Style x:Key="HeaderActionButton" TargetType="Button" BasedOn="{StaticResource ButtonRevealStyle}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="CornerRadius" Value="0" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Height" Value="32" />
<Setter Property="Width" Value="40" />
<Setter Property="Padding" Value="0" />
<Setter Property="FontFamily" Value="Segoe MDL2 Assets" />
<Setter Property="FontSize" Value="15" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
<Setter Property="TextWrapping" Value="WrapWholeWords"/>
</Style>
</ResourceDictionary> </ResourceDictionary>
</Application.Resources> </Application.Resources>
</Application> </Application>
+53 -13
View File
@@ -1,9 +1,12 @@
using System; using System;
using FoxTube.Core.Helpers; using FoxTube.Services;
using FoxTube.Utils;
using Windows.ApplicationModel; using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation; using Windows.ApplicationModel.Activation;
using Windows.UI.Popups; using Windows.UI;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace FoxTube namespace FoxTube
{ {
@@ -12,14 +15,14 @@ namespace FoxTube
public App() public App()
{ {
InitializeComponent(); InitializeComponent();
Suspending += OnSuspending; Suspending += OnSuspending;
UnhandledException += ErrorOccured; UnhandledException += ErrorOccured;
Metrics.StartSession();
} }
protected override async void OnLaunched(LaunchActivatedEventArgs e) protected override async void OnLaunched(LaunchActivatedEventArgs e)
{ {
await UsersControl.Initialize(); await UserManagement.Initialize();
await StoreInterop.UpdateStoreState(); await StoreInterop.UpdateStoreState();
if (Settings.LastReviewedVersion != Metrics.CurrentVersion) if (Settings.LastReviewedVersion != Metrics.CurrentVersion)
Inbox.PushChangelog(); Inbox.PushChangelog();
@@ -59,16 +62,53 @@ namespace FoxTube
("StackTrace", e.Exception.StackTrace)); ("StackTrace", e.Exception.StackTrace));
e.Handled = true; 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; ContentDialogResult result = await new ContentDialog
alert.CancelCommandIndex = 2; {
await alert.ShowAsync(); Title = "Something went wrong...",
Content = "It may be a bug or temporary server issues. Please, try again later\n\nIf this happens again try to reset your app settings or report the problem",
PrimaryButtonText = "Report the problem",
SecondaryButtonText = "Reset application",
CloseButtonText = "Close",
DefaultButton = ContentDialogButton.Primary
}.ShowAsync();
switch (result)
{
case ContentDialogResult.Primary:
Feedback.OpenFeedbackHub();
break;
case ContentDialogResult.Secondary:
Utils.Utils.InitializeFailsafeProtocol();
break;
default:
break;
}
}
public static void UpdateTitleBar(bool isDark)
{
ApplicationViewTitleBar titleBar = ApplicationView.GetForCurrentView().TitleBar;
titleBar.ButtonBackgroundColor = Colors.Transparent;
titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
titleBar.ButtonInactiveForegroundColor = Colors.Gray;
if (isDark)
{
titleBar.ButtonForegroundColor =
titleBar.ButtonHoverForegroundColor =
titleBar.ButtonPressedForegroundColor = Colors.White;
titleBar.ButtonHoverBackgroundColor = Color.FromArgb(50, 255, 255, 255);
titleBar.ButtonPressedBackgroundColor = Color.FromArgb(30, 255, 255, 255);
}
else
{
titleBar.ButtonForegroundColor =
titleBar.ButtonHoverForegroundColor =
titleBar.ButtonPressedForegroundColor = Colors.Black;
titleBar.ButtonHoverBackgroundColor = Color.FromArgb(50, 0, 0, 0);
titleBar.ButtonPressedBackgroundColor = Color.FromArgb(70, 0, 0, 0);
}
} }
} }
} }
+84
View File
@@ -0,0 +1,84 @@
using Google.Apis.YouTube.v3.Data;
using System.Collections.Generic;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media.Imaging;
namespace FoxTube.Utils
{
public static class MenuItemsList
{
public static List<Microsoft.UI.Xaml.Controls.NavigationViewItemBase> GetMenuItems(bool authorized)
{
List<Microsoft.UI.Xaml.Controls.NavigationViewItemBase> list = new List<Microsoft.UI.Xaml.Controls.NavigationViewItemBase>
{
GetItem("Home", new SymbolIcon(Symbol.Home), "home")
};
if (authorized)
list.AddRange(new Microsoft.UI.Xaml.Controls.NavigationViewItemBase[]
{
GetItem("Subscriptions", new SymbolIcon(Symbol.People), "subscriptions"),
new Microsoft.UI.Xaml.Controls.NavigationViewItemHeader { Content = "Library" },
GetItem("History", new FontIcon { Glyph = "\xE81C" }, "history"),
GetItem("Liked videos", new SymbolIcon(Symbol.Like), "liked"),
GetItem("Watch later", new SymbolIcon(Symbol.Clock), "watchLater"),
GetItem("Downloads", new SymbolIcon(Symbol.Download), "downloads")
});
else
list.AddRange(new Microsoft.UI.Xaml.Controls.NavigationViewItemBase[]
{
GetItem("Downloads", new SymbolIcon(Symbol.Download), "downloads"),
new Microsoft.UI.Xaml.Controls.NavigationViewItemHeader { Content = "Best of YouTube" },
GetItem("Music", new FontIcon { Glyph = "\xE189" }, "UC-9-kyTW8ZkZNDHQJ6FgpwQ"),
GetItem("Sports", new FontIcon { Glyph = "\xE95E" }, "UCEgdi0XIXXZ-qJOFPf4JSKw"),
GetItem("Movies", new FontIcon { Glyph = "\xE8B2" }, "UClgRkhTL3_hImCAmdLfDE4g"),
GetItem("News", new FontIcon { Glyph = "\xE12A" }, "UCYfdidRxbB8Qhf0Nx7ioOYw"),
GetItem("Live", new FontIcon { Glyph = "\xE93E" }, "UC4R8DWoMoI7CAwX8_LjQHig"),
GetItem("Spotlight", new FontIcon { Glyph = "\xECAD" }, "UC8iNz9uwDGfomRnnKKbOhOQ"),
GetItem("360° videos", new FontIcon { Glyph = "\xF131" }, "UCzuqhhs6NWbgTzMuM09WKDQ"),
});
return list;
}
private static Microsoft.UI.Xaml.Controls.NavigationViewItem GetItem(string content, IconElement icon, string tag) =>
new Microsoft.UI.Xaml.Controls.NavigationViewItem
{
Content = content,
Icon = icon,
Tag = tag
};
public static Microsoft.UI.Xaml.Controls.NavigationViewItem GenerateItemFromSubscription(Subscription subscription)
{
StackPanel stack = new StackPanel
{
Orientation = Orientation.Horizontal,
Padding = new Thickness(5),
Margin = new Thickness(-5, 0, 0, 0)
};
stack.Children.Add(new Microsoft.UI.Xaml.Controls.PersonPicture
{
Height = 20,
Margin = new Thickness(-5, 0, 15, 0),
ProfilePicture = new BitmapImage().LoadImage(subscription.Snippet.Thumbnails.Default__.Url, 20, 20)
});
stack.Children.Add(new TextBlock
{
FontSize = 14,
Text = subscription.Snippet.Title
});
return new Microsoft.UI.Xaml.Controls.NavigationViewItem
{
Content = stack,
Tag = subscription.Snippet.ChannelId
};
}
}
}
+35
View File
@@ -0,0 +1,35 @@
namespace FoxTube
{
public enum NavigationTarget
{
Home,
Settings,
Downloads
}
public static class Navigation
{
public static NavigationTarget CurrentPage { get; private set; }
public static object CurrentParameter { get; private set; }
public static void NavigateTo(NavigationTarget destination) =>
NavigateTo(destination, null);
public static void NavigateTo(NavigationTarget destination, object parameters)
{
MainPage.Current.Navigate(destination switch
{
NavigationTarget.Settings => typeof(Views.Settings),
NavigationTarget.Downloads => typeof(Views.Downloads),
_ => UserManagement.Authorized ? typeof(Views.Home) : typeof(Views.HomeSections.Trending),
},
parameters);
CurrentPage = destination;
CurrentParameter = parameters;
}
public static void RefreshCurrentPage() =>
MainPage.Current.Refresh();
}
}
+55
View File
@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI.Core;
using Windows.UI.Xaml.Data;
namespace FoxTube.Models
{
public class ViewItemsCollection : ObservableCollection<object>, ISupportIncrementalLoading
{
public event EventHandler ItemsUpdated;
public bool HasMoreItems
{
get => _hasMoreItems;
private set
{
_hasMoreItems = value;
ItemsUpdated?.Invoke(this, null);
}
}
private bool _hasMoreItems = true;
private IIncrementalLoadingHost Host { get; set; }
public ViewItemsCollection(IIncrementalLoadingHost host) =>
Host = host;
public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count) =>
AsyncInfo.Run((c) => LoadItems());
private async Task<LoadMoreItemsResult> LoadItems()
{
(List<object> items, bool hasMore) = await Host.LoadMoreItems();
HasMoreItems = hasMore;
await Host.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
items.ForEach(i =>
Add(i));
});
return new LoadMoreItemsResult { Count = (uint)items.Count };
}
}
public interface IIncrementalLoadingHost
{
Task<(List<object>, bool)> LoadMoreItems();
CoreDispatcher Dispatcher { get; }
}
}
+61 -33
View File
@@ -1,64 +1,92 @@
<AppBarButton <Button
x:Class="FoxTube.Controls.AccountManager" x:Class="FoxTube.Controls.AccountManager"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" mc:Ignorable="d"
Label="Sign in"
xmlns:ui="using:Microsoft.UI.Xaml.Controls" xmlns:ui="using:Microsoft.UI.Xaml.Controls"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls" xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls" xmlns:data="using:Google.Apis.Oauth2.v2.Data"
Style="{StaticResource AppBarButtonRevealStyle}" Loaded="AppBarButton_Loaded"
Loaded="AppBarButton_Loaded"> Style="{StaticResource ButtonRevealStyle}"
CornerRadius="0"
Padding="10,0"
Height="32"
Background="Transparent">
<AppBarButton.Icon> <StackPanel Orientation="Horizontal">
<FontIcon Glyph="&#xE1E2;"/> <FontIcon Glyph="&#xE1E2;" x:Name="icon" FontSize="15" Visibility="Visible"/>
</AppBarButton.Icon> <PersonPicture Width="20" x:Name="profileIcon" Visibility="Collapsed"/>
<TextBlock x:Name="buttonLabel" Text="Sign in" Margin="10,0,0,0" Style="{StaticResource CaptionTextBlockStyle}" VerticalAlignment="Center"/>
</StackPanel>
<AppBarButton.Flyout> <Button.Flyout>
<Flyout Opening="Flyout_Opening"> <Flyout Opening="Flyout_Opening">
<StackPanel Margin="-12" Width="300"> <StackPanel Margin="-12" Width="300">
<Grid Height="60"> <Grid Height="60">
<controls:ImageEx x:Name="banner" Stretch="UniformToFill" <controls:ImageEx x:Name="bannerImage" Stretch="UniformToFill"
PlaceholderSource="/Assets/DefaultChannelBanner.png" PlaceholderSource="/Assets/DefaultChannelBanner.png"
PlaceholderStretch="UniformToFill"/> PlaceholderStretch="UniformToFill"/>
<Grid Padding="10" ColumnSpacing="20"> <Grid Padding="10" ColumnSpacing="20" RequestedTheme="Dark">
<Grid.Background> <Grid.Background>
<AcrylicBrush TintColor="Black" TintOpacity=".2"/> <AcrylicBrush FallbackColor="Transparent" TintColor="Black" TintOpacity="0" TintLuminosityOpacity=".5" Opacity=".9"/>
</Grid.Background> </Grid.Background>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
<ColumnDefinition/> <ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<PersonPicture Height="40" x:Name="avatar"/> <PersonPicture Height="40" x:Name="avatar"/>
<StackPanel Grid.Column="1"> <StackPanel Grid.Column="1">
<TextBlock x:Name="name" Text="█████████"/> <TextBlock x:Name="name" Text="[Name]"/>
<TextBlock x:Name="email" Text="██████████████████"/> <TextBlock x:Name="email" Text="[email]" FontStyle="Italic"/>
</StackPanel> </StackPanel>
<Button FontFamily="Segoe MDL2 Assets" Content="&#xE115;" ToolTipService.ToolTip="Account settings" Grid.Column="2" Background="Transparent"/>
</Grid> </Grid>
</Grid> </Grid>
<ui:NavigationViewList> <NavigationViewList>
<ui:NavigationViewItem Icon="Contact" Content="My channel"/> <NavigationViewItem Tapped="NavigationViewItem_Tapped" Icon="Contact" Content="My channel" Tag="channel"/>
<ui:NavigationViewItem Icon="Upload" Content="Upload a video"/> <NavigationViewItem Tapped="NavigationViewItem_Tapped" Icon="Upload" Content="Upload a video" Tag="upload"/>
<ui:NavigationViewItem Content="Start a broadcast"> <NavigationViewItem Tapped="NavigationViewItem_Tapped" Content="Start a broadcast" Tag="broadcast">
<ui:NavigationViewItem.Icon> <NavigationViewItem.Icon>
<FontIcon Glyph="&#xE93E;"/> <FontIcon Glyph="&#xE93E;"/>
</ui:NavigationViewItem.Icon> </NavigationViewItem.Icon>
</ui:NavigationViewItem> </NavigationViewItem>
<ui:NavigationViewItem Content="Creator Stuido"> <NavigationViewItem Tapped="NavigationViewItem_Tapped" Content="Creator Stuido" Tag="creatorStudio">
<ui:NavigationViewItem.Icon> <NavigationViewItem.Icon>
<FontIcon Glyph="&#xE2B1;"/> <FontIcon Glyph="&#xE2B1;"/>
</ui:NavigationViewItem.Icon> </NavigationViewItem.Icon>
</ui:NavigationViewItem> </NavigationViewItem>
<ui:NavigationViewItemSeparator/> </NavigationViewList>
<ui:NavigationViewItem Content="Sign out" Foreground="Red"> <NavigationViewList ItemClick="SwitchUser" IsItemClickEnabled="True" x:Name="usersList">
<ui:NavigationViewItem.Icon> <NavigationViewList.ItemTemplate>
<DataTemplate x:DataType="data:Userinfoplus">
<StackPanel Orientation="Horizontal" Padding="5" Margin="-5,0,0,0">
<ui:PersonPicture Height="20" Margin="-5,0,15,0">
<ui:PersonPicture.ProfilePicture>
<BitmapImage UriSource="{Binding Picture}" DecodePixelHeight="20" DecodePixelWidth="20"/>
</ui:PersonPicture.ProfilePicture>
</ui:PersonPicture>
<StackPanel>
<TextBlock FontSize="14" Text="{Binding Name, TargetNullValue='[name]'}"/>
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="{Binding Email}" Margin="0,-6,0,0"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</NavigationViewList.ItemTemplate>
<NavigationViewItemHeader Content="Switch account"/>
</NavigationViewList>
<NavigationViewList>
<NavigationViewItemSeparator/>
<NavigationViewItem Tapped="NavigationViewItem_Tapped" x:Name="addAccountButton" Content="Add account" Tag="addUser" Icon="Add"/>
<NavigationViewItem Tapped="NavigationViewItem_Tapped" Content="Sign out" Foreground="Red" Tag="logout">
<NavigationViewItem.Icon>
<FontIcon Glyph="&#xE1E0;"/> <FontIcon Glyph="&#xE1E0;"/>
</ui:NavigationViewItem.Icon> </NavigationViewItem.Icon>
</ui:NavigationViewItem> </NavigationViewItem>
</ui:NavigationViewList> </NavigationViewList>
</StackPanel> </StackPanel>
</Flyout> </Flyout>
</AppBarButton.Flyout> </Button.Flyout>
</AppBarButton> </Button>
+68 -19
View File
@@ -1,43 +1,92 @@
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using FoxTube.Models;
using System.Linq;
using Google.Apis.Oauth2.v2.Data;
using Windows.UI.Xaml.Media.Imaging; using Windows.UI.Xaml.Media.Imaging;
namespace FoxTube.Controls namespace FoxTube.Controls
{ {
public sealed partial class AccountManager : AppBarButton public sealed partial class AccountManager : Button
{ {
private User CurrentUser { get; set; }
public AccountManager() => public AccountManager() =>
InitializeComponent(); InitializeComponent();
async void Flyout_Opening(object sender, object e) private async void Flyout_Opening(object sender, object e)
{ {
if (UsersControl.Authorized) if (UserManagement.Authorized)
return; return;
(sender as Flyout).Hide(); (sender as Flyout).Hide();
if (await UsersControl.AddUser()) await UserManagement.AddUser();
UpdateData();
} }
void AppBarButton_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) private void AppBarButton_Loaded(object sender, RoutedEventArgs e)
{ {
if (UsersControl.Authorized) if (UserManagement.Authorized)
UpdateData(); UpdateData(true);
UserManagement.UserStateUpdated += (s, e) => UpdateData(e);
}
private void UpdateData(bool authorized)
{
CurrentUser = UserManagement.CurrentUser;
if (authorized)
{
buttonLabel.Text = name.Text = CurrentUser.Channel.Snippet.Title;
email.Text = CurrentUser.UserInfo.Email;
profileIcon.ProfilePicture = new BitmapImage().LoadImage(CurrentUser.Channel.Snippet.Thumbnails.Default__.Url, 20, 20);
avatar.ProfilePicture = new BitmapImage().LoadImage(CurrentUser.Channel.Snippet.Thumbnails.Default__.Url, 40, 40);
bannerImage.Source = new BitmapImage().LoadImage(CurrentUser.Channel.BrandingSettings.Image.BannerMobileLowImageUrl, 60);
ToolTipService.SetToolTip(this, $"{CurrentUser.UserInfo.Name} ({CurrentUser.UserInfo.Email})");
icon.Visibility = Visibility.Collapsed;
profileIcon.Visibility = Visibility.Visible;
var users = UserManagement.Users.Where(i => i.Id != CurrentUser.UserInfo.Id).ToList();
usersList.ItemsSource = users;
usersList.Visibility = users.Count > 0 ? Visibility.Visible : Visibility.Visible;
addAccountButton.Visibility = UserManagement.CanAddAccounts ? Visibility.Visible : Visibility.Collapsed;
}
else else
MainPage.Current.Update(); {
buttonLabel.Text = name.Text = "Sign in";
ToolTipService.SetToolTip(this, null);
icon.Visibility = Visibility.Visible;
profileIcon.Visibility = Visibility.Collapsed;
}
} }
void UpdateData() private async void SwitchUser(object sender, ItemClickEventArgs e)
{ {
Label = UsersControl.CurrentUser.UserInfo.Name; Userinfoplus user = (Userinfoplus)e.ClickedItem;
Icon = new SymbolIcon(Symbol.Contact); await UserManagement.SwitchUser(UserManagement.Users.ToList().IndexOf(user));
}
banner.Source = new BitmapImage(UsersControl.CurrentUser.Channel.BrandingSettings.Image.BannerMobileLowImageUrl.ToUri()) { DecodePixelWidth = 300, DecodePixelHeight = 60 }; private async void NavigationViewItem_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
avatar.ProfilePicture = new BitmapImage(UsersControl.CurrentUser.Channel.Snippet.Thumbnails.Default__.Url.ToUri()) { DecodePixelHeight = 40, DecodePixelWidth = 40 }; {
name.Text = UsersControl.CurrentUser.UserInfo.Name; switch ((sender as NavigationViewItem).Tag as string)
email.Text = UsersControl.CurrentUser.UserInfo.Email; {
case "channel":
MainPage.Current.Update(); case "upload":
case "broadcast":
case "creatorStudio":
break;
case "addUser":
await UserManagement.AddUser();
break;
case "logout":
await UserManagement.Logout();
break;
}
} }
} }
} }
+9 -21
View File
@@ -5,26 +5,19 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls" xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:Windows10version1809="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract, 7)"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="300" d:DesignHeight="300"
d:DesignWidth="400" d:DesignWidth="400"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Margin="3" Margin="3"
SizeChanged="UserControl_SizeChanged" SizeChanged="UserControl_SizeChanged"
Visibility="Collapsed"
Opacity="0"> Opacity="0">
<UserControl.OpacityTransition> <UserControl.OpacityTransition>
<ScalarTransition/> <ScalarTransition/>
</UserControl.OpacityTransition> </UserControl.OpacityTransition>
<controls:DropShadowPanel BlurRadius="10" ShadowOpacity=".5" <Button Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Style="{StaticResource ButtonRevealStyle}" CornerRadius="5" Padding="0" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch">
OffsetX="2" OffsetY="2" <Grid RowSpacing="5" x:Name="grid">
Color="Black"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch">
<Button Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Style="{StaticResource ButtonRevealStyle}" Windows10version1809:CornerRadius="5" Padding="0" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowSpacing="5" x:Name="grid">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="20"/> <RowDefinition Height="20"/>
@@ -33,17 +26,13 @@
<controls:ImageEx PlaceholderStretch="UniformToFill" CornerRadius="5,5,0,0" PlaceholderSource="/Assets/DefaultVideoThumbnail.png" Source="{Binding advert.MainImages[0].Url}"/> <controls:ImageEx PlaceholderStretch="UniformToFill" CornerRadius="5,5,0,0" PlaceholderSource="/Assets/DefaultVideoThumbnail.png" Source="{Binding advert.MainImages[0].Url}"/>
<controls:DropShadowPanel VerticalAlignment="Top" HorizontalAlignment="Left" Margin="5" OffsetX="2" OffsetY="2"> <StackPanel Padding="5,2,5,3" Background="Orange" CornerRadius="5" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="5">
<StackPanel Padding="5,2,5,3" Background="Orange" CornerRadius="5"> <TextBlock Text="Sponsored content" Foreground="Black" Style="{StaticResource CaptionTextBlockStyle}"/>
<TextBlock Text="Sponsored content" Foreground="Black" FontSize="12"/>
</StackPanel> </StackPanel>
</controls:DropShadowPanel>
<controls:DropShadowPanel VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5,10" OffsetX="2" OffsetY="2" x:Name="cta"> <StackPanel Padding="5,2,5,3" Background="Yellow" CornerRadius="5" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5" x:Name="cta">
<StackPanel Padding="5,2,5,3" Background="Yellow" CornerRadius="5"> <TextBlock Text="{x:Bind advert.CallToActionText}" MaxLines="1" Foreground="Black" Style="{StaticResource CaptionTextBlockStyle}"/>
<TextBlock Text="{x:Bind advert.CallToActionText}" Foreground="Black" FontSize="12"/>
</StackPanel> </StackPanel>
</controls:DropShadowPanel>
<Grid Grid.Row="1" ColumnSpacing="10" Margin="10,0"> <Grid Grid.Row="1" ColumnSpacing="10" Margin="10,0">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@@ -53,12 +42,11 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<controls:ImageEx CornerRadius="999" BorderThickness="3" BorderBrush="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Background="Red" <controls:ImageEx CornerRadius="999" BorderThickness="3" BorderBrush="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Background="Red"
Width="50" Height="50" VerticalAlignment="Bottom" Margin="0,-30,0,0" PlaceholderSource="/Assets/Icons/Contact.png" PlaceholderStretch="UniformToFill" Source="{x:Bind advert.AdIcon}"/> Width="50" Height="50" VerticalAlignment="Bottom" Margin="0,-30,0,0" PlaceholderSource="/Assets/Icons/Contact.png" PlaceholderStretch="UniformToFill" Source="{x:Bind advert.AdIcon}"/>
<TextBlock Text="{x:Bind advert.SponsoredBy}" Grid.Column="1"/> <TextBlock Text="{x:Bind advert.SponsoredBy}" Grid.Column="1" MaxLines="1"/>
<TextBlock x:Name="description" Text="" Grid.Column="2"/> <TextBlock x:Name="description" Grid.Column="2" MaxLines="1" Foreground="Gray"/>
</Grid> </Grid>
<TextBlock Margin="10,0" Grid.Row="2" MaxLines="2" TextTrimming="CharacterEllipsis" TextWrapping="WrapWholeWords" Text="{x:Bind advert.Title}"/> <TextBlock Margin="10,0" Grid.Row="2" MaxLines="2" Text="{x:Bind advert.Title}"/>
</Grid> </Grid>
</Button> </Button>
</controls:DropShadowPanel>
</UserControl> </UserControl>
+8 -5
View File
@@ -1,6 +1,5 @@
using FoxTube.Core.Helpers; using FoxTube.Utils;
using Microsoft.Advertising.WinRT.UI; using Microsoft.Advertising.WinRT.UI;
using Microsoft.Toolkit.Uwp.UI.Controls;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
@@ -11,8 +10,9 @@ namespace FoxTube.Controls.Cards
/// </summary> /// </summary>
public sealed partial class AdvertCard : UserControl public sealed partial class AdvertCard : UserControl
{ {
NativeAdsManagerV2 manager = new NativeAdsManagerV2(Constants.ApplicationId, Constants.AdsId); readonly NativeAdsManagerV2 manager = new NativeAdsManagerV2(StoreInterop.ApplicationId, StoreInterop.AdsId);
NativeAdV2 advert; NativeAdV2 advert;
public AdvertCard() public AdvertCard()
{ {
InitializeComponent(); InitializeComponent();
@@ -23,7 +23,7 @@ namespace FoxTube.Controls.Cards
void ErrorOccurred(object sender, NativeAdErrorEventArgs e) void ErrorOccurred(object sender, NativeAdErrorEventArgs e)
{ {
(Parent as StaggeredPanel)?.Children.Remove(this); (Parent as Panel)?.Children.Remove(this);
Metrics.AddEvent("Error has occured while loading ad", Metrics.AddEvent("Error has occured while loading ad",
("Code", e.ErrorCode.ToString()), ("Code", e.ErrorCode.ToString()),
("Message", e.ErrorMessage), ("Message", e.ErrorMessage),
@@ -37,14 +37,17 @@ namespace FoxTube.Controls.Cards
if (string.IsNullOrWhiteSpace(advert.CallToActionText)) if (string.IsNullOrWhiteSpace(advert.CallToActionText))
cta.Visibility = Visibility.Collapsed; cta.Visibility = Visibility.Collapsed;
description.Text += $"{advert.Price} {advert.Rating}"; description.Text = $"{advert.Price} {advert.Rating}";
e.NativeAd.RegisterAdContainer(grid); e.NativeAd.RegisterAdContainer(grid);
Opacity = 1;
Metrics.AddEvent("Advert loaded", Metrics.AddEvent("Advert loaded",
("Region", Settings.Region), ("Region", Settings.Region),
("Version", Metrics.CurrentVersion)); ("Version", Metrics.CurrentVersion));
} }
void UserControl_SizeChanged(object sender, SizeChangedEventArgs e) => void UserControl_SizeChanged(object sender, SizeChangedEventArgs e) =>
Height = .75 * ActualWidth; Height = .75 * ActualWidth;
} }
+24 -22
View File
@@ -5,48 +5,45 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls" xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:Windows10version1809="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract, 7)"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="300" d:DesignHeight="300"
d:DesignWidth="400" d:DesignWidth="400"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Margin="3" Margin="3"
SizeChanged="UserControl_SizeChanged"> Opacity="0">
<UserControl.OpacityTransition>
<ScalarTransition/>
</UserControl.OpacityTransition>
<Button Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Style="{StaticResource ButtonRevealStyle}" Windows10version1809:CornerRadius="5" Padding="0" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <Button Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Style="{StaticResource ButtonRevealStyle}" CornerRadius="5" Padding="0" VerticalContentAlignment="Stretch" VerticalAlignment="Stretch">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowSpacing="5"> <Grid RowSpacing="5">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="20"/> <RowDefinition Height="20"/>
<RowDefinition/> <RowDefinition/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<controls:ImageEx PlaceholderStretch="UniformToFill" CornerRadius="5,5,0,0" PlaceholderSource="/Assets/DefaultVideoThumbnail.png"/> <controls:ImageEx PlaceholderStretch="UniformToFill" CornerRadius="5,5,0,0" PlaceholderSource="/Assets/DefaultVideoThumbnail.png" Source="{x:Bind VideoData.Snippet.Thumbnails.Maxres.Url}"/>
<Grid> <Grid x:Name="watched" Visibility="Collapsed">
<Grid.Background> <Grid.Background>
<SolidColorBrush Color="Black" Opacity=".5"/> <SolidColorBrush Color="Black" Opacity=".5"/>
</Grid.Background> </Grid.Background>
<controls:DropShadowPanel VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10" OffsetX="2" OffsetY="2">
<StackPanel Padding="5,2,5,3" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" CornerRadius="5"> <StackPanel Padding="5,2,5,3" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" CornerRadius="5" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="5">
<TextBlock Text="Watched" Foreground="Gray" FontSize="12"/> <TextBlock Text="Watched" Foreground="Gray" Style="{StaticResource CaptionTextBlockStyle}"/>
</StackPanel> </StackPanel>
</controls:DropShadowPanel> <ProgressBar VerticalAlignment="Bottom" Margin="59,0,0,0" Value="50"/>
<ProgressBar VerticalAlignment="Bottom" Margin="59,0,0,0" Foreground="Red" Value="50"/>
</Grid> </Grid>
<controls:DropShadowPanel VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5,10" OffsetX="2" OffsetY="2"> <StackPanel Padding="5,2,5,3" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" CornerRadius="5" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5,10">
<StackPanel Padding="5,2,5,3" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" CornerRadius="5"> <TextBlock Text="[Duration] • [Timestamp]" Foreground="Gray" Style="{StaticResource CaptionTextBlockStyle}"/>
<TextBlock Text="██████ • ██████" Foreground="Gray" FontSize="12"/>
</StackPanel> </StackPanel>
</controls:DropShadowPanel>
<controls:DropShadowPanel VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5,35" OffsetX="2" OffsetY="2"> <StackPanel Padding="5,2,5,3" Background="Red" BorderThickness="1" BorderBrush="White" CornerRadius="5" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5,35" Visibility="Collapsed">
<StackPanel Padding="5,2,5,3" Background="Red" BorderThickness="1" BorderBrush="White" CornerRadius="5" Orientation="Horizontal">
<FontIcon Glyph="&#xEC44;" VerticalAlignment="Center" Foreground="White" FontSize="12" Margin="0,0,5,0"/> <FontIcon Glyph="&#xEC44;" VerticalAlignment="Center" Foreground="White" FontSize="12" Margin="0,0,5,0"/>
<TextBlock Text="LIVE" VerticalAlignment="Center" Foreground="White" FontSize="12" FontWeight="Bold"/> <TextBlock Text="LIVE" VerticalAlignment="Center" Foreground="White" Style="{StaticResource CaptionTextBlockStyle}" FontWeight="Bold"/>
</StackPanel> </StackPanel>
</controls:DropShadowPanel>
<Grid Grid.Row="1" ColumnSpacing="10" Margin="10,0"> <Grid Grid.Row="1" ColumnSpacing="10" Margin="10,0">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@@ -56,11 +53,11 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<controls:ImageEx CornerRadius="999" BorderThickness="3" BorderBrush="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Background="Red" <controls:ImageEx CornerRadius="999" BorderThickness="3" BorderBrush="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Background="Red"
Width="50" Height="50" VerticalAlignment="Bottom" Margin="0,-30,0,0" PlaceholderSource="/Assets/Icons/Contact.png" PlaceholderStretch="UniformToFill"/> Width="50" Height="50" VerticalAlignment="Bottom" Margin="0,-30,0,0" PlaceholderSource="/Assets/Icons/Contact.png" PlaceholderStretch="UniformToFill"/>
<TextBlock Text="██████████" Grid.Column="1" TextTrimming="CharacterEllipsis"/> <TextBlock Text="{x:Bind VideoData.Snippet.ChannelTitle}" Grid.Column="1" MaxLines="1"/>
<TextBlock Text="██████████" Grid.Column="2" Foreground="Gray"/> <TextBlock Text="[Views]" Grid.Column="2" MaxLines="1" Foreground="Gray"/>
</Grid> </Grid>
<TextBlock Margin="10,0" Grid.Row="2" MaxLines="2" TextTrimming="CharacterEllipsis" TextWrapping="WrapWholeWords" Text="██████████"/> <TextBlock Margin="10,0" Grid.Row="2" MaxLines="2" Text="{x:Bind VideoData.Snippet.Title}"/>
</Grid> </Grid>
<Button.ContextFlyout> <Button.ContextFlyout>
@@ -71,6 +68,11 @@
<FontIcon Glyph="&#xE727;"/> <FontIcon Glyph="&#xE727;"/>
</MenuFlyoutItem.Icon> </MenuFlyoutItem.Icon>
</MenuFlyoutItem> </MenuFlyoutItem>
<MenuFlyoutItem Text="Open in picture-in-picture mode">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE2B3;"/>
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
<MenuFlyoutItem Icon="Contact" Text="View channel"/> <MenuFlyoutItem Icon="Contact" Text="View channel"/>
<MenuFlyoutSeparator/> <MenuFlyoutSeparator/>
<MenuFlyoutItem Icon="Link" Text="Copy link"/> <MenuFlyoutItem Icon="Link" Text="Copy link"/>
+17 -4
View File
@@ -1,14 +1,27 @@
using Windows.UI.Xaml; using Google.Apis.YouTube.v3.Data;
using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
namespace FoxTube.Controls.Cards namespace FoxTube.Controls.Cards
{ {
public sealed partial class VideoCard : UserControl public sealed partial class VideoCard : UserControl
{ {
public VideoCard() => Video VideoData { get; set; }
public VideoCard(Video meta)
{
InitializeComponent(); InitializeComponent();
void UserControl_SizeChanged(object sender, SizeChangedEventArgs e) => VideoData = meta;
Height = .75 * ActualWidth;
Opacity = 1;
}
public VideoCard(Video meta, Playlist playlist, IEnumerable<PlaylistItem> playlistItems) =>
InitializeComponent();
//void UserControl_SizeChanged(object sender, SizeChangedEventArgs e) =>
// Height = .75 * ActualWidth;
} }
} }
@@ -0,0 +1,40 @@
<ContentDialog
x:Class="FoxTube.Controls.Dialogs.DownloadVideoDialog"
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"
Title="Download video"
Loading="ContentDialog_Loading"
IsPrimaryButtonEnabled="False"
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
PrimaryButtonText="Download"
CloseButtonText="Cancel"
DefaultButton="Primary">
<StackPanel>
<Grid Height="60" ColumnSpacing="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<controls:ImageEx PlaceholderSource="/Assets/DefaultVideoThumbnail.png" Stretch="UniformToFill" Source="{x:Bind Meta.Thumbnails.LowResUrl}" PlaceholderStretch="UniformToFill"/>
<StackPanel Grid.Column="1">
<TextBlock Text="{x:Bind Meta.Title}"/>
<TextBlock Text="{x:Bind Meta.Author}" Style="{StaticResource CaptionTextBlockStyle}" FontStyle="Italic"/>
<TextBlock Text="{x:Bind Meta.Duration}" Style="{StaticResource CaptionTextBlockStyle}" Foreground="Gray"/>
</StackPanel>
</Grid>
<ComboBox Header="Select download quality" HorizontalAlignment="Stretch" PlaceholderText="No qualities available to download" SelectedIndex="0" Margin="0,5" x:Name="qualitiesList" SelectionChanged="SelectionChanged"/>
<TextBox IsReadOnly="True" Header="Location" PlaceholderText="Folder/FileName" x:Name="location"/>
<Button Content="Change" HorizontalAlignment="Right" Margin="0,5" Click="SelectSaveLocation"/>
</StackPanel>
</ContentDialog>
@@ -0,0 +1,72 @@
using System;
using System.Linq;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using YoutubeExplode.Videos;
using YoutubeExplode.Videos.Streams;
namespace FoxTube.Controls.Dialogs
{
public sealed partial class DownloadVideoDialog : ContentDialog
{
public Video Meta { get; set; }
public StreamManifest Manifest { get; set; }
public StorageFile File { get; set; }
public DownloadVideoDialog(Video meta, StreamManifest manifest)
{
InitializeComponent();
Meta = meta;
Manifest = manifest;
foreach (MuxedStreamInfo i in manifest.GetMuxed())
qualitiesList.Items.Add(new ComboBoxItem
{
Content = i.VideoQualityLabel,
Tag = i
});
AudioOnlyStreamInfo audioStream = manifest.GetAudioOnly().FirstOrDefault();
if (audioStream != null)
qualitiesList.Items.Add(new ComboBoxItem
{
Content = "Audio track only",
Tag = audioStream
});
}
private async void ContentDialog_Loading(FrameworkElement sender, object args)
{
StorageFolder defaultFolder = await Services.DownloadsCenter.GetDefaultDownloadsFolder();
location.Text = $"{defaultFolder.Name}\\{Meta.Title.ReplaceInvalidChars('_')}.mp4";
}
private async void SelectSaveLocation(object sender, RoutedEventArgs e)
{
FileSavePicker picker = new FileSavePicker
{
SuggestedFileName = Meta.Title.ReplaceInvalidChars('_'),
DefaultFileExtension = ".mp4",
SuggestedStartLocation = PickerLocationId.VideosLibrary
};
picker.FileTypeChoices.Add("Video file", new[] { ".mp4" });
File = await picker.PickSaveFileAsync();
location.Text = $"{(await File.GetParentAsync()).Name}\\{File.Name}";
}
private void SelectionChanged(object sender, SelectionChangedEventArgs e) =>
IsPrimaryButtonEnabled = true;
private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
}
}
}
@@ -0,0 +1,22 @@
<ContentDialog
x:Class="FoxTube.Controls.Dialogs.ProOfferDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="What's you get in PRO version"
PrimaryButtonText="Purchase"
CloseButtonText="Close"
DefaultButton="Primary"
PrimaryButtonClick="ContentDialog_PrimaryButtonClick">
<StackPanel>
<TextBlock>
- Several downloads at time
<LineBreak/>- No ads
<LineBreak/>- Custom theme accent color
<LineBreak/>- Multiple accounts management
</TextBlock>
</StackPanel>
</ContentDialog>
@@ -0,0 +1,31 @@
using FoxTube.Utils;
using System;
using Windows.UI.Xaml.Controls;
namespace FoxTube.Controls.Dialogs
{
public sealed partial class ProOfferDialog : ContentDialog
{
public ProOfferDialog() =>
InitializeComponent();
private async void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
if (!await StoreInterop.PurchaseApp())
return;
ContentDialog dialog = new ContentDialog
{
Title = "Thank you for your purchase!",
Content = "Thanks for purchasing full version of the app (^∇^)\n" +
"In order to complete changes we need to reopen it. Or you can do it later (but some elements may be broken)",
PrimaryButtonText = "Restart",
CloseButtonText = "Later",
DefaultButton = ContentDialogButton.Primary
};
dialog.PrimaryButtonClick += (s, e) => Utils.Utils.RestartApp();
await dialog.ShowAsync();
}
}
}
+76
View File
@@ -0,0 +1,76 @@
<ListViewItem
x:Class="FoxTube.Controls.DownloadListItem"
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"
d:DesignHeight="100"
HorizontalContentAlignment="Stretch"
Padding="5">
<ListViewItem.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem Text="Delete" Icon="Delete"/>
<MenuFlyoutItem Text="Select">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE762;"/>
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
</MenuFlyout>
</ListViewItem.ContextFlyout>
<controls:DropShadowPanel HorizontalContentAlignment="Stretch">
<Grid Padding="10" ColumnSpacing="10" Background="{ThemeResource SystemChromeLowColor}" CornerRadius="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<controls:ImageEx PlaceholderStretch="UniformToFill" CornerRadius="2" Height="75" PlaceholderSource="/Assets/DefaultVideoThumbnail.png"/>
<Border CornerRadius="5,0,0,0" Background="{StaticResource SystemChromeMediumColor}" VerticalAlignment="Bottom" HorizontalAlignment="Right" Padding="10,2">
<TextBlock Text="2:13:45" Style="{StaticResource CaptionTextBlockStyle}"/>
</Border>
<StackPanel Grid.Column="1">
<TextBlock Text="[Quality] Video title" Style="{StaticResource TitleTextBlockStyle}" MaxLines="1"/>
<TextBlock Text="Author" MaxLines="1"/>
<TextBlock Text="video_file_path.mp4" Style="{StaticResource CaptionTextBlockStyle}" MaxLines="1"/>
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Horizontal" Visibility="Collapsed">
<Button Width="75" Height="75" Padding="0" Background="Transparent">
<StackPanel>
<TextBlock Text="&#xED25;" FontFamily="Segoe MDL2 Assets" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Open" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center"/>
</StackPanel>
</Button>
<Button Width="75" Height="75" Padding="0" Background="Transparent" Margin="10,0,0,0">
<StackPanel>
<TextBlock Text="&#xE2B4;" FontFamily="Segoe MDL2 Assets" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Go to original" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center" HorizontalAlignment="Center"/>
</StackPanel>
</Button>
</StackPanel>
<Grid Grid.Column="2" RowSpacing="5" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Downloading..." RelativePanel.Above="progressBar"/>
<TextBlock Text="50%" RelativePanel.AlignRightWithPanel="True" RelativePanel.Above="progressBar" Grid.Column="1" HorizontalAlignment="Right"/>
<ProgressBar Value="50" Width="200" Grid.Row="1" Grid.ColumnSpan="2"/>
<Button Content="&#xE106;" ToolTipService.ToolTip="Cancel" RelativePanel.Below="progressBar" RelativePanel.AlignRightWithPanel="True" Background="Transparent" FontFamily="Segoe MDL2 Assets" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Right"/>
</Grid>
</Grid>
</controls:DropShadowPanel>
</ListViewItem>
+14
View File
@@ -0,0 +1,14 @@
using Windows.UI.Xaml.Controls;
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
namespace FoxTube.Controls
{
public sealed partial class DownloadListItem : ListViewItem
{
public DownloadListItem()
{
this.InitializeComponent();
}
}
}
+84 -9
View File
@@ -1,21 +1,96 @@
<UserControl <Grid
x:Class="FoxTube.Controls.ItemsGrid" x:Class="FoxTube.Controls.ItemsGrid"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls" xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:models="using:FoxTube.Models"
xmlns:controls1="using:FoxTube.Controls"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="1080" d:DesignHeight="1080"
d:DesignWidth="1920"> d:DesignWidth="1920">
<Grid> <TextBlock Text="&#xD8;" FontSize="100" Foreground="Gray" Opacity="0" x:Name="empty" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<controls:StaggeredPanel x:Name="grid" DesiredColumnWidth="350"/>
<controls:DropShadowPanel x:Name="empty" HorizontalAlignment="Center" VerticalAlignment="Center" <controls:AdaptiveGridView x:Name="grid" DesiredWidth="400" Padding="5">
BlurRadius="10" ShadowOpacity=".5" <controls:AdaptiveGridView.ItemContainerTransitions>
OffsetX="2" OffsetY="2"> <TransitionCollection>
<TextBlock Text="&#xD8;" FontSize="100" Foreground="Gray"/> <EntranceThemeTransition IsStaggeringEnabled="True"/>
</controls:DropShadowPanel> <AddDeleteThemeTransition/>
</TransitionCollection>
</controls:AdaptiveGridView.ItemContainerTransitions>
<controls:AdaptiveGridView.ItemTemplate>
<DataTemplate x:DataType="models:VideoItem">
<Grid RowSpacing="5" CornerRadius="5" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Padding="0,0,0,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="20"/>
<RowDefinition Height="38"/>
</Grid.RowDefinitions>
<controls:ImageEx PlaceholderStretch="UniformToFill" CornerRadius="5,5,0,0" PlaceholderSource="/Assets/DefaultVideoThumbnail.png" Source="{x:Bind Meta.Snippet.Thumbnails.Maxres.Url}"/>
<StackPanel Padding="5,2,5,3" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" CornerRadius="5" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5,10">
<TextBlock Text="{x:Bind TimeLabel}" Foreground="Gray" Style="{StaticResource CaptionTextBlockStyle}"/>
</StackPanel>
<StackPanel Padding="5,2,5,3" Background="Red" BorderThickness="1" BorderBrush="White" CornerRadius="5" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5,35" Opacity="{x:Bind LiveLabelOpacity}">
<FontIcon Glyph="&#xEC44;" VerticalAlignment="Center" Foreground="White" FontSize="12" Margin="0,0,5,0"/>
<TextBlock Text="{x:Bind LiveLabel}" VerticalAlignment="Center" Foreground="White" Style="{StaticResource CaptionTextBlockStyle}" FontWeight="Bold"/>
</StackPanel>
<Grid Grid.Row="1" ColumnSpacing="10" Margin="10,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<controls:ImageEx CornerRadius="999" BorderThickness="3" BorderBrush="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Background="Red"
Width="50" Height="50" VerticalAlignment="Bottom" Margin="0,-30,0,0" PlaceholderSource="/Assets/Icons/Contact.png" Source="{x:Bind ChannelMeta.LogoUrl}" PlaceholderStretch="UniformToFill"/>
<TextBlock Text="{x:Bind Meta.Snippet.ChannelTitle}" Grid.Column="1" MaxLines="1"/>
<TextBlock Text="{x:Bind ViewsLabel}" Grid.Column="2" MaxLines="1" Foreground="Gray"/>
</Grid> </Grid>
</UserControl>
<TextBlock Margin="10,0" Grid.Row="2" MaxLines="2" Text="{x:Bind Meta.Snippet.Title}" TextWrapping="WrapWholeWords" TextTrimming="CharacterEllipsis"/>
<Grid.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem Icon="Play" Text="Play"/>
<MenuFlyoutItem Text="Play incognito">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE727;"/>
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
<MenuFlyoutItem Text="Open in picture-in-picture mode">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE2B3;"/>
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
<MenuFlyoutItem Icon="Contact" Text="View channel"/>
<MenuFlyoutSeparator/>
<MenuFlyoutItem Icon="Link" Text="Copy link"/>
<MenuFlyoutItem Icon="Globe" Text="Open in browser"/>
<MenuFlyoutItem Icon="Share" Text="Share"/>
<MenuFlyoutSeparator/>
<MenuFlyoutSubItem Icon="Download" Text="Download"/>
<MenuFlyoutSubItem Icon="Add" Text="Add to">
<MenuFlyoutItem Text="New playlist" Icon="Add"/>
<ToggleMenuFlyoutItem Text="Watch later" Icon="Clock"/>
<MenuFlyoutSeparator/>
</MenuFlyoutSubItem>
<MenuFlyoutItem Text="Remove from playlist" Icon="Delete" Visibility="Visible" Foreground="Red"/>
</MenuFlyout>
</Grid.ContextFlyout>
</Grid>
</DataTemplate>
</controls:AdaptiveGridView.ItemTemplate>
<controls:AdaptiveGridView.Footer>
<ProgressBar IsIndeterminate="True" x:Name="progressBar" Background="Transparent" VerticalAlignment="Bottom"/>
</controls:AdaptiveGridView.Footer>
</controls:AdaptiveGridView>
<controls1:LoadingScreen x:Name="loadingScreen"/>
</Grid>
+17 -18
View File
@@ -1,31 +1,30 @@
using FoxTube.Controls.Cards; using Windows.UI.Xaml.Controls;
using FoxTube.Core.Helpers; using FoxTube.Models;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace FoxTube.Controls namespace FoxTube.Controls
{ {
public sealed partial class ItemsGrid : UserControl public sealed partial class ItemsGrid : Grid
{ {
UIElementCollection Items => grid.Children; private ViewItemsCollection ItemsSource
public int ItemsCount => Items.Count; {
get => grid.ItemsSource as ViewItemsCollection;
set => grid.ItemsSource = value;
}
public LoadingScreen LoadingScreen => loadingScreen;
public ItemsGrid() => public ItemsGrid() =>
InitializeComponent(); InitializeComponent();
public void Add(UIElement item) public void Initialize(IIncrementalLoadingHost host)
{ {
empty.Opacity = 0; ItemsSource = new ViewItemsCollection(host);
ItemsSource.ItemsUpdated += (s, e) =>
if (!StoreInterop.AdsDisabled && ItemsCount % 5 == 0 && ItemsCount > 0)
Items.Add(new AdvertCard());
Items.Add(item);
}
public void Clear()
{ {
Items.Clear(); empty.Opacity = ItemsSource.Count > 0 ? 0 : 1;
empty.Opacity = 1; progressBar.IsIndeterminate = ItemsSource.HasMoreItems;
loadingScreen.Hide();
};
} }
} }
} }
+50
View File
@@ -0,0 +1,50 @@
<UserControl
x:Class="FoxTube.Controls.LoadingScreen"
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"
Opacity="1"
Visibility="Visible"
Loaded="UserControl_Loaded">
<UserControl.OpacityTransition>
<ScalarTransition/>
</UserControl.OpacityTransition>
<Grid Background="{ThemeResource AppBarBackgroundThemeBrush}">
<controls:AdaptiveGridView DesiredWidth="400" Padding="5" SelectionMode="None" ScrollViewer.VerticalScrollMode="Disabled" ScrollViewer.VerticalScrollBarVisibility="Hidden" x:Name="grid">
<controls:AdaptiveGridView.OpacityTransition>
<ScalarTransition Duration="0:0:2"/>
</controls:AdaptiveGridView.OpacityTransition>
<controls:AdaptiveGridView.ItemContainerTransitions>
<TransitionCollection>
<EntranceThemeTransition IsStaggeringEnabled="True"/>
<AddDeleteThemeTransition/>
</TransitionCollection>
</controls:AdaptiveGridView.ItemContainerTransitions>
</controls:AdaptiveGridView>
<StackPanel VerticalAlignment="Center" x:Name="errorPanel" Visibility="Collapsed">
<StackPanel.OpacityTransition>
<ScalarTransition/>
</StackPanel.OpacityTransition>
<FontIcon Glyph="&#xE7BA;" HorizontalAlignment="Center" FontSize="100" x:Name="icon"/>
<TextBlock Text="Hmm... We can't load this page right now" HorizontalAlignment="Center" Style="{StaticResource SubheaderTextBlockStyle}" x:Name="title"/>
<TextBlock Text="There's must be a bug or templorary server issue. Please, try again later" HorizontalAlignment="Center" Style="{StaticResource TitleTextBlockStyle}" x:Name="subtitle"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,20" x:Name="commonErrorActions">
<Button Content="Refresh page" Background="Red" Foreground="White" Click="RefreshPage"/>
<Button Content="Leave feedback" Margin="10,0,0,0" x:Name="feedbackButton" Click="LeaveFeedback"/>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,20" x:Name="networkErrorActions">
<Button Content="Open network settings" Click="OpenNetworkSettings"/>
<Button Content="Open troubleshooter" Background="Red" Foreground="White" Margin="10,0" Click="OpenTroubleshooter"/>
<Button Content="Refresh page" Click="RefreshPage"/>
</StackPanel>
</StackPanel>
</Grid>
</UserControl>
+116
View File
@@ -0,0 +1,116 @@
using FoxTube.Utils;
using System;
using System.Threading;
using System.Threading.Tasks;
using Windows.System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
namespace FoxTube.Controls
{
public sealed partial class LoadingScreen : UserControl
{
CancellationTokenSource cts = new CancellationTokenSource();
public LoadingScreen() =>
InitializeComponent();
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
feedbackButton.Visibility = Feedback.HasFeedbackHub ? Visibility.Visible : Visibility.Collapsed;
for (int i = 0; i < 25; i++)
grid.Items.Add(new Image
{
Source = new SvgImageSource("ms-appx:///Assets/Templates/CardTemplate.svg".ToUri())
});
}
private async void Shimmering(CancellationToken token)
{
while (true)
{
grid.Opacity = .75;
await Task.Delay(2000);
if (token.IsCancellationRequested)
break;
grid.Opacity = 1;
await Task.Delay(2000);
if (token.IsCancellationRequested)
break;
}
}
public async void Activate()
{
Visibility = Visibility.Visible;
Opacity = 1;
errorPanel.Opacity = 0;
await Task.Delay(500);
errorPanel.Visibility = Visibility.Collapsed;
cts = new CancellationTokenSource();
Shimmering(cts.Token);
}
public async void Hide()
{
Opacity = 0;
await Task.Delay(500);
Visibility = Visibility.Collapsed;
cts.Cancel();
}
public async void ShowError(bool isInternetError)
{
if (isInternetError)
{
icon.Glyph = "\xEB63";
title.Text = "Hmm... We can't load this page right now";
subtitle.Text = "We can't connect to Internet services. Please, check your connection or try again later";
networkErrorActions.Visibility = Visibility.Visible;
commonErrorActions.Visibility = Visibility.Collapsed;
}
else
{
icon.Glyph = "\xE7BA";
title.Text = "Hmm... Something went wrong";
subtitle.Text = "There's must be a bug or templorary server issue. Please, try again later";
networkErrorActions.Visibility = Visibility.Collapsed;
commonErrorActions.Visibility = Visibility.Visible;
}
cts.Cancel();
Visibility = Visibility.Visible;
Opacity = 1;
grid.Opacity = 0;
await Task.Delay(500);
errorPanel.Visibility = Visibility.Visible;
errorPanel.Opacity = 1;
}
private void LeaveFeedback(object sender, RoutedEventArgs e) =>
Feedback.OpenFeedbackHub();
private async void OpenNetworkSettings(object sender, RoutedEventArgs e) =>
await Launcher.LaunchUriAsync("ms-settings:network".ToUri());
private void RefreshPage(object sender, RoutedEventArgs e) =>
Navigation.RefreshCurrentPage();
private async void OpenTroubleshooter(object sender, RoutedEventArgs e) =>
await Launcher.LaunchUriAsync("ms-settings:troubleshoot".ToUri());
}
}
+68 -14
View File
@@ -13,7 +13,7 @@
<DefaultLanguage>en-US</DefaultLanguage> <DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier> <TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.18362.0</TargetPlatformVersion> <TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.18362.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion> <TargetPlatformMinVersion>10.0.18362.0</TargetPlatformMinVersion>
<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>
@@ -105,6 +105,21 @@
<Compile Include="App.xaml.cs"> <Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon> <DependentUpon>App.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Classes\MenuItemsList.cs" />
<Compile Include="Classes\Navigation.cs" />
<Compile Include="Classes\ViewItemsCollection.cs" />
<Compile Include="Controls\Dialogs\DownloadVideoDialog.xaml.cs">
<DependentUpon>DownloadVideoDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\Dialogs\ProOfferDialog.xaml.cs">
<DependentUpon>ProOfferDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\DownloadListItem.xaml.cs">
<DependentUpon>DownloadListItem.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\LoadingScreen.xaml.cs">
<DependentUpon>LoadingScreen.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\AccountManager.xaml.cs"> <Compile Include="Controls\AccountManager.xaml.cs">
<DependentUpon>AccountManager.xaml</DependentUpon> <DependentUpon>AccountManager.xaml</DependentUpon>
</Compile> </Compile>
@@ -127,9 +142,21 @@
<DependentUpon>MainPage.xaml</DependentUpon> <DependentUpon>MainPage.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Views\Downloads.xaml.cs">
<DependentUpon>Downloads.xaml</DependentUpon>
</Compile>
<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\HomeSections\Recommended.xaml.cs">
<DependentUpon>Recommended.xaml</DependentUpon>
</Compile>
<Compile Include="Views\HomeSections\Subscriptions.xaml.cs">
<DependentUpon>Subscriptions.xaml</DependentUpon>
</Compile>
<Compile Include="Views\HomeSections\Trending.xaml.cs">
<DependentUpon>Trending.xaml</DependentUpon>
</Compile>
<Compile Include="Views\Search.xaml.cs"> <Compile Include="Views\Search.xaml.cs">
<DependentUpon>Search.xaml</DependentUpon> <DependentUpon>Search.xaml</DependentUpon>
</Compile> </Compile>
@@ -145,9 +172,6 @@
<Compile Include="Views\SettingsSections\Inbox.xaml.cs"> <Compile Include="Views\SettingsSections\Inbox.xaml.cs">
<DependentUpon>Inbox.xaml</DependentUpon> <DependentUpon>Inbox.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\SettingsSections\Translate.xaml.cs">
<DependentUpon>Translate.xaml</DependentUpon>
</Compile>
<Compile Include="Views\Subscriptions.xaml.cs"> <Compile Include="Views\Subscriptions.xaml.cs">
<DependentUpon>Subscriptions.xaml</DependentUpon> <DependentUpon>Subscriptions.xaml</DependentUpon>
</Compile> </Compile>
@@ -184,6 +208,11 @@
<Content Include="Assets\Square150x150Logo.scale-125.png" /> <Content Include="Assets\Square150x150Logo.scale-125.png" />
<Content Include="Assets\Square150x150Logo.scale-150.png" /> <Content Include="Assets\Square150x150Logo.scale-150.png" />
<Content Include="Assets\Square150x150Logo.scale-400.png" /> <Content Include="Assets\Square150x150Logo.scale-400.png" />
<Content Include="Assets\Square44x44Logo.altform-lightunplated_targetsize-16.png" />
<Content Include="Assets\Square44x44Logo.altform-lightunplated_targetsize-24.png" />
<Content Include="Assets\Square44x44Logo.altform-lightunplated_targetsize-256.png" />
<Content Include="Assets\Square44x44Logo.altform-lightunplated_targetsize-32.png" />
<Content Include="Assets\Square44x44Logo.altform-lightunplated_targetsize-48.png" />
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-16.png" /> <Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-16.png" />
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-256.png" /> <Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-256.png" />
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-32.png" /> <Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-32.png" />
@@ -202,6 +231,7 @@
<Content Include="Assets\StoreLogo.scale-150.png" /> <Content Include="Assets\StoreLogo.scale-150.png" />
<Content Include="Assets\StoreLogo.scale-200.png" /> <Content Include="Assets\StoreLogo.scale-200.png" />
<Content Include="Assets\StoreLogo.scale-400.png" /> <Content Include="Assets\StoreLogo.scale-400.png" />
<Content Include="Assets\Templates\CardTemplate.svg" />
<Content Include="Assets\Wide310x150Logo.scale-100.png" /> <Content Include="Assets\Wide310x150Logo.scale-100.png" />
<Content Include="Assets\Wide310x150Logo.scale-125.png" /> <Content Include="Assets\Wide310x150Logo.scale-125.png" />
<Content Include="Assets\Wide310x150Logo.scale-150.png" /> <Content Include="Assets\Wide310x150Logo.scale-150.png" />
@@ -240,18 +270,50 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Controls\Dialogs\DownloadVideoDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Controls\Dialogs\ProOfferDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Controls\DownloadListItem.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Controls\ItemsGrid.xaml"> <Page Include="Controls\ItemsGrid.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Controls\LoadingScreen.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="MainPage.xaml"> <Page Include="MainPage.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Views\Downloads.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\Home.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\HomeSections\Recommended.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\HomeSections\Subscriptions.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\HomeSections\Trending.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\Search.xaml"> <Page Include="Views\Search.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
@@ -272,10 +334,6 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Views\SettingsSections\Translate.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\Subscriptions.xaml"> <Page Include="Views\Subscriptions.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
@@ -286,20 +344,16 @@
<Version>10.1811.22001</Version> <Version>10.1811.22001</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform"> <PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.2.9</Version> <Version>6.2.10</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls"> <PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls">
<Version>6.0.0</Version> <Version>6.0.0</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.UI.Xaml"> <PackageReference Include="Microsoft.UI.Xaml">
<Version>2.3.191129002</Version> <Version>2.4.0</Version>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\FoxTube.Background\FoxTube.Background.csproj">
<Project>{fc9128d7-e3aa-48ed-8641-629794b88b28}</Project>
<Name>FoxTube.Background</Name>
</ProjectReference>
<ProjectReference Include="..\FoxTube.Core\FoxTube.Core.csproj"> <ProjectReference Include="..\FoxTube.Core\FoxTube.Core.csproj">
<Project>{29c01e10-76e7-4527-984f-b0eef7e1ac64}</Project> <Project>{29c01e10-76e7-4527-984f-b0eef7e1ac64}</Project>
<Name>FoxTube.Core</Name> <Name>FoxTube.Core</Name>
+34 -127
View File
@@ -6,13 +6,8 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" mc:Ignorable="d"
xmlns:ui="using:Microsoft.UI.Xaml.Controls" xmlns:ui="using:Microsoft.UI.Xaml.Controls"
xmlns:controls="using:FoxTube.Controls" xmlns:controls="using:FoxTube.Controls" xmlns:models="using:FoxTube.Models"
xmlns:toolkit="using:Microsoft.Toolkit.Uwp.UI.Controls" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
xmlns:models="using:FoxTube.Core.Models"
xmlns:data="using:Google.Apis.YouTube.v3.Data">
<Page.Background>
<AcrylicBrush BackgroundSource="HostBackdrop" TintColor="{ThemeResource SystemAltHighColor}" FallbackColor="{ThemeResource SystemAltHighColor}" TintOpacity=".5"/>
</Page.Background>
<Grid> <Grid>
<Border x:Name="AppTitleBar" <Border x:Name="AppTitleBar"
@@ -21,22 +16,26 @@
Height="{Binding ElementName=NavigationViewControl, Path=CompactPaneLength}" Height="{Binding ElementName=NavigationViewControl, Path=CompactPaneLength}"
Canvas.ZIndex="1"> Canvas.ZIndex="1">
<TextBlock x:Name="AppTitle" <TextBlock Text="FoxTube"
Text="FoxTube" VerticalAlignment="Center" Margin="12,0"
VerticalAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}" /> Style="{StaticResource CaptionTextBlockStyle}" />
</Border> </Border>
<ui:NavigationView x:Name="NavigationViewControl" <ui:NavigationView x:Name="NavigationViewControl"
IsTitleBarAutoPaddingEnabled="False" IsTitleBarAutoPaddingEnabled="False"
DisplayModeChanged="NavigationView_DisplayModeChanged" DisplayModeChanged="NavigationView_DisplayModeChanged"
PaneClosing="NavigationView_PaneClosing"
PaneOpening="NavigationView_PaneOpening"
BackRequested="NavigationViewControl_BackRequested" BackRequested="NavigationViewControl_BackRequested"
ItemInvoked="NavigationViewControl_ItemInvoked"> ItemInvoked="NavigationViewControl_ItemInvoked"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ui:NavigationView.PaneHeader>
<TextBlock Style="{StaticResource TitleTextBlockStyle}" Text="Menu" VerticalAlignment="Center" Margin="10,0" Name="title"/>
</ui:NavigationView.PaneHeader>
<ui:NavigationView.AutoSuggestBox> <ui:NavigationView.AutoSuggestBox>
<AutoSuggestBox QueryIcon="Find" PlaceholderText="Search YouTube..." TextChanged="AutoSuggestBox_TextChanged" QuerySubmitted="AutoSuggestBox_QuerySubmitted" TextMemberPath="Text"> <AutoSuggestBox QueryIcon="Find" PlaceholderText="Search YouTube..." TextChanged="AutoSuggestBox_TextChanged" QuerySubmitted="AutoSuggestBox_QuerySubmitted" TextMemberPath="Text" >
<AutoSuggestBox.ItemTemplate> <AutoSuggestBox.ItemTemplate>
<DataTemplate x:DataType="models:SearchSuggestion"> <DataTemplate x:DataType="models:SearchSuggestion">
<Grid ColumnSpacing="10"> <Grid ColumnSpacing="10">
@@ -54,122 +53,30 @@
</ui:NavigationView.AutoSuggestBox> </ui:NavigationView.AutoSuggestBox>
<ui:NavigationView.PaneFooter> <ui:NavigationView.PaneFooter>
<ui:NavigationViewList> <NavigationViewList>
<ui:NavigationViewItemSeparator/> <NavigationViewItemSeparator/>
<ui:NavigationViewItem Icon="Shop" Content="Get Pro" x:Name="RemoveAds" Tapped="RemoveAds_Tapped"/> <NavigationViewItem Icon="Shop" Content="Get Pro" x:Name="removeAds" Tapped="RemoveAds_Tapped"/>
</ui:NavigationViewList> </NavigationViewList>
</ui:NavigationView.PaneFooter> </ui:NavigationView.PaneFooter>
<ui:NavigationView.MenuItemTemplate> <Grid Margin="0,32,0,0">
<DataTemplate x:DataType="data:Subscription"> <Frame x:Name="content" Navigated="Content_Navigated"/>
<StackPanel Orientation="Horizontal" Padding="5" Margin="-5,0,0,0" Tag="{Binding Snippet.ResourceId.ChannelId}">
<PersonPicture Height="20" Margin="-5,0,15,0">
<PersonPicture.ProfilePicture>
<BitmapImage UriSource="{Binding Snippet.Thumbnails.Medium.Url}" DecodePixelHeight="20" DecodePixelWidth="20"/>
</PersonPicture.ProfilePicture>
</PersonPicture>
<TextBlock FontSize="14" Text="{Binding Snippet.Title}"/>
</StackPanel>
</DataTemplate>
</ui:NavigationView.MenuItemTemplate>
<ui:NavigationView.MenuItems>
<ui:NavigationViewItem Icon="Home" Content="Home" x:Name="home"/>
<ui:NavigationViewItem Content="Subscriptions" x:Name="subscriptions">
<ui:NavigationViewItem.Icon>
<FontIcon Glyph="&#xE125;"/>
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
<ui:NavigationViewItemHeader Content="Library" x:Name="libraryHeader"/>
<ui:NavigationViewItem Content="History" x:Name="history">
<ui:NavigationViewItem.Icon>
<FontIcon Glyph="&#xE81C;"/>
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
<ui:NavigationViewItem Content="Liked videos" x:Name="liked">
<ui:NavigationViewItem.Icon>
<FontIcon Glyph="&#xE19F;"/>
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
<ui:NavigationViewItem Icon="Clock" Content="Watch later" x:Name="wl"/>
<ui:NavigationViewItem Icon="Download" Content="Downloads" x:Name="download"/>
<ui:NavigationViewItemHeader Content="Subscriptions" x:Name="subscriptionsHeader"/>
<ui:NavigationViewItemHeader Content="Best of YouTube" x:Name="categoriesHeader"/>
<ui:NavigationViewItem Content="Music" x:Name="music">
<ui:NavigationViewItem.Icon>
<FontIcon Glyph="&#xE189;"/>
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
<ui:NavigationViewItem Content="Sports" x:Name="sports">
<ui:NavigationViewItem.Icon>
<FontIcon Glyph="&#xE95E;"/>
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
<ui:NavigationViewItem Content="Movies" x:Name="movies">
<ui:NavigationViewItem.Icon>
<FontIcon Glyph="&#xE8B2;"/>
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
<ui:NavigationViewItem Content="News" x:Name="news">
<ui:NavigationViewItem.Icon>
<FontIcon Glyph="&#xE12A;"/>
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
<ui:NavigationViewItem Content="Live" x:Name="live">
<ui:NavigationViewItem.Icon>
<FontIcon Glyph="&#xE93E;"/>
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
<ui:NavigationViewItem Content="Spotlight" x:Name="spotlight">
<ui:NavigationViewItem.Icon>
<FontIcon Glyph="&#xECAD;"/>
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
<ui:NavigationViewItem Content="360&#xB0; video" x:Name="vr">
<ui:NavigationViewItem.Icon>
<FontIcon Glyph="&#xF131;"/>
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
</ui:NavigationView.MenuItems>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid Margin="0,40,0,0" Padding="13,0" x:Name="headerGrid">
<TextBlock Style="{StaticResource TitleTextBlockStyle}" Text="Home" VerticalAlignment="Center" Name="title"/>
<CommandBar HorizontalAlignment="Right" Background="Transparent" DefaultLabelPosition="Right">
<AppBarButton x:Name="LeaveFeedback" Click="LeaveFeedback_Click">
<AppBarButton.Icon>
<FontIcon Glyph="&#xED15;" Margin="0,0,-10,0"/>
</AppBarButton.Icon>
</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"/>
</CommandBar>
</Grid>
<Frame x:Name="content" Grid.Row="1" Navigated="Content_Navigated"/>
<Frame x:Name="video" Grid.Row="1" Visibility="Collapsed"/>
<toolkit:Loading IsLoading="False" x:Name="loading" VerticalContentAlignment="Center" Grid.RowSpan="2">
<toolkit:Loading.Background>
<AcrylicBrush BackgroundSource="HostBackdrop" TintColor="{ThemeResource SystemColorBackgroundColor}" TintOpacity=".5"/>
</toolkit:Loading.Background>
<ProgressRing Height="100" Width="100" IsActive="True"/>
</toolkit:Loading>
</Grid> </Grid>
</ui:NavigationView> </ui:NavigationView>
<StackPanel Orientation="Horizontal" Margin="0,0,0,0" HorizontalAlignment="Right" VerticalAlignment="Top" x:Name="toolbar">
<controls:AccountManager/>
<Button x:Name="leaveFeedback" Click="LeaveFeedback_Click" ToolTipService.ToolTip="Leave feedback"
Content="&#xED15;" Style="{StaticResource HeaderActionButton}"/>
<Button x:Name="refresh" Click="Refresh_Click" Content="&#xE149;" Style="{StaticResource HeaderActionButton}" ToolTipService.ToolTip="Refresh page" Opacity="0">
<Button.OpacityTransition>
<ScalarTransition/>
</Button.OpacityTransition>
</Button>
<Button Height="32" Width="46" Style="{StaticResource HeaderActionButton}" Margin="52,0,0,0" IsTabStop="False"/>
<Button Height="32" Width="46" Style="{StaticResource HeaderActionButton}" IsTabStop="False"/>
<Button Height="32" Width="46" Style="{StaticResource HeaderActionButton}" IsTabStop="False"/>
</StackPanel>
</Grid> </Grid>
</Page> </Page>
+140 -201
View File
@@ -1,57 +1,52 @@
using FoxTube.Core.Helpers; using FoxTube.Attributes;
using FoxTube.Core.Models; using FoxTube.Controls.Dialogs;
using FoxTube.Utils;
using FoxTube.Services;
using Google.Apis.YouTube.v3.Data; using Google.Apis.YouTube.v3.Data;
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Windows.ApplicationModel.Core; using Windows.ApplicationModel.Core;
using Windows.Foundation.Metadata;
using Windows.UI;
using Windows.UI.Popups;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
// TODO: Fix header (UI)
namespace FoxTube namespace FoxTube
{ {
public sealed partial class MainPage : Page public sealed partial class MainPage : Windows.UI.Xaml.Controls.Page
{ {
public static MainPage Current { get; set; } public static MainPage Current { get; set; }
public MainPage() public MainPage()
{ {
Current = this; Current = this;
InitializeComponent(); InitializeComponent();
#region Setup theme
if (Settings.Theme == 0) if (Settings.Theme == 0)
RequestedTheme = ElementTheme.Light; RequestedTheme = ElementTheme.Light;
else if (Settings.Theme == 1) else if (Settings.Theme == 1)
RequestedTheme = ElementTheme.Dark; RequestedTheme = ElementTheme.Dark;
Navigate(typeof(Views.Home)); if (RequestedTheme == ElementTheme.Default)
App.UpdateTitleBar(Application.Current.RequestedTheme == ApplicationTheme.Dark);
else
App.UpdateTitleBar(RequestedTheme == ElementTheme.Dark);
Window.Current.SetTitleBar(AppTitleBar); Window.Current.SetTitleBar(AppTitleBar);
CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true; CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
#endregion
ApplicationViewTitleBar titleBar = ApplicationView.GetForCurrentView().TitleBar; removeAds.Visibility = StoreInterop.AdsDisabled ? Visibility.Collapsed : Visibility.Visible;
titleBar.ButtonBackgroundColor = Colors.Transparent;
titleBar.ButtonHoverBackgroundColor = Color.FromArgb(50, 255, 255, 255);
titleBar.ButtonPressedBackgroundColor = Color.FromArgb(20, 255, 255, 255);
if (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 = RequestedTheme == ElementTheme.Dark ? Colors.White : Colors.Black;
LeaveFeedback.Visibility = Feedback.HasFeedbackHub ? Visibility.Visible : Visibility.Collapsed;
RemoveAds.Visibility = StoreInterop.AdsDisabled ? Visibility.Collapsed : Visibility.Visible;
if (!StoreInterop.AdsDisabled) if (!StoreInterop.AdsDisabled)
RemoveAds.Content += $" ({StoreInterop.Price})"; removeAds.Content += $" ({StoreInterop.Price})";
leaveFeedback.Visibility = Feedback.HasFeedbackHub ?
Visibility.Visible : Visibility.Collapsed;
UserManagement.SubscriptionsChanged += UsersControl_SubscriptionsChanged;
UserManagement.UserStateUpdated += UsersControl_UserStateUpdated;
UsersControl_UserStateUpdated(this, UserManagement.Authorized);
if (Settings.PromptReview) if (Settings.PromptReview)
Feedback.PromptReview(); Feedback.PromptReview();
@@ -59,212 +54,156 @@ namespace FoxTube
Feedback.PromptFeedback(); Feedback.PromptFeedback();
} }
void NavigationView_DisplayModeChanged(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewDisplayModeChangedEventArgs args) #region Navigation
private void Content_Navigated(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs args)
{ {
Thickness currMargin = AppTitleBar.Margin;
AppTitleBar.Margin = new Thickness(
sender.CompactPaneLength * (sender.DisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Minimal ? 2 : 1),
currMargin.Top,
currMargin.Right,
currMargin.Bottom);
UpdateAppTitleMargin(sender);
}
void NavigationView_PaneClosing(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewPaneClosingEventArgs args) =>
UpdateAppTitleMargin(sender);
void NavigationView_PaneOpening(Microsoft.UI.Xaml.Controls.NavigationView sender, object args) =>
UpdateAppTitleMargin(sender);
void UpdateAppTitleMargin(Microsoft.UI.Xaml.Controls.NavigationView sender)
{
const int smallLeftIndent = 4, largeLeftIndent = 12;
if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 7))
{
AppTitle.TranslationTransition = new Vector3Transition();
if (sender.DisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Expanded && sender.IsPaneOpen)
AppTitle.Translation = new System.Numerics.Vector3(smallLeftIndent, 0, 0);
else
AppTitle.Translation = new System.Numerics.Vector3(largeLeftIndent, 0, 0);
}
else
{
Thickness currMargin = AppTitle.Margin;
if (sender.DisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Expanded && sender.IsPaneOpen)
AppTitle.Margin = new Thickness(smallLeftIndent, currMargin.Top, currMargin.Right, currMargin.Bottom);
else
AppTitle.Margin = new Thickness(largeLeftIndent, currMargin.Top, currMargin.Right, currMargin.Bottom);
}
}
void LeaveFeedback_Click(object sender, RoutedEventArgs e) =>
Feedback.OpenFeedbackHub();
async void RemoveAds_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
{
bool success = await StoreInterop.PurchaseApp();
if (success)
{
MessageDialog dialog = new MessageDialog("Thanks for purchasing full version of the app (^∇^) In order to complete changes we need to reopen it. Or you can do it later (but some elements may be broken)", "Thank you for your purchase!");
dialog.Commands.Add(new UICommand("Restart", (command) => Utils.RestartApp()));
dialog.Commands.Add(new UICommand("Later"));
dialog.CancelCommandIndex = 1;
dialog.DefaultCommandIndex = 0;
await dialog.ShowAsync();
}
}
public static void Navigate(Type pageType) =>
Navigate(pageType, null);
public static void Navigate(Type pageType, object param)
{
if (pageType == Current.content.CurrentSourcePageType && param == (Current.content.Content as PageView).Parameter)
return;
// TODO: Add navigation logic for videos
Current.content.Navigate(pageType, param);
}
public static void SetHeader(string title) =>
Current.title.Text = title;
void Content_Navigated(object sender, NavigationEventArgs e)
{
refresh.Visibility = (e.Content is IRefreshable) ? Visibility.Visible : Visibility.Collapsed;
NavigationViewControl.IsBackEnabled = content.CanGoBack; NavigationViewControl.IsBackEnabled = content.CanGoBack;
title.Text = (e.Content as PageView).Header ?? "FoxTube";
switch(e.SourcePageType.Name) refresh.Opacity = Attribute.IsDefined(args.SourcePageType, typeof(RefreshableAttribute)) ? 1 : 0;
switch (args.SourcePageType.Name)
{ {
case "Home":
NavigationViewControl.SelectedItem = home;
break;
case "Settings": case "Settings":
NavigationViewControl.SelectedItem = NavigationViewControl.SettingsItem; NavigationViewControl.SelectedItem = NavigationViewControl.SettingsItem;
break; break;
case "Subscriptions": case "Downloads":
NavigationViewControl.SelectedItem = subscriptions; NavigationViewControl.SelectedItem = NavigationViewControl.MenuItems.FirstOrDefault(i => ((FrameworkElement)i).Tag as string == "downloads");
break;
case "Home":
case "Trending":
NavigationViewControl.SelectedItem = NavigationViewControl.MenuItems.FirstOrDefault(i => ((FrameworkElement)i).Tag as string == "home");
break;
case "Channel":
NavigationViewControl.SelectedItem = NavigationViewControl.MenuItems.FirstOrDefault(i => ((FrameworkElement)i).Tag == args.Parameter);
break; break;
default: default:
NavigationViewControl.SelectedItem = null; NavigationViewControl.SelectedItem = null;
break; break;
// TODO: Update menu selector
} }
} }
void Refresh_Click(object sender, RoutedEventArgs e) private void NavigationViewControl_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
{ {
if (video.Content != null) (NavigationTarget target, object parameters) suggestedTransition = (NavigationTarget.Home, null);
(video.Content as IRefreshable)?.RefreshPage();
if (args.IsSettingsInvoked)
suggestedTransition = (NavigationTarget.Settings, null);
else else
(content.Content as IRefreshable)?.RefreshPage(); suggestedTransition = args.InvokedItemContainer.Tag as string switch
}
void AutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{ {
if (sender.Text.Length < 3 || args.Reason != AutoSuggestionBoxTextChangeReason.UserInput) "home" => (NavigationTarget.Home, null),
"downloads" => (NavigationTarget.Downloads, null),
_ => (NavigationTarget.Home, null) // TODO: Navigate to channel
};
if (Navigation.CurrentPage == suggestedTransition.target && Navigation.CurrentParameter == suggestedTransition.parameters)
return; return;
// TODO: Load suggestions Navigation.NavigateTo(suggestedTransition.target, suggestedTransition.parameters);
}
#endregion
// TODO: Remove #region Search
sender.ItemsSource = new List<SearchSuggestion> private async void AutoSuggestBox_TextChanged(Windows.UI.Xaml.Controls.AutoSuggestBox sender, Windows.UI.Xaml.Controls.AutoSuggestBoxTextChangedEventArgs args)
{ {
new SearchSuggestion("Suggestion 0"), if (sender.Text.Length >= 3 && args.Reason == Windows.UI.Xaml.Controls.AutoSuggestionBoxTextChangeReason.UserInput)
new SearchSuggestion("Suggestion 1"), sender.ItemsSource = await Search.GetSuggestions(sender.Text);
new SearchSuggestion("Suggestion 2"),
new SearchSuggestion("Suggestion 3"),
new SearchSuggestion("Suggestion 4"),
new SearchSuggestion("History entry 0", true),
new SearchSuggestion("History entry 1", true),
new SearchSuggestion("History entry 2", true)
};
} }
void AutoSuggestBox_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args) private void AutoSuggestBox_QuerySubmitted(Windows.UI.Xaml.Controls.AutoSuggestBox sender, Windows.UI.Xaml.Controls.AutoSuggestBoxQuerySubmittedEventArgs args)
{ {
if (args.QueryText.Length < 3) if (args.QueryText.Length < 3)
return; return;
History.AddSearchHistoryEntry(args.QueryText);
// TODO: Go to search // TODO: Go to search
Navigate(typeof(Views.Search)); }
#endregion
#region Users management
private void UsersControl_UserStateUpdated(object sender, bool authorized)
{
// Add general menu items
NavigationViewControl.MenuItems.Clear();
MenuItemsList.GetMenuItems(authorized).ForEach(i =>
NavigationViewControl.MenuItems.Add(i));
// Add subscriptions list to the menu
if (authorized && UserManagement.CurrentUser.Subscriptions.Count > 0)
{
NavigationViewControl.MenuItems.Add(new NavigationViewItemHeader { Content = "Subscriptions" });
UserManagement.CurrentUser.Subscriptions.GetRange(0, Math.Min(UserManagement.CurrentUser.Subscriptions.Count, 10)).ForEach(i =>
NavigationViewControl.MenuItems.Add(MenuItemsList.GenerateItemFromSubscription(i)));
} }
void NavigationViewControl_BackRequested(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewBackRequestedEventArgs args) // TODO: Menu selector resets after menu update
// Refresh page
if (content.CurrentSourcePageType == null || content.CurrentSourcePageType.Name.Belongs("Home", "Trending"))
Navigation.NavigateTo(NavigationTarget.Home);
else
Refresh();
}
private void UsersControl_SubscriptionsChanged(object sender, Subscription subscription)
{
if (NavigationViewControl.MenuItems.FirstOrDefault(i => ((NavigationViewItemBase)i).Tag as string == subscription.Snippet.ChannelId) is NavigationViewItem container)
{
NavigationViewControl.MenuItems.Remove(container);
if (UserManagement.CurrentUser.Subscriptions.Count < 1)
NavigationViewControl.MenuItems.RemoveAt(NavigationViewControl.MenuItems.Count - 1);
}
else
{
if (UserManagement.CurrentUser.Subscriptions.Count == 1)
NavigationViewControl.MenuItems.Add(new NavigationViewItemHeader { Content = "Subscriptions" });
if (UserManagement.CurrentUser.Subscriptions.Count.Belongs(1, 10))
NavigationViewControl.MenuItems.Add(MenuItemsList.GenerateItemFromSubscription(subscription));
}
}
#endregion
#region Navigation actions
public void Refresh()
{
if (!Attribute.IsDefined(content.CurrentSourcePageType, typeof(RefreshableAttribute)))
return;
content.Navigate(content.CurrentSourcePageType ?? typeof(Views.Home), Navigation.CurrentParameter);
content.BackStack.RemoveAt(content.BackStack.Count - 1);
}
public void Navigate(Type target, object parameter) =>
content.Navigate(target, parameter);
#endregion
#region Simple button actions
private void NavigationViewControl_BackRequested(NavigationView sender, NavigationViewBackRequestedEventArgs args)
{ {
// TODO: Add backward navigation logic for videos
if (content.CanGoBack) if (content.CanGoBack)
content.GoBack(); content.GoBack();
} }
void NavigationViewControl_ItemInvoked(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewItemInvokedEventArgs args) private void Refresh_Click(object sender, RoutedEventArgs e) =>
Refresh();
private async void RemoveAds_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e) =>
await new ProOfferDialog().ShowAsync();
private void LeaveFeedback_Click(object sender, RoutedEventArgs e) =>
Feedback.OpenFeedbackHub();
private void NavigationView_DisplayModeChanged(NavigationView sender, NavigationViewDisplayModeChangedEventArgs args) =>
AppTitleBar.Margin = new Thickness()
{ {
if (args.IsSettingsInvoked) Left = sender.CompactPaneLength * (sender.DisplayMode == NavigationViewDisplayMode.Minimal ? 2 : 1),
Navigate(typeof(Views.Settings)); Right = toolbar.ActualWidth + 190
else };
switch((args.InvokedItemContainer as Microsoft.UI.Xaml.Controls.NavigationViewItem).Name) #endregion
{
case "home":
Navigate(typeof(Views.Home));
break;
case "subscriptions":
Navigate(typeof(Views.Subscriptions));
break;
case "history":
break;
case "liked":
break;
case "wl":
break;
case "download":
break;
case "music":
break;
case "sports":
break;
case "movies":
break;
case "news":
break;
case "live":
break;
case "spotlight":
break;
case "vr":
break;
default:
break;
}
}
public void Update()
{
if(UsersControl.Authorized)
{
for (int i = NavigationViewControl.MenuItems.IndexOf(subscriptions); i < NavigationViewControl.MenuItems.IndexOf(categoriesHeader); i++)
(NavigationViewControl.MenuItems[i] as FrameworkElement).Visibility = Visibility.Visible;
for (int i = NavigationViewControl.MenuItems.IndexOf(categoriesHeader); i < NavigationViewControl.MenuItems.Count; i++)
(NavigationViewControl.MenuItems[i] as FrameworkElement).Visibility = Visibility.Collapsed;
foreach (Subscription i in UsersControl.CurrentUser.Subscriptions)
NavigationViewControl.MenuItems.Insert(NavigationViewControl.MenuItems.IndexOf(categoriesHeader), i);
}
else
{
IEnumerable<object> subs = from i in NavigationViewControl.MenuItems
where string.IsNullOrWhiteSpace((i as FrameworkElement).Name)
select i;
foreach (object i in subs)
NavigationViewControl.MenuItems.Remove(i);
for (int i = NavigationViewControl.MenuItems.IndexOf(subscriptions); i < NavigationViewControl.MenuItems.IndexOf(categoriesHeader); i++)
(NavigationViewControl.MenuItems[i] as FrameworkElement).Visibility = Visibility.Collapsed;
for (int i = NavigationViewControl.MenuItems.IndexOf(categoriesHeader); i < NavigationViewControl.MenuItems.Count; i++)
(NavigationViewControl.MenuItems[i] as FrameworkElement).Visibility = Visibility.Visible;
}
}
} }
} }
+2 -12
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="#282828"> <uap:VisualElements DisplayName="FoxTube" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="YouTube Client for Windows 10" BackgroundColor="#404040">
<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" />
@@ -23,7 +23,7 @@
<uap:ShowOn Tile="square310x310Logo" /> <uap:ShowOn Tile="square310x310Logo" />
</uap:ShowNameOnTiles> </uap:ShowNameOnTiles>
</uap:DefaultTile> </uap:DefaultTile>
<uap:SplashScreen Image="Assets\SplashScreen.png" BackgroundColor="#282828" /> <uap:SplashScreen Image="Assets\SplashScreen.png" BackgroundColor="#404040" />
<uap:LockScreen Notification="badgeAndTileText" BadgeLogo="Assets\BadgeLogo.png"/> <uap:LockScreen Notification="badgeAndTileText" BadgeLogo="Assets\BadgeLogo.png"/>
</uap:VisualElements> </uap:VisualElements>
<Extensions> <Extensions>
@@ -32,16 +32,6 @@
<uap:DisplayName>FoxTube</uap:DisplayName> <uap:DisplayName>FoxTube</uap:DisplayName>
</uap:Protocol > </uap:Protocol >
</uap:Extension> </uap:Extension>
<Extension Category="windows.backgroundTasks" EntryPoint="FoxTube.Background.BackgroundProcessor">
<BackgroundTasks>
<Task Type="general" />
<Task Type="systemEvent" />
<Task Type="timer" />
<Task Type="pushNotification" />
<uap:Task Type="chatMessageNotification" />
<uap:Task Type="mediaProcessing" />
</BackgroundTasks>
</Extension>
</Extensions> </Extensions>
</Application> </Application>
</Applications> </Applications>
+365
View File
@@ -0,0 +1,365 @@
<Page
x:Class="FoxTube.Views.Downloads"
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"
xmlns:models="using:FoxTube.Models"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Pivot>
<Pivot.RightHeader>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<Style TargetType="Button" BasedOn="{StaticResource ButtonRevealStyle}">
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Width" Value="32"/>
<Setter Property="Height" Value="32"/>
</Style>
<Style TargetType="ToggleButton" BasedOn="{StaticResource ToggleButtonRevealStyle}">
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Width" Value="32"/>
<Setter Property="Height" Value="32"/>
</Style>
</StackPanel.Resources>
<Button Content="&#xE107;" ToolTipService.ToolTip="Delete" Name="deleteItemsButton" IsEnabled="False" Visibility="Collapsed">
<Button.Flyout>
<Flyout>
<StackPanel>
<TextBlock Text="Are you sure? This action cannot be undone"/>
<CheckBox Content="Also delete downloaded files" x:Name="deleteFilesCheckbox"/>
<Button Content="Delete" Background="Red" FontFamily="White" Click="DeleteSelectedItems"/>
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
<ToggleButton Content="&#xE762;" ToolTipService.ToolTip="Selecttion mode" Margin="10,0" Checked="ToggleButton_Checked" Unchecked="ToggleButton_Unchecked"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button Content="Open folder" Margin="10,0" Click="OpenDefaultFolder"/>
<Button Content="&#xE115;" Width="32" ToolTipService.ToolTip="Downloads settings" FontFamily="Segoe MDL2 Assets" Click="OpenDownloadSettings"/>
<AutoSuggestBox QueryIcon="Add" PlaceholderText="Download video by URL or ID" Width="300" Margin="10" QuerySubmitted="AutoSuggestBox_QuerySubmitted" TextChanged="AutoSuggestBox_TextChanged"/>
</StackPanel>
</StackPanel>
</Pivot.RightHeader>
<PivotItem Header="Downloads">
<Grid>
<StackPanel VerticalAlignment="Center" x:Name="empty" Margin="10">
<StackPanel.OpacityTransition>
<ScalarTransition/>
</StackPanel.OpacityTransition>
<TextBlock TextAlignment="Center" Text="You haven't downloaded anything yet" Style="{StaticResource SubheaderTextBlockStyle}"/>
<TextBlock TextAlignment="Center" Text="To download video press &quot;Download&quot; button from video page or a video card context menu and select download quality" Style="{StaticResource SubtitleTextBlockStyle}"/>
</StackPanel>
<ScrollViewer>
<StackPanel>
<ListView x:Name="downloadHistoryList" SelectionChanged="List_SelectionChanged" SelectionMode="None">
<ListView.ItemContainerTransitions>
<TransitionCollection>
<EntranceThemeTransition IsStaggeringEnabled="True"/>
<AddDeleteThemeTransition/>
</TransitionCollection>
</ListView.ItemContainerTransitions>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="ContextFlyout">
<Setter.Value>
<MenuFlyout>
<MenuFlyoutItem Text="Delete" Icon="Delete" Click="DeleteOneItem"/>
<MenuFlyoutItem Text="Select" Click="SelectOneItem">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE762;"/>
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
<MenuFlyoutItem Text="Show in folder" Click="ShowInFolder">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE19C;"/>
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
</MenuFlyout>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:SavedVideo">
<controls:DropShadowPanel HorizontalContentAlignment="Stretch">
<Grid Padding="10" ColumnSpacing="10" Background="{ThemeResource SystemChromeLowColor}" CornerRadius="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<controls:ImageEx PlaceholderStretch="UniformToFill" CornerRadius="2" Height="75" PlaceholderSource="/Assets/DefaultVideoThumbnail.png" Source="{x:Bind Thumbnail}"/>
<Border CornerRadius="5,0,0,0" Background="{StaticResource SystemChromeMediumColor}" VerticalAlignment="Bottom" HorizontalAlignment="Right" Padding="10,2">
<TextBlock Text="{x:Bind Duration}" Style="{StaticResource CaptionTextBlockStyle}"/>
</Border>
<StackPanel Grid.Column="1">
<TextBlock Text="{x:Bind Title}" Style="{StaticResource TitleTextBlockStyle}" MaxLines="1"/>
<TextBlock Text="{x:Bind Author}" MaxLines="1"/>
<TextBlock Text="{x:Bind Path}" Style="{StaticResource CaptionTextBlockStyle}" MaxLines="1"/>
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Horizontal" Tag="{x:Bind}">
<Button Width="75" Height="75" Padding="0" Background="Transparent" Click="OpenVideo">
<StackPanel>
<TextBlock Text="&#xED25;" FontFamily="Segoe MDL2 Assets" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Open" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center"/>
</StackPanel>
</Button>
<Button Width="75" Height="75" Padding="0" Background="Transparent" Margin="10,0,0,0" Click="OpenOriginal">
<StackPanel>
<TextBlock Text="&#xE2B4;" FontFamily="Segoe MDL2 Assets" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Go to original" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center" HorizontalAlignment="Center"/>
</StackPanel>
</Button>
</StackPanel>
</Grid>
</controls:DropShadowPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView x:Name="list" SelectionChanged="List_SelectionChanged" SelectionMode="None">
<ListView.ItemContainerTransitions>
<TransitionCollection>
<EntranceThemeTransition IsStaggeringEnabled="True"/>
<AddDeleteThemeTransition/>
</TransitionCollection>
</ListView.ItemContainerTransitions>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="ContextFlyout">
<Setter.Value>
<MenuFlyout>
<MenuFlyoutItem Text="Delete" Icon="Delete" Click="DeleteOneItem"/>
<MenuFlyoutItem Text="Select" Click="SelectOneItem">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE762;"/>
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
<MenuFlyoutItem Text="Show in folder" Click="SelectOneItem">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE19C;"/>
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
</MenuFlyout>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:DownloadItem">
<controls:DropShadowPanel HorizontalContentAlignment="Stretch">
<Grid Padding="10" ColumnSpacing="10" Background="{ThemeResource SystemChromeLowColor}" CornerRadius="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<controls:ImageEx PlaceholderStretch="UniformToFill" CornerRadius="2" Height="75" PlaceholderSource="/Assets/DefaultVideoThumbnail.png" Source="{x:Bind Thumbnail}"/>
<Border CornerRadius="5,0,0,0" Background="{StaticResource SystemChromeMediumColor}" VerticalAlignment="Bottom" HorizontalAlignment="Right" Padding="10,2">
<TextBlock Text="{x:Bind Duration}" Style="{StaticResource CaptionTextBlockStyle}"/>
</Border>
<StackPanel Grid.Column="1">
<TextBlock Text="{x:Bind Title}" Style="{StaticResource TitleTextBlockStyle}" MaxLines="1"/>
<TextBlock Text="{x:Bind Author}" MaxLines="1"/>
<TextBlock Text="{x:Bind Path}" Style="{StaticResource CaptionTextBlockStyle}" MaxLines="1"/>
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Horizontal" Visibility="Collapsed">
<Button Width="75" Height="75" Padding="0" Background="Transparent">
<StackPanel>
<TextBlock Text="&#xED25;" FontFamily="Segoe MDL2 Assets" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Open" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center"/>
</StackPanel>
</Button>
<Button Width="75" Height="75" Padding="0" Background="Transparent" Margin="10,0,0,0">
<StackPanel>
<TextBlock Text="&#xE2B4;" FontFamily="Segoe MDL2 Assets" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Go to original" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center" HorizontalAlignment="Center"/>
</StackPanel>
</Button>
</StackPanel>
<Grid Grid.Column="2" RowSpacing="5" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Downloading..." RelativePanel.Above="progressBar"/>
<TextBlock Text="50%" RelativePanel.AlignRightWithPanel="True" RelativePanel.Above="progressBar" Grid.Column="1" HorizontalAlignment="Right"/>
<ProgressBar Value="50" Width="200" Grid.Row="1" Grid.ColumnSpan="2"/>
<Button Content="&#xE106;" ToolTipService.ToolTip="Cancel" RelativePanel.Below="progressBar" RelativePanel.AlignRightWithPanel="True" Background="Transparent" FontFamily="Segoe MDL2 Assets" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Right"/>
</Grid>
</Grid>
</controls:DropShadowPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListViewItem HorizontalContentAlignment="Stretch" Padding="5">
<ListViewItem.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem Text="Delete" Icon="Delete"/>
<MenuFlyoutItem Text="Select">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE762;"/>
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
</MenuFlyout>
</ListViewItem.ContextFlyout>
<controls:DropShadowPanel HorizontalContentAlignment="Stretch">
<Grid Padding="10" ColumnSpacing="10" Background="{ThemeResource SystemChromeLowColor}" CornerRadius="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<controls:ImageEx PlaceholderStretch="UniformToFill" CornerRadius="2" Height="75" PlaceholderSource="/Assets/DefaultVideoThumbnail.png"/>
<Border CornerRadius="5,0,0,0" Background="{StaticResource SystemChromeMediumColor}" VerticalAlignment="Bottom" HorizontalAlignment="Right" Padding="10,2">
<TextBlock Text="2:13:45" Style="{StaticResource CaptionTextBlockStyle}"/>
</Border>
<StackPanel Grid.Column="1">
<TextBlock Text="[Quality] Video title" Style="{StaticResource TitleTextBlockStyle}" MaxLines="1"/>
<TextBlock Text="Author" MaxLines="1"/>
<TextBlock Text="video_file_path.mp4" Style="{StaticResource CaptionTextBlockStyle}" MaxLines="1"/>
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Horizontal" Visibility="Collapsed">
<Button Width="75" Height="75" Padding="0" Background="Transparent">
<StackPanel>
<TextBlock Text="&#xED25;" FontFamily="Segoe MDL2 Assets" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Open" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center"/>
</StackPanel>
</Button>
<Button Width="75" Height="75" Padding="0" Background="Transparent" Margin="10,0,0,0">
<StackPanel>
<TextBlock Text="&#xE2B4;" FontFamily="Segoe MDL2 Assets" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Go to original" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center" HorizontalAlignment="Center"/>
</StackPanel>
</Button>
</StackPanel>
<Grid Grid.Column="2" RowSpacing="5" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Downloading..." RelativePanel.Above="progressBar"/>
<TextBlock Text="50%" RelativePanel.AlignRightWithPanel="True" RelativePanel.Above="progressBar" Grid.Column="1" HorizontalAlignment="Right"/>
<ProgressBar Value="50" Width="200" Grid.Row="1" Grid.ColumnSpan="2"/>
<Button Content="&#xE106;" ToolTipService.ToolTip="Cancel" RelativePanel.Below="progressBar" RelativePanel.AlignRightWithPanel="True" Background="Transparent" FontFamily="Segoe MDL2 Assets" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Right"/>
</Grid>
</Grid>
</controls:DropShadowPanel>
</ListViewItem>
<ListViewItem HorizontalContentAlignment="Stretch" Padding="5">
<ListViewItem.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem Text="Delete" Icon="Delete"/>
<MenuFlyoutItem Text="Select">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE762;"/>
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
</MenuFlyout>
</ListViewItem.ContextFlyout>
<controls:DropShadowPanel HorizontalContentAlignment="Stretch">
<Grid Padding="10" ColumnSpacing="10" Background="{ThemeResource SystemChromeLowColor}" CornerRadius="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<controls:ImageEx PlaceholderStretch="UniformToFill" CornerRadius="2" Height="75" PlaceholderSource="/Assets/DefaultVideoThumbnail.png"/>
<Border CornerRadius="5,0,0,0" Background="{StaticResource SystemChromeMediumColor}" VerticalAlignment="Bottom" HorizontalAlignment="Right" Padding="10,2">
<TextBlock Text="2:13:45" Style="{StaticResource CaptionTextBlockStyle}"/>
</Border>
<StackPanel Grid.Column="1">
<TextBlock Text="[Quality] Video title" Style="{StaticResource TitleTextBlockStyle}" MaxLines="1"/>
<TextBlock Text="Author" MaxLines="1"/>
<TextBlock Text="video_file_path.mp4" Style="{StaticResource CaptionTextBlockStyle}" MaxLines="1"/>
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Horizontal" Visibility="Visible">
<Button Width="75" Height="75" Padding="0" Background="Transparent">
<StackPanel>
<TextBlock Text="&#xED25;" FontFamily="Segoe MDL2 Assets" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Open" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center"/>
</StackPanel>
</Button>
<Button Width="75" Height="75" Padding="0" Background="Transparent" Margin="10,0,0,0">
<StackPanel>
<TextBlock Text="&#xE2B4;" FontFamily="Segoe MDL2 Assets" FontSize="30" HorizontalAlignment="Center"/>
<TextBlock Text="Go to original" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center" HorizontalAlignment="Center"/>
</StackPanel>
</Button>
</StackPanel>
<Grid Grid.Column="2" RowSpacing="5" VerticalAlignment="Center" Visibility="Collapsed">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Downloading..." RelativePanel.Above="progressBar"/>
<TextBlock Text="50%" RelativePanel.AlignRightWithPanel="True" RelativePanel.Above="progressBar" Grid.Column="1" HorizontalAlignment="Right"/>
<ProgressBar Value="50" Width="200" Grid.Row="1" Grid.ColumnSpan="2"/>
<Button Content="&#xE106;" ToolTipService.ToolTip="Cancel" RelativePanel.Below="progressBar" RelativePanel.AlignRightWithPanel="True" Background="Transparent" FontFamily="Segoe MDL2 Assets" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Right"/>
</Grid>
</Grid>
</controls:DropShadowPanel>
</ListViewItem>
</ListView>
</StackPanel>
</ScrollViewer>
</Grid>
</PivotItem>
</Pivot>
</Page>
+114
View File
@@ -0,0 +1,114 @@
using FoxTube.Controls.Dialogs;
using FoxTube.Services;
using FoxTube.Models;
using System;
using System.Collections.Generic;
using Windows.System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using YoutubeExplode;
using YoutubeExplode.Videos;
using YoutubeExplode.Videos.Streams;
using System.IO;
namespace FoxTube.Views
{
/// <summary>
/// Video download page
/// </summary>
public sealed partial class Downloads : Page
{
public Downloads()
{
InitializeComponent();
downloadHistoryList.ItemsSource = DownloadsCenter.History;
// TODO: Add downloads list
UpdateList();
}
private void ToggleButton_Checked(object sender, RoutedEventArgs e)
{
deleteItemsButton.Visibility = Visibility.Visible;
deleteItemsButton.IsEnabled = false;
list.SelectionMode = ListViewSelectionMode.Multiple;
}
private void ToggleButton_Unchecked(object sender, RoutedEventArgs e)
{
deleteItemsButton.Visibility = Visibility.Collapsed;
list.SelectionMode = ListViewSelectionMode.None;
}
private void List_SelectionChanged(object sender, SelectionChangedEventArgs e) =>
deleteItemsButton.IsEnabled = list.SelectedItems.Count > 0;
private void DeleteSelectedItems(object sender, RoutedEventArgs e)
{
// TODO: Delete downloads
}
private async void OpenDefaultFolder(object sender, RoutedEventArgs e) =>
await Launcher.LaunchFolderAsync(await DownloadsCenter.GetDefaultDownloadsFolder());
private void OpenDownloadSettings(object sender, RoutedEventArgs e) =>
Navigation.NavigateTo(NavigationTarget.Settings, "downloads");
public void UpdateList() =>
empty.Opacity = (((list.ItemsSource as List<object>)?.Count) ?? list.Items.Count) > 0 ? 0 : 1;
private async void AutoSuggestBox_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
{
YoutubeClient client = new YoutubeClient(UserManagement.Service.HttpClient);
VideoId? id;
Video meta;
if ((id = VideoId.TryParse(args.QueryText)) == null || (meta = await client.Videos.GetAsync(id.Value)) == null)
{
sender.Items.Clear();
sender.Items.Add(new ComboBoxItem
{
Content = "No video found",
IsEnabled = false
});
return;
}
StreamManifest manifest = await client.Videos.Streams.GetManifestAsync(id.Value);
await new DownloadVideoDialog(meta, manifest).ShowAsync();
}
private void AutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args) =>
sender.Items.Clear();
private void DeleteOneItem(object sender, RoutedEventArgs e)
{
}
private void SelectOneItem(object sender, RoutedEventArgs e)
{
object item = ((sender as FrameworkElement).Parent as FrameworkElement).Parent;
ListView list;
}
private void OpenOriginal(object sender, RoutedEventArgs e)
{
SavedVideo item = (sender as FrameworkElement).Parent.GetValue(TagProperty) as SavedVideo;
Navigation.NavigateTo(NavigationTarget.Home, item.Id); // TODO: Replace with actual navigation
}
private async void OpenVideo(object sender, RoutedEventArgs e)
{
SavedVideo item = (sender as FrameworkElement).Parent.GetValue(TagProperty) as SavedVideo;
await Launcher.LaunchUriAsync(item.Path.ToUri());
}
private async void ShowInFolder(object sender, RoutedEventArgs e)
{
SavedVideo item = (sender as FrameworkElement).Parent.GetValue(TagProperty) as SavedVideo;
await Launcher.LaunchUriAsync(new FileInfo(item.Path).Directory.FullName.ToUri());
}
}
}
+7 -46
View File
@@ -1,61 +1,22 @@
<models:PageView <Page
xmlns:models="using:FoxTube.Core.Models"
NavigationCacheMode="Enabled" NavigationCacheMode="Enabled"
x:Class="FoxTube.Views.Home" x:Class="FoxTube.Views.Home"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns: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:toolkit="using:Microsoft.Toolkit.Uwp.UI.Controls" xmlns:homesections="using:FoxTube.Views.HomeSections"
xmlns:controls="using:FoxTube.Controls" mc:Ignorable="d">
mc:Ignorable="d"
Header="Home">
<Pivot> <Pivot>
<PivotItem Header="Recommended"> <PivotItem Header="Recommended">
<Grid> <homesections:Recommended/>
<RefreshContainer>
<ScrollViewer Padding="5,0">
<controls:ItemsGrid x:Name="recommendedItems"/>
</ScrollViewer>
</RefreshContainer>
<toolkit:Loading IsLoading="False" x:Name="recommendedLoading" VerticalContentAlignment="Center">
<toolkit:Loading.Background>
<AcrylicBrush BackgroundSource="HostBackdrop" TintColor="{ThemeResource SystemColorBackgroundColor}" TintOpacity=".5"/>
</toolkit:Loading.Background>
<ProgressRing Height="100" Width="100" IsActive="True"/>
</toolkit:Loading>
</Grid>
</PivotItem> </PivotItem>
<PivotItem Header="Trending"> <PivotItem Header="Trending">
<Grid> <homesections:Trending/>
<RefreshContainer>
<ScrollViewer Padding="5,0">
<controls:ItemsGrid x:Name="trendingItems"/>
</ScrollViewer>
</RefreshContainer>
<toolkit:Loading IsLoading="False" x:Name="trendingLoading" VerticalContentAlignment="Center">
<toolkit:Loading.Background>
<AcrylicBrush BackgroundSource="HostBackdrop" TintColor="{ThemeResource SystemColorBackgroundColor}" TintOpacity=".5"/>
</toolkit:Loading.Background>
<ProgressRing Height="100" Width="100" IsActive="True"/>
</toolkit:Loading>
</Grid>
</PivotItem> </PivotItem>
<PivotItem Header="Subscriptions"> <PivotItem Header="Subscriptions">
<Grid> <homesections:Subscriptions/>
<RefreshContainer>
<ScrollViewer Padding="5,0">
<controls:ItemsGrid x:Name="subscriptionsItems"/>
</ScrollViewer>
</RefreshContainer>
<toolkit:Loading IsLoading="False" x:Name="subscriptionsLoading" VerticalContentAlignment="Center">
<toolkit:Loading.Background>
<AcrylicBrush BackgroundSource="HostBackdrop" TintColor="{ThemeResource SystemColorBackgroundColor}" TintOpacity=".5"/>
</toolkit:Loading.Background>
<ProgressRing Height="100" Width="100" IsActive="True"/>
</toolkit:Loading>
</Grid>
</PivotItem> </PivotItem>
</Pivot> </Pivot>
</models:PageView> </Page>
+4 -23
View File
@@ -1,35 +1,16 @@
using FoxTube.Controls.Cards; using FoxTube.Attributes;
using FoxTube.Core.Models; using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation; using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
namespace FoxTube.Views 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 : PageView, IRefreshable [Refreshable]
public sealed partial class Home : Page
{ {
public Home() => public Home() =>
InitializeComponent(); InitializeComponent();
public void RefreshPage()
{
throw new System.NotImplementedException();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (e.NavigationMode != NavigationMode.New)
return;
for (int i = 0; i < 25; i++)
{
recommendedItems.Add(new VideoCard());
}
}
} }
} }
@@ -0,0 +1,17 @@
<Page
x:Class="FoxTube.Views.HomeSections.Recommended"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:controls="using:FoxTube.Controls"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
Loaded="Page_Loaded">
<Grid>
<RefreshContainer>
<ListView x:Name="list"/>
</RefreshContainer>
<controls:LoadingScreen x:Name="loadingScreen"/>
</Grid>
</Page>
@@ -0,0 +1,37 @@
using FoxTube.Attributes;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace FoxTube.Views.HomeSections
{
/// <summary>
/// Page with videos recommeded to user
/// </summary>
[Refreshable]
public sealed partial class Recommended : Page
{
public Recommended() =>
InitializeComponent();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (e.NavigationMode == NavigationMode.New)
LoadContent();
}
private void Page_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
if (!(Parent is Frame))
LoadContent();
}
private void LoadContent()
{
loadingScreen.Activate();
// TODO: Load content
}
}
}
@@ -0,0 +1,20 @@
<Page
NavigationCacheMode="Enabled"
x:Class="FoxTube.Views.HomeSections.Subscriptions"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:controls="using:FoxTube.Controls"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
Loaded="Page_Loaded">
<Grid>
<RefreshContainer>
<ScrollViewer Padding="5,0">
<controls:ItemsGrid x:Name="grid"/>
</ScrollViewer>
</RefreshContainer>
<controls:LoadingScreen x:Name="loadingScreen"/>
</Grid>
</Page>
@@ -0,0 +1,38 @@
using FoxTube.Attributes;
using FoxTube.Controls.Cards;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace FoxTube.Views.HomeSections
{
/// <summary>
/// Users subscriptions videos page
/// </summary>
[Refreshable]
public sealed partial class Subscriptions : Page
{
public Subscriptions() =>
InitializeComponent();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (e.NavigationMode == NavigationMode.New)
LoadContent();
}
private void Page_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
if (!(Parent is Frame))
LoadContent();
}
private void LoadContent()
{
loadingScreen.Activate();
// TODO: Load content
}
}
}
+17
View File
@@ -0,0 +1,17 @@
<Page
NavigationCacheMode="Enabled"
x:Class="FoxTube.Views.HomeSections.Trending"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:controls="using:FoxTube.Controls"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
Loaded="Page_Loaded">
<Grid>
<RefreshContainer>
<controls:ItemsGrid x:Name="grid"/>
</RefreshContainer>
</Grid>
</Page>
@@ -0,0 +1,61 @@
using FoxTube.Attributes;
using FoxTube.Controls.Cards;
using FoxTube.Models;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace FoxTube.Views.HomeSections
{
/// <summary>
/// YouTube trending videos page
/// </summary>
[Refreshable]
public sealed partial class Trending : Page, IIncrementalLoadingHost
{
VideosResource.ListRequest client;
public Trending() =>
InitializeComponent();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (e.NavigationMode != NavigationMode.Back)
LoadContent();
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
if (!(Parent is Frame))
LoadContent();
}
private void LoadContent()
{
client = UserManagement.Service.Videos.List("snippet,liveStreamingDetails");
client.MaxResults = 25;
client.Chart = VideosResource.ListRequest.ChartEnum.MostPopular;
client.RegionCode = FoxTube.Settings.Region;
grid.Initialize(this);
}
public async Task<(List<object>, bool)> LoadMoreItems()
{
VideoListResponse response = await client.ExecuteAsync();
client.PageToken = response.NextPageToken;
return (response.Items.Select(i => new VideoItem(i) as object).ToList(),
!string.IsNullOrWhiteSpace(response.NextPageToken));
}
}
}
+3 -4
View File
@@ -1,4 +1,4 @@
<models:PageView <Page
xmlns:models="using:FoxTube.Core.Models" xmlns:models="using:FoxTube.Core.Models"
x:Class="FoxTube.Views.Search" x:Class="FoxTube.Views.Search"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
@@ -8,8 +8,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:FoxTube.Controls" xmlns:controls="using:FoxTube.Controls"
xmlns:toolkit="using:Microsoft.Toolkit.Uwp.UI.Controls" xmlns:toolkit="using:Microsoft.Toolkit.Uwp.UI.Controls"
mc:Ignorable="d" mc:Ignorable="d">
Header="Search">
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
@@ -98,4 +97,4 @@
<ProgressRing Height="100" Width="100" IsActive="True"/> <ProgressRing Height="100" Width="100" IsActive="True"/>
</toolkit:Loading> </toolkit:Loading>
</Grid> </Grid>
</models:PageView> </Page>
+5 -20
View File
@@ -1,39 +1,24 @@
using FoxTube.Core.Models; using FoxTube.Attributes;
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;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives; 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 FoxTube.Views namespace FoxTube.Views
{ {
/// <summary> /// <summary>
/// Search results page /// Search results page
/// </summary> /// </summary>
public sealed partial class Search : PageView, IRefreshable [Refreshable]
public sealed partial class Search : Page
{ {
bool closingByToggle = false; bool closingByToggle = false;
public Search() => public Search() =>
InitializeComponent(); InitializeComponent();
public void RefreshPage()
{
throw new NotImplementedException();
}
void ToggleFilters_Click(object sender, RoutedEventArgs e) void ToggleFilters_Click(object sender, RoutedEventArgs e)
{ {
if(filters.Visibility == Visibility.Visible) if (filters.Visibility == Visibility.Visible)
{ {
filters.Visibility = Visibility.Collapsed; filters.Visibility = Visibility.Collapsed;
(sender as HyperlinkButton).Content = "Show filters \xE71C"; (sender as HyperlinkButton).Content = "Show filters \xE71C";
@@ -47,7 +32,7 @@ namespace FoxTube.Views
private void MenuFlyout_Closing(FlyoutBase sender, FlyoutBaseClosingEventArgs args) private void MenuFlyout_Closing(FlyoutBase sender, FlyoutBaseClosingEventArgs args)
{ {
if(closingByToggle) if (closingByToggle)
{ {
args.Cancel = true; args.Cancel = true;
closingByToggle = false; closingByToggle = false;
+7 -20
View File
@@ -1,40 +1,27 @@
<models:PageView <Page
xmlns:models="using:FoxTube.Core.Models"
x:Class="FoxTube.Views.Settings" x:Class="FoxTube.Views.Settings"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns: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:settingssections="using:FoxTube.Views.SettingsSections" xmlns:settingssections="using:FoxTube.Views.SettingsSections"
mc:Ignorable="d" mc:Ignorable="d">
Header="Settings">
<Page.Resources> <Pivot SelectedIndex="0" Name="pivot">
<Style TargetType="ScrollViewer">
<Setter Property="Padding" Value="10,0"/>
</Style>
</Page.Resources>
<Pivot SelectedIndex="0" Name="pivot" IsHeaderItemsCarouselEnabled="False">
<PivotItem Name="generalTab" Header="Preferences"> <PivotItem Name="generalTab" Header="Preferences">
<ScrollViewer> <ScrollViewer Padding="15,0">
<settingssections:General/> <settingssections:General/>
</ScrollViewer> </ScrollViewer>
</PivotItem> </PivotItem>
<PivotItem Name="aboutTab" Header="About us"> <PivotItem Name="aboutTab" Header="About us">
<ScrollViewer> <ScrollViewer Padding="15,0">
<settingssections:About/> <settingssections:About/>
</ScrollViewer> </ScrollViewer>
</PivotItem> </PivotItem>
<!--<PivotItem Name="translateTab" Header="Help us translate this app">
<ScrollViewer>
<settingssections:Translate/>
</ScrollViewer>
</PivotItem>-->
<PivotItem Name="inboxTab" Header="Inbox"> <PivotItem Name="inboxTab" Header="Inbox">
<ScrollViewer> <ScrollViewer Padding="15,0">
<settingssections:Inbox x:Name="inbox"/> <settingssections:Inbox x:Name="inbox"/>
</ScrollViewer> </ScrollViewer>
</PivotItem> </PivotItem>
</Pivot> </Pivot>
</models:PageView> </Page>
+8 -11
View File
@@ -1,4 +1,4 @@
using FoxTube.Core.Models; using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation; using Windows.UI.Xaml.Navigation;
namespace FoxTube.Views namespace FoxTube.Views
@@ -6,7 +6,7 @@ namespace FoxTube.Views
/// <summary> /// <summary>
/// Settings page /// Settings page
/// </summary> /// </summary>
public sealed partial class Settings : PageView public sealed partial class Settings : Page
{ {
public Settings() => public Settings() =>
InitializeComponent(); InitializeComponent();
@@ -20,26 +20,23 @@ namespace FoxTube.Views
string[] param = (e.Parameter as string).Split('/'); string[] param = (e.Parameter as string).Split('/');
object focus; switch (param[0])
switch(param[0])
{ {
case "about": case "about":
case "info": case "info":
focus = aboutTab; pivot.SelectedItem = aboutTab;
break; break;
case "inbox": case "inbox":
case "message": case "message":
case "changelog": case "changelog":
focus = inboxTab; pivot.SelectedItem = inboxTab;
if (param.Length > 1)
inbox.Open(param[1]);
break; break;
default: default:
focus = generalTab; pivot.SelectedItem = generalTab;
break; break;
} }
pivot.SelectedItem = focus;
if (focus == inboxTab && param.Length > 1)
inbox.Open(param[1]);
} }
} }
} }
+4 -4
View File
@@ -12,14 +12,14 @@
<ColumnDefinition/> <ColumnDefinition/>
<ColumnDefinition Width="auto"/> <ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<controls:DropShadowPanel Grid.Column="1" VerticalAlignment="Top" OffsetX="5" OffsetY="5"> <controls:DropShadowPanel Grid.Column="1" VerticalAlignment="Top">
<Image Source="/Assets/StoreLogo.scale-400.png" Width="150"/> <Image Source="/Assets/StoreLogo.scale-400.png" Width="150"/>
</controls:DropShadowPanel> </controls:DropShadowPanel>
<StackPanel> <StackPanel>
<StackPanel.ChildrenTransitions> <StackPanel.ChildrenTransitions>
<TransitionCollection> <TransitionCollection>
<EntranceThemeTransition IsStaggeringEnabled="True"/> <EntranceThemeTransition IsStaggeringEnabled="True" FromVerticalOffset="100"/>
</TransitionCollection> </TransitionCollection>
</StackPanel.ChildrenTransitions> </StackPanel.ChildrenTransitions>
@@ -43,7 +43,7 @@
Twitter: <Hyperlink NavigateUri="https://twitter.com/xfox111">@xfox111</Hyperlink> Twitter: <Hyperlink NavigateUri="https://twitter.com/xfox111">@xfox111</Hyperlink>
<LineBreak/>Vkontakte: <Hyperlink NavigateUri="https://vk.com/XFox.Mike">@XFox.Mike</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/>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/>E-mail: <Hyperlink NavigateUri="mailto:michael@xfox111.net">michael@xfox111.net</Hyperlink>
<LineBreak/>My website: <Hyperlink NavigateUri="https://xfox111.net">https://xfox111.net</Hyperlink> <LineBreak/>My website: <Hyperlink NavigateUri="https://xfox111.net">https://xfox111.net</Hyperlink>
</TextBlock> </TextBlock>
</StackPanel> </StackPanel>
@@ -51,7 +51,7 @@
<StackPanel Margin="0,10,0,0"> <StackPanel Margin="0,10,0,0">
<TextBlock Text="Legal stuff" Style="{StaticResource TitleTextBlockStyle}"/> <TextBlock Text="Legal stuff" Style="{StaticResource TitleTextBlockStyle}"/>
<TextBlock> <TextBlock>
<Hyperlink NavigateUri="https://xfox111.net/Projects/FoxTube/PrivacyPolicy.txt">Our Privacy Policy</Hyperlink> <Hyperlink NavigateUri="https://xfox111.net/Projects/FoxTube/Privacy">Our Privacy Policy</Hyperlink>
<LineBreak/><Hyperlink NavigateUri="https://youtube.com/t/privacy">YouTube 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/terms">YouTube Terms of use</Hyperlink>
<LineBreak/><Hyperlink NavigateUri="https://youtube.com/t/community_guidelines">YouTube Community Guidelines</Hyperlink> <LineBreak/><Hyperlink NavigateUri="https://youtube.com/t/community_guidelines">YouTube Community Guidelines</Hyperlink>
+2 -2
View File
@@ -1,4 +1,4 @@
using FoxTube.Core.Helpers; using FoxTube.Utils;
using System; using System;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
@@ -21,7 +21,7 @@ namespace FoxTube.Views.SettingsSections
feedback.Visibility = Visibility.Visible; feedback.Visibility = Visibility.Visible;
} }
void OpenFeedbackHub(object sender, RoutedEventArgs e) => private void OpenFeedbackHub(object sender, RoutedEventArgs e) =>
Feedback.OpenFeedbackHub(); Feedback.OpenFeedbackHub();
} }
} }
+24 -6
View File
@@ -4,15 +4,24 @@
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"
mc:Ignorable="d"> mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel> <StackPanel>
<StackPanel.ChildrenTransitions> <StackPanel.ChildrenTransitions>
<TransitionCollection> <TransitionCollection>
<EntranceThemeTransition IsStaggeringEnabled="True"/> <EntranceThemeTransition IsStaggeringEnabled="True" FromVerticalOffset="100"/>
</TransitionCollection> </TransitionCollection>
</StackPanel.ChildrenTransitions> </StackPanel.ChildrenTransitions>
<StackPanel Margin="0,0,0,10">
<ComboBox Header="Default homepage tab" Width="250">
<ComboBoxItem Content="Recommended"/>
<ComboBoxItem Content="Trending"/>
<ComboBoxItem Content="Subscriptions"/>
</ComboBox>
</StackPanel>
<StackPanel Margin="0,0,0,10"> <StackPanel Margin="0,0,0,10">
<TextBlock Text="Region &#x26; search" Style="{StaticResource TitleTextBlockStyle}"/> <TextBlock Text="Region &#x26; search" Style="{StaticResource TitleTextBlockStyle}"/>
<ComboBox Header="App interface language" Width="250" Name="language" SelectionChanged="LanguageChanged"> <ComboBox Header="App interface language" Width="250" Name="language" SelectionChanged="LanguageChanged">
@@ -21,7 +30,7 @@
</ComboBox> </ComboBox>
<Button Content="Restart application" x:Name="restart" Visibility="Collapsed" Foreground="White" Background="Red" Margin="5" Click="Restart"/> <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="Preffered content language" Width="250" Name="relevanceLanguage" SelectionChanged="RelevanceLanguageChanged" Loaded="LoadRelevaneLanguageList"/>
<ComboBox Header="Region" Width="250" Name="region" SelectionChanged="RegionChanged" Loaded="LoadRegionList"/> <ComboBox Header="Region" Width="250" Name="region" SelectionChanged="RegionChanged" Loaded="LoadRegionList"/>
<ComboBox Header="SafeSearch" Width="250" Name="safeSearch" SelectionChanged="SafeSearchChanged"> <ComboBox Header="SafeSearch" Width="250" Name="safeSearch" SelectionChanged="SafeSearchChanged">
<ComboBoxItem Content="Moderate"/> <ComboBoxItem Content="Moderate"/>
@@ -48,15 +57,24 @@
<ToggleSwitch OnContent="Recieve messages from developers" OffContent="Recieve messages from developers" Name="developersNews" Toggled="DevelopersNotificationsChanged"/> <ToggleSwitch OnContent="Recieve messages from developers" OffContent="Recieve messages from developers" Name="developersNews" Toggled="DevelopersNotificationsChanged"/>
</StackPanel> </StackPanel>
<StackPanel Margin="0,0,0,10">
<TextBlock Text="Downloads" Style="{StaticResource TitleTextBlockStyle}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="0,5">
<TextBox Header="Default downloads location" Width="250" IsReadOnly="True" PlaceholderText="//Videos/FoxTube"/>
<Button VerticalAlignment="Bottom" FontFamily="Segoe MDL2 Assets" Content="&#xE10C;" Margin="5,0"/>
</StackPanel>
<ToggleSwitch OnContent="Ask where to save before downloading" OffContent="Ask where to save before downloading"/>
</StackPanel>
<StackPanel Margin="0,0,0,10"> <StackPanel Margin="0,0,0,10">
<TextBlock Text="Theme" Style="{StaticResource TitleTextBlockStyle}"/> <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="Light" Name="light" Tag="0" GroupName="theme" Checked="ThemeChanged"/>
<RadioButton Content="Dark" Name="dark" Tag="1" 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"/> <RadioButton Content="Windows default" Tag="2" Name="system" GroupName="theme" Checked="ThemeChanged"/>
</StackPanel>
<HyperlinkButton Content="Windows color settings" NavigateUri="ms-settings:colors"/> <HyperlinkButton Content="Windows color settings" NavigateUri="ms-settings:colors"/>
</StackPanel> </StackPanel>
<Button Content="Reset application" Click="ResetApp"/>
</StackPanel> </StackPanel>
</Page> </Page>
+26 -31
View File
@@ -1,8 +1,5 @@
using FoxTube.Core.Helpers; using System.Linq;
using System.Linq;
using Windows.Globalization; using Windows.Globalization;
using Windows.UI;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
@@ -42,24 +39,24 @@ namespace FoxTube.Views.SettingsSections
} }
} }
void LoadRelevaneLanguageList(object sender, RoutedEventArgs e) private void LoadRelevaneLanguageList(object sender, RoutedEventArgs e)
{ {
// TODO: Add list loading // TODO: Add list loading
} }
void LoadRegionList(object sender, RoutedEventArgs e) private void LoadRegionList(object sender, RoutedEventArgs e)
{ {
// TODO: Add list loading // TODO: Add list loading
} }
void LoadQualitiesList(object sender, RoutedEventArgs e) private void LoadQualitiesList(object sender, RoutedEventArgs e)
{ {
// TODO: Add qualities loading // TODO: Add qualities loading
quality.SelectedItem = quality.Items.FirstOrDefault(i => ((ComboBoxItem)i).Tag.ToString() == FoxTube.Settings.DesiredVideoQuality); quality.SelectedItem = quality.Items.FirstOrDefault(i => ((ComboBoxItem)i).Tag.ToString() == FoxTube.Settings.DesiredVideoQuality);
} }
void LanguageChanged(object sender, SelectionChangedEventArgs e) private void LanguageChanged(object sender, SelectionChangedEventArgs e)
{ {
if ((language.SelectedItem as ComboBoxItem).Tag.ToString() == FoxTube.Settings.Language) if ((language.SelectedItem as ComboBoxItem).Tag.ToString() == FoxTube.Settings.Language)
return; return;
@@ -69,69 +66,67 @@ namespace FoxTube.Views.SettingsSections
restart.Visibility = Visibility.Visible; restart.Visibility = Visibility.Visible;
} }
void Restart(object sender, RoutedEventArgs e) => private void Restart(object sender, RoutedEventArgs e) =>
Utils.RestartApp(); Utils.Utils.RestartApp();
void RelevanceLanguageChanged(object sender, SelectionChangedEventArgs e) => private void RelevanceLanguageChanged(object sender, SelectionChangedEventArgs e) =>
FoxTube.Settings.RelevanceLanguage = ((ComboBoxItem)relevanceLanguage.SelectedItem).Tag.ToString(); FoxTube.Settings.RelevanceLanguage = ((ComboBoxItem)relevanceLanguage.SelectedItem).Tag.ToString();
void RegionChanged(object sender, SelectionChangedEventArgs e) => private void RegionChanged(object sender, SelectionChangedEventArgs e) =>
FoxTube.Settings.Region = ((ComboBoxItem)region.SelectedItem).Tag.ToString(); FoxTube.Settings.Region = ((ComboBoxItem)region.SelectedItem).Tag.ToString();
void SafeSearchChanged(object sender, SelectionChangedEventArgs e) => private void SafeSearchChanged(object sender, SelectionChangedEventArgs e) =>
FoxTube.Settings.SafeSearch = safeSearch.SelectedIndex; FoxTube.Settings.SafeSearch = safeSearch.SelectedIndex;
void QualityChanged(object sender, SelectionChangedEventArgs e) => private void QualityChanged(object sender, SelectionChangedEventArgs e) =>
FoxTube.Settings.DesiredVideoQuality = (quality.SelectedItem as ComboBoxItem).Tag as string; FoxTube.Settings.DesiredVideoQuality = (quality.SelectedItem as ComboBoxItem).Tag as string;
void MeteredWarningChanged(object sender, RoutedEventArgs e) => private void MeteredWarningChanged(object sender, RoutedEventArgs e) =>
FoxTube.Settings.CheckConnection = meteredWarning.IsOn; FoxTube.Settings.CheckConnection = meteredWarning.IsOn;
void AutoplayChanged(object sender, RoutedEventArgs e) => private void AutoplayChanged(object sender, RoutedEventArgs e) =>
FoxTube.Settings.Autoplay = autoplay.IsOn; FoxTube.Settings.Autoplay = autoplay.IsOn;
void ExplicitWarningChanged(object sender, RoutedEventArgs e) => private void ExplicitWarningChanged(object sender, RoutedEventArgs e) =>
FoxTube.Settings.BlockExplicitContent = explicitWarning.IsOn; FoxTube.Settings.BlockExplicitContent = explicitWarning.IsOn;
void ChannelNotificationsChanged(object sender, RoutedEventArgs e) => private void ChannelNotificationsChanged(object sender, RoutedEventArgs e) =>
FoxTube.Settings.VideoNotifications = channelNotifications.IsOn; FoxTube.Settings.VideoNotifications = channelNotifications.IsOn;
void ClipboardProcessingChanged(object sender, RoutedEventArgs e) => private void ClipboardProcessingChanged(object sender, RoutedEventArgs e) =>
FoxTube.Settings.ProcessClipboard = clipboardProcessing.IsOn; FoxTube.Settings.ProcessClipboard = clipboardProcessing.IsOn;
void DevelopersNotificationsChanged(object sender, RoutedEventArgs e) => private void DevelopersNotificationsChanged(object sender, RoutedEventArgs e) =>
FoxTube.Settings.DevNotifications = developersNews.IsOn; FoxTube.Settings.DevNotifications = developersNews.IsOn;
void ThemeChanged(object sender, RoutedEventArgs e) private void ThemeChanged(object sender, RoutedEventArgs e)
{ {
if (FoxTube.Settings.Theme.ToString() == (string)(sender as RadioButton).Tag) if (FoxTube.Settings.Theme.ToString() == (string)(sender as RadioButton).Tag)
return; return;
switch((sender as RadioButton).Name) switch ((sender as RadioButton).Name)
{ {
case "light": case "light":
FoxTube.Settings.Theme = 0; FoxTube.Settings.Theme = 0;
MainPage.Current.RequestedTheme = ElementTheme.Light; MainPage.Current.RequestedTheme = ElementTheme.Light;
App.UpdateTitleBar(false);
break; break;
case "dark": case "dark":
FoxTube.Settings.Theme = 1; FoxTube.Settings.Theme = 1;
MainPage.Current.RequestedTheme = ElementTheme.Dark; MainPage.Current.RequestedTheme = ElementTheme.Dark;
App.UpdateTitleBar(true);
break; break;
default: default:
FoxTube.Settings.Theme = 2; FoxTube.Settings.Theme = 2;
MainPage.Current.RequestedTheme = ElementTheme.Default; MainPage.Current.RequestedTheme = ElementTheme.Default;
App.UpdateTitleBar(Application.Current.RequestedTheme == ApplicationTheme.Dark);
break; break;
} }
}
ApplicationViewTitleBar titleBar = ApplicationView.GetForCurrentView().TitleBar; private void ResetApp(object sender, RoutedEventArgs e)
if (MainPage.Current.RequestedTheme == ElementTheme.Default) {
titleBar.ButtonForegroundColor = Utils.Utils.InitializeFailsafeProtocol();
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;
} }
} }
} }
+31 -18
View File
@@ -5,7 +5,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls" xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:models="using:FoxTube.Core.Models" xmlns:models="using:FoxTube.Models"
mc:Ignorable="d" mc:Ignorable="d"
Loaded="Page_Loaded"> Loaded="Page_Loaded">
@@ -13,13 +13,20 @@
<Style TargetType="controls:DropShadowPanel"> <Style TargetType="controls:DropShadowPanel">
<Setter Property="OffsetX" Value="3"/> <Setter Property="OffsetX" Value="3"/>
<Setter Property="OffsetY" Value="3"/> <Setter Property="OffsetY" Value="3"/>
<Setter Property="ShadowOpacity" Value=".5"/>
</Style> </Style>
</Page.Resources> </Page.Resources>
<controls:MasterDetailsView Background="Transparent" MasterPaneWidth="400" CompactModeThresholdWidth="850" x:Name="masterDetailsView" BackButtonBehavior="Inline"> <controls:MasterDetailsView MasterPaneWidth="400" CompactModeThresholdWidth="850" x:Name="masterDetailsView" BackButtonBehavior="Inline">
<controls:MasterDetailsView.ItemContainerTransitions>
<TransitionCollection>
<EntranceThemeTransition IsStaggeringEnabled="True" FromVerticalOffset="100"/>
</TransitionCollection>
</controls:MasterDetailsView.ItemContainerTransitions>
<controls:MasterDetailsView.MasterHeader> <controls:MasterDetailsView.MasterHeader>
<StackPanel> <StackPanel Margin="0,0,0,10">
<ProgressBar IsIndeterminate="True" x:Name="progressBar"/> <ProgressBar IsIndeterminate="True" x:Name="progressBar" Background="Transparent"/>
<ComboBox Header="Filter" HorizontalAlignment="Stretch" x:Name="filter" SelectionChanged="FilterChanged" IsEnabled="False"> <ComboBox Header="Filter" HorizontalAlignment="Stretch" x:Name="filter" SelectionChanged="FilterChanged" IsEnabled="False">
<ComboBoxItem Content="All"/> <ComboBoxItem Content="All"/>
<ComboBoxItem Content="Changelogs"/> <ComboBoxItem Content="Changelogs"/>
@@ -27,6 +34,7 @@
</ComboBox> </ComboBox>
</StackPanel> </StackPanel>
</controls:MasterDetailsView.MasterHeader> </controls:MasterDetailsView.MasterHeader>
<controls:MasterDetailsView.NoSelectionContent> <controls:MasterDetailsView.NoSelectionContent>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center"> <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<controls:DropShadowPanel Margin="20,0"> <controls:DropShadowPanel Margin="20,0">
@@ -37,11 +45,13 @@
</controls:DropShadowPanel> </controls:DropShadowPanel>
</StackPanel> </StackPanel>
</controls:MasterDetailsView.NoSelectionContent> </controls:MasterDetailsView.NoSelectionContent>
<controls:MasterDetailsView.ItemContainerStyle> <controls:MasterDetailsView.ItemContainerStyle>
<Style TargetType="ListViewItem"> <Style TargetType="ListViewItem">
<Setter Property="Padding" Value="0"/> <Setter Property="Padding" Value="0"/>
</Style> </Style>
</controls:MasterDetailsView.ItemContainerStyle> </controls:MasterDetailsView.ItemContainerStyle>
<controls:MasterDetailsView.ItemTemplate> <controls:MasterDetailsView.ItemTemplate>
<DataTemplate x:DataType="models:InboxItem"> <DataTemplate x:DataType="models:InboxItem">
<Grid ColumnSpacing="10" Margin="10"> <Grid ColumnSpacing="10" Margin="10">
@@ -49,38 +59,41 @@
<ColumnDefinition Width="auto"/> <ColumnDefinition Width="auto"/>
<ColumnDefinition/> <ColumnDefinition/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
<Setter Property="MaxLines" Value="1"/>
<Setter Property="TextWrapping" Value="WrapWholeWords"/>
</Style>
</Grid.Resources>
<PersonPicture Width="50" VerticalAlignment="Top" ProfilePicture="{Binding Avatar}" Initials="{Binding DefaultIcon}" FontFamily="Segoe MDL2 Assets" Foreground="White"/> <PersonPicture Width="50" VerticalAlignment="Top" ProfilePicture="{Binding Avatar}" Initials="{Binding DefaultIcon}" FontFamily="Segoe MDL2 Assets" Foreground="White"/>
<StackPanel Grid.Column="1"> <StackPanel Grid.Column="1">
<TextBlock Text="{Binding Title}" Style="{StaticResource SubtitleTextBlockStyle}"/> <TextBlock Text="{Binding Title}" Style="{StaticResource SubtitleTextBlockStyle}" MaxLines="1"/>
<TextBlock Text="{Binding Description}" MaxLines="2"/> <TextBlock Text="{Binding Description}" MaxLines="2"/>
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" FontStyle="Italic"> <TextBlock Style="{StaticResource CaptionTextBlockStyle}" FontStyle="Italic" MaxLines="1">
<Run Text="{Binding Type}"/> • <Run Text="{Binding ShortTimeStamp}"/> <Run Text="{Binding Type}"/> • <Run Text="{Binding ShortTimeStamp}"/>
</TextBlock> </TextBlock>
</StackPanel> </StackPanel>
</Grid> </Grid>
</DataTemplate> </DataTemplate>
</controls:MasterDetailsView.ItemTemplate> </controls:MasterDetailsView.ItemTemplate>
<controls:MasterDetailsView.DetailsTemplate> <controls:MasterDetailsView.DetailsTemplate>
<DataTemplate x:DataType="models:InboxItem"> <DataTemplate x:DataType="models:InboxItem">
<ScrollViewer> <ScrollViewer>
<RelativePanel Margin="10"> <Grid RowSpacing="10" Margin="10">
<PersonPicture x:Name="avatar" Foreground="White" FontFamily="Segoe MDL2 Assets" Initials="{Binding DefaultIcon}" ProfilePicture="{Binding Avatar}" Height="60" Margin="10"/> <Grid.RowDefinitions>
<StackPanel RelativePanel.RightOf="avatar"> <RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<RelativePanel Margin="0,10">
<PersonPicture x:Name="avatar" Foreground="White" FontFamily="Segoe MDL2 Assets" Initials="{Binding DefaultIcon}" ProfilePicture="{Binding Avatar}" Height="60"/>
<StackPanel RelativePanel.RightOf="avatar" Margin="10,0">
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="{Binding Title}"/> <TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="{Binding Title}"/>
<TextBlock Text="{Binding TimeStamp}"/> <TextBlock Text="{Binding TimeStamp}"/>
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" FontStyle="Italic" Text="{Binding Type}"/> <TextBlock Style="{StaticResource CaptionTextBlockStyle}" FontStyle="Italic" Text="{Binding Type}"/>
</StackPanel> </StackPanel>
<controls:MarkdownTextBlock Background="Transparent" RelativePanel.Below="avatar" Text="{Binding Content}"/>
</RelativePanel> </RelativePanel>
<controls:MarkdownTextBlock Background="Transparent" Grid.Row="1" Text="{Binding Content}"/>
</Grid>
</ScrollViewer> </ScrollViewer>
</DataTemplate> </DataTemplate>
</controls:MasterDetailsView.DetailsTemplate> </controls:MasterDetailsView.DetailsTemplate>
+9 -14
View File
@@ -1,6 +1,5 @@
using FoxTube.Core.Models; using FoxTube.Models;
using FoxTube.Core.Models.Inbox; using System.Linq;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
@@ -12,34 +11,30 @@ namespace FoxTube.Views.SettingsSections
/// </summary> /// </summary>
public sealed partial class Inbox : Page public sealed partial class Inbox : Page
{ {
List<InboxItem> items; InboxItem[] items;
string idToOpen; string idToOpen;
public Inbox() => public Inbox() =>
InitializeComponent(); InitializeComponent();
async void Page_Loaded(object sender, RoutedEventArgs e) private async void Page_Loaded(object sender, RoutedEventArgs e)
{ {
items = await Core.Helpers.Inbox.GetInbox(); items = await Services.Inbox.GetMessages();
// TODO: Remove
items.Add(new Changelog("1.0", "Changelog content", "Changelog description", DateTime.Now));
items.Add(new DeveloperMessage("id", "Message title", "Message content", DateTime.Now, ""));
filter.SelectedIndex = 0; filter.SelectedIndex = 0;
progressBar.Visibility = Visibility.Collapsed; progressBar.IsIndeterminate = false;
filter.IsEnabled = true; filter.IsEnabled = true;
if (idToOpen != null) if (idToOpen != null)
Open(idToOpen); Open(idToOpen);
} }
void FilterChanged(object sender, SelectionChangedEventArgs e) => private void FilterChanged(object sender, SelectionChangedEventArgs e) =>
masterDetailsView.ItemsSource = filter.SelectedIndex switch masterDetailsView.ItemsSource = filter.SelectedIndex switch
{ {
1 => items.FindAll(i => i is Changelog), 1 => items.Where(i => i.Id.StartsWith("changelog")),
2 => items.FindAll(i => i is DeveloperMessage), 2 => items.Where(i => i.Id.StartsWith("inbox")),
_ => items _ => items
}; };
@@ -1,68 +0,0 @@
<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"
xmlns:globalization="using:System.Globalization"
mc:Ignorable="d">
<StackPanel>
<TextBlock Text="Help us translate this app" Style="{StaticResource SubheaderTextBlockStyle}"/>
<TextBlock TextWrapping="WrapWholeWords" Text="You can help us make this app better and deliver it to more regions by translating it" Margin="0,0,0,10"/>
<TextBlock Text="It's quite simple:" Margin="0,0,0,10"/>
<ComboBox Header="1. Choose language you want to translate into" PlaceholderText="Choose language..." Name="LangList" Margin="0,0,0,10" MinWidth="350">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="globalization:CultureInfo">
<TextBlock Text="{Binding DisplayName}" Tag="{Binding ThreeLetterISOLanguageName}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Text="2. Save language pack file to your PC" Margin="0,0,0,10"/>
<Button Content="Export to PC (.zip)" Margin="0,0,0,10" Name="export" IsEnabled="False"/>
<TextBlock TextWrapping="WrapWholeWords" Text="3. Open archive's files with any text editor you want (Notepad, Wordpad, Notepad++, VS Code, etc.)" Margin="0,0,0,10"/>
<TextBlock TextWrapping="WrapWholeWords" Text="4. Edit file by translating nececcary words and sentences" Margin="0,0,0,10"/>
<TextBlock TextWrapping="WrapWholeWords" Text="5. Upload final package to our servers" Margin="0,0,0,10"/>
<StackPanel Name="submitNotification" Visibility="Collapsed" BorderThickness="2" BorderBrush="OrangeRed" Width="350" HorizontalAlignment="Left" Margin="0,0,0,10" Padding="0,0,0,3">
<TextBlock Foreground="OrangeRed" FontWeight="SemiBold" Text="Attention! Once you submitted this language pack you won't be able to contribute to the language anymore. Think twice before continuing" TextWrapping="WrapWholeWords" Margin="5"/>
</StackPanel>
<Button Content="Choose file to upload" Margin="-1,0,0,10" HorizontalAlignment="Left" VerticalAlignment="Top" Name="upload" IsEnabled="False"/>
<Border Background="{ThemeResource SystemChromeMediumLowColor}" CornerRadius="10" Padding="10" HorizontalAlignment="Left" Name="certification" Visibility="Collapsed">
<StackPanel>
<TextBlock FontWeight="Bold" Text="Package certification result"/>
<StackPanel Orientation="Horizontal" Margin="0,5" Name="certificationStatus">
<FontIcon Glyph="&#xEC61;" Foreground="Green"/>
<TextBlock Text="Passed" Margin="5,0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Visibility="Visible">
<Button Content="Upload" Name="submit"/>
<Button Content="View log" Name="log"/>
<Button Content="Choose another file" Margin="10,0,0,0" Name="chooseFile"/>
</StackPanel>
<ProgressBar HorizontalAlignment="Stretch" IsIndeterminate="True" Name="uploadingProgress" Visibility="Visible"/>
</StackPanel>
</Border>
<TextBlock TextWrapping="WrapWholeWords">
It takes about 2-3 weeks to process new language pack and include it to the next updateThank you for your help &#x1F61A;<LineBreak/>
Best wishes,</TextBlock>
<TextBlock Text=" XFox"/>
<StackPanel Orientation="Horizontal" BorderBrush="Green" BorderThickness="5" Margin="0,10,30,0" Visibility="Collapsed" Name="greenResult">
<TextBlock FontFamily="Segoe MDL2 Assets" Text="&#xE76E;" FontSize="40" Foreground="Green" Margin="5"/>
<StackPanel>
<TextBlock Text="Your language pack has been sent!" Foreground="Green" FontWeight="Bold" FontSize="20"/>
<TextBlock Text="Thank you! It's very imortant for us. You help us making the app better" Foreground="Green"/>
</StackPanel>
</StackPanel>
</StackPanel>
</Page>
@@ -1,30 +0,0 @@
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();
}
}
}
+3 -4
View File
@@ -1,4 +1,4 @@
<models:PageView <Page
xmlns:models="using:FoxTube.Core.Models" xmlns:models="using:FoxTube.Core.Models"
x:Class="FoxTube.Views.Subscriptions" x:Class="FoxTube.Views.Subscriptions"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
@@ -7,8 +7,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls" xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
mc:Ignorable="d" mc:Ignorable="d">
Header="Subscriptions">
<ListView Padding="10" SelectionMode="None"> <ListView Padding="10" SelectionMode="None">
<ListViewItem Padding="0" HorizontalAlignment="Left"> <ListViewItem Padding="0" HorizontalAlignment="Left">
@@ -38,4 +37,4 @@
</Grid> </Grid>
</ListViewItem> </ListViewItem>
</ListView> </ListView>
</models:PageView> </Page>
+2 -16
View File
@@ -1,25 +1,11 @@
using FoxTube.Core.Models; using Windows.UI.Xaml.Controls;
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;
namespace FoxTube.Views namespace FoxTube.Views
{ {
/// <summary> /// <summary>
/// User's subscriptions list /// User's subscriptions list
/// </summary> /// </summary>
public sealed partial class Subscriptions : PageView public sealed partial class Subscriptions : Page
{ {
public Subscriptions() => public Subscriptions() =>
InitializeComponent(); InitializeComponent();