From dc9c327652a21d53bef25535e85a666e069e4783 Mon Sep 17 00:00:00 2001 From: Unnoen Date: Tue, 18 Jan 2022 03:45:52 +1100 Subject: [PATCH] Checkbox and Logger components. Layout changes to Configure page. Also added TODOs and a basic .editorconfig to suppress annoying warnings. --- .editorconfig | 22 +++++ Wabbajack.App.Blazor/.gitignore | 2 +- .../Components/InfoBlock.razor.scss | 3 +- .../Components/InfoImage.razor.scss | 3 +- Wabbajack.App.Blazor/Components/Logger.razor | 5 -- .../Components/ModlistItem.razor.cs | 4 +- .../Components/OptionCheckbox.razor | 25 ++++++ .../Components/OptionCheckbox.razor.scss | 56 +++++++++++++ Wabbajack.App.Blazor/Components/SideBar.razor | 4 +- Wabbajack.App.Blazor/Components/TopBar.razor | 5 +- .../Components/VirtualLogger.razor | 26 ++++++ .../Components/VirtualLogger.razor.scss | 23 ++++++ Wabbajack.App.Blazor/MainWindow.xaml.cs | 4 +- Wabbajack.App.Blazor/Pages/Configure.razor | 82 +++++++++---------- Wabbajack.App.Blazor/Pages/Configure.razor.cs | 15 ++-- .../Pages/Configure.razor.scss | 16 +++- Wabbajack.App.Blazor/Pages/Gallery.razor | 4 +- Wabbajack.App.Blazor/Utility/Dialog.cs | 6 +- Wabbajack.sln | 11 ++- 19 files changed, 241 insertions(+), 75 deletions(-) create mode 100644 .editorconfig delete mode 100644 Wabbajack.App.Blazor/Components/Logger.razor create mode 100644 Wabbajack.App.Blazor/Components/OptionCheckbox.razor create mode 100644 Wabbajack.App.Blazor/Components/OptionCheckbox.razor.scss create mode 100644 Wabbajack.App.Blazor/Components/VirtualLogger.razor create mode 100644 Wabbajack.App.Blazor/Components/VirtualLogger.razor.scss diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..471223b3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,22 @@ +root = true + +# All files +[*] +indent_style = space +indent_size = 4 +insert_final_newline = true + +# C# and Razor files +[*.{cs,razor}] + +# CS8602: Dereference of a possibly null reference. +# CS8618: Non-nullable member is uninitialized. +# Reason: The compiler/IDE doesn't quite understand Dependency Injection yet. +dotnet_diagnostic.CS8602.severity = none +dotnet_diagnostic.CS8618.severity = none + +# RZ10012: Markup element with unexpected name. +# Reason: The component namespace is added to the global _Imports.razor file. +dotnet_diagnostic.RZ10012.severity = none + +dotnet_sort_system_directives_first = true diff --git a/Wabbajack.App.Blazor/.gitignore b/Wabbajack.App.Blazor/.gitignore index 5f282702..69a3b7d7 100644 --- a/Wabbajack.App.Blazor/.gitignore +++ b/Wabbajack.App.Blazor/.gitignore @@ -1 +1 @@ - \ No newline at end of file +.sonarqube \ No newline at end of file diff --git a/Wabbajack.App.Blazor/Components/InfoBlock.razor.scss b/Wabbajack.App.Blazor/Components/InfoBlock.razor.scss index 40d2e27c..bb4a2a8f 100644 --- a/Wabbajack.App.Blazor/Components/InfoBlock.razor.scss +++ b/Wabbajack.App.Blazor/Components/InfoBlock.razor.scss @@ -5,7 +5,6 @@ flex-direction: column; justify-content: center; align-content: center; - margin: 1rem; .supertitle { margin-left: 0.5rem; @@ -36,4 +35,4 @@ margin-top: 0.5rem; color: rgba(255, 255, 255, 0.5); } -} \ No newline at end of file +} diff --git a/Wabbajack.App.Blazor/Components/InfoImage.razor.scss b/Wabbajack.App.Blazor/Components/InfoImage.razor.scss index af93dcf0..d2e9ea57 100644 --- a/Wabbajack.App.Blazor/Components/InfoImage.razor.scss +++ b/Wabbajack.App.Blazor/Components/InfoImage.razor.scss @@ -4,7 +4,6 @@ flex-direction: column; justify-content: center; align-content: center; - margin: 1rem; .mod-feature { margin-left: -10px; @@ -37,4 +36,4 @@ margin-left: 1rem; color: rgba(255, 255, 255, 0.75); } -} \ No newline at end of file +} diff --git a/Wabbajack.App.Blazor/Components/Logger.razor b/Wabbajack.App.Blazor/Components/Logger.razor deleted file mode 100644 index 3269d963..00000000 --- a/Wabbajack.App.Blazor/Components/Logger.razor +++ /dev/null @@ -1,5 +0,0 @@ -

