housekeeping: Add Live.Avalonia, Upgrade Dependencies (#49)

* Update Avalonia
* Update packages where possible
* Incorporate Live.Avalonia
* Add ReactiveUI.Validation bindings
* Avoid using the carousel
* Theme changing now works again
* Address analyzer warnings
This commit is contained in:
Artyom V. Gorchakov 2021-02-28 13:31:08 +03:00 коммит произвёл GitHub
Родитель 31f4a50dc0
Коммит 21e7f1f4ab
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
33 изменённых файлов: 256 добавлений и 253 удалений

Просмотреть файл

@ -22,7 +22,7 @@ internal class Build : NukeBuild
public static int Main() => Execute<Build>(x => x.RunInteractive);
[Parameter] readonly string Configuration = IsLocalBuild ? "Debug" : "Release";
[Parameter] readonly string Configuration = "Release";
[Parameter] readonly bool Interactive;
[Parameter] readonly bool Full;

Просмотреть файл

@ -10,7 +10,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Nuke.Common" Version="0.24.11" />
<PackageReference Include="Nuke.Common" Version="5.0.2" />
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -2,18 +2,18 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Camelotia.Presentation.Avalonia.App">
<Application.Styles>
<StyleInclude Source="avares://Citrus.Avalonia/Citrus.xaml"/>
<StyleInclude Source="avares://Citrus.Avalonia/Sea.xaml"/>
<Style>
<Style.Resources>
<GeometryDrawing x:Key="ChevronRight" Brush="{DynamicResource ThemeAccentBrush}" Geometry="F1M6.3901,12.2803L5.3291,11.2193 8.5491,8.0003 5.3291,4.7803 6.3901,3.7193 10.6701,8.0003z" />
<GeometryDrawing x:Key="ChevronDown" Brush="{DynamicResource ThemeAccentBrush}" Geometry="F1M8,12L2.331,6.897 3.669,5.411 8,9.309 12.331,5.411 13.669,6.897z" />
<GeometryDrawing x:Key="ArrowUp" Brush="{DynamicResource ThemeCardBrush}" Geometry="M 256,464 C 370.9,464 464,370.9 464,256 464,141.1 370.9,48 256,48 141.1,48 48,141.1 48,256 c 0,114.9 93.1,208 208,208 z m 0,-32 C 209,432 164.8,413.7 131.6,380.4 98.3,347.2 80,303 80,256 80,209 98.3,164.8 131.6,131.6 164.8,98.3 209,80 256,80 c 47,0 91.2,18.3 124.4,51.6 33.3,33.2 51.6,77.4 51.6,124.4 0,47 -18.3,91.2 -51.6,124.4 C 347.2,413.7 303,432 256,432 Z M 147.6,301.3 c -7.5,-7.5 -7.5,-19.8 0,-27.3 l 95.7,-95.4 c 7.3,-7.3 19.1,-7.5 26.6,-0.6 l 94.3,94 c 3.8,3.8 5.7,8.7 5.7,13.7 0,4.9 -1.9,9.9 -5.6,13.6 -7.5,7.5 -19.7,7.6 -27.3,0 l -81,-79.8 -81.1,81.9 c -7.5,7.5 -19.7,7.5 -27.3,-0.1 z" />
<GeometryDrawing x:Key="ArrowDown" Brush="{DynamicResource ThemeCardBrush}" Geometry="m 48,256 c 0,114.9 93.1,208 208,208 114.9,0 208,-93.1 208,-208 C 464,141.1 370.9,48 256,48 141.1,48 48,141.1 48,256 Z m 32,0 C 80,209 98.3,164.8 131.6,131.6 164.8,98.3 209,80 256,80 c 47,0 91.2,18.3 124.4,51.6 33.3,33.2 51.6,77.4 51.6,124.4 0,47 -18.3,91.2 -51.6,124.4 C 347.2,413.7 303,432 256,432 209,432 164.8,413.7 131.6,380.4 98.3,347.2 80,303 80,256 Z M 210.7,147.6 c 7.5,-7.5 19.8,-7.5 27.3,0 l 95.4,95.7 c 7.3,7.3 7.5,19.1 0.6,26.6 l -94,94.3 c -3.8,3.8 -8.7,5.7 -13.7,5.7 -4.9,0 -9.9,-1.9 -13.6,-5.6 -7.5,-7.5 -7.6,-19.7 0,-27.3 l 79.9,-81.1 -81.9,-81.1 c -7.6,-7.4 -7.6,-19.6 0,-27.2 z" />
<GeometryDrawing x:Key="FolderDrawing" Brush="{DynamicResource HighlightBrush}" Geometry="M213.338 96H74.666C51.197 96 32 115.198 32 138.667v234.666C32 396.802 51.197 416 74.666 416h362.668C460.803 416 480 396.802 480 373.333V186.667C480 163.198 460.803 144 437.334 144H256.006l-42.668-48z"/>
<GeometryDrawing x:Key="FileDrawing" Brush="{DynamicResource ThemeAccentBrush}" Geometry="F1M225,-200C211.192886352539,-200,200,-188.807113647461,200,-175C200,-161.192886352539,211.192886352539,-150,225,-150L375,-150C388.80712890625,-150,400,-161.192886352539,400,-175C400,-188.807113647461,388.80712890625,-200,375,-200L225,-200z M225,-300C211.192886352539,-300,200,-288.80712890625,200,-275C200,-261.19287109375,211.192886352539,-250,225,-250L300,-250C313.80712890625,-250,325,-261.19287109375,325,-275C325,-288.80712890625,313.80712890625,-300,300,-300L225,-300z M350,-500L350,-421.25C349.129821777344,-410.510803222656,357.027465820313,-401.055877685547,367.75,-400L443.5,-400 350,-500z M164,-550L364,-550C371.054473876953,-549.983337402344,377.773529052734,-546.986999511719,382.5,-541.75L493.5,-416.75C497.667449951172,-412.1650390625,499.983825683594,-406.195892333984,500,-400L500,-112.5C499.802276611328,-95.7246856689453,492.948059082031,-79.7151184082031,480.945465087891,-67.9938430786133C468.94287109375,-56.2725677490234,452.775299072266,-49.7999038696289,436,-50.0000038146973L164,-50.0000038146973C147.224716186523,-49.7999038696289,131.05712890625,-56.2725677490234,119.054534912109,-67.9938430786133C107.051948547363,-79.7151184082031,100.197738647461,-95.7246856689453,100,-112.5L100,-487.5C100.197738647461,-504.275299072266,107.051948547363,-520.284851074219,119.054534912109,-532.006164550781C131.05712890625,-543.727416992188,147.224716186523,-550.200073242188,164,-550z"/>
<GeometryDrawing x:Key="LogoDrawing" Brush="{DynamicResource ThemeAccentBrush}" Geometry="M12.19 2.38a9.344 9.344 0 0 0-9.234 6.893c.053-.02-.055.013 0 0-3.875 2.551-3.922 8.11-.247 10.941l.006-.007-.007.03a6.717 6.717 0 0 0 4.077 1.356h5.173l.03.03h5.192c6.687.053 9.376-8.605 3.835-12.35a9.365 9.365 0 0 0-2.821-4.552l-.043.043.006-.05A9.344 9.344 0 0 0 12.19 2.38zm-.358 4.146c1.244-.04 2.518.368 3.486 1.15a5.186 5.186 0 0 1 1.862 4.078v.518c3.53-.07 3.53 5.262 0 5.193h-5.193l-.008.009v-.04H6.785a2.59 2.59 0 0 1-1.067-.23h.001a2.597 2.597 0 1 1 3.437-3.437l3.013-3.012A6.747 6.747 0 0 0 8.11 8.24c.018-.01.04-.026.054-.023a5.186 5.186 0 0 1 3.67-1.69z"/>
<GeometryDrawing x:Key="CloudDrawing" Brush="{DynamicResource ThemeAccentBrush}" Geometry="M16.5,16H8A3,3 0 0,1 5,13A3,3 0 0,1 8,10C8.05,10 8.09,10 8.14,10C8.58,8.28 10.13,7 12,7A4,4 0 0,1 16,11H16.5A2.5,2.5 0 0,1 19,13.5A2.5,2.5 0 0,1 16.5,16M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z"/>
</Style.Resources>
<Style.Resources>
<GeometryDrawing x:Key="ChevronRight" Brush="{DynamicResource ThemeAccentBrush}" Geometry="F1M6.3901,12.2803L5.3291,11.2193 8.5491,8.0003 5.3291,4.7803 6.3901,3.7193 10.6701,8.0003z" />
<GeometryDrawing x:Key="ChevronDown" Brush="{DynamicResource ThemeAccentBrush}" Geometry="F1M8,12L2.331,6.897 3.669,5.411 8,9.309 12.331,5.411 13.669,6.897z" />
<GeometryDrawing x:Key="ArrowUp" Brush="{DynamicResource ThemeForegroundBrush}" Geometry="M 256,464 C 370.9,464 464,370.9 464,256 464,141.1 370.9,48 256,48 141.1,48 48,141.1 48,256 c 0,114.9 93.1,208 208,208 z m 0,-32 C 209,432 164.8,413.7 131.6,380.4 98.3,347.2 80,303 80,256 80,209 98.3,164.8 131.6,131.6 164.8,98.3 209,80 256,80 c 47,0 91.2,18.3 124.4,51.6 33.3,33.2 51.6,77.4 51.6,124.4 0,47 -18.3,91.2 -51.6,124.4 C 347.2,413.7 303,432 256,432 Z M 147.6,301.3 c -7.5,-7.5 -7.5,-19.8 0,-27.3 l 95.7,-95.4 c 7.3,-7.3 19.1,-7.5 26.6,-0.6 l 94.3,94 c 3.8,3.8 5.7,8.7 5.7,13.7 0,4.9 -1.9,9.9 -5.6,13.6 -7.5,7.5 -19.7,7.6 -27.3,0 l -81,-79.8 -81.1,81.9 c -7.5,7.5 -19.7,7.5 -27.3,-0.1 z" />
<GeometryDrawing x:Key="ArrowDown" Brush="{DynamicResource ThemeForegroundBrush}" Geometry="m 48,256 c 0,114.9 93.1,208 208,208 114.9,0 208,-93.1 208,-208 C 464,141.1 370.9,48 256,48 141.1,48 48,141.1 48,256 Z m 32,0 C 80,209 98.3,164.8 131.6,131.6 164.8,98.3 209,80 256,80 c 47,0 91.2,18.3 124.4,51.6 33.3,33.2 51.6,77.4 51.6,124.4 0,47 -18.3,91.2 -51.6,124.4 C 347.2,413.7 303,432 256,432 209,432 164.8,413.7 131.6,380.4 98.3,347.2 80,303 80,256 Z M 210.7,147.6 c 7.5,-7.5 19.8,-7.5 27.3,0 l 95.4,95.7 c 7.3,7.3 7.5,19.1 0.6,26.6 l -94,94.3 c -3.8,3.8 -8.7,5.7 -13.7,5.7 -4.9,0 -9.9,-1.9 -13.6,-5.6 -7.5,-7.5 -7.6,-19.7 0,-27.3 l 79.9,-81.1 -81.9,-81.1 c -7.6,-7.4 -7.6,-19.6 0,-27.2 z" />
<GeometryDrawing x:Key="FolderDrawing" Brush="{DynamicResource HighlightBrush}" Geometry="M213.338 96H74.666C51.197 96 32 115.198 32 138.667v234.666C32 396.802 51.197 416 74.666 416h362.668C460.803 416 480 396.802 480 373.333V186.667C480 163.198 460.803 144 437.334 144H256.006l-42.668-48z"/>
<GeometryDrawing x:Key="FileDrawing" Brush="{DynamicResource ThemeAccentBrush}" Geometry="F1M225,-200C211.192886352539,-200,200,-188.807113647461,200,-175C200,-161.192886352539,211.192886352539,-150,225,-150L375,-150C388.80712890625,-150,400,-161.192886352539,400,-175C400,-188.807113647461,388.80712890625,-200,375,-200L225,-200z M225,-300C211.192886352539,-300,200,-288.80712890625,200,-275C200,-261.19287109375,211.192886352539,-250,225,-250L300,-250C313.80712890625,-250,325,-261.19287109375,325,-275C325,-288.80712890625,313.80712890625,-300,300,-300L225,-300z M350,-500L350,-421.25C349.129821777344,-410.510803222656,357.027465820313,-401.055877685547,367.75,-400L443.5,-400 350,-500z M164,-550L364,-550C371.054473876953,-549.983337402344,377.773529052734,-546.986999511719,382.5,-541.75L493.5,-416.75C497.667449951172,-412.1650390625,499.983825683594,-406.195892333984,500,-400L500,-112.5C499.802276611328,-95.7246856689453,492.948059082031,-79.7151184082031,480.945465087891,-67.9938430786133C468.94287109375,-56.2725677490234,452.775299072266,-49.7999038696289,436,-50.0000038146973L164,-50.0000038146973C147.224716186523,-49.7999038696289,131.05712890625,-56.2725677490234,119.054534912109,-67.9938430786133C107.051948547363,-79.7151184082031,100.197738647461,-95.7246856689453,100,-112.5L100,-487.5C100.197738647461,-504.275299072266,107.051948547363,-520.284851074219,119.054534912109,-532.006164550781C131.05712890625,-543.727416992188,147.224716186523,-550.200073242188,164,-550z"/>
<GeometryDrawing x:Key="LogoDrawing" Brush="{DynamicResource ThemeAccentBrush}" Geometry="M12.19 2.38a9.344 9.344 0 0 0-9.234 6.893c.053-.02-.055.013 0 0-3.875 2.551-3.922 8.11-.247 10.941l.006-.007-.007.03a6.717 6.717 0 0 0 4.077 1.356h5.173l.03.03h5.192c6.687.053 9.376-8.605 3.835-12.35a9.365 9.365 0 0 0-2.821-4.552l-.043.043.006-.05A9.344 9.344 0 0 0 12.19 2.38zm-.358 4.146c1.244-.04 2.518.368 3.486 1.15a5.186 5.186 0 0 1 1.862 4.078v.518c3.53-.07 3.53 5.262 0 5.193h-5.193l-.008.009v-.04H6.785a2.59 2.59 0 0 1-1.067-.23h.001a2.597 2.597 0 1 1 3.437-3.437l3.013-3.012A6.747 6.747 0 0 0 8.11 8.24c.018-.01.04-.026.054-.023a5.186 5.186 0 0 1 3.67-1.69z"/>
<GeometryDrawing x:Key="CloudDrawing" Brush="{DynamicResource ThemeAccentBrush}" Geometry="M16.5,16H8A3,3 0 0,1 5,13A3,3 0 0,1 8,10C8.05,10 8.09,10 8.14,10C8.58,8.28 10.13,7 12,7A4,4 0 0,1 16,11H16.5A2.5,2.5 0 0,1 19,13.5A2.5,2.5 0 0,1 16.5,16M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z"/>
</Style.Resources>
</Style>
</Application.Styles>
</Application>

Просмотреть файл

@ -1,4 +1,9 @@
using System;
using System.Diagnostics;
using System.Reactive;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Layout;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
using Camelotia.Presentation.AppState;
@ -7,34 +12,71 @@ using Camelotia.Presentation.Avalonia.Views;
using Camelotia.Presentation.Infrastructure;
using Camelotia.Presentation.ViewModels;
using Camelotia.Services;
using Live.Avalonia;
using ReactiveUI;
namespace Camelotia.Presentation.Avalonia
{
public class App : Application
public class App : Application, ILiveView
{
public override void Initialize() => AvaloniaXamlLoader.Load(this);
public override void OnFrameworkInitializationCompleted()
{
// Configure ReactiveUI suspension management.
Akavache.BlobCache.ApplicationName = "CamelotiaV2";
var suspension = new AutoSuspendHelper(ApplicationLifetime);
RxApp.SuspensionHost.CreateNewAppState = () => new MainState();
RxApp.SuspensionHost.SetupDefaultSuspendResume(new NewtonsoftJsonSuspensionDriver("appstate.json"));
suspension.OnFrameworkInitializationCompleted();
if (Debugger.IsAttached || IsRelease())
{
var window = new Window
{
Height = 590,
Width = 850,
MinHeight = 590,
MinWidth = 850,
};
window.Content = CreateView(window);
window.Show();
}
else
{
var window = new LiveViewHost(this, Console.WriteLine)
{
Height = 590,
Width = 850,
MinHeight = 590,
MinWidth = 850,
Content = "Please wait for the app to rebuild from sources...",
HorizontalContentAlignment = HorizontalAlignment.Center,
VerticalContentAlignment = VerticalAlignment.Center,
};
window.StartWatchingSourceFilesForHotReloading();
window.Show();
}
RxApp.DefaultExceptionHandler = Observer.Create<Exception>(Console.WriteLine);
base.OnFrameworkInitializationCompleted();
}
// Configure app dependencies.
var window = new MainView();
var styles = new AvaloniaStyleManager(window);
var mainState = RxApp.SuspensionHost.GetAppState<MainState>();
public object CreateView(Window window)
{
var view = new MainView();
var styles = new AvaloniaStyleManager(view);
view.SwitchThemeButton.Click += (_, _) => styles.UseNextTheme();
view.DataContext ??= CreateViewModel(window);
return view;
}
Akavache.BlobCache.ApplicationName = "CamelotiaV2";
window.SwitchThemeButton.Click += (sender, args) => styles.UseNextTheme();
window.DataContext = new MainViewModel(
mainState,
private static MainViewModel CreateViewModel(Window window)
{
var main = RxApp.SuspensionHost.GetAppState<MainState>();
return new MainViewModel(
main,
new CloudFactory(
mainState.CloudConfiguration,
main.CloudConfiguration,
new AvaloniaYandexAuthenticator(),
Akavache.BlobCache.UserAccount),
(state, provider) => new CloudViewModel(
@ -50,8 +92,15 @@ namespace Camelotia.Presentation.Avalonia
provider),
new AvaloniaFileManager(window),
provider));
}
window.Show();
private static bool IsRelease()
{
#if RELEASE
return true;
#else
return false;
#endif
}
}
}

Просмотреть файл

@ -8,16 +8,13 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.9.12" />
<PackageReference Include="Avalonia.Desktop" Version="0.9.12" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.9.12" />
<PackageReference Include="Citrus.Avalonia" Version="1.2.6" />
<PackageReference Include="XamlNameReferenceGenerator" Version="0.2.1-preview" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Pharmacist.MsBuild" Version="1.8.1" PrivateAssets="all" />
<PackageReference Include="Pharmacist.Common" Version="1.8.1" />
<PackageReference Include="Avalonia" Version="0.10.0" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.0" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.0" />
<PackageReference Include="Avalonia.ReactiveUI.Events" Version="0.10.0" />
<PackageReference Include="Citrus.Avalonia" Version="1.4.3" />
<PackageReference Include="Live.Avalonia" Version="1.2.1" />
<PackageReference Include="XamlNameReferenceGenerator" Version="0.5.1" />
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -1,10 +1,9 @@
using Avalonia;
using Avalonia.Logging.Serilog;
using Avalonia.ReactiveUI;
namespace Camelotia.Presentation.Avalonia
{
public sealed class Program
public static class Program
{
public static void Main(string[] args) => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
@ -12,6 +11,6 @@ namespace Camelotia.Presentation.Avalonia
=> AppBuilder.Configure<App>()
.UseReactiveUI()
.UsePlatformDetect()
.LogToDebug();
.LogToTrace();
}
}

Просмотреть файл

@ -1,6 +1,6 @@
using System;
using Avalonia.Controls;
using Avalonia.Markup.Xaml.Styling;
using Avalonia.Styling;
namespace Camelotia.Presentation.Avalonia.Services
{
@ -20,47 +20,19 @@ namespace Camelotia.Presentation.Avalonia.Services
private readonly StyleInclude _citrusStyle = CreateStyle("avares://Citrus.Avalonia/Citrus.xaml");
private readonly StyleInclude _rustStyle = CreateStyle("avares://Citrus.Avalonia/Rust.xaml");
private readonly StyleInclude _seaStyle = CreateStyle("avares://Citrus.Avalonia/Sea.xaml");
private readonly Window _window;
private readonly IStyleHost _window;
public AvaloniaStyleManager(Window window)
public AvaloniaStyleManager(IStyleHost window)
{
_window = window;
// We add the style to the window styles section, so it
// will override the default style defined in App.xaml.
if (window.Styles.Count == 0)
window.Styles.Add(_seaStyle);
// If there are styles defined already, we assume that
// the first style imported it related to citrus.
// This allows one to override citrus styles.
else window.Styles[0] = _seaStyle;
}
public Theme CurrentTheme { get; private set; } = Theme.Sea;
public void UseTheme(Theme theme)
{
// Here, we change the first style in the main window styles
// section, and the main window instantly refreshes. Remember
// to invoke such methods from the UI thread.
_window.Styles[0] = theme switch
{
Theme.Citrus => _citrusStyle,
Theme.Sea => _seaStyle,
Theme.Rust => _rustStyle,
Theme.Candy => _candyStyle,
Theme.Magma => _magmaStyle,
_ => throw new ArgumentOutOfRangeException(nameof(theme))
};
CurrentTheme = theme;
}
public void UseNextTheme()
{
// This method allows to support switching among all
// supported color schemes one by one.
public void UseNextTheme() =>
UseTheme(CurrentTheme switch
{
Theme.Citrus => Theme.Sea,
@ -70,7 +42,6 @@ namespace Camelotia.Presentation.Avalonia.Services
Theme.Magma => Theme.Citrus,
_ => throw new ArgumentOutOfRangeException(nameof(CurrentTheme))
});
}
private static StyleInclude CreateStyle(string url)
{
@ -80,5 +51,19 @@ namespace Camelotia.Presentation.Avalonia.Services
Source = new Uri(url)
};
}
private void UseTheme(Theme theme)
{
CurrentTheme = theme;
_window.Styles[0] = CurrentTheme switch
{
Theme.Citrus => _citrusStyle,
Theme.Sea => _seaStyle,
Theme.Rust => _rustStyle,
Theme.Candy => _candyStyle,
Theme.Magma => _magmaStyle,
_ => throw new ArgumentOutOfRangeException(nameof(theme))
};
}
}
}
}

Просмотреть файл

@ -1,17 +1,8 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:Camelotia.Presentation.Avalonia.Views"
x:Class="Camelotia.Presentation.Avalonia.Views.AuthView"
xmlns:designTime="clr-namespace:Camelotia.Presentation.DesignTime;assembly=Camelotia.Presentation">
<Design.DataContext>
<designTime:DesignTimeAuthViewModel />
</Design.DataContext>
<Carousel Name="AuthTabs">
<Carousel.PageTransition>
<PageSlide Duration="0.25" Orientation="Vertical" />
</Carousel.PageTransition>
<views:DirectAuthView DataContext="{Binding DirectAuth}" />
<views:OAuthView DataContext="{Binding OAuth}" />
<views:HostAuthView DataContext="{Binding HostAuth}" />
</Carousel>
</UserControl>
</UserControl>

Просмотреть файл

@ -1,7 +1,7 @@
using System;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using Avalonia.Controls;
using Avalonia.Layout;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
using Camelotia.Presentation.Interfaces;
@ -16,21 +16,28 @@ namespace Camelotia.Presentation.Avalonia.Views
AvaloniaXamlLoader.Load(this);
this.WhenActivated(disposables =>
{
this.WhenAnyValue(x => x.ViewModel.SupportsDirectAuth)
.Where(supports => supports)
.Subscribe(supports => AuthTabs.SelectedIndex = 0)
.DisposeWith(disposables);
this.WhenAnyValue(x => x.ViewModel.SupportsOAuth)
.Where(supports => supports)
.Subscribe(supports => AuthTabs.SelectedIndex = 1)
.DisposeWith(disposables);
this.WhenAnyValue(x => x.ViewModel.SupportsHostAuth)
.Where(supports => supports)
.Subscribe(supports => AuthTabs.SelectedIndex = 2)
this.WhenAnyValue(x => x.ViewModel)
.Where(context => context != null)
.Select(ResolveControl)
.BindTo(this, x => x.Content)
.DisposeWith(disposables);
});
}
private static IControl ResolveControl(IAuthViewModel context)
{
if (context.SupportsDirectAuth)
return new DirectAuthView { DataContext = context.DirectAuth };
if (context.SupportsOAuth)
return new OAuthView { DataContext = context.OAuth };
if (context.SupportsHostAuth)
return new HostAuthView { DataContext = context.HostAuth };
return new TextBlock
{
Text = "No supported authentication method found.",
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
}
}
}

