Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: Add stylecop and Roslynator, Configurable Tokens #46

Merged
merged 8 commits into from
Jan 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
450 changes: 450 additions & 0 deletions .editorconfig

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions build/Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal class Build : NukeBuild
const string CoverageFileName = "coverage.cobertura.xml";

public static int Main() => Execute<Build>(x => x.RunInteractive);

[Parameter] readonly string Configuration = IsLocalBuild ? "Debug" : "Release";
[Parameter] readonly bool Interactive;
[Parameter] readonly bool Full;
Expand All @@ -35,7 +35,7 @@ internal class Build : NukeBuild
.GlobDirectories("**/bin", "**/obj", "**/AppPackages", "**/BundleArtifacts")
.Concat(RootDirectory.GlobDirectories("**/artifacts"))
.ForEach(DeleteDirectory));

Target RunUnitTests => _ => _
.DependsOn(Clean)
.Executes(() => SourceDirectory
Expand Down Expand Up @@ -171,7 +171,7 @@ void BuildApp(MSBuildTargetPlatform platform)
.Executes(() => SourceDirectory
.GlobFiles($"**/{InteractiveProjectName}.csproj")
.Where(x => Interactive)
.ForEach(path =>
.ForEach(path =>
DotNetRun(settings => settings
.SetProjectFile(path)
.SetConfiguration(Configuration)
Expand Down
8 changes: 8 additions & 0 deletions src/Camelotia.Avalonia.sln
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Camelotia.Tests", "Cameloti
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "build", "..\build\build.csproj", "{8550B110-E789-4117-B9D3-7503D3C3B364}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3465E22A-2B94-448B-BF5E-37E464BF62D5}"
ProjectSection(SolutionItems) = preProject
..\.editorconfig = ..\.editorconfig
..\.gitignore = ..\.gitignore
Directory.build.props = Directory.build.props
stylecop.json = stylecop.json
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down
29 changes: 14 additions & 15 deletions src/Camelotia.Presentation.Avalonia/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using Avalonia;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
using Camelotia.Presentation.AppState;
using Camelotia.Presentation.Avalonia.Services;
using Camelotia.Presentation.Avalonia.Views;
using Camelotia.Presentation.ViewModels;
using Camelotia.Presentation.AppState;
using Camelotia.Presentation.Infrastructure;
using Camelotia.Presentation.ViewModels;
using Camelotia.Services;
using ReactiveUI;

Expand All @@ -23,20 +23,22 @@ public override void OnFrameworkInitializationCompleted()
RxApp.SuspensionHost.SetupDefaultSuspendResume(new NewtonsoftJsonSuspensionDriver("appstate.json"));
suspension.OnFrameworkInitializationCompleted();
base.OnFrameworkInitializationCompleted();

// Configure app dependencies.
var window = new MainView();
var styles = new AvaloniaStyleManager(window);
var mainState = RxApp.SuspensionHost.GetAppState<MainState>();

Akavache.BlobCache.ApplicationName = "CamelotiaV2";
window.SwitchThemeButton.Click += (sender, args) => styles.UseNextTheme();
window.DataContext = new MainViewModel(
RxApp.SuspensionHost.GetAppState<MainState>(),
mainState,
new CloudFactory(
new AvaloniaYandexAuthenticator(),
Akavache.BlobCache.UserAccount
),
(state, provider) => new CloudViewModel(state,
mainState.CloudConfiguration,
new AvaloniaYandexAuthenticator(),
Akavache.BlobCache.UserAccount),
(state, provider) => new CloudViewModel(
state,
owner => new CreateFolderViewModel(state.CreateFolderState, owner, provider),
owner => new RenameFileViewModel(state.RenameFileState, owner, provider),
(file, owner) => new FileViewModel(owner, file),
Expand All @@ -45,14 +47,11 @@ public override void OnFrameworkInitializationCompleted()
new DirectAuthViewModel(state.AuthState.DirectAuthState, provider),
new HostAuthViewModel(state.AuthState.HostAuthState, provider),
new OAuthViewModel(provider),
provider
),
provider),
new AvaloniaFileManager(window),
provider
)
);

provider));

window.Show();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ public sealed class AvaloniaFileManager : IFileManager
public async Task<Stream> OpenWrite(string name)
{
var fileDialog = new OpenFolderDialog();
var folder = await fileDialog.ShowAsync(_window);
var folder = await fileDialog.ShowAsync(_window).ConfigureAwait(false);
var path = Path.Combine(folder, name);
return File.Create(path);
}

public async Task<(string Name, Stream Stream)> OpenRead()
{
var fileDialog = new OpenFileDialog {AllowMultiple = false};
var files = await fileDialog.ShowAsync(_window);
var fileDialog = new OpenFileDialog { AllowMultiple = false };
var files = await fileDialog.ShowAsync(_window).ConfigureAwait(false);
var path = files.First();

var attributes = File.GetAttributes(path);
var isFolder = attributes.HasFlag(FileAttributes.Directory);
if (isFolder) throw new Exception("Folders are not supported.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@

namespace Camelotia.Presentation.Avalonia.Services
{
// Borrowed from https://github.com/worldbeater/citrus.avalonia
public sealed class AvaloniaStyleManager
{
public enum Theme { Citrus, Sea, Rust, Candy, Magma }

public enum Theme
{
Citrus,
Sea,
Rust,
Candy,
Magma
}

private readonly StyleInclude _magmaStyle = CreateStyle("avares://Citrus.Avalonia/Magma.xaml");
private readonly StyleInclude _candyStyle = CreateStyle("avares://Citrus.Avalonia/Candy.xaml");
private readonly StyleInclude _citrusStyle = CreateStyle("avares://Citrus.Avalonia/Citrus.xaml");
Expand All @@ -19,20 +25,20 @@ public enum Theme { Citrus, Sea, Rust, Candy, Magma }
public AvaloniaStyleManager(Window window)
{
_window = window;

// We add the style to the window styles section, so it
// will override the default style defined in App.xaml.
// 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
Expand All @@ -47,7 +53,7 @@ public void UseTheme(Theme theme)
Theme.Magma => _magmaStyle,
_ => throw new ArgumentOutOfRangeException(nameof(theme))
};

CurrentTheme = theme;
}

Expand All @@ -65,7 +71,7 @@ public void UseNextTheme()
_ => throw new ArgumentOutOfRangeException(nameof(CurrentTheme))
});
}

private static StyleInclude CreateStyle(string url)
{
var self = new Uri("resm:Styles?assembly=Citrus.Avalonia.Sandbox");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ public async Task<string> ReceiveCode(Uri uri, Uri returnUrl)
}
.Start();

var context = await listener.GetContextAsync();
var context = await listener.GetContextAsync().ConfigureAwait(false);
var code = context.Request.QueryString["code"];

var buffer = Encoding.UTF8.GetBytes(SuccessContent);
context.Response.ContentLength64 = buffer.Length;
await context.Response.OutputStream.WriteAsync(buffer, 0, buffer.Length);
await context.Response.OutputStream.WriteAsync(buffer, 0, buffer.Length).ConfigureAwait(false);

context.Response.Close();
listener.Close();
Expand Down
4 changes: 2 additions & 2 deletions src/Camelotia.Presentation.Avalonia/Views/AuthView.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using Camelotia.Presentation.Interfaces;
using System;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
using Camelotia.Presentation.Interfaces;
using ReactiveUI;

namespace Camelotia.Presentation.Avalonia.Views
Expand Down
10 changes: 4 additions & 6 deletions src/Camelotia.Presentation.Avalonia/Views/FolderView.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
using System;
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Avalonia.ReactiveUI;
using Camelotia.Presentation.Interfaces;
using ReactiveUI;
Expand All @@ -15,22 +11,24 @@ namespace Camelotia.Presentation.Avalonia.Views
public sealed class FolderView : ReactiveUserControl<IFolderViewModel>
{
private MenuItem TopLevelMenu => this.FindControl<MenuItem>("TopLevelMenu");

private DrawingPresenter ArrowRight => this.FindControl<DrawingPresenter>("ArrowRight");

private DrawingPresenter ArrowDown => this.FindControl<DrawingPresenter>("ArrowDown");

public FolderView()
{
AvaloniaXamlLoader.Load(this);
this.WhenActivated(disposables =>
{
{
this.WhenAnyValue(x => x.TopLevelMenu.IsSubMenuOpen)
.BindTo(this, x => x.ArrowDown.IsVisible)
.DisposeWith(disposables);

this.WhenAnyValue(x => x.TopLevelMenu.IsSubMenuOpen)
.Select(menuOpen => !menuOpen)
.BindTo(this, x => x.ArrowRight.IsVisible)
.DisposeWith(disposables);
.DisposeWith(disposables);
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Camelotia.Presentation.Avalonia/Views/MainView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Camelotia.Presentation.Avalonia.Views
public sealed class MainView : ReactiveWindow<IMainViewModel>
{
public Button SwitchThemeButton => this.FindControl<Button>("SwitchThemeButton");

public MainView()
{
this.WhenActivated(disposables => { });
Expand Down
14 changes: 7 additions & 7 deletions src/Camelotia.Presentation.Uwp/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
using System;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Camelotia.Presentation.Uwp.Views;
using Camelotia.Presentation.AppState;
using Camelotia.Presentation.Infrastructure;
using Camelotia.Presentation.Uwp.Views;
using ReactiveUI;
using Windows.ApplicationModel.Activation;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace Camelotia.Presentation.Uwp
{
sealed partial class App : Application
public sealed partial class App : Application
{
public App() => InitializeComponent();

Expand Down Expand Up @@ -41,7 +41,7 @@ protected override async void OnLaunched(LaunchActivatedEventArgs e)
}
}

void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
private void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
Expand Down
34 changes: 20 additions & 14 deletions src/Camelotia.Presentation.Uwp/Bootstrapper.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
using Camelotia.Presentation.Interfaces;
using Camelotia.Presentation.AppState;
using Camelotia.Presentation.Interfaces;
using Camelotia.Presentation.Uwp.Services;
using Camelotia.Presentation.ViewModels;
using Camelotia.Services;
using Camelotia.Services.Models;
using ReactiveUI;
using Camelotia.Services;
using Camelotia.Presentation.AppState;

namespace Camelotia.Presentation.Uwp
{
public sealed class Bootstrapper
{
public static IMainViewModel BuildMainViewModel()
{
var mainState = RxApp.SuspensionHost.GetAppState<MainState>();
return new MainViewModel(
RxApp.SuspensionHost.GetAppState<MainState>(),
mainState,
new CloudFactory(
new UniversalWindowsYandexAuthenticator(),
mainState.CloudConfiguration,
new UniversalWindowsYandexAuthenticator(),
Akavache.BlobCache.UserAccount,
new[] { CloudType.Yandex, CloudType.VkDocs, CloudType.Ftp, CloudType.Sftp, CloudType.GitHub }
),
(state, provider) => new CloudViewModel(state,
new[]
{
CloudType.Yandex,
CloudType.VkDocs,
CloudType.Ftp,
CloudType.Sftp,
CloudType.GitHub
}),
(state, provider) => new CloudViewModel(
state,
owner => new CreateFolderViewModel(state.CreateFolderState, owner, provider),
owner => new RenameFileViewModel(state.RenameFileState, owner, provider),
(file, owner) => new FileViewModel(owner, file),
Expand All @@ -28,12 +37,9 @@ public static IMainViewModel BuildMainViewModel()
new DirectAuthViewModel(state.AuthState.DirectAuthState, provider),
new HostAuthViewModel(state.AuthState.HostAuthState, provider),
new OAuthViewModel(provider),
provider
),
new UniversalWindowsFileManager(),
provider
)
);
provider),
new UniversalWindowsFileManager(),
provider));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using Camelotia.Services.Interfaces;
using Windows.Storage.Pickers;
using Windows.Storage;
using System.Threading.Tasks;
using System.IO;
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Camelotia.Services.Interfaces;
using Windows.Storage;
using Windows.Storage.Pickers;

namespace Camelotia.Presentation.Uwp.Services
{
Expand All @@ -16,7 +16,7 @@ public sealed class UniversalWindowsFileManager : IFileManager
picker.FileTypeFilter.Add("*");
var file = await picker.PickSingleFileAsync();
if (file == null) return (null, null);
var stream = await file.OpenStreamForReadAsync();
var stream = await file.OpenStreamForReadAsync().ConfigureAwait(false);
return (file.Name, stream);
}

Expand All @@ -28,7 +28,7 @@ public async Task<Stream> OpenWrite(string name)
var file = await picker.PickSaveFileAsync();
if (file == null) return null;
await FileIO.WriteTextAsync(file, string.Empty);
var stream = await file.OpenStreamForWriteAsync();
var stream = await file.OpenStreamForWriteAsync().ConfigureAwait(false);
return stream;
}
}
Expand Down
Loading