Logger

- -@code { - -} \ No newline at end of file diff --git a/Wabbajack.App.Blazor/Components/ModlistItem.razor.cs b/Wabbajack.App.Blazor/Components/ModlistItem.razor.cs index b2d8f146..e1646b6d 100644 --- a/Wabbajack.App.Blazor/Components/ModlistItem.razor.cs +++ b/Wabbajack.App.Blazor/Components/ModlistItem.razor.cs @@ -14,7 +14,7 @@ using Wabbajack.Paths.IO; using Wabbajack.RateLimiter; using Wabbajack.Services.OSIntegrated.Services; - +// TODO: [High] Move logic to Gallery page. namespace Wabbajack.App.Blazor.Components { public partial class ModlistItem @@ -61,4 +61,4 @@ namespace Wabbajack.App.Blazor.Components private void UpdateDownloadState(DownloadState.DownloadStateEnum state, ModlistMetadata metadata) => _dispatcher.Dispatch(new UpdateDownloadState(state, metadata)); } -} \ No newline at end of file +} diff --git a/Wabbajack.App.Blazor/Components/OptionCheckbox.razor b/Wabbajack.App.Blazor/Components/OptionCheckbox.razor new file mode 100644 index 00000000..2a07944a --- /dev/null +++ b/Wabbajack.App.Blazor/Components/OptionCheckbox.razor @@ -0,0 +1,25 @@ + + +@code { + // TODO: [Low] Implement parameters to customize style. + // TODO: [High] Implement a way to set a passed bool without using callback function. + + [Parameter] + public string Label { get; set; } + + [Parameter] + public EventCallback OnChecked { get; set; } + + private bool IsChecked { get; set; } + + private async Task CheckBoxChanged(ChangeEventArgs e) + { + IsChecked = (bool)(e.Value ?? false); + await OnChecked.InvokeAsync(IsChecked); + } + +} diff --git a/Wabbajack.App.Blazor/Components/OptionCheckbox.razor.scss b/Wabbajack.App.Blazor/Components/OptionCheckbox.razor.scss new file mode 100644 index 00000000..71e9ba1d --- /dev/null +++ b/Wabbajack.App.Blazor/Components/OptionCheckbox.razor.scss @@ -0,0 +1,56 @@ +@import "../Shared/Globals.scss"; +$checkbox-background: rgba(255, 255, 255, 0.2); +$checkbox-background-hover: darkgrey; +$checkbox-background-checked: $accent-color; +$checkbox-size: 0.75rem; + +.option { + position: relative; + display: block; + margin: 0.25rem; + padding-left: 2rem; + cursor: pointer; + user-select: none; + + &:hover input ~ .checkmark { + background-color: $checkbox-background-hover; + } + + input { + position: absolute; + opacity: 0; + cursor: pointer; + height: 0; + width: 0; + + &:checked ~ .checkmark { + background-color: $checkbox-background-checked; + + &:after { + display: block; + left: calc(0.5 * #{$checkbox-size}); + top: calc(0.25 * #{$checkbox-size}); + width: calc(0.25 * #{$checkbox-size}); + height: calc(0.65 * #{$checkbox-size}); + border: solid white; + border-width: 0 3px 3px 0; + transform: rotate(45deg); + } + } + } + + .checkmark { + position: absolute; + top: 0; + left: 0; + height: calc(1.5 * #{$checkbox-size}); + width: calc(1.5 * #{$checkbox-size}); + background-color: $checkbox-background; + + &:after { + content: ""; + position: absolute; + display: none; + } + } +} diff --git a/Wabbajack.App.Blazor/Components/SideBar.razor b/Wabbajack.App.Blazor/Components/SideBar.razor index d16ebca6..801da8b6 100644 --- a/Wabbajack.App.Blazor/Components/SideBar.razor +++ b/Wabbajack.App.Blazor/Components/SideBar.razor @@ -1,4 +1,5 @@  -@code { - -} \ No newline at end of file diff --git a/Wabbajack.App.Blazor/Components/TopBar.razor b/Wabbajack.App.Blazor/Components/TopBar.razor index 99e2f387..9924bb3d 100644 --- a/Wabbajack.App.Blazor/Components/TopBar.razor +++ b/Wabbajack.App.Blazor/Components/TopBar.razor @@ -1,4 +1,5 @@ -
+@* TODO: [Low] Indicate current page. *@ +
-
\ No newline at end of file +
diff --git a/Wabbajack.App.Blazor/Components/VirtualLogger.razor b/Wabbajack.App.Blazor/Components/VirtualLogger.razor new file mode 100644 index 00000000..19db2ddc --- /dev/null +++ b/Wabbajack.App.Blazor/Components/VirtualLogger.razor @@ -0,0 +1,26 @@ +@using Wabbajack.App.Blazor.Models + +
+ + @logItem.LongMessage + +
+ +@code { + + // TODO: [Low] More parameters to customise the logger. E.g. Reverse order. + // TODO: [High] Find a way to auto-scroll. (JS interop?) + + [Parameter] + public IObservable Messages { get; set; } + + private List _consoleLog = new(); + + protected override async Task OnInitializedAsync() + { + Messages.Subscribe(_consoleLog.Add); + + await base.OnInitializedAsync(); + } + +} diff --git a/Wabbajack.App.Blazor/Components/VirtualLogger.razor.scss b/Wabbajack.App.Blazor/Components/VirtualLogger.razor.scss new file mode 100644 index 00000000..d7b0a461 --- /dev/null +++ b/Wabbajack.App.Blazor/Components/VirtualLogger.razor.scss @@ -0,0 +1,23 @@ +// TODO: [Low] Logging levels? +#virtual-logger { + height: 100%; + overflow-y: scroll; + width: 100%; + + .info { + } + + .warn { + } + + .error { + } + + span { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 0.85rem; + } +} diff --git a/Wabbajack.App.Blazor/MainWindow.xaml.cs b/Wabbajack.App.Blazor/MainWindow.xaml.cs index 395a3830..44e063a9 100644 --- a/Wabbajack.App.Blazor/MainWindow.xaml.cs +++ b/Wabbajack.App.Blazor/MainWindow.xaml.cs @@ -29,7 +29,7 @@ namespace Wabbajack.App.Blazor try { - // TODO: Not sure how to set this up. + // TODO: [Low] Not sure how to set this up. //_logger.LogInformation("Wabbajack Build - {Sha}", ThisAssembly.Git.Sha); _logger.LogInformation("Running in {EntryPoint}", KnownFolders.EntryPoint); @@ -59,4 +59,4 @@ namespace Wabbajack.App.Blazor // Required so compiler doesn't complain about not finding the type. [MC3050] public partial class Main { } -} \ No newline at end of file +} diff --git a/Wabbajack.App.Blazor/Pages/Configure.razor b/Wabbajack.App.Blazor/Pages/Configure.razor index b3292008..b04b5f70 100644 --- a/Wabbajack.App.Blazor/Pages/Configure.razor +++ b/Wabbajack.App.Blazor/Pages/Configure.razor @@ -3,37 +3,52 @@ @namespace Wabbajack.App.Blazor.Pages
-
+
- @if (!string.IsNullOrEmpty(ModList.Name)) - { - if (_installState.Value.CurrentInstallState != InstallState.InstallStateEnum.Installing) + @* TODO: [High] Find a cleaner way to show/hide components based on state. *@ + @* TODO: [Low] Split each "side" into their own components? *@ +
+ @if (!string.IsNullOrEmpty(ModList.Name)) { - + if (_installState.Value.CurrentInstallState != InstallState.InstallStateEnum.Installing) + { + + } + else if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Installing) + { + + // TODO: [Low] Step logging. + } } - else if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Installing) +
+
+ @if (!string.IsNullOrEmpty(Image)) { - + if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Configuration) + { + + } + else if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Installing) + { + // TODO: [Low] Implement featured mod slideshow. + + } } - } - @if (!string.IsNullOrEmpty(Image)) - { - if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Configuration) - { - - } - else if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Installing) - { - - } - } +
+ @if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Installing) + { +
+ +
+ } @if (_installState.Value.CurrentInstallState != InstallState.InstallStateEnum.Installing) {
+ @* TODO: [High] Turn path selectors into components. *@
Target Modlist Install Location @@ -47,33 +62,14 @@
- - - - - - - + + + +
Browse Gallery
} -
\ No newline at end of file +
diff --git a/Wabbajack.App.Blazor/Pages/Configure.razor.cs b/Wabbajack.App.Blazor/Pages/Configure.razor.cs index 81db5f5f..90c177d5 100644 --- a/Wabbajack.App.Blazor/Pages/Configure.razor.cs +++ b/Wabbajack.App.Blazor/Pages/Configure.razor.cs @@ -2,7 +2,6 @@ using System.Diagnostics; using System.IO; using System.Threading; -using System.Threading.Tasks; using Fluxor; using Microsoft.AspNetCore.Components; using Wabbajack.App.Blazor.Store; @@ -14,6 +13,9 @@ using Wabbajack.App.Blazor.Utility; using Wabbajack.Downloaders.GameFile; using Wabbajack.Hashing.xxHash64; using Wabbajack.Services.OSIntegrated; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Wabbajack.App.Blazor.Models; namespace Wabbajack.App.Blazor.Pages { @@ -27,6 +29,7 @@ namespace Wabbajack.App.Blazor.Pages [Inject] private SystemParametersConstructor _parametersConstructor { get; set; } [Inject] private IGameLocator _gameLocator { get; set; } [Inject] private SettingsManager _settingsManager { get; set; } + [Inject] private LoggerProvider _loggerProvider { get; set; } private string Image { get; set; } private ModList ModList { get; set; } = new(); // Init a new modlist so we can listen for changes in Blazor components. @@ -34,7 +37,8 @@ namespace Wabbajack.App.Blazor.Pages private AbsolutePath InstallPath { get; set; } private AbsolutePath DownloadPath { get; set; } - private string StatusText { get; set; } + private string StatusText { get; set; } + private LoggerProvider.ILogMessage CurrentLog { get; set; } private const string InstallSettingsPrefix = "install-settings-"; @@ -97,11 +101,11 @@ namespace Wabbajack.App.Blazor.Pages Debug.Print(ex.Message); } } - + private async Task Install() { _dispatcher.Dispatch(new UpdateInstallState(InstallState.InstallStateEnum.Installing, ModList, ModListPath, InstallPath, DownloadPath)); - Task.Run(BeginInstall); + await Task.Run(BeginInstall); } private async Task BeginInstall() @@ -136,6 +140,7 @@ namespace Wabbajack.App.Blazor.Pages InvokeAsync(StateHasChanged); } }; + await installer.Begin(CancellationToken.None); } catch (Exception ex) @@ -152,4 +157,4 @@ namespace Wabbajack.App.Blazor.Pages public AbsolutePath DownloadLoadction { get; set; } public ModlistMetadata Metadata { get; set; } } -} \ No newline at end of file +} diff --git a/Wabbajack.App.Blazor/Pages/Configure.razor.scss b/Wabbajack.App.Blazor/Pages/Configure.razor.scss index 98fde2df..a511fa26 100644 --- a/Wabbajack.App.Blazor/Pages/Configure.razor.scss +++ b/Wabbajack.App.Blazor/Pages/Configure.razor.scss @@ -25,7 +25,7 @@ $checkbox-size: 0.75rem; color: white; flex-direction: column; - .image { + .install-background { position: absolute; width: calc(100% - #{$sidebar-width}); height: calc(100% - #{$header-height}); @@ -43,7 +43,19 @@ $checkbox-size: 0.75rem; display: flex; flex: 1; overflow: hidden; + align-items: center; + .left-side, .right-side { + flex: 1; + } } + .logger-container { + height: 200px; + width: 100%; + padding: 0.5rem; + background: rgb(0 0 0 / 20%); + color: lightgrey; + border: solid 1px black; + } .settings { font-size: 0.85rem; @@ -148,4 +160,4 @@ $checkbox-size: 0.75rem; } } } -} \ No newline at end of file +} diff --git a/Wabbajack.App.Blazor/Pages/Gallery.razor b/Wabbajack.App.Blazor/Pages/Gallery.razor index b42a2438..1ea7a793 100644 --- a/Wabbajack.App.Blazor/Pages/Gallery.razor +++ b/Wabbajack.App.Blazor/Pages/Gallery.razor @@ -37,11 +37,11 @@ } catch (Exception ex) { - //TODO: Figure out why an exception is thrown on first navigation. + //TODO: [Critical] Figure out why an exception is thrown on first navigation. Debug.Print(ex.Message); _logger.LogError(ex, "Error while loading lists"); } await base.OnInitializedAsync(); } -} \ No newline at end of file +} diff --git a/Wabbajack.App.Blazor/Utility/Dialog.cs b/Wabbajack.App.Blazor/Utility/Dialog.cs index a7d1f006..5a4596fc 100644 --- a/Wabbajack.App.Blazor/Utility/Dialog.cs +++ b/Wabbajack.App.Blazor/Utility/Dialog.cs @@ -8,6 +8,10 @@ namespace Wabbajack.App.Blazor.Utility; public static class Dialog { + /* + * TODO: [Critical] CommonOpenFileDialog.ShowDialog() causes UI freeze and crash. + * This method seems to alleviate it, but it still occasionally happens. + */ public static async Task ShowDialogNonBlocking(bool isFolderPicker = false) { return await Task.Factory.StartNew(() => @@ -22,4 +26,4 @@ public static class Dialog .ContinueWith(result => result.Result?.ToAbsolutePath()) .ConfigureAwait(false); } -} \ No newline at end of file +} diff --git a/Wabbajack.sln b/Wabbajack.sln index 3aa31f62..ab7f6512 100644 --- a/Wabbajack.sln +++ b/Wabbajack.sln @@ -119,11 +119,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wabbajack.Launcher", "Wabba EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wabbajack.App.Wpf", "Wabbajack.App.Wpf\Wabbajack.App.Wpf.csproj", "{372B2DD2-EAA3-4E18-98A7-B9838C7B41F4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wabbajack.Networking.Steam", "Wabbajack.Networking.Steam\Wabbajack.Networking.Steam.csproj", "{AB9A5C22-10CC-4EE0-A808-FB1DC9E24247}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wabbajack.Networking.Steam", "Wabbajack.Networking.Steam\Wabbajack.Networking.Steam.csproj", "{AB9A5C22-10CC-4EE0-A808-FB1DC9E24247}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wabbajack.Networking.Steam.Test", "Wabbajack.Networking.Steam.Test\Wabbajack.Networking.Steam.Test.csproj", "{D6351587-CAF6-4CB6-A2BD-5368E69F297C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wabbajack.Networking.Steam.Test", "Wabbajack.Networking.Steam.Test\Wabbajack.Networking.Steam.Test.csproj", "{D6351587-CAF6-4CB6-A2BD-5368E69F297C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wabbajack.App.Blazor", "Wabbajack.App.Blazor\Wabbajack.App.Blazor.csproj", "{C6E9B15D-510F-4074-AB1C-069F36BA4622}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wabbajack.App.Blazor", "Wabbajack.App.Blazor\Wabbajack.App.Blazor.csproj", "{C6E9B15D-510F-4074-AB1C-069F36BA4622}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{18E36813-CB53-4172-8FF3-EFE3B9B30A5F}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution