Archived
1
0

Done main page, settings, and basic logic

This commit is contained in:
Michael Gordeev
2020-05-03 13:13:41 +03:00
parent 94bb593e50
commit e292bb15d8
80 changed files with 2889 additions and 0 deletions
+51
View File
@@ -0,0 +1,51 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30011.22
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinTorrent", "WinTorrent\WinTorrent.csproj", "{88F8E34F-0129-4856-A1F7-4A89DA892C9B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Debug|ARM.ActiveCfg = Debug|ARM
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Debug|ARM.Build.0 = Debug|ARM
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Debug|ARM.Deploy.0 = Debug|ARM
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Debug|ARM64.ActiveCfg = Debug|ARM64
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Debug|ARM64.Build.0 = Debug|ARM64
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Debug|ARM64.Deploy.0 = Debug|ARM64
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Debug|x64.ActiveCfg = Debug|x64
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Debug|x64.Build.0 = Debug|x64
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Debug|x64.Deploy.0 = Debug|x64
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Debug|x86.ActiveCfg = Debug|x86
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Debug|x86.Build.0 = Debug|x86
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Debug|x86.Deploy.0 = Debug|x86
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Release|ARM.ActiveCfg = Release|ARM
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Release|ARM.Build.0 = Release|ARM
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Release|ARM.Deploy.0 = Release|ARM
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Release|ARM64.ActiveCfg = Release|ARM64
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Release|ARM64.Build.0 = Release|ARM64
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Release|ARM64.Deploy.0 = Release|ARM64
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Release|x64.ActiveCfg = Release|x64
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Release|x64.Build.0 = Release|x64
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Release|x64.Deploy.0 = Release|x64
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Release|x86.ActiveCfg = Release|x86
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Release|x86.Build.0 = Release|x86
{88F8E34F-0129-4856-A1F7-4A89DA892C9B}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E3A42E8C-A604-4B2B-9820-C44F47BB4D17}
EndGlobalSection
EndGlobal
+33
View File
@@ -0,0 +1,33 @@
<Application
x:Class="WinTorrent.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/TemplateDictionaries/AutoSuggestBoxTemplateDictionary.xaml"/>
<ResourceDictionary Source="/TemplateDictionaries/NavigationViewItemTemplateDictionary.xaml"/>
<ResourceDictionary Source="/TemplateDictionaries/ListViewItemTemplateDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Color x:Key="SystemAccentColor">DeepSkyBlue</Color>
<Style TargetType="Button" BasedOn="{StaticResource ButtonRevealStyle}">
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="CornerRadius" Value="2"/>
</Style>
<Style TargetType="NavigationViewItem">
<Setter Property="Foreground" Value="{ThemeResource SystemChromeGrayColor}"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="CornerRadius" Value="2"/>
</Style>
<Style TargetType="ComboBox">
<Setter Property="CornerRadius" Value="2"/>
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
+136
View File
@@ -0,0 +1,136 @@
using System;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.Core;
using Windows.UI;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using WinTorrent.Pages;
using WinTorrent.Utils;
namespace WinTorrent
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
sealed partial class App : Application
{
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
InitializeComponent();
Suspending += OnSuspending;
}
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);
}
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
if (!(Window.Current.Content is Frame rootFrame))
{
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
Window.Current.Content = rootFrame;
}
if (!e.PrelaunchActivated)
{
if (rootFrame.Content == null)
rootFrame.Navigate(typeof(MainPage), e.Arguments);
Window.Current.Activate();
}
rootFrame.RequestedTheme = Settings.Theme switch
{
0 => ElementTheme.Light,
1 => ElementTheme.Dark,
_ => RequestedTheme == ApplicationTheme.Dark ? ElementTheme.Dark : ElementTheme.Light
};
if (rootFrame.RequestedTheme == ElementTheme.Dark)
rootFrame.Background = new AcrylicBrush
{
TintOpacity = .8,
TintColor = Colors.Black,
BackgroundSource = AcrylicBackgroundSource.HostBackdrop,
FallbackColor = Color.FromArgb(255, 31, 31, 31)
};
else
rootFrame.Background = new AcrylicBrush
{
TintOpacity = .5,
TintColor = Colors.White,
BackgroundSource = AcrylicBackgroundSource.HostBackdrop,
FallbackColor = Color.FromArgb(255, 230, 230, 230)
};
UpdateTitleBar(rootFrame.RequestedTheme == ElementTheme.Dark);
}
/// <summary>
/// Invoked when Navigation to a certain page fails
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
//TODO: Save application state and stop any background activity
deferral.Complete();
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 754 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 872 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1000 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

@@ -0,0 +1,17 @@
<ContentDialog
x:Class="WinTorrent.Dialogs.AddTorrentDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinTorrent.Dialogs"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="TITLE"
PrimaryButtonText="Button1"
SecondaryButtonText="Button2"
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
SecondaryButtonClick="ContentDialog_SecondaryButtonClick">
<Grid>
</Grid>
</ContentDialog>
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Content Dialog item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
namespace WinTorrent.Dialogs
{
public sealed partial class AddTorrentDialog : ContentDialog
{
public AddTorrentDialog()
{
this.InitializeComponent();
}
private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
}
private void ContentDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
}
}
}
+63
View File
@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
namespace WinTorrent.Models
{
public struct DataSize : IComparable<DataSize>, IEquatable<DataSize>, IComparer<DataSize>
{
public long ByteSize { get; set; }
public DataSize(long sizeInBytes) =>
ByteSize = sizeInBytes;
public override string ToString() =>
$"{ByteSize} B";
public int CompareTo(DataSize other) =>
(int)Math.Clamp(ByteSize - other.ByteSize, -1, 1);
public bool Equals(DataSize other) =>
ByteSize == other.ByteSize;
public int Compare(DataSize x, DataSize y) =>
(int)Math.Clamp(x.ByteSize - y.ByteSize, -1, 1);
public static double operator /(DataSize s1, DataSize s2) =>
s1.ByteSize / s2.ByteSize;
public static bool operator ==(DataSize s1, DataSize s2) =>
s1.ByteSize == s2.ByteSize;
public static bool operator !=(DataSize s1, DataSize s2) =>
s1.ByteSize != s2.ByteSize;
public static bool operator ==(DataSize s1, int s2) =>
s1.ByteSize == s2;
public static bool operator !=(DataSize s1, int s2) =>
s1.ByteSize != s2;
}
public struct DownloadSpeed : IComparable<DownloadSpeed>, IEquatable<DownloadSpeed>, IComparer<DownloadSpeed>
{
public long BytesPerSecond { get; set; }
public DownloadSpeed(long bps) =>
BytesPerSecond = bps;
public override string ToString() =>
$"{BytesPerSecond} B/s";
public int CompareTo(DownloadSpeed other) =>
(int)Math.Clamp(BytesPerSecond - other.BytesPerSecond, -1, 1);
public bool Equals(DownloadSpeed other) =>
BytesPerSecond == other.BytesPerSecond;
public int Compare(DownloadSpeed x, DownloadSpeed y) =>
(int)Math.Clamp(x.BytesPerSecond - y.BytesPerSecond, -1, 1);
public static double operator /(DownloadSpeed s1, DownloadSpeed s2) =>
s1.BytesPerSecond / s2.BytesPerSecond;
public static bool operator ==(DownloadSpeed s1, DownloadSpeed s2) =>
s1.BytesPerSecond == s2.BytesPerSecond;
public static bool operator !=(DownloadSpeed s1, DownloadSpeed s2) =>
s1.BytesPerSecond != s2.BytesPerSecond;
}
}
@@ -0,0 +1,38 @@
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using WinTorrent.Pages;
namespace WinTorrent.Models
{
class PointerHoverStateTrigger : StateTriggerBase
{
public TorrentItem TargetItem
{
get => _targetItem;
set
{
if (_targetItem == value)
return;
if (_targetElement != null)
{
_targetElement.PointerEntered -= PointerEntered;
_targetElement.PointerExited -= PointerExited;
}
_targetItem = value;
_targetElement = ((Window.Current.Content as Frame).Content as MainPage).list.ContainerFromItem(_targetItem) as FrameworkElement;
_targetElement.PointerEntered += PointerEntered;
_targetElement.PointerExited += PointerExited;
}
}
private TorrentItem _targetItem;
private FrameworkElement _targetElement;
private void PointerExited(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e) =>
SetActive(false);
private void PointerEntered(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e) =>
SetActive(true);
}
}
+133
View File
@@ -0,0 +1,133 @@
using System;
using System.ComponentModel;
using Windows.Storage;
using WinTorrent.Utils;
namespace WinTorrent.Models
{
public enum TorrentState
{
Initializing = 0,
Downloading = 1,
Cancelling = 2,
Pausing = 3,
Paused = 4,
Resuming = 5,
Completed = 6,
Seeding = 7,
Error = 8
}
public class TorrentItem : INotifyPropertyChanged
{
public event TorrentStateChangedEventHandler StateChanged;
public event PropertyChangedEventHandler PropertyChanged;
public string Title
{
get => _title;
set
{
if (_title == value)
return;
_title = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Title)));
}
}
private string _title;
public TorrentState State
{
get => _state;
set
{
if (_state == value)
return;
TorrentState previousState = _state;
_state = value;
StateChanged?.Invoke(this, previousState);
TorrentClient.OnItemStateChanged(this, previousState);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(State)));
}
}
private TorrentState _state = TorrentState.Initializing;
public DownloadSpeed TransmissionSpeed
{
get => _transmissionSpeed;
set
{
if (_transmissionSpeed == value)
return;
_transmissionSpeed = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(TransmissionSpeed)));
}
}
private DownloadSpeed _transmissionSpeed;
public DataSize Downloaded
{
get => _downloaded;
set
{
if (_downloaded == value)
return;
_downloaded = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Downloaded)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Progress)));
}
}
private DataSize _downloaded;
public DataSize TotalSize
{
get => _totalSize;
set
{
if (_totalSize == value)
return;
_totalSize = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(TotalSize)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Progress)));
}
}
private DataSize _totalSize;
public double Progress => TotalSize != 0 ? ((double)Downloaded.ByteSize / TotalSize.ByteSize) : 0;
public int SeedCount
{
get => _seedCount;
set
{
if (_seedCount == value)
return;
_seedCount = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SeedCount)));
}
}
private int _seedCount;
public TimeSpan RemainingTime
{
get => _remainingTime;
set
{
if (_remainingTime == value)
return;
_remainingTime = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SeedCount)));
}
}
private TimeSpan _remainingTime;
public IStorageItem Files { get; set; }
}
}
@@ -0,0 +1,46 @@
using Windows.UI.Xaml;
namespace WinTorrent.Models
{
public class TorrentStateDataTrigger : StateTriggerBase
{
public TorrentState TargetState
{
get => _targetState;
set
{
if (_targetState == value)
return;
_targetState = value;
UpdateTrigger();
}
}
private TorrentState _targetState;
public TorrentItem TargetElement
{
get => _targetElement;
set
{
if (_targetElement == value)
return;
if (_targetElement != null)
_targetElement.StateChanged -= TargetElementStateChanged;
_targetElement = value;
_targetElement.StateChanged += TargetElementStateChanged;
UpdateTrigger();
}
}
private TorrentItem _targetElement;
private void UpdateTrigger() =>
SetActive(TargetElement?.State == TargetState);
private void TargetElementStateChanged(TorrentItem sender, TorrentState previousState) =>
UpdateTrigger();
}
}
+55
View File
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
IgnorableNamespaces="uap mp">
<Identity
Name="ce54543c-294b-4541-b28d-ae993c9aab5f"
Publisher="CN=XFox"
Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="ce54543c-294b-4541-b28d-ae993c9aab5f" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>Wintor</DisplayName>
<PublisherDisplayName>XFox</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="WinTorrent.App">
<uap:VisualElements
DisplayName="WinTorrent"
Square150x150Logo="Assets\Square150x150Logo.png"
Square44x44Logo="Assets\Square44x44Logo.png"
Description="BitTorrent client for Windows 10"
BackgroundColor="deepSkyBlue">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" ShortName="WinTorrent" Square71x71Logo="Assets\SmallTile.png" Square310x310Logo="Assets\LargeTile.png">
<uap:ShowNameOnTiles>
<uap:ShowOn Tile="square150x150Logo"/>
<uap:ShowOn Tile="wide310x150Logo"/>
<uap:ShowOn Tile="square310x310Logo"/>
</uap:ShowNameOnTiles>
</uap:DefaultTile >
<uap:SplashScreen Image="Assets\SplashScreen.png" BackgroundColor="deepSkyBlue"/>
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
</Capabilities>
</Package>
+336
View File
@@ -0,0 +1,336 @@
<Page
NavigationCacheMode="Enabled"
x:Class="WinTorrent.Pages.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:models="using:WinTorrent.Models"
mc:Ignorable="d">
<Page.Resources>
<ThemeShadow x:Name="sharedShadow"/>
</Page.Resources>
<Grid>
<Grid.BackgroundTransition>
<BrushTransition/>
</Grid.BackgroundTransition>
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Background="Transparent" x:Name="TitleBar" Grid.ColumnSpan="2"/>
<Grid Grid.Row="1" Grid.ColumnSpan="2" x:Name="shadowRecieverGrid"/>
<Grid Grid.Row="1" Padding="30,70">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<NavigationViewList SelectionMode="Single" SelectionChanged="NavigationViewList_SelectionChanged" x:Name="navigationList">
<NavigationViewItem Icon="List" Content="All" Tag="all"/>
<NavigationViewItem Icon="Download" Content="Downloading" Tag="downloading"/>
<NavigationViewItem Icon="Upload" Content="Seeding" Tag="seeding"/>
<NavigationViewItem Content="Completed" Tag="completed">
<NavigationViewItem.Icon>
<FontIcon Glyph="&#xE001;"/>
</NavigationViewItem.Icon>
</NavigationViewItem>
<NavigationViewItem Icon="Pause" Content="Paused" Tag="paused"/>
</NavigationViewList>
<NavigationViewList Grid.Row="1" IsItemClickEnabled="True" SelectionMode="None">
<NavigationViewItem Icon="Add" Content="Add torrent" Tag="newTorrent" Foreground="{StaticResource SystemAccentColor}" Tapped="AddTorrent"/>
<NavigationViewItem Icon="Setting" Content="Settings" Tag="settings" Tapped="OpenSettings"/>
</NavigationViewList>
</Grid>
<ListView Grid.Row="1" x:Name="list" Grid.Column="1" SelectionMode="None" Padding="20" ItemClick="list_ItemClick" IsItemClickEnabled="True" x:FieldModifier="public">
<ListView.Header>
<AutoSuggestBox x:Name="search" UpdateTextOnSelect="False" SuggestionChosen="AutoSuggestBox_SuggestionChosen" QueryIcon="Find" Margin="0,50" PlaceholderText="Search for a torrent or insert magnet link" Height="38" TextChanged="AutoSuggestBox_TextChanged" Shadow="{StaticResource sharedShadow}"/>
</ListView.Header>
<ListView.ItemContainerTransitions>
<TransitionCollection>
<EntranceThemeTransition IsStaggeringEnabled="True"/>
<ContentThemeTransition VerticalOffset="30"/>
</TransitionCollection>
</ListView.ItemContainerTransitions>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Margin" Value="0,0,0,10"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="ContextFlyout">
<Setter.Value>
<MenuFlyout>
<MenuFlyoutItem Text="View details" Icon="View" Click="ViewItem"/>
<MenuFlyoutItem Text="Pause" Icon="Pause" Click="PauseItem"/>
<MenuFlyoutItem Text="Delete" Icon="Delete" Click="DeleteItem"/>
<MenuFlyoutSubItem Text="Priority">
<MenuFlyoutSubItem.Icon>
<FontIcon Glyph="&#xE728;"/>
</MenuFlyoutSubItem.Icon>
<ToggleMenuFlyoutItem Text="High" Tag="highPriority" Click="SetPriority"/>
<ToggleMenuFlyoutItem Text="Noraml" Tag="normalPriority" Click="SetPriority"/>
<ToggleMenuFlyoutItem Text="Low" Tag="lowPriority" Click="SetPriority"/>
</MenuFlyoutSubItem>
<MenuFlyoutSubItem Text="Seed torrent">
<MenuFlyoutSubItem.Icon>
<FontIcon Glyph="&#xE704;"/>
</MenuFlyoutSubItem.Icon>
<ToggleMenuFlyoutItem Text="On" Tag="seedOn" Click="SetSeeding"/>
<ToggleMenuFlyoutItem Text="Off" Tag="seedOff" Click="SetSeeding"/>
</MenuFlyoutSubItem>
</MenuFlyout>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:TorrentItem">
<UserControl>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="TorentStateGroup">
<VisualState x:Name="Initializing">
<VisualState.StateTriggers>
<models:TorrentStateDataTrigger TargetElement="{x:Bind}" TargetState="Initializing"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="StatusIcon.Symbol" Value="Clock"/>
<Setter Target="StatusLabel.Text" Value="Initializing"/>
<Setter Target="SpeedLabel.Visibility" Value="Collapsed"/>
<Setter Target="ProgressLabel.Visibility" Value="Collapsed"/>
<Setter Target="EtaLabel.Visibility" Value="Collapsed"/>
<Setter Target="PauseButton.Visibility" Value="Collapsed"/>
<Setter Target="StatusIcon.Foreground" Value="Orange"/>
<Setter Target="StatusLabel.Foreground" Value="Orange"/>
<Setter Target="ProgressBar.Foreground" Value="Orange"/>
<Setter Target="ProgressBar.IsIndeterminate" Value="True"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Downloading"/>
<VisualState x:Name="Cancelling">
<VisualState.StateTriggers>
<models:TorrentStateDataTrigger TargetElement="{x:Bind}" TargetState="Cancelling"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="StatusIcon.Symbol" Value="Clear"/>
<Setter Target="StatusLabel.Text" Value="Cancelling"/>
<Setter Target="SpeedLabel.Visibility" Value="Collapsed"/>
<Setter Target="ProgressLabel.Visibility" Value="Collapsed"/>
<Setter Target="EtaLabel.Visibility" Value="Collapsed"/>
<Setter Target="PauseButton.Visibility" Value="Collapsed"/>
<Setter Target="StatusIcon.Foreground" Value="Orange"/>
<Setter Target="StatusLabel.Foreground" Value="Orange"/>
<Setter Target="ProgressBar.Foreground" Value="Orange"/>
<Setter Target="ProgressBar.IsIndeterminate" Value="True"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pausing">
<VisualState.StateTriggers>
<models:TorrentStateDataTrigger TargetElement="{x:Bind}" TargetState="Pausing"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="StatusIcon.Symbol" Value="Pause"/>
<Setter Target="StatusLabel.Text" Value="Pausing"/>
<Setter Target="PauseButton.Visibility" Value="Collapsed"/>
<Setter Target="StatusIcon.Foreground" Value="Gray"/>
<Setter Target="StatusLabel.Foreground" Value="Gray"/>
<Setter Target="ProgressBar.Foreground" Value="Gray"/>
<Setter Target="ProgressBar.IsIndeterminate" Value="True"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Paused">
<VisualState.StateTriggers>
<models:TorrentStateDataTrigger TargetElement="{x:Bind}" TargetState="Paused"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="StatusIcon.Symbol" Value="Pause"/>
<Setter Target="PauseButtonIcon.Symbol" Value="Play"/>
<Setter Target="StatusLabel.Text" Value="Paused"/>
<Setter Target="SpeedLabel.Visibility" Value="Collapsed"/>
<Setter Target="ProgressLabel.Visibility" Value="Collapsed"/>
<Setter Target="EtaLabel.Visibility" Value="Collapsed"/>
<Setter Target="StatusIcon.Foreground" Value="Gray"/>
<Setter Target="StatusLabel.Foreground" Value="Gray"/>
<Setter Target="ProgressBar.Foreground" Value="Gray"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Resuming">
<VisualState.StateTriggers>
<models:TorrentStateDataTrigger TargetElement="{x:Bind}" TargetState="Resuming"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="StatusIcon.Symbol" Value="Clock"/>
<Setter Target="StatusLabel.Text" Value="Resuming"/>
<Setter Target="SpeedLabel.Visibility" Value="Collapsed"/>
<Setter Target="ProgressLabel.Visibility" Value="Collapsed"/>
<Setter Target="EtaLabel.Visibility" Value="Collapsed"/>
<Setter Target="PauseButton.Visibility" Value="Collapsed"/>
<Setter Target="ProgressBar.IsIndeterminate" Value="True"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Completed">
<VisualState.StateTriggers>
<models:TorrentStateDataTrigger TargetElement="{x:Bind}" TargetState="Completed"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="StatusIcon.Symbol" Value="Accept"/>
<Setter Target="PauseButtonIcon.Symbol" Value="Globe"/>
<Setter Target="PauseButton.(ToolTipService.ToolTip)" Value="Seed torrent"/>
<Setter Target="StatusLabel.Text" Value="Completed"/>
<Setter Target="SpeedLabel.Visibility" Value="Collapsed"/>
<Setter Target="ProgressLabel.Visibility" Value="Collapsed"/>
<Setter Target="EtaLabel.Visibility" Value="Collapsed"/>
<Setter Target="StatusIcon.Foreground" Value="#5b5"/>
<Setter Target="StatusLabel.Foreground" Value="#5b5"/>
<Setter Target="ProgressBar.Foreground" Value="#5b5"/>
<Setter Target="ProgressBar.Value" Value="100"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Seeding">
<VisualState.StateTriggers>
<models:TorrentStateDataTrigger TargetElement="{x:Bind}" TargetState="Seeding"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="StatusIcon.Symbol" Value="Upload"/>
<Setter Target="StatusLabel.Text" Value="Seeding"/>
<Setter Target="ProgressLabel.Visibility" Value="Collapsed"/>
<Setter Target="EtaLabel.Visibility" Value="Collapsed"/>
<Setter Target="PauseButton.Visibility" Value="Collapsed"/>
<Setter Target="StatusIcon.Foreground" Value="#5b5"/>
<Setter Target="StatusLabel.Foreground" Value="#5b5"/>
<Setter Target="ProgressBar.Foreground" Value="#5b5"/>
<Setter Target="ProgressBar.Value" Value="1"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Error">
<VisualState.StateTriggers>
<models:TorrentStateDataTrigger TargetElement="{x:Bind}" TargetState="Error"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="StatusIcon.Symbol" Value="Clear"/>
<Setter Target="PauseButtonIcon.Symbol" Value="RepeatAll"/>
<Setter Target="PauseButton.(ToolTipService.ToolTip)" Value="Retry"/>
<Setter Target="StatusLabel.Text" Value="Error"/>
<Setter Target="SpeedLabel.Visibility" Value="Collapsed"/>
<Setter Target="ProgressLabel.Visibility" Value="Collapsed"/>
<Setter Target="EtaLabel.Visibility" Value="Collapsed"/>
<Setter Target="PauseButton.Visibility" Value="Visible"/>
<Setter Target="StatusIcon.Foreground" Value="Red"/>
<Setter Target="StatusLabel.Foreground" Value="Red"/>
<Setter Target="ProgressBar.Foreground" Value="Red"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Storyboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="PauseButton" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2" To="0" EnableDependentAnimation="True"/>
</Storyboard>
</VisualState.Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<VisualState.StateTriggers>
<models:PointerHoverStateTrigger TargetItem="{x:Bind}"/>
</VisualState.StateTriggers>
<VisualState.Storyboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="PauseButton" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2" To="1" EnableDependentAnimation="True"/>
</Storyboard>
</VisualState.Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="3"/>
</Grid.RowDefinitions>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" x:Name="caTarget" Grid.RowSpan="2"/>
<Grid RowSpacing="10" ColumnSpacing="10" Margin="30">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.ColumnSpan="4" Text="{Binding Title}" MaxLines="1" TextTrimming="CharacterEllipsis"/>
<SymbolIcon x:Name="StatusIcon" Grid.Row="1" Grid.Column="0" Symbol="Download" Foreground="{StaticResource SystemAccentColor}" />
<TextBlock x:Name="StatusLabel" Grid.Row="1" Grid.Column="1" Text="Downloading" Foreground="{StaticResource SystemAccentColor}"/>
<TextBlock x:Name="SpeedLabel" Grid.Row="1" Grid.Column="2" Text="{Binding TransmissionSpeed}" Foreground="Gray"/>
<TextBlock x:Name="ProgressLabel" Grid.Row="1" Grid.Column="3" Foreground="Gray">
<Run Text="{Binding Downloaded}"/> of <Run Text="{Binding TotalSize}"/>
</TextBlock>
<TextBlock x:Name="EtaLabel" Grid.Row="1" Grid.Column="4" Foreground="Gray">
<Run Text="{Binding RemainingTime}"/> remaining
</TextBlock>
<Button x:Name="PauseButton" Grid.Column="5" Grid.RowSpan="2" Background="Transparent" Height="50" Width="50" Opacity="0" Tag="{Binding}" Click="PauseItem">
<SymbolIcon x:Name="PauseButtonIcon" Symbol="Pause"/>
</Button>
</Grid>
<ProgressBar x:Name="ProgressBar" Grid.Row="2" Grid.ColumnSpan="4" Height="3" Value="{Binding Progress}" Background="Transparent" Maximum="1" Minimum="0"/>
</Grid>
</UserControl>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Page>
+119
View File
@@ -0,0 +1,119 @@
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Navigation;
using WinTorrent.Dialogs;
using WinTorrent.Models;
using WinTorrent.Utils;
namespace WinTorrent.Pages
{
public sealed partial class MainPage : Page
{
public MainPage()
{
InitializeComponent();
sharedShadow.Receivers.Add(shadowRecieverGrid);
search.Translation += new System.Numerics.Vector3(0, 0, 10);
navigationList.SelectedIndex = 0;
TorrentClient.TorrentItemStateChanged += (s, e) => NavigationViewList_SelectionChanged(this, null);
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
Window.Current.SetTitleBar(TitleBar);
}
private void OpenSettings(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e) =>
Frame.Navigate(typeof(SettingsPage), null, new SlideNavigationTransitionInfo { Effect = SlideNavigationTransitionEffect.FromLeft });
private async void AddTorrent(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e) =>
await new AddTorrentDialog().ShowAsync();
private void NavigationViewList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
list.ItemsSource = (navigationList.SelectedItem as NavigationViewItem)?.Tag as string switch
{
"downloading" => TorrentClient.Torrents.FindAll(i => i.State.BelongsTo(TorrentState.Downloading, TorrentState.Cancelling, TorrentState.Error, TorrentState.Initializing, TorrentState.Pausing)),
"seeding" => TorrentClient.Torrents.FindAll(i => i.State.BelongsTo(TorrentState.Seeding)),
"completed" => TorrentClient.Torrents.FindAll(i => i.State.BelongsTo(TorrentState.Completed, TorrentState.Seeding)),
"paused" => TorrentClient.Torrents.FindAll(i => i.State.BelongsTo(TorrentState.Paused, TorrentState.Resuming)),
_ => TorrentClient.Torrents
};
search.ItemsSource = null;
}
private void AutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{
if (args.Reason != AutoSuggestionBoxTextChangeReason.UserInput)
return;
sender.ItemsSource = null;
navigationList.SelectedIndex = 0;
var result = TorrentClient.Torrents.FindAll(i =>
i.Title.ToLowerInvariant().Contains(sender.Text.ToLowerInvariant()) ||
(i.Files?.Path.ToLowerInvariant().Contains(sender.Text.ToLowerInvariant()) ?? false) ||
i.State.ToString().ToLowerInvariant().Contains(sender.Text.ToLowerInvariant()));
list.ItemsSource = result;
if (result.Count < 1)
{
if (sender.Text.ToUri() is Uri magnetUrl && magnetUrl.IsAbsoluteUri)
{
sender.ItemsSource = new[] { $"Add torrent from URL: {magnetUrl.AbsoluteUri}" };
}
else
{
sender.ItemsSource = new[] { "No results found" };
}
}
}
private void AutoSuggestBox_SuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
{
if (args.SelectedItem as string == "No results found")
return;
// TODO: Add torrent from URL
}
private void PauseItem(object sender, RoutedEventArgs e)
{
}
private void list_ItemClick(object sender, ItemClickEventArgs e) =>
OpenItem(e.ClickedItem as TorrentItem);
private void ViewItem(object sender, RoutedEventArgs e) =>
OpenItem(list.ItemFromContainer(((sender as FrameworkElement).Parent as FrameworkElement).Parent) as TorrentItem);
private void OpenItem(TorrentItem item)
{
if (list.ContainerFromItem(item) as ListViewItem != null)
list.PrepareConnectedAnimation("ca1", item, "caTarget");
Frame.Navigate(typeof(TorrentDetailsPage), item);
}
private void SetSeeding(object sender, RoutedEventArgs e)
{
}
private void SetPriority(object sender, RoutedEventArgs e)
{
}
private void DeleteItem(object sender, RoutedEventArgs e)
{
}
}
}
+158
View File
@@ -0,0 +1,158 @@
<Page
x:Class="WinTorrent.Pages.SettingsPage"
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"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.Resources>
<Style TargetType="NavigationViewItemSeparator">
<Setter Property="Margin" Value="-16,20"/>
</Style>
<Style x:Key="Header" TargetType="TextBlock" BasedOn="{StaticResource TitleTextBlockStyle}">
<Setter Property="FontWeight" Value="SemiBold"/>
</Style>
<Style TargetType="ToggleSwitch">
<Setter Property="IsOn" Value="True"/>
</Style>
</Page.Resources>
<Grid>
<Grid.BackgroundTransition>
<BrushTransition />
</Grid.BackgroundTransition>
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Background="Transparent" Click="BackRequested" Height="32" CornerRadius="0">
<FontIcon Glyph="&#xE0A6;" FontSize="14"/>
</Button>
<Border Grid.Column="1" x:Name="TitleBar" Background="Transparent">
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="Settings" VerticalAlignment="Center" Margin="10,0"/>
</Border>
<ScrollViewer Grid.Row="1" Grid.ColumnSpan="2">
<StackPanel Margin="50">
<TextBlock Text="General" Style="{StaticResource Header}"/>
<Grid RowSpacing="10" ColumnSpacing="50">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text="Launch app on Windows startup" VerticalAlignment="Center"/>
<ToggleSwitch Grid.Row="0" Grid.Column="1"/>
<TextBlock Grid.Row="1" Text="Run on power saving mode" VerticalAlignment="Center"/>
<ToggleSwitch Grid.Row="1" Grid.Column="1" IsOn="False"/>
</Grid>
<NavigationViewItemSeparator/>
<TextBlock Text="Downloading" Style="{StaticResource Header}"/>
<Grid RowSpacing="10" ColumnSpacing="50">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text="Automatically seed completed torrents" VerticalAlignment="Center"/>
<ToggleSwitch Grid.Row="0" Grid.Column="1"/>
<TextBox Grid.Row="1" Header="Default folder" PlaceholderText="Downloads" IsReadOnly="True"/>
<Button Grid.Row="1" Grid.Column="1" Content="Change" VerticalAlignment="Bottom"/>
</Grid>
<NavigationViewItemSeparator/>
<TextBlock Text="Speed" Style="{StaticResource Header}"/>
<Grid RowSpacing="10" ColumnSpacing="50">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="150"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text="Download (MB/s)" VerticalAlignment="Center"/>
<TextBlock Grid.Row="1" Text="Uplaod (MB/s)" VerticalAlignment="Center"/>
<TextBlock Grid.Row="2" Text="Default priority" VerticalAlignment="Center"/>
<TextBox Grid.Row="0" Grid.Column="1" PlaceholderText="Unlimited"/>
<TextBox Grid.Row="1" Grid.Column="1" PlaceholderText="Unlimited"/>
<ComboBox Grid.Row="2" Grid.Column="1" SelectedIndex="1" HorizontalAlignment="Stretch">
<ComboBoxItem Content="High"/>
<ComboBoxItem Content="Normal"/>
<ComboBoxItem Content="Low"/>
</ComboBox>
</Grid>
<NavigationViewItemSeparator/>
<TextBlock Text="Theme" Style="{StaticResource Header}"/>
<StackPanel>
<RadioButton Content="Light" Name="light" Tag="0" GroupName="theme" Checked="ThemeChanged"/>
<RadioButton Content="Dark" Name="dark" Tag="1" GroupName="theme" Checked="ThemeChanged"/>
<RadioButton Content="Windows default" Name="system" Tag="2" GroupName="theme" Checked="ThemeChanged"/>
<HyperlinkButton Content="Windows color settings" NavigateUri="ms-settings:colors"/>
</StackPanel>
<NavigationViewItemSeparator/>
<TextBlock Text="About" Style="{StaticResource Header}"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="150"/>
</Grid.ColumnDefinitions>
<StackPanel>
<TextBlock Text="WinTorrent" Style="{StaticResource SubtitleTextBlockStyle}"/>
<TextBlock Text="v20.10301.1" Style="{StaticResource CaptionTextBlockStyle}" Foreground="Gray" FontStyle="Italic"/>
<TextBlock>It's an open source software! Check out the code on <Hyperlink NavigateUri="https://github.com/xfox111/WinTorrent">GitHub</Hyperlink></TextBlock>
<StackPanel Margin="0,10">
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}">Idea and design by @proxedised</TextBlock>
<TextBlock>
Reddit: <Hyperlink NavigateUri="https://www.reddit.com/user/proxedised">@proxedised</Hyperlink>
</TextBlock>
</StackPanel>
<StackPanel Margin="0,10">
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}">Developed by Michael "XFox" Gordeev</TextBlock>
<TextBlock>
Twitter: <Hyperlink NavigateUri="https://twitter.com/xfox111">@xfox111</Hyperlink>
<LineBreak/>LinkedIn: <Hyperlink NavigateUri="https://linkedin.com/in/xfox">@xfox</Hyperlink>
<LineBreak/>Website: <Hyperlink NavigateUri="https://xfox111.net">https://xfox111.net/</Hyperlink>
</TextBlock>
</StackPanel>
<Button Content="Leave feedback" Name="feedback"/>
</StackPanel>
<Image Source="/Assets/Square150x150Logo.scale-200.png" Grid.Column="1" VerticalAlignment="Top"/>
</Grid>
</StackPanel>
</ScrollViewer>
</Grid>
</Page>
@@ -0,0 +1,71 @@
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
using WinTorrent.Utils;
namespace WinTorrent.Pages
{
public sealed partial class SettingsPage : Page
{
public SettingsPage()
{
InitializeComponent();
Window.Current.SetTitleBar(TitleBar);
feedback.Visibility = Feedback.HasFeedbackHub ? Visibility.Visible : Visibility.Collapsed;
switch (Settings.Theme)
{
case 0:
light.IsChecked = true;
break;
case 1:
dark.IsChecked = true;
break;
case 2:
system.IsChecked = true;
break;
}
// TODO: Add settings management
}
private void BackRequested(object sender, RoutedEventArgs e) =>
Frame.Navigate(typeof(MainPage), null, new DrillInNavigationTransitionInfo());
private void ThemeChanged(object sender, RoutedEventArgs e)
{
if (Settings.Theme.ToString() == (string)(sender as RadioButton).Tag)
return;
Settings.Theme = int.Parse((sender as RadioButton).Tag as string);
Frame.RequestedTheme = (sender as RadioButton).Name switch
{
"light" => ElementTheme.Light,
"dark" => ElementTheme.Dark,
_ => Application.Current.RequestedTheme == ApplicationTheme.Dark ? ElementTheme.Dark : ElementTheme.Light
};
if (Frame.RequestedTheme == ElementTheme.Dark)
Frame.Background = new AcrylicBrush
{
TintOpacity = .8,
TintColor = Colors.Black,
BackgroundSource = AcrylicBackgroundSource.HostBackdrop,
FallbackColor = Color.FromArgb(255, 31, 31, 31)
};
else
Frame.Background = new AcrylicBrush
{
TintOpacity = .5,
TintColor = Colors.White,
BackgroundSource = AcrylicBackgroundSource.HostBackdrop,
FallbackColor = Color.FromArgb(255, 230, 230, 230)
};
App.UpdateTitleBar(Frame.RequestedTheme == ElementTheme.Dark);
}
}
}
@@ -0,0 +1,38 @@
<Page
x:Class="WinTorrent.Pages.TorrentDetailsPage"
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">
<Grid>
<Grid.BackgroundTransition>
<BrushTransition/>
</Grid.BackgroundTransition>
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid x:Name="caTarget" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Grid.RowSpan="2" Grid.ColumnSpan="2"/>
<Button Background="Transparent" Click="BackRequested" Height="32" CornerRadius="0">
<FontIcon Glyph="&#xE0A6;" FontSize="14"/>
</Button>
<Border Grid.Column="1" x:Name="TitleBar" Background="Transparent">
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="Torrent download overview" VerticalAlignment="Center" Margin="10,0"/>
</Border>
<ScrollViewer Grid.Row="1" Grid.ColumnSpan="2">
<StackPanel Margin="50">
<TextBlock Text="Torrent download overview" Style="{StaticResource TitleTextBlockStyle}" FontWeight="SemiBold" Opacity="1"/>
</StackPanel>
</ScrollViewer>
</Grid>
</Page>
@@ -0,0 +1,32 @@
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Navigation;
using WinTorrent.Models;
namespace WinTorrent.Pages
{
public sealed partial class TorrentDetailsPage : Page
{
public TorrentItem Item { get; private set; }
public TorrentDetailsPage()
{
InitializeComponent();
Window.Current.SetTitleBar(TitleBar);
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
Item = e.Parameter as TorrentItem;
if (ConnectedAnimationService.GetForCurrentView().GetAnimation("ca1") is ConnectedAnimation animation)
animation.TryStart(caTarget);
}
private void BackRequested(object sender, RoutedEventArgs e) =>
Frame.Navigate(typeof(MainPage), null, new DrillInNavigationTransitionInfo());
}
}
@@ -0,0 +1,29 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Wintor")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Wintor")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]
@@ -0,0 +1,31 @@
<!--
This file contains Runtime Directives used by .NET Native. The defaults here are suitable for most
developers. However, you can modify these parameters to modify the behavior of the .NET Native
optimizer.
Runtime Directives are documented at https://go.microsoft.com/fwlink/?LinkID=391919
To fully enable reflection for App1.MyClass and all of its public/private members
<Type Name="App1.MyClass" Dynamic="Required All"/>
To enable dynamic creation of the specific instantiation of AppClass<T> over System.Int32
<TypeInstantiation Name="App1.AppClass" Arguments="System.Int32" Activate="Required Public" />
Using the Namespace directive to apply reflection policy to all the types in a particular namespace
<Namespace Name="DataClasses.ViewModels" Serialize="All" />
-->
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<!--
An Assembly element with Name="*Application*" applies to all assemblies in
the application package. The asterisks are not wildcards.
-->
<Assembly Name="*Application*" Dynamic="Required All" />
<!-- Add your application specific runtime directives here. -->
</Application>
</Directives>
@@ -0,0 +1,258 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="AutoSuggestBoxTextBoxStyle" TargetType="TextBox">
<Setter Property="MinWidth" Value="{ThemeResource TextControlThemeMinWidth}"/>
<Setter Property="MinHeight" Value="{ThemeResource TextControlThemeMinHeight}"/>
<Setter Property="Foreground" Value="{ThemeResource TextControlForeground}"/>
<Setter Property="Background" Value="{ThemeResource TextControlBackground}"/>
<Setter Property="BorderBrush" Value="{ThemeResource TextControlBorderBrush}"/>
<Setter Property="SelectionHighlightColor" Value="{ThemeResource TextControlSelectionHighlightColor}"/>
<Setter Property="BorderThickness" Value="{ThemeResource TextControlBorderThemeThickness}"/>
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden"/>
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False"/>
<Setter Property="Padding" Value="{ThemeResource TextControlThemePadding}"/>
<Setter Property="IsSpellCheckEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Grid>
<Grid.Resources>
<Style x:Name="DeleteButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="ButtonLayoutGrid" Background="{ThemeResource TextControlButtonBackground}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{ThemeResource TextControlButtonBorderBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonLayoutGrid" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBackgroundPointerOver}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonLayoutGrid" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBorderBrushPointerOver}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="GlyphElement" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonForegroundPointerOver}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonLayoutGrid" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBackgroundPressed}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonLayoutGrid" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBorderBrushPressed}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="GlyphElement" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonForegroundPressed}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" Storyboard.TargetName="ButtonLayoutGrid" Storyboard.TargetProperty="Opacity" To="0"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<TextBlock x:Name="GlyphElement" AutomationProperties.AccessibilityView="Raw" FontStyle="Normal" FontFamily="{ThemeResource SymbolThemeFontFamily}" Foreground="{ThemeResource TextControlButtonForeground}" FontSize="{ThemeResource AutoSuggestBoxIconFontSize}" HorizontalAlignment="Center" Text="&#xE10A;" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Name="QueryButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" BackgroundSizing="{TemplateBinding BackgroundSizing}" Background="{ThemeResource TextControlButtonBackground}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{ThemeResource TextControlButtonBorderBrush}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" FontSize="{ThemeResource AutoSuggestBoxIconFontSize}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBackgroundPointerOver}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBorderBrushPointerOver}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonForegroundPointerOver}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBackgroundPressed}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBorderBrushPressed}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonForegroundPressed}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Opacity" To="0"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</ContentPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HeaderContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlHeaderForegroundDisabled}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundDisabled}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushDisabled}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundDisabled}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlPlaceholderForegroundDisabled}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushPointerOver}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemChromeAltHighColor}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlPlaceholderForegroundPointerOver}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundPointerOver}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlPlaceholderForegroundFocused}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundFocused}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushFocused}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundFocused}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="RequestedTheme">
<DiscreteObjectKeyFrame KeyTime="0" Value="Light"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="QueryButton" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonForeground}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HighlightStrip" Storyboard.TargetProperty="Value">
<DiscreteObjectKeyFrame KeyTime="0" Value="100"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ButtonStates">
<VisualState x:Name="ButtonVisible">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="DeleteButton" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="ButtonCollapsed"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="BorderElement" Background="{ThemeResource SystemChromeLowColor}" BorderThickness="0" Grid.ColumnSpan="3" Grid.RowSpan="1" Grid.Row="1" CornerRadius="1"/>
<ContentPresenter x:Name="HeaderContentPresenter" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.ColumnSpan="3" FontWeight="Normal" Foreground="{ThemeResource TextControlHeaderForeground}" Margin="{ThemeResource AutoSuggestBoxTopHeaderMargin}" Grid.Row="0" TextWrapping="Wrap" Visibility="Collapsed" x:DeferLoadStrategy="Lazy"/>
<ScrollViewer Grid.Column="1" x:Name="ContentElement" AutomationProperties.AccessibilityView="Raw" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsTabStop="False" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" Margin="{TemplateBinding BorderThickness}" Padding="7" Grid.Row="1" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" ZoomMode="Disabled"/>
<ContentControl Grid.Column="1" x:Name="PlaceholderTextContentPresenter" Content="{TemplateBinding PlaceholderText}" Grid.ColumnSpan="2" Foreground="{ThemeResource TextControlPlaceholderForeground}" IsTabStop="False" IsHitTestVisible="False" Margin="{TemplateBinding BorderThickness}" Padding="7" Grid.Row="1"/>
<Button x:Name="DeleteButton" AutomationProperties.AccessibilityView="Raw" BorderThickness="{TemplateBinding BorderThickness}" Grid.Column="2" FontSize="{TemplateBinding FontSize}" IsTabStop="False" MinWidth="34" Grid.Row="1" Style="{StaticResource QueryButtonStyle}" VerticalAlignment="Stretch" Visibility="Collapsed" Width="38" Height="38" Content="&#xE106;" FontFamily="Segoe MDL2 Assets"/>
<Button x:Name="QueryButton" AutomationProperties.AccessibilityView="Raw" BorderThickness="{TemplateBinding BorderThickness}" Grid.Column="0" FontSize="{TemplateBinding FontSize}" IsTabStop="False" MinWidth="34" Grid.Row="1" Style="{StaticResource QueryButtonStyle}" VerticalAlignment="Stretch" Width="38" Height="38" Foreground="{ThemeResource TextControlPlaceholderForeground}"/>
<ContentPresenter x:Name="DescriptionPresenter" AutomationProperties.AccessibilityView="Raw" Content="{TemplateBinding Description}" Grid.ColumnSpan="3" Foreground="{ThemeResource SystemControlDescriptionTextForegroundBrush}" Grid.Row="2" x:Load="False"/>
<Grid VerticalAlignment="Bottom" Height="2" Grid.RowSpan="3" Grid.ColumnSpan="3">
<ProgressBar x:Name="HighlightStrip" Value="0" Background="Transparent"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="AutoSuggestBox">
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="TextBoxStyle" Value="{StaticResource AutoSuggestBoxTextBoxStyle}"/>
<Setter Property="UseSystemFocusVisuals" Value="{ThemeResource IsApplicationFocusVisualKindReveal}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="AutoSuggestBox">
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Orientation">
<VisualState x:Name="Landscape"/>
<VisualState x:Name="Portrait"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<TextBox x:Name="TextBox" ScrollViewer.BringIntoViewOnFocusChange="False" Description="{TemplateBinding Description}" DesiredCandidateWindowAlignment="BottomEdge" Header="{TemplateBinding Header}" Margin="0" PlaceholderText="{TemplateBinding PlaceholderText}" Style="{TemplateBinding TextBoxStyle}" UseSystemFocusVisuals="{TemplateBinding UseSystemFocusVisuals}" Width="{TemplateBinding Width}" Canvas.ZIndex="0"/>
<Popup x:Name="SuggestionsPopup">
<Border x:Name="SuggestionsContainer">
<ListView x:Name="SuggestionsList" Background="{ThemeResource AutoSuggestBoxSuggestionsListBackground}" BorderThickness="{ThemeResource AutoSuggestListBorderThemeThickness}" BorderBrush="{ThemeResource AutoSuggestBoxSuggestionsListBorderBrush}" DisplayMemberPath="{TemplateBinding DisplayMemberPath}" ItemContainerStyle="{TemplateBinding ItemContainerStyle}" ItemTemplate="{TemplateBinding ItemTemplate}" IsItemClickEnabled="True" ItemTemplateSelector="{TemplateBinding ItemTemplateSelector}" MaxHeight="{ThemeResource AutoSuggestListMaxHeight}" Margin="{ThemeResource AutoSuggestListMargin}" Padding="{ThemeResource AutoSuggestListPadding}"/>
</Border>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
@@ -0,0 +1,76 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinTorrent">
<Style TargetType="ListViewItem">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
<Setter Property="Background" Value="{ThemeResource ListViewItemBackground}"/>
<Setter Property="Foreground" Value="{ThemeResource ListViewItemForeground}"/>
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="IsHoldingEnabled" Value="True"/>
<Setter Property="Padding" Value="12,0,12,0"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}"/>
<Setter Property="MinHeight" Value="{ThemeResource ListViewItemMinHeight}"/>
<Setter Property="AllowDrop" Value="False"/>
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}"/>
<Setter Property="FocusVisualMargin" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ListViewItemPresenter x:Name="Root" CheckBrush="{ThemeResource ListViewItemCheckBrush}" ContentMargin="{TemplateBinding Padding}" CheckBoxBrush="{ThemeResource ListViewItemCheckBoxBrush}" ContentTransitions="{TemplateBinding ContentTransitions}" CheckMode="{ThemeResource ListViewItemCheckMode}" DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}" DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}" DragBackground="{ThemeResource ListViewItemDragBackground}" DragForeground="{ThemeResource ListViewItemDragForeground}" FocusBorderBrush="{ThemeResource ListViewItemFocusBorderBrush}" FocusVisualMargin="{TemplateBinding FocusVisualMargin}" FocusSecondaryBorderBrush="{ThemeResource ListViewItemFocusSecondaryBorderBrush}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Control.IsTemplateFocusTarget="True" PressedBackground="{ThemeResource ListViewItemBackgroundPressed}" PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackground}" PointerOverForeground="{ThemeResource ListViewItemForegroundPointerOver}" PointerOverBackground="{ThemeResource ListViewItemBackgroundPointerOver}" RevealBorderThickness="{ThemeResource ListViewItemRevealBorderThemeThickness}" ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" RevealBorderBrush="{ThemeResource ListViewItemRevealBorderBrush}" RevealBackground="{ThemeResource ListViewItemRevealBackground}" SelectedForeground="{ThemeResource ListViewItemForegroundSelected}" SelectionCheckMarkVisualEnabled="{ThemeResource ListViewItemSelectionCheckMarkVisualEnabled}" SelectedBackground="{ThemeResource ListViewItemBackgroundSelected}" SelectedPressedBackground="{ThemeResource ListViewItemBackgroundSelectedPressed}" SelectedPointerOverBackground="{ThemeResource ListViewItemBackgroundSelectedPointerOver}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Selected"/>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="PointerOver"/>
<Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPointerOver}"/>
<Setter Target="Root.Background" Value="Red"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOverSelected">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="PointerOver"/>
<Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPointerOver}"/>
<Setter Target="Root.Background" Value="Red"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOverPressed">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="Pressed"/>
<Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPressed}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="Pressed"/>
<Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPressed}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PressedSelected">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="Pressed"/>
<Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPressed}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DisabledStates">
<VisualState x:Name="Enabled"/>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="Root.RevealBorderThickness" Value="0"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</ListViewItemPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
@@ -0,0 +1,493 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinTorrent">
<Style x:Key="NavigationViewItemPresenterStyleWhenOnLeftPane" TargetType="NavigationViewItemPresenter">
<Setter Property="Foreground" Value="{ThemeResource NavigationViewItemForeground}"/>
<Setter Property="Background" Value="{ThemeResource NavigationViewItemBackground}"/>
<Setter Property="BorderBrush" Value="{ThemeResource NavigationViewItemBorderBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource NavigationViewItemBorderThickness}"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="NavigationViewItemPresenter">
<Grid x:Name="LayoutRoot" Background="{TemplateBinding Background}" Height="40" Control.IsTemplateFocusTarget="True">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PointerStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Target="SelectionIndicator.Opacity" Value="0"/>
<Setter Target="SelectionIndicator.Height" Value="0"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="LayoutRoot.(RevealBrush.State)" Value="PointerOver"/>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource NavigationViewItemBackgroundPointerOver}"/>
<Setter Target="RevealBorder.BorderBrush" Value="{ThemeResource NavigationViewItemBorderBrushPointerOver}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource NavigationViewItemForegroundPointerOver}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource NavigationViewItemForegroundPointerOver}"/>
<Setter Target="SelectionIndicator.Opacity" Value="0"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="LayoutRoot.(RevealBrush.State)" Value="Pressed"/>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource NavigationViewItemBackgroundPressed}"/>
<Setter Target="RevealBorder.BorderBrush" Value="{ThemeResource NavigationViewItemBorderBrushPressed}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource NavigationViewItemForegroundPressed}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource NavigationViewItemForegroundPressed}"/>
<Setter Target="SelectionIndicator.Opacity" Value="0"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource NavigationViewItemBackgroundSelected}"/>
<Setter Target="RevealBorder.BorderBrush" Value="{ThemeResource NavigationViewItemBorderBrushSelected}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource NavigationViewItemForegroundSelected}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource NavigationViewItemForegroundSelected}"/>
<Setter Target="ContentPresenter.FontWeight" Value="SemiBold"/>
<Setter Target="SelectionIndicator.Opacity" Value="1"/>
</VisualState.Setters>
<VisualState.Storyboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="SelectionIndicator" Storyboard.TargetProperty="Height" To="24" EnableDependentAnimation="True" Duration="0:0:0.1">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</VisualState.Storyboard>
</VisualState>
<VisualState x:Name="PointerOverSelected">
<VisualState.Setters>
<Setter Target="LayoutRoot.(RevealBrush.State)" Value="PointerOver"/>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource NavigationViewItemBackgroundSelectedPointerOver}"/>
<Setter Target="RevealBorder.BorderBrush" Value="{ThemeResource NavigationViewItemBorderBrushSelectedPointerOver}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource NavigationViewItemForegroundSelectedPointerOver}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource NavigationViewItemForegroundSelectedPointerOver}"/>
<Setter Target="ContentPresenter.FontWeight" Value="SemiBold"/>
<Setter Target="SelectionIndicator.Opacity" Value="1"/>
</VisualState.Setters>
<VisualState.Storyboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="SelectionIndicator" Storyboard.TargetProperty="Height" To="28" EnableDependentAnimation="True" Duration="0:0:0.1">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</VisualState.Storyboard>
</VisualState>
<VisualState x:Name="PressedSelected">
<VisualState.Setters>
<Setter Target="LayoutRoot.(RevealBrush.State)" Value="Pressed"/>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource NavigationViewItemBackgroundSelectedPressed}"/>
<Setter Target="RevealBorder.BorderBrush" Value="{ThemeResource NavigationViewItemBorderBrushSelectedPressed}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource NavigationViewItemForegroundSelectedPressed}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource NavigationViewItemForegroundSelectedPressed}"/>
<Setter Target="ContentPresenter.FontWeight" Value="SemiBold"/>
<Setter Target="SelectionIndicator.Opacity" Value="1"/>
</VisualState.Setters>
<VisualState.Storyboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="SelectionIndicator" Storyboard.TargetProperty="Height" To="24" EnableDependentAnimation="True" Duration="0:0:0.1">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</VisualState.Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DisabledStates">
<VisualState x:Name="Enabled"/>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="RevealBorder.BorderBrush" Value="{ThemeResource NavigationViewItemBorderBrushCheckedDisabled}"/>
<Setter Target="LayoutRoot.Opacity" Value="{ThemeResource ListViewItemDisabledThemeOpacity}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="IconStates">
<VisualState x:Name="IconVisible"/>
<VisualState x:Name="IconCollapsed">
<VisualState.Setters>
<Setter Target="IconBox.Visibility" Value="Collapsed"/>
<Setter Target="IconColumn.Width" Value="16"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid HorizontalAlignment="Left" Margin="4,0,0,0" VerticalAlignment="Center">
<Rectangle x:Name="SelectionIndicator" Fill="{ThemeResource NavigationViewSelectionIndicatorForeground}" Height="24" Opacity="0" Width="3">
<Rectangle.OpacityTransition>
<ScalarTransition/>
</Rectangle.OpacityTransition>
</Rectangle>
</Grid>
<Border x:Name="RevealBorder" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}"/>
<Grid x:Name="ContentGrid" HorizontalAlignment="Left" Height="40">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="IconColumn" Width="48"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Viewbox x:Name="IconBox" Margin="{ThemeResource NavigationViewItemIconBoxMargin}">
<ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" Foreground="{TemplateBinding Foreground}"/>
</Viewbox>
<ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" Grid.Column="1" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Foreground="{TemplateBinding Foreground}"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="NavigationViewItemPresenterStyleWhenOnLeftPaneWithRevealFocus" TargetType="NavigationViewItemPresenter">
<Setter Property="Foreground" Value="{ThemeResource NavigationViewItemForeground}"/>
<Setter Property="Background" Value="{ThemeResource NavigationViewItemBackground}"/>
<Setter Property="BorderBrush" Value="{ThemeResource NavigationViewItemBorderBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource NavigationViewItemBorderThickness}"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="NavigationViewItemPresenter">
<Grid x:Name="LayoutRoot" Background="{TemplateBinding Background}" Height="40" Control.IsTemplateFocusTarget="True">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="DisabledStates">
<VisualState x:Name="Enabled"/>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="LayoutRoot.Opacity" Value="{ThemeResource ListViewItemDisabledThemeOpacity}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource SystemControlHighlightAccentBrush}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource SystemControlHighlightAltChromeWhiteBrush}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltChromeWhiteBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="PointerFocused"/>
</VisualStateGroup>
<VisualStateGroup x:Name="IconStates">
<VisualState x:Name="IconVisible"/>
<VisualState x:Name="IconCollapsed">
<VisualState.Setters>
<Setter Target="IconBox.Visibility" Value="Collapsed"/>
<Setter Target="IconColumn.Width" Value="16"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid HorizontalAlignment="Left" Margin="4,0,0,0" VerticalAlignment="Center">
<Rectangle x:Name="SelectionIndicator" Fill="{ThemeResource NavigationViewSelectionIndicatorForeground}" Height="24" Opacity="0.0" Width="2"/>
</Grid>
<Grid x:Name="ContentGrid" HorizontalAlignment="Left" Height="40">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="IconColumn" Width="48"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Viewbox x:Name="IconBox" Margin="{ThemeResource NavigationViewItemIconBoxMargin}">
<ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" Foreground="{TemplateBinding Foreground}"/>
</Viewbox>
<ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" Grid.Column="1" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="NavigationViewItemPresenterStyleWhenOnTopPane" TargetType="NavigationViewItemPresenter">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="NavigationViewItemPresenter">
<Grid x:Name="LayoutRoot" Background="{TemplateBinding Background}" Control.IsTemplateFocusTarget="True">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PointerStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource TopNavigationViewItemBackgroundPointerOver}"/>
<Setter Target="PointerRectangle.Fill" Value="{ThemeResource NavigationViewItemBackgroundPointerOver}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource TopNavigationViewItemForegroundPointerOver}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource TopNavigationViewItemForegroundPointerOver}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource TopNavigationViewItemBackgroundPressed}"/>
<Setter Target="PointerRectangle.Fill" Value="{ThemeResource NavigationViewItemBackgroundPressed}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource TopNavigationViewItemForegroundPressed}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource TopNavigationViewItemForegroundPressed}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource TopNavigationViewItemBackgroundSelected}"/>
<Setter Target="PointerRectangle.Fill" Value="{ThemeResource NavigationViewItemBackgroundSelected}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource TopNavigationViewItemForegroundSelected}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource TopNavigationViewItemForegroundSelected}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOverSelected">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource TopNavigationViewItemBackgroundPointerOver}"/>
<Setter Target="PointerRectangle.Fill" Value="{ThemeResource NavigationViewItemBackgroundSelectedPointerOver}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource TopNavigationViewItemForegroundPointerOver}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource TopNavigationViewItemForegroundPointerOver}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PressedSelected">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource TopNavigationViewItemBackgroundPressed}"/>
<Setter Target="PointerRectangle.Fill" Value="{ThemeResource NavigationViewItemBackgroundSelectedPressed}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource TopNavigationViewItemForegroundPressed}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource TopNavigationViewItemForegroundPressed}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DisabledStates">
<VisualState x:Name="Enabled"/>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="Icon.Foreground" Value="{ThemeResource TopNavigationViewItemForegroundDisabled}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource TopNavigationViewItemForegroundDisabled}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="NavigationViewIconPositionStates">
<VisualState x:Name="IconOnLeft"/>
<VisualState x:Name="IconOnly">
<VisualState.Setters>
<Setter Target="PointerRectangle.Visibility" Value="Visible"/>
<Setter Target="LayoutRoot.Width" Value="48"/>
<Setter Target="ContentPresenter.Visibility" Value="Collapsed"/>
<Setter Target="SelectionIndicatorGrid.Margin" Value="4,0,4,4"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="ContentOnly">
<VisualState.Setters>
<Setter Target="IconBox.Visibility" Value="Collapsed"/>
<Setter Target="ContentPresenter.Margin" Value="12,0"/>
<Setter Target="SelectionIndicatorGrid.Margin" Value="12,0,12,4"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle x:Name="PointerRectangle" Fill="Transparent" Visibility="Collapsed"/>
<Grid x:Name="ContentGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Viewbox x:Name="IconBox" HorizontalAlignment="Center" Height="16" Margin="16,0,0,0" VerticalAlignment="Center" Width="16">
<ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" Foreground="{ThemeResource TopNavigationViewItemForeground}"/>
</Viewbox>
<ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" Grid.Column="1" Foreground="{ThemeResource TopNavigationViewItemForeground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="8,0,16,0" TextWrapping="NoWrap" VerticalAlignment="Center"/>
</Grid>
<Grid x:Name="SelectionIndicatorGrid" Margin="16,0,16,4" VerticalAlignment="Bottom">
<Rectangle x:Name="SelectionIndicator" Fill="{ThemeResource NavigationViewSelectionIndicatorForeground}" Height="2" Opacity="0"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="NavigationViewItemPresenterStyleWhenOnTopPaneWithRevealFocus" TargetType="NavigationViewItemPresenter">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="NavigationViewItemPresenter">
<Grid x:Name="LayoutRoot" Background="{TemplateBinding Background}" Control.IsTemplateFocusTarget="True">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="DisabledStates">
<VisualState x:Name="Enabled"/>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="Icon.Foreground" Value="{ThemeResource TopNavigationViewItemForegroundDisabled}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource TopNavigationViewItemForegroundDisabled}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource TopNavigationViewItemRevealBackgroundFocused}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource TopNavigationViewItemRevealIconForegroundFocused}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource TopNavigationViewItemRevealContentForegroundFocused}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="PointerFocused"/>
</VisualStateGroup>
<VisualStateGroup x:Name="NavigationViewIconPositionStates">
<VisualState x:Name="IconOnLeft"/>
<VisualState x:Name="IconOnly">
<VisualState.Setters>
<Setter Target="PointerRectangle.Visibility" Value="Visible"/>
<Setter Target="LayoutRoot.Width" Value="48"/>
<Setter Target="ContentPresenter.Visibility" Value="Collapsed"/>
<Setter Target="SelectionIndicatorGrid.Margin" Value="4,0"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="ContentOnly">
<VisualState.Setters>
<Setter Target="IconBox.Visibility" Value="Collapsed"/>
<Setter Target="ContentPresenter.Margin" Value="12,0"/>
<Setter Target="SelectionIndicatorGrid.Margin" Value="12,0"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle x:Name="PointerRectangle" Fill="Transparent" Visibility="Collapsed"/>
<Grid x:Name="ContentGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Viewbox x:Name="IconBox" HorizontalAlignment="Center" Height="16" Margin="16,0,0,0" VerticalAlignment="Center" Width="16">
<ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" Foreground="{ThemeResource DefaultTextForegroundThemeBrush}"/>
</Viewbox>
<ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" Grid.Column="1" Foreground="{ThemeResource DefaultTextForegroundThemeBrush}" Margin="8,0,16,0" TextWrapping="NoWrap" VerticalAlignment="Center"/>
</Grid>
<Grid x:Name="SelectionIndicatorGrid" Margin="16,0,16,4" VerticalAlignment="Bottom">
<Rectangle x:Name="SelectionIndicator" Fill="{ThemeResource NavigationViewSelectionIndicatorForeground}" Height="2" Opacity="0"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="NavigationViewItemPresenterStyleWhenOnTopPaneOverflow" TargetType="NavigationViewItemPresenter">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="NavigationViewItemPresenter">
<Grid x:Name="LayoutRoot" Background="{TemplateBinding Background}" Height="40" Control.IsTemplateFocusTarget="True">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PointerStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource NavigationViewItemBackgroundPointerOver}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource NavigationViewItemForegroundPointerOver}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource NavigationViewItemForegroundPointerOver}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource NavigationViewItemBackgroundPressed}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource NavigationViewItemForegroundPressed}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource NavigationViewItemForegroundPressed}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource NavigationViewItemBackgroundSelected}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource NavigationViewItemForegroundSelected}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource NavigationViewItemForegroundSelected}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOverSelected">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource NavigationViewItemBackgroundSelectedPointerOver}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource NavigationViewItemForegroundPointerOver}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource NavigationViewItemForegroundPointerOver}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PressedSelected">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource NavigationViewItemBackgroundSelectedPressed}"/>
<Setter Target="Icon.Foreground" Value="{ThemeResource NavigationViewItemForegroundPressed}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource NavigationViewItemForegroundPressed}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DisabledStates">
<VisualState x:Name="Enabled"/>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="Icon.Foreground" Value="{ThemeResource TopNavigationViewItemForegroundDisabled}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource TopNavigationViewItemForegroundDisabled}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="NavigationViewIconPositionStates">
<VisualState x:Name="IconOnLeft"/>
<VisualState x:Name="IconOnly"/>
<VisualState x:Name="ContentOnly">
<VisualState.Setters>
<Setter Target="IconBox.Visibility" Value="Collapsed"/>
<Setter Target="ContentPresenter.Margin" Value="16,0"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name="ContentGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Viewbox x:Name="IconBox" HorizontalAlignment="Center" Height="16" Margin="16,0,0,0" VerticalAlignment="Center" Width="16">
<ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" Foreground="{TemplateBinding Foreground}"/>
</Viewbox>
<ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" Grid.Column="1" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="12,0,16,0" TextWrapping="NoWrap" VerticalAlignment="Center"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="NavigationViewItem">
<Setter Property="Foreground" Value="{ThemeResource NavigationViewItemForeground}"/>
<Setter Property="Background" Value="{ThemeResource NavigationViewItemBackground}"/>
<Setter Property="BorderBrush" Value="{ThemeResource NavigationViewItemBorderBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource NavigationViewItemBorderThickness}"/>
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="NavigationViewItem">
<NavigationViewItemPresenter x:Name="NavigationViewItemPresenter" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Icon="{TemplateBinding Icon}" IsTabStop="False" Margin="{TemplateBinding Margin}" Padding="{TemplateBinding Padding}" UseSystemFocusVisuals="{TemplateBinding UseSystemFocusVisuals}" VerticalAlignment="{TemplateBinding VerticalAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ItemOnNavigationViewListPositionStates">
<VisualState x:Name="OnLeftNavigation">
<VisualState.Setters>
<Setter Target="NavigationViewItemPresenter.Style" Value="{StaticResource NavigationViewItemPresenterStyleWhenOnLeftPane}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="OnLeftNavigationReveal">
<VisualState.Setters>
<Setter Target="NavigationViewItemPresenter.Style" Value="{StaticResource NavigationViewItemPresenterStyleWhenOnLeftPaneWithRevealFocus}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="OnTopNavigationPrimary">
<VisualState.Setters>
<Setter Target="NavigationViewItemPresenter.Style" Value="{StaticResource NavigationViewItemPresenterStyleWhenOnTopPane}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="OnTopNavigationPrimaryReveal">
<VisualState.Setters>
<Setter Target="NavigationViewItemPresenter.Style" Value="{StaticResource NavigationViewItemPresenterStyleWhenOnTopPaneWithRevealFocus}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="OnTopNavigationOverflow">
<VisualState.Setters>
<Setter Target="NavigationViewItemPresenter.Style" Value="{StaticResource NavigationViewItemPresenterStyleWhenOnTopPaneOverflow}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</NavigationViewItemPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
+17
View File
@@ -0,0 +1,17 @@
using System;
using System.Linq;
namespace WinTorrent
{
public static class Extensions
{
public static bool BelongsTo<T>(this T obj, params T[] set) =>
set.Contains(obj);
public static Uri ToUri(this string str)
{
Uri.TryCreate(str, UriKind.RelativeOrAbsolute, out Uri uri);
return uri;
}
}
}
+78
View File
@@ -0,0 +1,78 @@
using Microsoft.Services.Store.Engagement;
using System;
using Windows.Services.Store;
using Windows.UI.Xaml.Controls;
namespace WinTorrent.Utils
{
public static class Feedback
{
public static bool HasFeedbackHub => StoreServicesFeedbackLauncher.IsSupported();
public static async void OpenFeedbackHub()
{
if (HasFeedbackHub)
await StoreServicesFeedbackLauncher.GetDefault().LaunchAsync();
}
public static async void PromptFeedback()
{
if (!HasFeedbackHub)
{
Settings.PromptFeedback = false;
return;
}
ContentDialog dialog = new ContentDialog
{
Title = "Have some thoughts?",
PrimaryButtonText = "Sure!",
SecondaryButtonText = "Don't ask me anymore",
CloseButtonText = "Maybe later",
DefaultButton = ContentDialogButton.Primary,
Content = new TextBlock
{
Text = "Would you like to share something you like or dislike in the app? Or perhaps you have some ideas? Leave feedback!"
}
};
ContentDialogResult result = await dialog.ShowAsync();
if (result != ContentDialogResult.None)
Settings.PromptFeedback = false;
if (result == ContentDialogResult.Primary)
OpenFeedbackHub();
}
public static async void PromptReview()
{
ContentDialog dialog = new ContentDialog
{
Title = "Like our app?",
PrimaryButtonText = "Sure!",
SecondaryButtonText = "Don't ask me anymore",
CloseButtonText = "Maybe later",
DefaultButton = ContentDialogButton.Primary,
Content = new TextBlock
{
Text = "Could you leave a feedback on Microsfot Store page? It's very important for me :)"
}
};
ContentDialogResult result = await dialog.ShowAsync();
if (result != ContentDialogResult.None)
Settings.PromptReview = false;
if (result == ContentDialogResult.Primary)
await StoreContext.GetDefault().RequestRateAndReviewAppAsync();
}
}
}
+57
View File
@@ -0,0 +1,57 @@
using Microsoft.AppCenter;
using Microsoft.AppCenter.Analytics;
using Microsoft.AppCenter.Crashes;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using Windows.ApplicationModel;
using Windows.Storage;
namespace WinTorrent.Utils
{
public static class Metrics
{
static readonly ApplicationDataContainer storage = ApplicationData.Current.RoamingSettings;
static readonly Stopwatch sw = new Stopwatch();
public static TimeSpan Uptime
{
get => (TimeSpan?)storage.Values["Metrics.SpentTime"] ?? TimeSpan.FromSeconds(0);
set => storage.Values["Metrics.SpentTime"] = value;
}
public static string CurrentVersion
{
get
{
PackageVersion v = Package.Current.Id.Version;
return $"{v.Major}.{v.Minor}.{v.Revision}.{v.Build}";
}
}
public static void StartSession()
{
sw.Start();
AppCenter.Start("45774462-9ea7-438a-96fc-03982666f39e", typeof(Analytics), typeof(Crashes));
AppCenter.SetCountryCode(new RegionInfo(CultureInfo.CurrentUICulture.Name).TwoLetterISORegionName);
}
public static void EndSession()
{
sw.Stop();
Uptime += sw.Elapsed;
AddEvent("Session closed",
("Duration", sw.Elapsed.ToString()),
("Spend time total", Uptime.ToString()));
}
public static void AddEvent(string eventName, params (string key, string value)[] details)
{
Dictionary<string, string> parameters = new Dictionary<string, string>();
foreach (var (key, value) in details)
parameters.Add(key, value);
Analytics.TrackEvent(eventName, parameters.Count > 0 ? parameters : null);
}
}
}
+70
View File
@@ -0,0 +1,70 @@
using System;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.Storage;
using Windows.Storage.AccessCache;
namespace WinTorrent.Utils
{
public static class Settings
{
static readonly ApplicationDataContainer settings = ApplicationData.Current.RoamingSettings;
public static bool Startup
{
get => (bool?)settings.Values["Startup"] ?? false;
set => settings.Values["Startup"] = value;
}
public static bool RunOnSaver
{
get => (bool?)settings.Values["RunOnSaver"] ?? false;
set => settings.Values["RunOnSaver"] = value;
}
public static bool SeedCompleted
{
get => (bool?)settings.Values["SeedCompleted"] ?? true;
set => settings.Values["SeedCompleted"] = value;
}
public static string DefaultFolder
{
get => (string)settings.Values["DefaultFolder"] ?? "";
set => settings.Values["DefaultFolder"] = value;
}
public static int DownloadLimit
{
get => (int?)settings.Values["DownloadLimit"] ?? 0;
set => settings.Values["DownloadLimit"] = value;
}
public static int UploadLimit
{
get => (int?)settings.Values["UploadLimit"] ?? 0;
set => settings.Values["UploadLimit"] = value;
}
public static bool PromptReview
{
get => (bool?)settings.Values["PromptReview"] ?? Metrics.Uptime.TotalHours > 24;
set => settings.Values["PromptReview"] = value;
}
public static bool PromptFeedback
{
get => (bool?)settings.Values["PromptFeedback"] ?? Metrics.Uptime.TotalHours > 12;
set => settings.Values["PromptFeedback"] = value;
}
public static int Theme
{
get => (int?)settings.Values["PreferedUITheme"] ?? 2; //System
set => settings.Values["PreferedUITheme"] = value;
}
public static async Task<StorageFolder> GetDefaultFolder()
{
if (string.IsNullOrWhiteSpace(DefaultFolder))
return await DownloadsFolder.CreateFolderAsync(Package.Current.DisplayName, CreationCollisionOption.OpenIfExists);
else
return await StorageApplicationPermissions.FutureAccessList.GetFolderAsync(DefaultFolder);
}
}
}
+140
View File
@@ -0,0 +1,140 @@
using System;
using System.Collections.Generic;
using WinTorrent.Models;
namespace WinTorrent.Utils
{
public delegate void TorrentStateChangedEventHandler(TorrentItem sender, TorrentState previousState);
public static class TorrentClient
{
public static event TorrentStateChangedEventHandler TorrentItemStateChanged;
public static List<TorrentItem> Torrents { get; }
static TorrentClient()
{
Torrents = new List<TorrentItem>
{
new TorrentItem
{
Title = "Microsoft Edge",
TotalSize = new DataSize(3221225472),
Downloaded = new DataSize(125829120),
TransmissionSpeed = new DownloadSpeed(33554432),
RemainingTime = TimeSpan.FromSeconds(36),
State = TorrentState.Downloading,
SeedCount = 15
},
new TorrentItem
{
Title = "Microsoft Edge",
TotalSize = new DataSize(3221225472),
Downloaded = new DataSize(125829120),
TransmissionSpeed = new DownloadSpeed(33554432),
RemainingTime = TimeSpan.FromSeconds(36),
State = TorrentState.Completed,
SeedCount = 15
},
new TorrentItem
{
Title = "Microsoft Edge",
TotalSize = new DataSize(3221225472),
Downloaded = new DataSize(125829120),
TransmissionSpeed = new DownloadSpeed(33554432),
RemainingTime = TimeSpan.FromSeconds(36),
State = TorrentState.Paused,
SeedCount = 15
},
new TorrentItem
{
Title = "Microsoft Edge",
TotalSize = new DataSize(3221225472),
Downloaded = new DataSize(125829120),
TransmissionSpeed = new DownloadSpeed(33554432),
RemainingTime = TimeSpan.FromSeconds(36),
State = TorrentState.Seeding,
SeedCount = 15
},
new TorrentItem
{
Title = "Microsoft Edge",
TotalSize = new DataSize(3221225472),
Downloaded = new DataSize(125829120),
TransmissionSpeed = new DownloadSpeed(33554432),
RemainingTime = TimeSpan.FromSeconds(36),
State = TorrentState.Cancelling,
SeedCount = 15
},
new TorrentItem
{
Title = "Microsoft Edge",
TotalSize = new DataSize(3221225472),
Downloaded = new DataSize(125829120),
TransmissionSpeed = new DownloadSpeed(33554432),
RemainingTime = TimeSpan.FromSeconds(36),
State = TorrentState.Initializing,
SeedCount = 15
},
new TorrentItem
{
Title = "Microsoft Edge",
TotalSize = new DataSize(3221225472),
Downloaded = new DataSize(125829120),
TransmissionSpeed = new DownloadSpeed(33554432),
RemainingTime = TimeSpan.FromSeconds(36),
State = TorrentState.Pausing,
SeedCount = 15
},
new TorrentItem
{
Title = "Microsoft Edge",
TotalSize = new DataSize(3221225472),
Downloaded = new DataSize(125829120),
TransmissionSpeed = new DownloadSpeed(33554432),
RemainingTime = TimeSpan.FromSeconds(36),
State = TorrentState.Resuming,
SeedCount = 15
},
new TorrentItem
{
Title = "Microsoft Edge",
TotalSize = new DataSize(3221225472),
Downloaded = new DataSize(125829120),
TransmissionSpeed = new DownloadSpeed(33554432),
RemainingTime = TimeSpan.FromSeconds(36),
State = TorrentState.Error,
SeedCount = 15
}
};
}
public static void AddTorrent()
{
}
public static void PauseTorrent()
{
}
public static void CancelTorrent()
{
}
public static void ResumeTorrent()
{
}
public static void SeedTorrent()
{
}
public static void OnItemStateChanged(TorrentItem item, TorrentState previousState) =>
TorrentItemStateChanged?.Invoke(item, previousState);
}
}
+279
View File
@@ -0,0 +1,279 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<LangVersion>8.0</LangVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{88F8E34F-0129-4856-A1F7-4A89DA892C9B}</ProjectGuid>
<OutputType>AppContainerExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>WinTorrent</RootNamespace>
<AssemblyName>WinTorrent</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.18362.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.18362.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WindowsXamlEnableOverview>true</WindowsXamlEnableOverview>
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\ARM\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
<OutputPath>bin\ARM\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\ARM64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>ARM64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM64'">
<OutputPath>bin\ARM64\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>ARM64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup>
<ItemGroup>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="Dialogs\AddTorrentDialog.xaml.cs">
<DependentUpon>AddTorrentDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Models\DataSize.cs" />
<Compile Include="Models\PointerHoverStateTrigger.cs" />
<Compile Include="Models\TorrentStateDataTrigger.cs" />
<Compile Include="Pages\TorrentDetailsPage.xaml.cs">
<DependentUpon>TorrentDetailsPage.xaml</DependentUpon>
</Compile>
<Compile Include="Utils\Extensions.cs" />
<Compile Include="Pages\MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Pages\SettingsPage.xaml.cs">
<DependentUpon>SettingsPage.xaml</DependentUpon>
</Compile>
<Compile Include="Utils\Feedback.cs" />
<Compile Include="Utils\Metrics.cs" />
<Compile Include="Utils\Settings.cs" />
<Compile Include="Utils\TorrentClient.cs" />
<Compile Include="Models\TorrentItem.cs" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<Content Include="Assets\LargeTile.scale-100.png" />
<Content Include="Assets\LargeTile.scale-125.png" />
<Content Include="Assets\LargeTile.scale-150.png" />
<Content Include="Assets\LargeTile.scale-200.png" />
<Content Include="Assets\LargeTile.scale-400.png" />
<Content Include="Assets\Ref.png" />
<Content Include="Assets\SmallTile.scale-100.png" />
<Content Include="Assets\SmallTile.scale-125.png" />
<Content Include="Assets\SmallTile.scale-150.png" />
<Content Include="Assets\SmallTile.scale-200.png" />
<Content Include="Assets\SmallTile.scale-400.png" />
<Content Include="Assets\SplashScreen.scale-100.png" />
<Content Include="Assets\SplashScreen.scale-125.png" />
<Content Include="Assets\SplashScreen.scale-150.png" />
<Content Include="Assets\SplashScreen.scale-400.png" />
<Content Include="Assets\Square150x150Logo.scale-100.png" />
<Content Include="Assets\Square150x150Logo.scale-125.png" />
<Content Include="Assets\Square150x150Logo.scale-150.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-256.png" />
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-32.png" />
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-48.png" />
<Content Include="Assets\Square44x44Logo.scale-100.png" />
<Content Include="Assets\Square44x44Logo.scale-125.png" />
<Content Include="Assets\Square44x44Logo.scale-150.png" />
<Content Include="Assets\Square44x44Logo.scale-400.png" />
<Content Include="Assets\Square44x44Logo.targetsize-16.png" />
<Content Include="Assets\Square44x44Logo.targetsize-24.png" />
<Content Include="Assets\Square44x44Logo.targetsize-256.png" />
<Content Include="Assets\Square44x44Logo.targetsize-32.png" />
<Content Include="Assets\Square44x44Logo.targetsize-48.png" />
<Content Include="Assets\StoreLogo.scale-100.png" />
<Content Include="Assets\StoreLogo.scale-125.png" />
<Content Include="Assets\StoreLogo.scale-150.png" />
<Content Include="Assets\StoreLogo.scale-200.png" />
<Content Include="Assets\StoreLogo.scale-400.png" />
<Content Include="Assets\Wide310x150Logo.scale-100.png" />
<Content Include="Assets\Wide310x150Logo.scale-125.png" />
<Content Include="Assets\Wide310x150Logo.scale-150.png" />
<Content Include="Assets\Wide310x150Logo.scale-400.png" />
<Content Include="Properties\Default.rd.xml" />
<Content Include="Assets\LockScreenLogo.scale-200.png" />
<Content Include="Assets\SplashScreen.scale-200.png" />
<Content Include="Assets\Square150x150Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="Pages\TorrentDetailsPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="TemplateDictionaries\ListViewItemTemplateDictionary.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="TemplateDictionaries\NavigationViewItemTemplateDictionary.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="TemplateDictionaries\AutoSuggestBoxTemplateDictionary.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Dialogs\AddTorrentDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Pages\MainPage.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Pages\SettingsPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AppCenter.Analytics">
<Version>3.2.1</Version>
</PackageReference>
<PackageReference Include="Microsoft.AppCenter.Crashes">
<Version>3.2.1</Version>
</PackageReference>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.2.10</Version>
</PackageReference>
<PackageReference Include="Microsoft.Services.Store.Engagement">
<Version>10.1901.28001</Version>
</PackageReference>
<PackageReference Include="MonoTorrent">
<Version>1.0.21</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>12.0.3</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<SDKReference Include="Microsoft.Services.Store.Engagement, Version=10.0">
<Name>Microsoft Engagement Framework</Name>
</SDKReference>
<SDKReference Include="Microsoft.VCLibs, Version=14.0">
<Name>Visual C++ 2015 Runtime for Universal Windows Platform Apps</Name>
</SDKReference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>