Просмотреть файл

@ -31,11 +31,7 @@
</StackPanel>
<TextBlock Text="Please, enter new folder name:" Margin="0 5" />
<TextBox Watermark="Folder name..." Text="{Binding Name, Mode=TwoWay}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Grid ColumnDefinitions="3*,2*">
<Button Grid.Column="0"
Content="Create folder"
HorizontalAlignment="Stretch"
@ -48,4 +44,4 @@
Margin="0 10" />
</Grid>
</StackPanel>
</UserControl>
</UserControl>

Просмотреть файл

@ -27,13 +27,22 @@
</StackPanel>
<TextBlock Text="Please, enter your user name:" Margin="0 5" />
<TextBox Watermark="User name..." Text="{Binding Username, Mode=TwoWay}" />
<TextBlock x:Name="UsernameValidation"
Foreground="{DynamicResource ErrorBrush}"
TextWrapping="Wrap" />
<TextBlock Text="Please, enter your password:" Margin="0 5" />
<TextBox Text="{Binding Password, Mode=TwoWay}"
Watermark="Password..."
PasswordChar="*" />
<TextBlock x:Name="PasswordValidation"
Foreground="{DynamicResource ErrorBrush}"
TextWrapping="Wrap" />
<Button Content="Login"
HorizontalAlignment="Stretch"
Command="{Binding Login}"
Margin="0 10" />
<TextBlock x:Name="FormValidation"
Foreground="{DynamicResource ErrorBrush}"
TextWrapping="Wrap" />
</StackPanel>
</UserControl>
</UserControl>

Просмотреть файл

@ -1,7 +1,9 @@
using System.Reactive.Disposables;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
using Camelotia.Presentation.Interfaces;
using ReactiveUI;
using ReactiveUI.Validation.Extensions;
namespace Camelotia.Presentation.Avalonia.Views
{
@ -10,7 +12,15 @@ namespace Camelotia.Presentation.Avalonia.Views
public DirectAuthView()
{
AvaloniaXamlLoader.Load(this);
this.WhenActivated(disposables => { });
this.WhenActivated(disposables =>
{
this.BindValidation(ViewModel, x => x.Username, x => x.UsernameValidation.Text)
.DisposeWith(disposables);
this.BindValidation(ViewModel, x => x.Password, x => x.PasswordValidation.Text)
.DisposeWith(disposables);
this.BindValidation(ViewModel, x => x.FormValidation.Text)
.DisposeWith(disposables);
});
}
}
}

Просмотреть файл

@ -15,14 +15,7 @@
<MenuItem Header="Unselect" Command="{Binding Provider.UnselectFile}" />
</ContextMenu>
</UserControl.ContextMenu>
<Grid Margin="10 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Grid Margin="10 0" ColumnDefinitions="Auto,3*,1*,1*,2*">
<DrawingPresenter Grid.Column="0"
IsVisible="{Binding IsFolder}"
Width="16"
@ -55,4 +48,4 @@
VerticalAlignment="Center"
Text="{Binding Modified}" />
</Grid>
</UserControl>
</UserControl>

