mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Checkbox and Logger components. Layout changes to Configure page.
Also added TODOs and a basic .editorconfig to suppress annoying warnings.
This commit is contained in:
parent
f2e29a9ab1
commit
dc9c327652
22
.editorconfig
Normal file
22
.editorconfig
Normal file
@ -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
|
2
Wabbajack.App.Blazor/.gitignore
vendored
2
Wabbajack.App.Blazor/.gitignore
vendored
@ -1 +1 @@
|
||||
|
||||
.sonarqube
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
<h3>Logger</h3>
|
||||
|
||||
@code {
|
||||
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
25
Wabbajack.App.Blazor/Components/OptionCheckbox.razor
Normal file
25
Wabbajack.App.Blazor/Components/OptionCheckbox.razor
Normal file
@ -0,0 +1,25 @@
|
||||
<label class="option">
|
||||
@Label
|
||||
<input type="checkbox" checked="@IsChecked" @onchange="CheckBoxChanged">
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
|
||||
@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<bool> OnChecked { get; set; }
|
||||
|
||||
private bool IsChecked { get; set; }
|
||||
|
||||
private async Task CheckBoxChanged(ChangeEventArgs e)
|
||||
{
|
||||
IsChecked = (bool)(e.Value ?? false);
|
||||
await OnChecked.InvokeAsync(IsChecked);
|
||||
}
|
||||
|
||||
}
|
56
Wabbajack.App.Blazor/Components/OptionCheckbox.razor.scss
Normal file
56
Wabbajack.App.Blazor/Components/OptionCheckbox.razor.scss
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
<div id="side-bar">
|
||||
@* TODO: [Low] Replace logo with SVG? *@
|
||||
<img class="logo" src="images/Logo_Dark_Transparent.png" alt="Wabbajack Logo">
|
||||
<div class="socials">
|
||||
<img src="images/icons/patreon.svg" alt="">
|
||||
@ -6,6 +7,3 @@
|
||||
<img src="images/icons/discord.svg" alt="">
|
||||
</div>
|
||||
</div>
|
||||
@code {
|
||||
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
<header id="top-bar">
|
||||
@* TODO: [Low] Indicate current page. *@
|
||||
<header id="top-bar">
|
||||
<nav>
|
||||
<ul>
|
||||
<li>
|
||||
@ -18,4 +19,4 @@
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
</header>
|
||||
|
26
Wabbajack.App.Blazor/Components/VirtualLogger.razor
Normal file
26
Wabbajack.App.Blazor/Components/VirtualLogger.razor
Normal file
@ -0,0 +1,26 @@
|
||||
@using Wabbajack.App.Blazor.Models
|
||||
|
||||
<div id="virtual-logger">
|
||||
<Virtualize Items="@_consoleLog" Context="logItem" OverscanCount="3">
|
||||
<span @key="logItem.MessageId">@logItem.LongMessage</span>
|
||||
</Virtualize>
|
||||
</div>
|
||||
|
||||
@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<LoggerProvider.ILogMessage> Messages { get; set; }
|
||||
|
||||
private List<LoggerProvider.ILogMessage> _consoleLog = new();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Messages.Subscribe(_consoleLog.Add);
|
||||
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
}
|
23
Wabbajack.App.Blazor/Components/VirtualLogger.razor.scss
Normal file
23
Wabbajack.App.Blazor/Components/VirtualLogger.razor.scss
Normal file
@ -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;
|
||||
}
|
||||
}
|
@ -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 { }
|
||||
}
|
||||
}
|
||||
|
@ -3,37 +3,52 @@
|
||||
@namespace Wabbajack.App.Blazor.Pages
|
||||
|
||||
<div id="content">
|
||||
<div class="image">
|
||||
<div class="install-background">
|
||||
<img src="@Image" alt="">
|
||||
</div>
|
||||
<div class="list">
|
||||
@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? *@
|
||||
<div class="left-side">
|
||||
@if (!string.IsNullOrEmpty(ModList.Name))
|
||||
{
|
||||
<InfoBlock Title="@ModList.Name" Subtitle="@ModList.Author" Comment="@ModList.Version.ToString()" Description="@ModList.Description"/>
|
||||
if (_installState.Value.CurrentInstallState != InstallState.InstallStateEnum.Installing)
|
||||
{
|
||||
<InfoBlock Title="@ModList.Name" Subtitle="@ModList.Author" Comment="@ModList.Version.ToString()" Description="@ModList.Description"/>
|
||||
}
|
||||
else if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Installing)
|
||||
{
|
||||
<InfoBlock Supertitle="Installing..." Title="@ModList.Name" Subtitle="@StatusText"/>
|
||||
// TODO: [Low] Step logging.
|
||||
}
|
||||
}
|
||||
else if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Installing)
|
||||
</div>
|
||||
<div class="right-side">
|
||||
@if (!string.IsNullOrEmpty(Image))
|
||||
{
|
||||
<InfoBlock Supertitle="Installing..." Title="@ModList.Name" Subtitle="@StatusText" Description="There will be a log here but I need to figure out logging and non-blocking UI stuff first."/>
|
||||
if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Configuration)
|
||||
{
|
||||
<InfoImage Image="@Image"/>
|
||||
}
|
||||
else if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Installing)
|
||||
{
|
||||
// TODO: [Low] Implement featured mod slideshow.
|
||||
<InfoImage Image="@Image" Title="Some Mod Title" Subtitle="Author and others" Description="This mod adds something cool but I'm not going to tell you anything."/>
|
||||
}
|
||||
}
|
||||
}
|
||||
@if (!string.IsNullOrEmpty(Image))
|
||||
{
|
||||
if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Configuration)
|
||||
{
|
||||
<InfoImage Image="@Image"/>
|
||||
}
|
||||
else if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Installing)
|
||||
{
|
||||
<InfoImage Image="@Image" Title="Some Mod Title" Subtitle="Author and others" Description="This mod adds something cool but I'm not going to tell you anything."/>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Installing)
|
||||
{
|
||||
<div class="logger-container">
|
||||
<VirtualLogger Messages="_loggerProvider.Messages"/>
|
||||
</div>
|
||||
}
|
||||
@if (_installState.Value.CurrentInstallState != InstallState.InstallStateEnum.Installing)
|
||||
{
|
||||
<div class="settings">
|
||||
<div class="locations">
|
||||
@* TODO: [High] Turn path selectors into components. *@
|
||||
<div class="labels">
|
||||
<span>Target Modlist</span>
|
||||
<span>Install Location</span>
|
||||
@ -47,33 +62,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="options">
|
||||
<label class="option">
|
||||
Overwrite Installation
|
||||
<input type="checkbox" checked="checked">
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
|
||||
<label class="option">
|
||||
<input type="checkbox">
|
||||
<span class="checkmark"></span>
|
||||
NTFS Compression
|
||||
</label>
|
||||
|
||||
<label class="option">
|
||||
<input type="checkbox">
|
||||
<span class="checkmark"></span>
|
||||
Do a sweet trick
|
||||
</label>
|
||||
|
||||
<label class="option">
|
||||
<input type="checkbox">
|
||||
<span class="checkmark"></span>
|
||||
Something else
|
||||
</label>
|
||||
<OptionCheckbox Label="Overwrite Installation"/>
|
||||
<OptionCheckbox Label="NTFS Compression"/>
|
||||
<OptionCheckbox Label="Do a sweet trick"/>
|
||||
<OptionCheckbox Label="Something else"/>
|
||||
</div>
|
||||
<div class="install">
|
||||
<img src="images/icons/play.svg" @onclick="Install" alt="Browse Gallery">
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<AbsolutePath?> ShowDialogNonBlocking(bool isFolderPicker = false)
|
||||
{
|
||||
return await Task.Factory.StartNew(() =>
|
||||
@ -22,4 +26,4 @@ public static class Dialog
|
||||
.ContinueWith(result => result.Result?.ToAbsolutePath())
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user