Просмотреть файл

@ -27,8 +27,7 @@ namespace Camelotia.Presentation.Avalonia.Views
this.ContextMenu
.Events()
.ContextMenuOpening
.Do(args => args.Cancel = false)
.MenuOpened
.Subscribe(args => ViewModel.Provider.SelectedFile = ViewModel)
.DisposeWith(disposables);
});

Просмотреть файл

@ -57,5 +57,4 @@
</StackPanel>
</Button>
</Grid>
</UserControl>
</UserControl>

Просмотреть файл

@ -1,6 +1,5 @@
using System.Reactive.Disposables;
using System.Reactive.Linq;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
using Camelotia.Presentation.Interfaces;

Просмотреть файл

@ -26,23 +26,34 @@
Margin="10" />
</StackPanel>
<TextBlock Text="Please, enter host address with port:" Margin="0 5" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Grid ColumnDefinitions="3*,2*">
<TextBox Grid.Column="0" Watermark="Address..." Text="{Binding Address, Mode=TwoWay}" />
<TextBox Grid.Column="1" Watermark="Port..." Text="{Binding Port, Mode=TwoWay}" Margin="10 5 0 5"/>
</Grid>
<TextBlock x:Name="AddressValidation"
Foreground="{DynamicResource ErrorBrush}"
TextWrapping="Wrap" />
<TextBlock x:Name="PortValidation"
Foreground="{DynamicResource ErrorBrush}"
TextWrapping="Wrap" />
<TextBlock Text="Please, enter your user name:" Margin="0 5" />
<TextBox Watermark="User name..." Text="{Binding Username, Mode=TwoWay}" />
<TextBlock x:Name="UsernameValidation"
Foreground="{DynamicResource ErrorBrush}"
TextWrapping="Wrap" />
<TextBlock Text="Please, enter your password:" Margin="0 5" />
<TextBox Text="{Binding Password, Mode=TwoWay}"
Watermark="Password..."
PasswordChar="*" />
<TextBlock x:Name="PasswordValidation"
Foreground="{DynamicResource ErrorBrush}"
TextWrapping="Wrap" />
<Button Content="Login"
HorizontalAlignment="Stretch"
Command="{Binding Login}"
Margin="0 10" />
<TextBlock x:Name="FormValidation"
Foreground="{DynamicResource ErrorBrush}"
TextWrapping="Wrap" />
</StackPanel>
</UserControl>
</UserControl>

Просмотреть файл

@ -1,7 +1,9 @@
using System.Reactive.Disposables;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
using Camelotia.Presentation.Interfaces;
using ReactiveUI;
using ReactiveUI.Validation.Extensions;
namespace Camelotia.Presentation.Avalonia.Views
{
@ -10,7 +12,19 @@ namespace Camelotia.Presentation.Avalonia.Views
public HostAuthView()
{
AvaloniaXamlLoader.Load(this);
this.WhenActivated(disposables => { });
this.WhenActivated(disposables =>
{
this.BindValidation(ViewModel, x => x.Address, x => x.AddressValidation.Text)
.DisposeWith(disposables);
this.BindValidation(ViewModel, x => x.Port, x => x.PortValidation.Text)
.DisposeWith(disposables);
this.BindValidation(ViewModel, x => x.Username, x => x.UsernameValidation.Text)
.DisposeWith(disposables);
this.BindValidation(ViewModel, x => x.Password, x => x.PasswordValidation.Text)
.DisposeWith(disposables);
this.BindValidation(ViewModel, x => x.FormValidation.Text)
.DisposeWith(disposables);
});
}
}
}

Просмотреть файл

@ -1,16 +1,18 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:interfaces="clr-namespace:Camelotia.Presentation.Interfaces;assembly=Camelotia.Presentation"
xmlns:views="clr-namespace:Camelotia.Presentation.Avalonia.Views"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:designTime="clr-namespace:Camelotia.Presentation.DesignTime;assembly=Camelotia.Presentation"
x:Class="Camelotia.Presentation.Avalonia.Views.MainView"
MinHeight="590" MinWidth="850"
Height="590" Width="850"
FontFamily="Ubuntu">
<UserControl
xmlns="https://github.com/avaloniaui"
xmlns:interfaces="clr-namespace:Camelotia.Presentation.Interfaces;assembly=Camelotia.Presentation"
xmlns:views="clr-namespace:Camelotia.Presentation.Avalonia.Views"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:designTime="clr-namespace:Camelotia.Presentation.DesignTime;assembly=Camelotia.Presentation"
xmlns:reactiveUi="http://reactiveui.net"
x:Class="Camelotia.Presentation.Avalonia.Views.MainView"
MinHeight="590" MinWidth="850"
Height="590" Width="850"
FontFamily="Ubuntu">
<Design.DataContext>
<designTime:DesignTimeMainViewModel />
</Design.DataContext>
<Window.Styles>
<UserControl.Styles>
<!-- The first StyleInclude here will be replaced at runtime,
see Services/AvaloniaStyleManager.cs for more info. Other
styles will override any styles defined before them. -->
@ -23,19 +25,9 @@
<Setter Property="Margin" Value="0" />
<Setter Property="Padding" Value="0" />
</Style>
</Window.Styles>
<Grid Background="{DynamicResource ThemeBackgroundBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
</UserControl.Styles>
<Grid Background="{DynamicResource ThemeBackgroundBrush}" ColumnDefinitions="1*,2*">
<Grid Grid.Column="0" RowDefinitions="Auto,Auto,*,Auto">
<StackPanel Grid.Row="0" Orientation="Horizontal">
<DrawingPresenter VerticalAlignment="Top"
Margin="20 10 0 0"
@ -47,11 +39,7 @@
Margin="15 14 15 10"
FontSize="17" />
</StackPanel>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid Grid.Row="1" ColumnDefinitions="*,Auto">
<ComboBox Grid.Column="0"
Margin="12 6 12 12"
Items="{Binding SupportedTypes, Mode=OneWay}"
@ -95,11 +83,7 @@
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Grid Grid.Row="3" Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Row="3" Margin="5" ColumnDefinitions="*,*">
<Button Grid.Column="0"
HorizontalAlignment="Stretch"
Command="{Binding Remove}"
@ -116,18 +100,14 @@
IsVisible="{Binding IsLoading}" />
</Grid>
<Grid Grid.Column="1">
<Carousel Items="{Binding Clouds, Mode=OneWay}"
IsVisible="{Binding WelcomeScreenCollapsed, Mode=OneWay}"
SelectedItem="{Binding SelectedProvider, Mode=OneWay}">
<Carousel.PageTransition>
<reactiveUi:TransitioningContentControl IsVisible="{Binding WelcomeScreenCollapsed, Mode=OneWay}">
<reactiveUi:TransitioningContentControl.PageTransition>
<CrossFade Duration="0.75" />
</Carousel.PageTransition>
<Carousel.DataTemplates>
<DataTemplate DataType="interfaces:ICloudViewModel">
<views:ProviderView DataContext="{Binding}" />
</DataTemplate>
</Carousel.DataTemplates>
</Carousel>
</reactiveUi:TransitioningContentControl.PageTransition>
<reactiveUi:TransitioningContentControl.Content>
<views:ProviderView DataContext="{Binding SelectedProvider, Mode=OneWay}" />
</reactiveUi:TransitioningContentControl.Content>
</reactiveUi:TransitioningContentControl>
<Grid IsVisible="{Binding WelcomeScreenVisible, Mode=OneWay}"
Background="{DynamicResource ThemeCardBrush}">
<StackPanel HorizontalAlignment="Center"
@ -138,4 +118,4 @@
</Grid>
</Grid>
</Grid>
</Window>
</UserControl>

Просмотреть файл

@ -5,7 +5,7 @@ using ReactiveUI;
namespace Camelotia.Presentation.Avalonia.Views
{
public sealed partial class MainView : ReactiveWindow<IMainViewModel>
public sealed partial class MainView : ReactiveUserControl<IMainViewModel>
{
public MainView()
{

Просмотреть файл

@ -38,23 +38,12 @@
</Style>
</UserControl.Styles>
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0"
Command="{Binding Back}"
ToolTip.Tip="Back"
Classes="Primary">
<Grid RowDefinitions="Auto,*,Auto,Auto">
<Grid Grid.Row="0" Margin="5" ColumnDefinitions="Auto,*,Auto">
<Button Grid.Column="0"
Command="{Binding Back}"
ToolTip.Tip="Back"
Classes="Primary">
<DrawingPresenter Height="16" Drawing="{DynamicResource ArrowUp}"/>
</Button>
<TextBlock Grid.Column="1"
@ -133,14 +122,7 @@
</Grid>
</Grid>
</Border>
<Grid Grid.Row="2" Margin="5 5 5 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Row="2" Margin="5 5 5 0" ColumnDefinitions="*,*,2*,*,*">
<Button Grid.Column="0"
Content="Delete"
Classes="Primary"
@ -167,14 +149,7 @@
HorizontalAlignment="Stretch"
Command="{Binding DownloadSelectedFile}" />
</Grid>
<Grid Grid.Row="3" Margin="5 0 5 5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Row="3" Margin="5 0 5 5" ColumnDefinitions="*,*,2*,*,*">
<Button Grid.Column="0"
Content="Logout"
Classes="Primary"

Просмотреть файл

@ -31,11 +31,7 @@
</StackPanel>
<TextBlock Text="Please, enter new file name:" Margin="0 5" />
<TextBox Text="{Binding NewName, Mode=TwoWay}" Watermark="File name..." />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Grid ColumnDefinitions="3*,2*">
<Button Grid.Column="0"
Content="Rename file"
HorizontalAlignment="Stretch"
@ -48,4 +44,4 @@
Margin="0 10" />
</Grid>
</StackPanel>
</UserControl>
</UserControl>

Просмотреть файл

@ -209,10 +209,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.2.11</Version>
<Version>6.2.12</Version>
</PackageReference>
<PackageReference Include="ReactiveUI.Events">
<Version>13.0.27</Version>
<Version>13.1.1</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -6,13 +6,13 @@
<UseWpf>true</UseWpf>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="akavache" Version="7.1.1" />
<PackageReference Include="akavache" Version="7.2.1" />
<PackageReference Include="MahApps.Metro" Version="2.4.3" />
<PackageReference Include="MaterialDesignColors" Version="1.2.7" />
<PackageReference Include="MaterialDesignThemes" Version="3.2.0" />
<PackageReference Include="MaterialDesignThemes.MahApps" Version="0.1.5" />
<PackageReference Include="ReactiveUI.Events.WPF" Version="13.0.27" />
<PackageReference Include="ReactiveUI.WPF" Version="13.0.27" />
<PackageReference Include="MaterialDesignColors" Version="2.0.0" />
<PackageReference Include="MaterialDesignThemes" Version="4.0.0" />
<PackageReference Include="MaterialDesignThemes.MahApps" Version="0.1.6" />
<PackageReference Include="ReactiveUI.Events.WPF" Version="13.1.1" />
<PackageReference Include="ReactiveUI.WPF" Version="13.1.1" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.0.4" />
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -56,9 +56,9 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Reactive" Version="4.4.1" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.7.1" />
<PackageReference Include="Xamarin.Forms" Version="4.8.0.1560" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="5.0.0" />
<PackageReference Include="Xamarin.Forms" Version="4.8.0.1821" />
<PackageReference Include="Xamarin.Android.Support.v7.Preference" Version="28.0.0.3" />
<PackageReference Include="Xamarin.Android.Support.Media.Compat" Version="28.0.0.3" />
<PackageReference Include="Xamarin.Android.Support.Fragment" Version="28.0.0.3" />
@ -71,9 +71,9 @@
<PackageReference Include="Xamarin.Android.Support.v7.CardView" Version="28.0.0.3" />
<PackageReference Include="Xamarin.Android.Support.v7.MediaRouter" Version="28.0.0.3" />
<PackageReference Include="Xamarin.Plugin.FilePicker" Version="2.1.41" />
<PackageReference Include="Xamarin.AndroidX.MediaRouter" Version="1.2.0.1" />
<PackageReference Include="Xamarin.AndroidX.MediaRouter" Version="1.2.2" />
<PackageReference Include="Xamarin.AndroidX.Palette" Version="1.0.0.6" />
<PackageReference Include="Xamarin.AndroidX.Preference" Version="1.1.1.6" />
<PackageReference Include="Xamarin.AndroidX.Preference" Version="1.1.1.7" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Threading.Tasks.Extensions">

Просмотреть файл

@ -58,10 +58,11 @@ namespace Camelotia.Presentation.Xamarin.Droid.Services
{
_activity.RequestPermissions(
new string[]
{
Manifest.Permission.ReadExternalStorage,
Manifest.Permission.WriteExternalStorage
}, 1);
{
Manifest.Permission.ReadExternalStorage,
Manifest.Permission.WriteExternalStorage
},
1);
}
}
}

Просмотреть файл

@ -10,8 +10,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ReactiveUI.XamForms" Version="13.0.27" />
<PackageReference Include="ReactiveUI.Events.XamForms" Version="13.0.27" />
<PackageReference Include="ReactiveUI.XamForms" Version="13.1.1" />
<PackageReference Include="ReactiveUI.Events.XamForms" Version="13.1.1" />
<PackageReference Include="Xamarin.Forms" Version="4.8.0.1821" />
<PackageReference Include="Xam.Plugin.Iconize" Version="3.5.0.112" />
<PackageReference Include="Xam.Plugin.Iconize.FontAwesome" Version="3.5.0.112" />

Просмотреть файл

@ -10,9 +10,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ReactiveUI" Version="13.0.27" />
<PackageReference Include="ReactiveUI.Fody" Version="13.0.27" />
<PackageReference Include="ReactiveUI.Validation" Version="2.0.1" />
<PackageReference Include="ReactiveUI" Version="13.1.1" />
<PackageReference Include="ReactiveUI.Fody" Version="13.1.1" />
<PackageReference Include="ReactiveUI.Validation" Version="2.1.1" />
</ItemGroup>
</Project>

Просмотреть файл

@ -28,7 +28,6 @@ namespace Camelotia.Presentation.ViewModels
private readonly ObservableAsPropertyHelper<bool> _hideBreadCrumbs;
private readonly ObservableAsPropertyHelper<string> _currentPath;
private readonly ObservableAsPropertyHelper<bool> _canInteract;
private readonly ObservableAsPropertyHelper<bool> _canInteractAuthenticated;
private readonly ObservableAsPropertyHelper<bool> _isLoading;
private readonly ObservableAsPropertyHelper<bool> _canLogout;
private readonly ObservableAsPropertyHelper<bool> _isReady;
@ -58,19 +57,16 @@ namespace Camelotia.Presentation.ViewModels
_canInteract = canInteract
.ToProperty(this, x => x.CanInteract);
var canInteractAuthenticated = this
var canRefresh = this
.WhenAnyValue(
x => x.Folder.IsVisible,
x => x.Rename.IsVisible,
x => x.Auth.IsAuthenticated,
(folder, rename, auth) => !folder && !rename && auth);
_canInteractAuthenticated = canInteractAuthenticated
.ToProperty(this, x => x.CanInteractAuthenticated);
(folder, rename, authenticated) => !folder && !rename && authenticated);
Refresh = ReactiveCommand.CreateFromTask(
() => cloud.GetFiles(CurrentPath),
canInteractAuthenticated);
canRefresh);
_files = Refresh
.Select(
@ -281,8 +277,6 @@ namespace Camelotia.Presentation.ViewModels
public bool CanInteract => _canInteract?.Value ?? false;
public bool CanInteractAuthenticated => _canInteractAuthenticated?.Value ?? false;
public IAuthViewModel Auth { get; }
public IRenameFileViewModel Rename { get; }

Просмотреть файл

@ -131,4 +131,4 @@ namespace Camelotia.Presentation.ViewModels
public bool IsReady => _isReady.Value;
}
}
}

Просмотреть файл

@ -7,13 +7,13 @@
<ItemGroup>
<PackageReference Include="DynamicData" Version="7.1.1" />
<PackageReference Include="akavache" Version="7.1.1" />
<PackageReference Include="akavache" Version="7.2.1" />
<PackageReference Include="FluentFTP" Version="33.0.3" />
<PackageReference Include="Google.Apis.Drive.v3" Version="1.49.0.2166" />
<PackageReference Include="Octokit" Version="0.48.0" />
<PackageReference Include="ssh.net" Version="2020.0.0-beta1" />
<PackageReference Include="Google.Apis.Drive.v3" Version="1.50.0.2236" />
<PackageReference Include="Octokit" Version="0.50.0" />
<PackageReference Include="ssh.net" Version="2020.0.1" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
<PackageReference Include="VkNet" Version="1.58.0" />
<PackageReference Include="VkNet" Version="1.60.0" />
</ItemGroup>
</Project>

Просмотреть файл

@ -4,13 +4,13 @@
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.msbuild" Version="2.9.0">
<PackageReference Include="coverlet.msbuild" Version="3.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" Version="5.10.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="ReactiveUI.Testing" Version="13.0.27" />
<PackageReference Include="ReactiveUI.Testing" Version="13.1.1" />
<PackageReference Include="NSubstitute" Version="4.2.2" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">

Просмотреть файл

@ -6,12 +6,11 @@
<None Include="$(MSBuildThisFileDirectory)..\LICENSE" Pack="true" PackagePath="LICENSE" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="stylecop.analyzers" Version="1.2.0-beta.205" PrivateAssets="all" />
<PackageReference Include="Roslynator.Analyzers" Version="3.0.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0" PrivateAssets="all" />
<PackageReference Include="stylecop.analyzers" Version="1.2.0-beta.321" PrivateAssets="all" />
<PackageReference Include="Roslynator.Analyzers" Version="3.1.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.3" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="$(MSBuildThisFileDirectory)stylecop.json" Link="stylecop.json" />
</ItemGroup>
</Project>