mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Too many changes to list.
This commit is contained in:
parent
fd9f9b86d9
commit
81102dbf64
12
Wabbajack.App.Blazor/.config/dotnet-tools.json
Normal file
12
Wabbajack.App.Blazor/.config/dotnet-tools.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"isRoot": true,
|
||||||
|
"tools": {
|
||||||
|
"excubo.webcompiler": {
|
||||||
|
"version": "2.7.14",
|
||||||
|
"commands": [
|
||||||
|
"webcompiler"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,3 @@
|
|||||||
root = true
|
|
||||||
|
|
||||||
# All files
|
# All files
|
||||||
[*]
|
[*]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
@ -20,3 +18,6 @@ dotnet_diagnostic.CS8618.severity = none
|
|||||||
dotnet_diagnostic.RZ10012.severity = none
|
dotnet_diagnostic.RZ10012.severity = none
|
||||||
|
|
||||||
dotnet_sort_system_directives_first = true
|
dotnet_sort_system_directives_first = true
|
||||||
|
|
||||||
|
[*.scss]
|
||||||
|
indent_size = 2
|
1
Wabbajack.App.Blazor/.gitignore
vendored
1
Wabbajack.App.Blazor/.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
.sonarqube
|
.sonarqube
|
||||||
**/*.css
|
**/*.css
|
||||||
|
**/*.css.map
|
||||||
|
@ -5,4 +5,4 @@
|
|||||||
Exit="OnExit">
|
Exit="OnExit">
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
</Application.Resources>
|
</Application.Resources>
|
||||||
</Application>
|
</Application>
|
||||||
|
@ -1,57 +1,56 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using Fluxor;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Wabbajack.App.Blazor.Models;
|
using Wabbajack.App.Blazor.Models;
|
||||||
|
using Wabbajack.App.Blazor.State;
|
||||||
using Wabbajack.App.Blazor.Utility;
|
using Wabbajack.App.Blazor.Utility;
|
||||||
using Wabbajack.DTOs;
|
using Wabbajack.DTOs;
|
||||||
using Wabbajack.Services.OSIntegrated;
|
using Wabbajack.Services.OSIntegrated;
|
||||||
|
|
||||||
namespace Wabbajack.App.Blazor
|
namespace Wabbajack.App.Blazor;
|
||||||
|
|
||||||
|
public partial class App
|
||||||
{
|
{
|
||||||
public partial class App
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
private readonly IHost _host;
|
||||||
|
|
||||||
|
public App()
|
||||||
{
|
{
|
||||||
private readonly IServiceProvider _serviceProvider;
|
_host = Host.CreateDefaultBuilder(Array.Empty<string>())
|
||||||
private readonly IHost _host;
|
.ConfigureLogging(c => { c.ClearProviders(); })
|
||||||
|
.ConfigureServices((host, services) => { ConfigureServices(services); })
|
||||||
public App()
|
.Build();
|
||||||
{
|
|
||||||
_host = Host.CreateDefaultBuilder(Array.Empty<string>())
|
|
||||||
.ConfigureLogging(c => { c.ClearProviders(); })
|
|
||||||
.ConfigureServices((host, services) => { ConfigureServices(services); })
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_serviceProvider = _host.Services;
|
_serviceProvider = _host.Services;
|
||||||
}
|
|
||||||
|
|
||||||
private static IServiceCollection ConfigureServices(IServiceCollection services)
|
|
||||||
{
|
|
||||||
services.AddOSIntegrated();
|
|
||||||
services.AddFluxor(o => o.ScanAssemblies(typeof(App).Assembly));
|
|
||||||
services.AddBlazorWebView();
|
|
||||||
services.AddAllSingleton<ILoggerProvider, LoggerProvider>();
|
|
||||||
services.AddTransient<MainWindow>();
|
|
||||||
services.AddSingleton<SystemParametersConstructor>();
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnStartup(object sender, StartupEventArgs e)
|
|
||||||
{
|
|
||||||
MainWindow mainWindow = _serviceProvider.GetRequiredService<MainWindow>();
|
|
||||||
mainWindow!.Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnExit(object sender, ExitEventArgs e)
|
|
||||||
{
|
|
||||||
Current.Shutdown();
|
|
||||||
// using (_host)
|
|
||||||
// {
|
|
||||||
// _host.StopAsync();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// base.OnExit(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private static IServiceCollection ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddOSIntegrated();
|
||||||
|
services.AddBlazorWebView();
|
||||||
|
services.AddAllSingleton<ILoggerProvider, LoggerProvider>();
|
||||||
|
services.AddTransient<MainWindow>();
|
||||||
|
services.AddSingleton<SystemParametersConstructor>();
|
||||||
|
services.AddSingleton<GlobalState>();
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnStartup(object sender, StartupEventArgs e)
|
||||||
|
{
|
||||||
|
var mainWindow = _serviceProvider.GetRequiredService<MainWindow>();
|
||||||
|
mainWindow!.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnExit(object sender, ExitEventArgs e)
|
||||||
|
{
|
||||||
|
Current.Shutdown();
|
||||||
|
// using (_host)
|
||||||
|
// {
|
||||||
|
// _host.StopAsync();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// base.OnExit(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
18
Wabbajack.App.Blazor/Components/BottomBar.razor
Normal file
18
Wabbajack.App.Blazor/Components/BottomBar.razor
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
@namespace Wabbajack.App.Blazor.Components
|
||||||
|
|
||||||
|
<footer id="bottom-bar">
|
||||||
|
<div class="image">
|
||||||
|
<img src="https://raw.githubusercontent.com/wabbajack-tools/mod-lists/master/total-skyrim-overhaul/2020.01.21-01.26.png" alt="">
|
||||||
|
</div>
|
||||||
|
<div class="info">
|
||||||
|
<div class="subtitle">[Subtitle]</div>
|
||||||
|
<div class="title">[Title]</div>
|
||||||
|
</div>
|
||||||
|
<div class="progress">
|
||||||
|
<ProgressBar/>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
}
|
44
Wabbajack.App.Blazor/Components/BottomBar.razor.scss
Normal file
44
Wabbajack.App.Blazor/Components/BottomBar.razor.scss
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
@import "../Shared/Globals.scss";
|
||||||
|
|
||||||
|
#bottom-bar {
|
||||||
|
position: fixed;
|
||||||
|
width: calc(100% - #{$sidebar-width});
|
||||||
|
height: $header-height;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
backdrop-filter: blur(2px) saturate(0.25);
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
//font-family: $raleway-font;
|
||||||
|
text-transform: uppercase;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
.image {
|
||||||
|
width: auto;
|
||||||
|
height: $header-height;
|
||||||
|
margin-right: 1rem;
|
||||||
|
padding: 0.25rem;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
.title {
|
||||||
|
font-size: 1.5em;
|
||||||
|
font-weight: 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
height: 20px;
|
||||||
|
flex: 1;
|
||||||
|
margin: 5rem;
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,6 @@
|
|||||||
<div id="info-block">
|
@namespace Wabbajack.App.Blazor.Components
|
||||||
|
|
||||||
|
<div id="info-block">
|
||||||
@if (Supertitle != string.Empty)
|
@if (Supertitle != string.Empty)
|
||||||
{
|
{
|
||||||
<span class="supertitle">@Supertitle</span>
|
<span class="supertitle">@Supertitle</span>
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
#info-block {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-content: center;
|
|
||||||
}
|
|
||||||
#info-block .supertitle {
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
font-weight: 100;
|
|
||||||
}
|
|
||||||
#info-block .title {
|
|
||||||
font-size: 4rem;
|
|
||||||
font-weight: 100;
|
|
||||||
margin-top: -1rem;
|
|
||||||
margin-bottom: -0.5rem;
|
|
||||||
}
|
|
||||||
#info-block .subtitle {
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
font-size: 2rem;
|
|
||||||
font-weight: 100;
|
|
||||||
}
|
|
||||||
#info-block .comment {
|
|
||||||
margin-left: 1rem;
|
|
||||||
color: rgba(255, 255, 255, 0.75);
|
|
||||||
}
|
|
||||||
#info-block .description {
|
|
||||||
margin-left: 1.5rem;
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
color: rgba(255, 255, 255, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=InfoBlock.razor.css.map */
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["InfoBlock.razor.scss"],"names":[],"mappings":"AAAC;EACC;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA","file":"InfoBlock.razor.css"}
|
|
@ -5,7 +5,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-content: center;
|
align-content: center;
|
||||||
|
|
||||||
.supertitle {
|
.supertitle {
|
||||||
margin-left: 0.5rem;
|
margin-left: 0.5rem;
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
<div id="info-image">
|
@namespace Wabbajack.App.Blazor.Components
|
||||||
|
|
||||||
|
<div id="info-image">
|
||||||
<div class="image">
|
<div class="image">
|
||||||
<img src="@Image" alt="">
|
<img src="@Image" alt="">
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
#info-image {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-content: center;
|
|
||||||
}
|
|
||||||
#info-image .mod-feature {
|
|
||||||
margin-left: -10px;
|
|
||||||
font-size: 2rem;
|
|
||||||
font-weight: 100;
|
|
||||||
}
|
|
||||||
#info-image .image {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
#info-image .image img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: contain;
|
|
||||||
}
|
|
||||||
#info-image .title {
|
|
||||||
font-size: 2rem;
|
|
||||||
font-weight: 100;
|
|
||||||
}
|
|
||||||
#info-image .subtitle {
|
|
||||||
font-size: 1.1rem;
|
|
||||||
font-weight: 100;
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
}
|
|
||||||
#info-image .description {
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
margin-left: 1rem;
|
|
||||||
color: rgba(255, 255, 255, 0.75);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=InfoImage.razor.css.map */
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["InfoImage.razor.scss"],"names":[],"mappings":"AAAC;EACC;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;AACA;EACE;EACA;EACA;;AAIJ;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA","file":"InfoImage.razor.css"}
|
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
.image {
|
.image {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
19
Wabbajack.App.Blazor/Components/InteractionIcon.razor
Normal file
19
Wabbajack.App.Blazor/Components/InteractionIcon.razor
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
@namespace Wabbajack.App.Blazor.Components
|
||||||
|
|
||||||
|
<img src="@Icon" class="interaction-icon" style="width: @Size; height: @Size; margin: 0;" alt="@Label" @onclick="OnClick">
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string Icon { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string Label { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string Size { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public EventCallback<MouseEventArgs> OnClick { get; set; }
|
||||||
|
|
||||||
|
}
|
@ -1,27 +1,14 @@
|
|||||||
@namespace Wabbajack.App.Blazor.Components
|
@using Wabbajack.DTOs
|
||||||
@using Wabbajack.App.Blazor.Store
|
|
||||||
@using Wabbajack.RateLimiter
|
@namespace Wabbajack.App.Blazor.Components
|
||||||
@inherits Fluxor.Blazor.Web.Components.FluxorComponent
|
|
||||||
|
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="display">
|
<div class="display">
|
||||||
<img src="@Metadata.Links.ImageUri" loading="lazy" class="image" alt="@Metadata.Title Image">
|
<img src="@Metadata.Links.ImageUri" loading="lazy" class="image" alt="@Metadata.Title">
|
||||||
<div class="interaction">
|
<div class="interaction">
|
||||||
@if (_downloadState.Value.CurrentDownloadState == DownloadState.DownloadStateEnum.Downloading)
|
@ChildContent
|
||||||
{
|
|
||||||
<img src="images/icons/install.svg" class="install hidden" alt="Install">
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<img src="images/icons/install.svg" class="install" alt="Install" @onclick="Download">
|
|
||||||
}
|
|
||||||
<img src="images/icons/info.svg" class="more" alt="Information">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@if (DownloadProgress != Percent.Zero)
|
|
||||||
{
|
|
||||||
<ProgressBar Percentage=@DownloadProgress></ProgressBar>
|
|
||||||
}
|
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="title">@Metadata.Title</div>
|
<div class="title">@Metadata.Title</div>
|
||||||
<div class="author">@Metadata.Author</div>
|
<div class="author">@Metadata.Author</div>
|
||||||
@ -29,3 +16,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="tags"></div>
|
<div class="tags"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public ModlistMetadata Metadata { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public RenderFragment ChildContent { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Fluxor;
|
|
||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
using Wabbajack.App.Blazor.Store;
|
|
||||||
using Wabbajack.Common;
|
|
||||||
using Wabbajack.DTOs;
|
|
||||||
using Wabbajack.DTOs.JsonConverters;
|
|
||||||
using Wabbajack.Installer;
|
|
||||||
using Wabbajack.Paths;
|
|
||||||
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
|
|
||||||
{
|
|
||||||
[Inject] private IState<DownloadState> _downloadState { get; set; }
|
|
||||||
[Inject] private IState<InstallState> _installState { get; set; }
|
|
||||||
[Inject] private ModListDownloadMaintainer _maintainer { get; set; }
|
|
||||||
[Inject] private IDispatcher _dispatcher { get; set; }
|
|
||||||
[Inject] private NavigationManager NavigationManager { get; set; }
|
|
||||||
|
|
||||||
[Parameter] public ModlistMetadata Metadata { get; set; }
|
|
||||||
|
|
||||||
public Percent DownloadProgress { get; set; }
|
|
||||||
|
|
||||||
private async Task Download()
|
|
||||||
{
|
|
||||||
await using Timer timer = new(_ => InvokeAsync(StateHasChanged));
|
|
||||||
timer.Change(TimeSpan.FromMilliseconds(250), TimeSpan.FromMilliseconds(250));
|
|
||||||
try
|
|
||||||
{
|
|
||||||
UpdateDownloadState(DownloadState.DownloadStateEnum.Downloading, Metadata);
|
|
||||||
(IObservable<Percent> progress, Task task) = _maintainer.DownloadModlist(Metadata);
|
|
||||||
IDisposable dispose = progress.Subscribe(p => DownloadProgress = p);
|
|
||||||
|
|
||||||
await task;
|
|
||||||
//await _wjClient.SendMetric("downloading", Metadata.Title);
|
|
||||||
UpdateDownloadState(DownloadState.DownloadStateEnum.Downloaded, Metadata);
|
|
||||||
dispose.Dispose();
|
|
||||||
|
|
||||||
AbsolutePath path = KnownFolders.EntryPoint.Combine("downloaded_mod_lists", Metadata.Links.MachineURL).WithExtension(Ext.Wabbajack);
|
|
||||||
_dispatcher.Dispatch(new UpdateInstallState(InstallState.InstallStateEnum.Configuration, null, path, null, null));
|
|
||||||
NavigationManager.NavigateTo("/configure");
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Debug.Print(e.Message);
|
|
||||||
UpdateDownloadState(DownloadState.DownloadStateEnum.Failure, Metadata);
|
|
||||||
}
|
|
||||||
|
|
||||||
await timer.DisposeAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateDownloadState(DownloadState.DownloadStateEnum state, ModlistMetadata metadata) =>
|
|
||||||
_dispatcher.Dispatch(new UpdateDownloadState(state, metadata));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
@font-face {
|
|
||||||
font-family: "Raleway";
|
|
||||||
src: url("fonts/Raleway-Variable.ttf");
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "YanoneKaffeesatz";
|
|
||||||
src: url("fonts/YanoneKaffeesatz-Variable.ttf");
|
|
||||||
}
|
|
||||||
.item {
|
|
||||||
width: 400px;
|
|
||||||
height: 450px;
|
|
||||||
overflow: hidden;
|
|
||||||
margin: 0.5rem;
|
|
||||||
padding: 1rem;
|
|
||||||
background: rgba(255, 255, 255, 0.1);
|
|
||||||
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
|
|
||||||
backdrop-filter: blur(7px);
|
|
||||||
-webkit-backdrop-filter: blur(7px);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.31);
|
|
||||||
}
|
|
||||||
.item:hover .display .image {
|
|
||||||
filter: blur(2px) brightness(70%);
|
|
||||||
}
|
|
||||||
.item:hover .display .interaction {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
.item .display {
|
|
||||||
position: relative;
|
|
||||||
height: 225px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.item .display .image {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: contain;
|
|
||||||
transition: all 250ms ease-in-out;
|
|
||||||
}
|
|
||||||
.item .display .interaction {
|
|
||||||
position: absolute;
|
|
||||||
opacity: 0;
|
|
||||||
transition: all 250ms ease-in-out;
|
|
||||||
}
|
|
||||||
.item .display .interaction img {
|
|
||||||
width: 75px;
|
|
||||||
height: 75px;
|
|
||||||
margin: 0;
|
|
||||||
transition: all 150ms ease-in-out;
|
|
||||||
}
|
|
||||||
.item .display .interaction img.hidden {
|
|
||||||
opacity: 0.25;
|
|
||||||
}
|
|
||||||
.item .display .interaction img:hover {
|
|
||||||
margin-left: 10px;
|
|
||||||
margin-right: 10px;
|
|
||||||
transform: scale(1.25);
|
|
||||||
}
|
|
||||||
.item .info {
|
|
||||||
padding-bottom: 1rem;
|
|
||||||
padding-left: 0.5rem;
|
|
||||||
padding-right: 0.5rem;
|
|
||||||
}
|
|
||||||
.item .info .title {
|
|
||||||
color: white;
|
|
||||||
font-weight: 100;
|
|
||||||
font-size: 2rem;
|
|
||||||
line-height: 2.5rem;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.item .info .author {
|
|
||||||
color: lightgray;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
.item .info .description {
|
|
||||||
color: grey;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
.item .tags {
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=ModlistItem.razor.css.map */
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["../Shared/Globals.scss","ModlistItem.razor.scss"],"names":[],"mappings":"AAAC;EACC;EACA;;AAGF;EACE;EACA;;ACFF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA,QAzBa;EA0Bb;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE,OA3CU;EA4CV,QA5CU;EA6CV;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;;AAMR;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAIJ;EACE","file":"ModlistItem.razor.css"}
|
|
@ -43,21 +43,11 @@ $hover-icon-size: 75px;
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: all 250ms ease-in-out;
|
transition: all 250ms ease-in-out;
|
||||||
|
|
||||||
img {
|
::deep img {
|
||||||
width: $hover-icon-size;
|
width: $hover-icon-size;
|
||||||
height: $hover-icon-size;
|
height: $hover-icon-size;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
transition: all 150ms ease-in-out;
|
transition: all 150ms ease-in-out;
|
||||||
|
|
||||||
&.hidden {
|
|
||||||
opacity: 0.25;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
margin-left: 10px;
|
|
||||||
margin-right: 10px;
|
|
||||||
transform: scale(1.25);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,4 +79,4 @@ $hover-icon-size: 75px;
|
|||||||
.tags {
|
.tags {
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
<div class="container">
|
@namespace Wabbajack.App.Blazor.Components
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<p class="title">
|
<p class="title">
|
||||||
Wabbajack 3.0
|
Wabbajack 3.0
|
||||||
@ -8,7 +10,3 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@code {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
.container {
|
|
||||||
background-image: linear-gradient(30deg, black 0%, rgba(0, 0, 0, 0.8) 30%, rgba(255, 255, 255, 0) 100%), url(images/Banner_Dark_Transparent.png);
|
|
||||||
background-size: cover;
|
|
||||||
background-position: center;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 1rem 1.5rem;
|
|
||||||
max-width: 56rem;
|
|
||||||
height: 9rem;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
|
|
||||||
backdrop-filter: blur(5px);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
||||||
}
|
|
||||||
.container .info {
|
|
||||||
align-self: flex-end;
|
|
||||||
}
|
|
||||||
.container .info .title {
|
|
||||||
color: white;
|
|
||||||
font-weight: 100;
|
|
||||||
font-size: 2.25rem;
|
|
||||||
line-height: 2.5rem;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.container .info .description {
|
|
||||||
color: grey;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=News.razor.css.map */
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["News.razor.scss"],"names":[],"mappings":"AAAC;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE","file":"News.razor.css"}
|
|
@ -28,4 +28,4 @@
|
|||||||
color: grey;
|
color: grey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
<label class="option">
|
@namespace Wabbajack.App.Blazor.Components
|
||||||
|
|
||||||
|
<label class="option">
|
||||||
@Label
|
@Label
|
||||||
<input type="checkbox" checked="@IsChecked" @onchange="CheckBoxChanged">
|
<input type="checkbox" checked="@IsChecked" @onchange="CheckBoxChanged">
|
||||||
<span class="checkmark"></span>
|
<span class="checkmark"></span>
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
@font-face {
|
|
||||||
font-family: "Raleway";
|
|
||||||
src: url("fonts/Raleway-Variable.ttf");
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "YanoneKaffeesatz";
|
|
||||||
src: url("fonts/YanoneKaffeesatz-Variable.ttf");
|
|
||||||
}
|
|
||||||
.option {
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
margin: 0.25rem;
|
|
||||||
padding-left: 2rem;
|
|
||||||
cursor: pointer;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
.option:hover input ~ .checkmark {
|
|
||||||
background-color: darkgrey;
|
|
||||||
}
|
|
||||||
.option input {
|
|
||||||
position: absolute;
|
|
||||||
opacity: 0;
|
|
||||||
cursor: pointer;
|
|
||||||
height: 0;
|
|
||||||
width: 0;
|
|
||||||
}
|
|
||||||
.option input:checked ~ .checkmark {
|
|
||||||
background-color: #5E437F;
|
|
||||||
}
|
|
||||||
.option input:checked ~ .checkmark:after {
|
|
||||||
display: block;
|
|
||||||
left: calc(0.5 * 0.75rem);
|
|
||||||
top: calc(0.25 * 0.75rem);
|
|
||||||
width: calc(0.25 * 0.75rem);
|
|
||||||
height: calc(0.65 * 0.75rem);
|
|
||||||
border: solid white;
|
|
||||||
border-width: 0 3px 3px 0;
|
|
||||||
transform: rotate(45deg);
|
|
||||||
}
|
|
||||||
.option .checkmark {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
height: calc(1.5 * 0.75rem);
|
|
||||||
width: calc(1.5 * 0.75rem);
|
|
||||||
background-color: rgba(255, 255, 255, 0.2);
|
|
||||||
}
|
|
||||||
.option .checkmark:after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=OptionCheckbox.razor.css.map */
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["../Shared/Globals.scss","OptionCheckbox.razor.scss"],"names":[],"mappings":"AAAC;EACC;EACA;;AAGF;EACE;EACA;;ACDF;EACI;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI,kBAboB;;AAgBxB;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI,kBDdG;;ACgBH;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAKZ;EACI;EACA;EACA;EACA;EACA;EACA,kBA9Cc;;AAgDd;EACI;EACA;EACA","file":"OptionCheckbox.razor.css"}
|
|
@ -1,56 +1,57 @@
|
|||||||
@import "../Shared/Globals.scss";
|
@import "../Shared/Globals.scss";
|
||||||
|
|
||||||
$checkbox-background: rgba(255, 255, 255, 0.2);
|
$checkbox-background: rgba(255, 255, 255, 0.2);
|
||||||
$checkbox-background-hover: darkgrey;
|
$checkbox-background-hover: darkgrey;
|
||||||
$checkbox-background-checked: $accent-color;
|
$checkbox-background-checked: $accent-color;
|
||||||
$checkbox-size: 0.75rem;
|
$checkbox-size: 0.75rem;
|
||||||
|
|
||||||
.option {
|
.option {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0.25rem;
|
margin: 0.25rem;
|
||||||
padding-left: 2rem;
|
padding-left: 2rem;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
&:hover input ~ .checkmark {
|
||||||
|
background-color: $checkbox-background-hover;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
user-select: none;
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
|
||||||
&:hover input ~ .checkmark {
|
&:checked ~ .checkmark {
|
||||||
background-color: $checkbox-background-hover;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
input {
|
.checkmark {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
opacity: 0;
|
top: 0;
|
||||||
cursor: pointer;
|
left: 0;
|
||||||
height: 0;
|
height: calc(1.5 * #{$checkbox-size});
|
||||||
width: 0;
|
width: calc(1.5 * #{$checkbox-size});
|
||||||
|
background-color: $checkbox-background;
|
||||||
|
|
||||||
&:checked ~ .checkmark {
|
&:after {
|
||||||
background-color: $checkbox-background-checked;
|
content: "";
|
||||||
|
position: absolute;
|
||||||
&:after {
|
display: none;
|
||||||
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,5 +1,11 @@
|
|||||||
@using Wabbajack.RateLimiter
|
@using Wabbajack.RateLimiter
|
||||||
<progress value="@Percentage.Value"> </progress>
|
|
||||||
|
@namespace Wabbajack.App.Blazor.Components
|
||||||
|
|
||||||
|
<div id="progress-bar">
|
||||||
|
<progress value="@Percentage.Value"></progress>
|
||||||
|
<span class="text">[Centre Text]</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
progress {
|
|
||||||
width: 100%;
|
|
||||||
height: 3px;
|
|
||||||
appearance: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=ProgressBar.razor.css.map */
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["ProgressBar.razor.scss"],"names":[],"mappings":"AAAC;EACC;EACA;EACA","file":"ProgressBar.razor.css"}
|
|
@ -1,5 +1,30 @@
|
|||||||
progress {
|
#progress-bar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 3px;
|
height: 100%;
|
||||||
appearance: none;
|
position: relative;
|
||||||
}
|
|
||||||
|
progress {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
appearance: none;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress[value]::-webkit-progress-bar {
|
||||||
|
background-color: #ededed;
|
||||||
|
border-radius: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress[value]::-webkit-progress-value {
|
||||||
|
border-radius: 40px;
|
||||||
|
background-color: mediumpurple;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
color: blue;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
<div id="side-bar">
|
@namespace Wabbajack.App.Blazor.Components
|
||||||
|
|
||||||
|
<div id="side-bar">
|
||||||
@* TODO: [Low] Replace logo with SVG? *@
|
@* TODO: [Low] Replace logo with SVG? *@
|
||||||
<img class="logo" src="images/Logo_Dark_Transparent.png" alt="Wabbajack Logo">
|
<img class="logo" src="images/Logo_Dark_Transparent.png" alt="Wabbajack Logo">
|
||||||
<div class="socials">
|
<div class="socials">
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
@font-face {
|
|
||||||
font-family: "Raleway";
|
|
||||||
src: url("fonts/Raleway-Variable.ttf");
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "YanoneKaffeesatz";
|
|
||||||
src: url("fonts/YanoneKaffeesatz-Variable.ttf");
|
|
||||||
}
|
|
||||||
#side-bar {
|
|
||||||
position: fixed;
|
|
||||||
height: 100%;
|
|
||||||
width: 75px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
border-right: 1px solid #404040;
|
|
||||||
backdrop-filter: brightness(0.8);
|
|
||||||
}
|
|
||||||
#side-bar .logo {
|
|
||||||
padding: 0.5rem;
|
|
||||||
display: block;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
vertical-align: middle;
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
#side-bar .socials {
|
|
||||||
width: 30px;
|
|
||||||
}
|
|
||||||
#side-bar .socials img {
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=SideBar.razor.css.map */
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["../Shared/Globals.scss","SideBar.razor.scss"],"names":[],"mappings":"AAAC;EACC;EACA;;AAGF;EACE;EACA;;ACLF;EACE;EACA;EACA,ODUc;ECTd;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EACE;EACA;EACA","file":"SideBar.razor.css"}
|
|
@ -1,22 +1,58 @@
|
|||||||
@* TODO: [Low] Indicate current page. *@
|
@using Wabbajack.App.Blazor.Pages
|
||||||
|
@using Wabbajack.App.Blazor.Shared
|
||||||
|
@using Wabbajack.App.Blazor.State
|
||||||
|
|
||||||
|
@namespace Wabbajack.App.Blazor.Components
|
||||||
|
|
||||||
|
@* TODO: [Low] Clean this up a bit. *@
|
||||||
<header id="top-bar">
|
<header id="top-bar">
|
||||||
<nav>
|
<nav class="@(GlobalState.NavigationAllowed ? "" : "disallow")">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<a href="/">Home</a>
|
<div class='item @CurrentPage("")' @onclick='() => Navigate("")'>Play</div>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="/gallery">Gallery</a>
|
<div class='item @CurrentPage("Gallery")' @onclick='() => Navigate("Gallery")'>Gallery</div>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="/SelectInstall">Install</a>
|
<div class='item @CurrentPage("Install")' @onclick='() => Navigate("Install")'>Install</div>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="/">Compile</a>
|
<div class='item @CurrentPage("Create")' @onclick='() => Navigate("Create")'>Create</div>
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="/">Settings</a>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
<div class="settings">
|
||||||
|
<InteractionIcon Icon="images/icons/adjust.svg" Label="Settings" Size="100%" OnClick="@(() => Navigate("Settings"))"/>
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
NavigationManager _navigationManager { get; set; }
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
GlobalState GlobalState { get; set; }
|
||||||
|
|
||||||
|
[CascadingParameter]
|
||||||
|
protected MainLayout _mainLayout { get; set; }
|
||||||
|
|
||||||
|
private void Navigate(string page)
|
||||||
|
{
|
||||||
|
_navigationManager.NavigateTo(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
_navigationManager.LocationChanged += (o, args) => StateHasChanged();
|
||||||
|
GlobalState.OnNavigationStateChange += StateHasChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string CurrentPage(string page)
|
||||||
|
{
|
||||||
|
string relativePath = _navigationManager.ToBaseRelativePath(_navigationManager.Uri).ToLower();
|
||||||
|
return page.ToLower() == relativePath ? "active" : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
@font-face {
|
|
||||||
font-family: "Raleway";
|
|
||||||
src: url("fonts/Raleway-Variable.ttf");
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "YanoneKaffeesatz";
|
|
||||||
src: url("fonts/YanoneKaffeesatz-Variable.ttf");
|
|
||||||
}
|
|
||||||
#top-bar {
|
|
||||||
position: fixed;
|
|
||||||
width: calc(100% - 75px);
|
|
||||||
height: 65px;
|
|
||||||
background-color: transparent;
|
|
||||||
backdrop-filter: blur(5px) grayscale(10%);
|
|
||||||
z-index: 2;
|
|
||||||
font-family: "Raleway", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
||||||
text-transform: uppercase;
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: flex-end;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
#top-bar nav {
|
|
||||||
font-weight: 100;
|
|
||||||
font-size: 1em;
|
|
||||||
line-height: 2rem;
|
|
||||||
}
|
|
||||||
#top-bar ul li {
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
#top-bar ul li a {
|
|
||||||
color: white;
|
|
||||||
display: block;
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: background-color 0.25s ease-in-out;
|
|
||||||
}
|
|
||||||
#top-bar ul li a:hover {
|
|
||||||
border-bottom: 2px solid #5E437F;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=TopBar.razor.css.map */
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["../Shared/Globals.scss","TopBar.razor.scss"],"names":[],"mappings":"AAAC;EACC;EACA;;AAGF;EACE;EACA;;ACLF;EACE;EACA;EACA,QDSc;ECRd;EACA;EACA;EAEA,aDSa;ECRb;EAEA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAIA;EACE;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE","file":"TopBar.razor.css"}
|
|
@ -7,7 +7,7 @@
|
|||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
backdrop-filter: blur(5px) grayscale(10%);
|
backdrop-filter: blur(5px) grayscale(10%);
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|
||||||
font-family: $raleway-font;
|
font-family: $raleway-font;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
|
||||||
@ -20,23 +20,47 @@
|
|||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
line-height: 2rem;
|
line-height: 2rem;
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
li {
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 10px;
|
|
||||||
a {
|
|
||||||
color: white;
|
|
||||||
display: block;
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: background-color .25s ease-in-out;
|
|
||||||
|
|
||||||
&:hover {
|
&.disallow {
|
||||||
border-bottom: 2px solid $accent-color;
|
background-color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
li {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
color: #dddddd;
|
||||||
|
display: block;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: border 100ms ease-in-out, color 100ms ease-in-out;
|
||||||
|
cursor: pointer;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: white;
|
||||||
|
border-bottom: 2px solid #824dc3;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.active):hover {
|
||||||
|
border-bottom: 2px solid $accent-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
.settings {
|
||||||
|
height: 60%;
|
||||||
|
margin: auto 1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
filter: brightness(80%);
|
||||||
|
transition: filter 100ms ease-in-out;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
filter: brightness(100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
@using Wabbajack.App.Blazor.Models
|
@using Wabbajack.App.Blazor.Models
|
||||||
|
|
||||||
|
@namespace Wabbajack.App.Blazor.Components
|
||||||
|
|
||||||
<div id="virtual-logger">
|
<div id="virtual-logger">
|
||||||
<Virtualize Items="@_consoleLog" Context="logItem" OverscanCount="3">
|
<Virtualize Items="@_consoleLog" Context="logItem" OverscanCount="3">
|
||||||
<span @key="logItem.MessageId">@logItem.LongMessage</span>
|
<span @key="logItem.MessageId">@logItem.LongMessage</span>
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
#virtual-logger {
|
|
||||||
height: 100%;
|
|
||||||
overflow-y: scroll;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
#virtual-logger span {
|
|
||||||
display: block;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=VirtualLogger.razor.css.map */
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["VirtualLogger.razor.scss"],"names":[],"mappings":"AACA;EACI;EACA;EACA;;AAWA;EACI;EACA;EACA;EACA;EACA","file":"VirtualLogger.razor.css"}
|
|
@ -1,23 +1,23 @@
|
|||||||
// TODO: [Low] Logging levels?
|
// TODO: [Low] Logging levels?
|
||||||
#virtual-logger {
|
#virtual-logger {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
}
|
}
|
||||||
|
|
||||||
.warn {
|
.warn {
|
||||||
}
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
display: block;
|
display: block;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
<Fluxor.Blazor.Web.StoreInitializer/>
|
<Fluxor.Blazor.Web.StoreInitializer/>
|
||||||
|
|
||||||
|
@using Wabbajack.App.Blazor.Shared
|
||||||
|
|
||||||
<Router AppAssembly="@GetType().Assembly">
|
<Router AppAssembly="@GetType().Assembly">
|
||||||
<Found Context="routeData">
|
<Found Context="routeData">
|
||||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(Shared.MainLayout)" />
|
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
|
||||||
</Found>
|
</Found>
|
||||||
<NotFound>
|
<NotFound>
|
||||||
<h1>Not found</h1>
|
<h1>Not found</h1>
|
||||||
<p>Sorry, there's nothing here.</p>
|
<p>Sorry, there's nothing here.</p>
|
||||||
</NotFound>
|
</NotFound>
|
||||||
</Router>
|
</Router>
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="MainWindow" Height="750" Width="1200" MinHeight="750" MinWidth="1200">
|
Title="MainWindow" Height="750" Width="1200" MinHeight="750" MinWidth="1200">
|
||||||
<Grid Background="#121212">
|
<Grid Background="#121212">
|
||||||
<blazor:BlazorWebView HostPage="wwwroot\index.html" Services="{StaticResource services}" x:Name="blazorWebView1">
|
<blazor:BlazorWebView HostPage="wwwroot\index.html" Services="{StaticResource services}"
|
||||||
|
x:Name="blazorWebView1">
|
||||||
<blazor:BlazorWebView.RootComponents>
|
<blazor:BlazorWebView.RootComponents>
|
||||||
<blazor:RootComponent Selector="#app" ComponentType="{x:Type local:Main}" />
|
<blazor:RootComponent Selector="#app" ComponentType="{x:Type local:Main}" />
|
||||||
</blazor:BlazorWebView.RootComponents>
|
</blazor:BlazorWebView.RootComponents>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using Fluxor;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Wabbajack.App.Blazor.Models;
|
using Wabbajack.App.Blazor.Models;
|
||||||
using Wabbajack.App.Blazor.Utility;
|
using Wabbajack.App.Blazor.Utility;
|
||||||
@ -7,56 +6,52 @@ using Wabbajack.Common;
|
|||||||
using Wabbajack.Installer;
|
using Wabbajack.Installer;
|
||||||
using Wabbajack.Paths.IO;
|
using Wabbajack.Paths.IO;
|
||||||
|
|
||||||
namespace Wabbajack.App.Blazor
|
namespace Wabbajack.App.Blazor;
|
||||||
|
|
||||||
|
public partial class MainWindow
|
||||||
{
|
{
|
||||||
public partial class MainWindow
|
private readonly ILogger<MainWindow> _logger;
|
||||||
|
private readonly LoggerProvider _loggerProvider;
|
||||||
|
private readonly SystemParametersConstructor _systemParams;
|
||||||
|
|
||||||
|
public MainWindow(ILogger<MainWindow> logger, IServiceProvider serviceProvider, LoggerProvider loggerProvider,
|
||||||
|
SystemParametersConstructor systemParams)
|
||||||
{
|
{
|
||||||
private readonly ILogger<MainWindow> _logger;
|
_logger = logger;
|
||||||
private readonly LoggerProvider _loggerProvider;
|
_loggerProvider = loggerProvider;
|
||||||
private readonly IStore _store;
|
_systemParams = systemParams;
|
||||||
private readonly SystemParametersConstructor _systemParams;
|
Resources.Add("services", serviceProvider);
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
public MainWindow(ILogger<MainWindow> logger, IStore store, IServiceProvider serviceProvider, LoggerProvider loggerProvider,
|
try
|
||||||
SystemParametersConstructor systemParams)
|
|
||||||
{
|
{
|
||||||
_logger = logger;
|
// TODO: [Low] Not sure how to set this up.
|
||||||
_store = store;
|
//_logger.LogInformation("Wabbajack Build - {Sha}", ThisAssembly.Git.Sha);
|
||||||
_loggerProvider = loggerProvider;
|
_logger.LogInformation("Running in {EntryPoint}", KnownFolders.EntryPoint);
|
||||||
_systemParams = systemParams;
|
|
||||||
_store.InitializeAsync().Wait();
|
|
||||||
Resources.Add("services", serviceProvider);
|
|
||||||
InitializeComponent();
|
|
||||||
|
|
||||||
try
|
SystemParameters p = _systemParams.Create();
|
||||||
{
|
|
||||||
// TODO: [Low] Not sure how to set this up.
|
|
||||||
//_logger.LogInformation("Wabbajack Build - {Sha}", ThisAssembly.Git.Sha);
|
|
||||||
_logger.LogInformation("Running in {EntryPoint}", KnownFolders.EntryPoint);
|
|
||||||
|
|
||||||
SystemParameters p = _systemParams.Create();
|
_logger.LogInformation("Detected Windows Version: {Version}", Environment.OSVersion.VersionString);
|
||||||
|
|
||||||
_logger.LogInformation("Detected Windows Version: {Version}", Environment.OSVersion.VersionString);
|
_logger.LogInformation(
|
||||||
|
"System settings - ({MemorySize} RAM) ({PageSize} Page), Display: {ScreenWidth} x {ScreenHeight} ({Vram} VRAM - VideoMemorySizeMb={ENBVRam})",
|
||||||
|
p.SystemMemorySize.ToFileSizeString(), p.SystemPageSize.ToFileSizeString(), p.ScreenWidth, p.ScreenHeight,
|
||||||
|
p.VideoMemorySize.ToFileSizeString(), p.EnbLEVRAMSize);
|
||||||
|
|
||||||
|
if (p.SystemPageSize == 0)
|
||||||
_logger.LogInformation(
|
_logger.LogInformation(
|
||||||
"System settings - ({MemorySize} RAM) ({PageSize} Page), Display: {ScreenWidth} x {ScreenHeight} ({Vram} VRAM - VideoMemorySizeMb={ENBVRam})",
|
"Page file is disabled! Consider increasing to 20000MB. A disabled page file can cause crashes and poor in-game performance");
|
||||||
p.SystemMemorySize.ToFileSizeString(), p.SystemPageSize.ToFileSizeString(), p.ScreenWidth, p.ScreenHeight,
|
else if (p.SystemPageSize < 2e+10)
|
||||||
p.VideoMemorySize.ToFileSizeString(), p.EnbLEVRAMSize);
|
_logger.LogInformation(
|
||||||
|
"Page file below recommended! Consider increasing to 20000MB. A suboptimal page file can cause crashes and poor in-game performance");
|
||||||
if (p.SystemPageSize == 0)
|
}
|
||||||
_logger.LogInformation(
|
catch (Exception ex)
|
||||||
"Page file is disabled! Consider increasing to 20000MB. A disabled page file can cause crashes and poor in-game performance");
|
{
|
||||||
else if (p.SystemPageSize < 2e+10)
|
_logger.LogError(ex, "Error during Main Window startup.");
|
||||||
_logger.LogInformation(
|
Environment.Exit(-1);
|
||||||
"Page file below recommended! Consider increasing to 20000MB. A suboptimal page file can cause crashes and poor in-game performance");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Error during Main Window startup.");
|
|
||||||
Environment.Exit(-1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required so compiler doesn't complain about not finding the type. [MC3050]
|
|
||||||
public partial class Main { }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Required so compiler doesn't complain about not finding the type. [MC3050]
|
||||||
|
public partial class Main { }
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
namespace Wabbajack.App.Blazor.Models;
|
namespace Wabbajack.App.Blazor.Models;
|
||||||
|
|
||||||
public class Install
|
public class Install { }
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -17,22 +17,22 @@ namespace Wabbajack.App.Blazor.Models;
|
|||||||
|
|
||||||
public class LoggerProvider : ILoggerProvider
|
public class LoggerProvider : ILoggerProvider
|
||||||
{
|
{
|
||||||
private readonly RelativePath _appName;
|
private readonly RelativePath _appName;
|
||||||
private readonly Configuration _configuration;
|
private readonly Configuration _configuration;
|
||||||
private readonly CompositeDisposable _disposables;
|
private readonly CompositeDisposable _disposables;
|
||||||
private readonly Stream _logFile;
|
private readonly Stream _logFile;
|
||||||
private readonly StreamWriter _logStream;
|
private readonly StreamWriter _logStream;
|
||||||
|
|
||||||
public readonly ReadOnlyObservableCollection<ILogMessage> _messagesFiltered;
|
public readonly ReadOnlyObservableCollection<ILogMessage> _messagesFiltered;
|
||||||
private readonly DateTime _startupTime;
|
private readonly DateTime _startupTime;
|
||||||
|
|
||||||
private long _messageId;
|
private long _messageId;
|
||||||
private readonly SourceCache<ILogMessage, long> _messageLog = new(m => m.MessageId);
|
private readonly SourceCache<ILogMessage, long> _messageLog = new(m => m.MessageId);
|
||||||
private readonly Subject<ILogMessage> _messages = new();
|
private readonly Subject<ILogMessage> _messages = new();
|
||||||
|
|
||||||
public LoggerProvider(Configuration configuration)
|
public LoggerProvider(Configuration configuration)
|
||||||
{
|
{
|
||||||
_startupTime = DateTime.UtcNow;
|
_startupTime = DateTime.UtcNow;
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
_configuration.LogLocation.CreateDirectory();
|
_configuration.LogLocation.CreateDirectory();
|
||||||
|
|
||||||
@ -49,14 +49,14 @@ public class LoggerProvider : ILoggerProvider
|
|||||||
.Subscribe();
|
.Subscribe();
|
||||||
|
|
||||||
_appName = typeof(LoggerProvider).Assembly.Location.ToAbsolutePath().FileName;
|
_appName = typeof(LoggerProvider).Assembly.Location.ToAbsolutePath().FileName;
|
||||||
LogPath = _configuration.LogLocation.Combine($"{_appName}.current.log");
|
LogPath = _configuration.LogLocation.Combine($"{_appName}.current.log");
|
||||||
_logFile = LogPath.Open(FileMode.Append, FileAccess.Write);
|
_logFile = LogPath.Open(FileMode.Append, FileAccess.Write);
|
||||||
|
|
||||||
_logStream = new StreamWriter(_logFile, Encoding.UTF8);
|
_logStream = new StreamWriter(_logFile, Encoding.UTF8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IObservable<ILogMessage> Messages => _messages;
|
public IObservable<ILogMessage> Messages => _messages;
|
||||||
public AbsolutePath LogPath { get; }
|
public AbsolutePath LogPath { get; }
|
||||||
public ReadOnlyObservableCollection<ILogMessage> MessageLog => _messagesFiltered;
|
public ReadOnlyObservableCollection<ILogMessage> MessageLog => _messagesFiltered;
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
@ -71,7 +71,7 @@ public class LoggerProvider : ILoggerProvider
|
|||||||
|
|
||||||
private void LogToFile(ILogMessage logMessage)
|
private void LogToFile(ILogMessage logMessage)
|
||||||
{
|
{
|
||||||
var line = $"[{logMessage.TimeStamp - _startupTime}] {logMessage.LongMessage}";
|
string? line = $"[{logMessage.TimeStamp - _startupTime}] {logMessage.LongMessage}";
|
||||||
lock (_logStream)
|
lock (_logStream)
|
||||||
{
|
{
|
||||||
_logStream.Write(line);
|
_logStream.Write(line);
|
||||||
@ -86,18 +86,18 @@ public class LoggerProvider : ILoggerProvider
|
|||||||
|
|
||||||
public class Logger : ILogger
|
public class Logger : ILogger
|
||||||
{
|
{
|
||||||
private readonly string _categoryName;
|
private readonly string _categoryName;
|
||||||
private readonly LoggerProvider _provider;
|
private readonly LoggerProvider _provider;
|
||||||
private ImmutableList<object> Scopes = ImmutableList<object>.Empty;
|
private ImmutableList<object> Scopes = ImmutableList<object>.Empty;
|
||||||
|
|
||||||
public Logger(LoggerProvider provider, string categoryName)
|
public Logger(LoggerProvider provider, string categoryName)
|
||||||
{
|
{
|
||||||
_categoryName = categoryName;
|
_categoryName = categoryName;
|
||||||
_provider = provider;
|
_provider = provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception,
|
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception,
|
||||||
Func<TState, Exception?, string> formatter)
|
Func<TState, Exception?, string> formatter)
|
||||||
{
|
{
|
||||||
Debug.WriteLine($"{logLevel} - {formatter(state, exception)}");
|
Debug.WriteLine($"{logLevel} - {formatter(state, exception)}");
|
||||||
_provider._messages.OnNext(new LogMessage<TState>(DateTime.UtcNow, _provider.NextMessageId(), logLevel,
|
_provider._messages.OnNext(new LogMessage<TState>(DateTime.UtcNow, _provider.NextMessageId(), logLevel,
|
||||||
@ -120,13 +120,13 @@ public class LoggerProvider : ILoggerProvider
|
|||||||
{
|
{
|
||||||
long MessageId { get; }
|
long MessageId { get; }
|
||||||
|
|
||||||
string ShortMessage { get; }
|
string ShortMessage { get; }
|
||||||
DateTime TimeStamp { get; }
|
DateTime TimeStamp { get; }
|
||||||
string LongMessage { get; }
|
string LongMessage { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private record LogMessage<TState>(DateTime TimeStamp, long MessageId, LogLevel LogLevel, EventId EventId,
|
private record LogMessage<TState>(DateTime TimeStamp, long MessageId, LogLevel LogLevel, EventId EventId,
|
||||||
TState State, Exception? Exception, Func<TState, Exception?, string> Formatter) : ILogMessage
|
TState State, Exception? Exception, Func<TState, Exception?, string> Formatter) : ILogMessage
|
||||||
{
|
{
|
||||||
public string ShortMessage => Formatter(State, Exception);
|
public string ShortMessage => Formatter(State, Exception);
|
||||||
|
|
||||||
@ -146,4 +146,4 @@ public class LoggerProvider : ILoggerProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
@page "/configure"
|
@page "/Configure"
|
||||||
@using Wabbajack.App.Blazor.Store
|
|
||||||
|
@using Wabbajack.App.Blazor.State
|
||||||
|
|
||||||
@namespace Wabbajack.App.Blazor.Pages
|
@namespace Wabbajack.App.Blazor.Pages
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
@ -12,11 +14,11 @@
|
|||||||
<div class="left-side">
|
<div class="left-side">
|
||||||
@if (!string.IsNullOrEmpty(ModList.Name))
|
@if (!string.IsNullOrEmpty(ModList.Name))
|
||||||
{
|
{
|
||||||
if (_installState.Value.CurrentInstallState != InstallState.InstallStateEnum.Installing)
|
if (InstallState != GlobalState.InstallStateEnum.Installing)
|
||||||
{
|
{
|
||||||
<InfoBlock Title="@ModList.Name" Subtitle="@ModList.Author" Comment="@ModList.Version.ToString()" Description="@ModList.Description"/>
|
<InfoBlock Title="@ModList.Name" Subtitle="@ModList.Author" Comment="@ModList.Version.ToString()" Description="@ModList.Description"/>
|
||||||
}
|
}
|
||||||
else if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Installing)
|
else if (InstallState == GlobalState.InstallStateEnum.Installing)
|
||||||
{
|
{
|
||||||
<InfoBlock Supertitle="Installing..." Title="@ModList.Name" Subtitle="@StatusText"/>
|
<InfoBlock Supertitle="Installing..." Title="@ModList.Name" Subtitle="@StatusText"/>
|
||||||
// TODO: [Low] Step logging.
|
// TODO: [Low] Step logging.
|
||||||
@ -26,11 +28,11 @@
|
|||||||
<div class="right-side">
|
<div class="right-side">
|
||||||
@if (!string.IsNullOrEmpty(Image))
|
@if (!string.IsNullOrEmpty(Image))
|
||||||
{
|
{
|
||||||
if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Configuration)
|
if (InstallState != GlobalState.InstallStateEnum.Installing)
|
||||||
{
|
{
|
||||||
<InfoImage Image="@Image"/>
|
<InfoImage Image="@Image"/>
|
||||||
}
|
}
|
||||||
else if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Installing)
|
else if (InstallState == GlobalState.InstallStateEnum.Installing)
|
||||||
{
|
{
|
||||||
// TODO: [Low] Implement featured mod slideshow.
|
// 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."/>
|
<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."/>
|
||||||
@ -38,13 +40,13 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@if (_installState.Value.CurrentInstallState == InstallState.InstallStateEnum.Installing)
|
@if (InstallState == GlobalState.InstallStateEnum.Installing)
|
||||||
{
|
{
|
||||||
<div class="logger-container">
|
<div class="logger-container">
|
||||||
<VirtualLogger Messages="_loggerProvider.Messages"/>
|
<VirtualLogger Messages="_loggerProvider.Messages"/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (_installState.Value.CurrentInstallState != InstallState.InstallStateEnum.Installing)
|
@if (InstallState != GlobalState.InstallStateEnum.Installing)
|
||||||
{
|
{
|
||||||
<div class="settings">
|
<div class="settings">
|
||||||
<div class="locations">
|
<div class="locations">
|
||||||
|
@ -2,9 +2,7 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Fluxor;
|
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Wabbajack.App.Blazor.Store;
|
|
||||||
using Wabbajack.DTOs;
|
using Wabbajack.DTOs;
|
||||||
using Wabbajack.DTOs.JsonConverters;
|
using Wabbajack.DTOs.JsonConverters;
|
||||||
using Wabbajack.Installer;
|
using Wabbajack.Installer;
|
||||||
@ -14,147 +12,147 @@ using Wabbajack.Downloaders.GameFile;
|
|||||||
using Wabbajack.Hashing.xxHash64;
|
using Wabbajack.Hashing.xxHash64;
|
||||||
using Wabbajack.Services.OSIntegrated;
|
using Wabbajack.Services.OSIntegrated;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Wabbajack.App.Blazor.Models;
|
using Wabbajack.App.Blazor.Models;
|
||||||
|
using Wabbajack.App.Blazor.State;
|
||||||
|
|
||||||
namespace Wabbajack.App.Blazor.Pages
|
namespace Wabbajack.App.Blazor.Pages;
|
||||||
|
|
||||||
|
public partial class Configure
|
||||||
{
|
{
|
||||||
public partial class Configure
|
[Inject] private NavigationManager NavigationManager { get; set; }
|
||||||
|
[Inject] private GlobalState GlobalState { get; set; }
|
||||||
|
[Inject] private DTOSerializer _dtos { get; set; }
|
||||||
|
[Inject] private IServiceProvider _serviceProvider { get; set; }
|
||||||
|
[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.
|
||||||
|
private AbsolutePath ModListPath { get; set; }
|
||||||
|
private AbsolutePath InstallPath { get; set; }
|
||||||
|
private AbsolutePath DownloadPath { get; set; }
|
||||||
|
|
||||||
|
private string StatusText { get; set; }
|
||||||
|
public GlobalState.InstallStateEnum InstallState { get; set; }
|
||||||
|
private LoggerProvider.ILogMessage CurrentLog { get; set; }
|
||||||
|
|
||||||
|
private const string InstallSettingsPrefix = "install-settings-";
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
[Inject] private NavigationManager NavigationManager { get; set; }
|
// var Location = KnownFolders.EntryPoint.Combine("downloaded_mod_lists", machineURL).WithExtension(Ext.Wabbajack);
|
||||||
[Inject] private IState<InstallState> _installState { get; set; }
|
GlobalState.OnInstallStateChange += () => InstallState = GlobalState.InstallState;
|
||||||
[Inject] private DTOSerializer _dtos { get; set; }
|
await CheckValidInstallPath();
|
||||||
[Inject] private IDispatcher _dispatcher { get; set; }
|
await base.OnInitializedAsync();
|
||||||
[Inject] private IServiceProvider _serviceProvider { get; set; }
|
}
|
||||||
[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 async Task CheckValidInstallPath()
|
||||||
private ModList ModList { get; set; } = new(); // Init a new modlist so we can listen for changes in Blazor components.
|
{
|
||||||
private AbsolutePath ModListPath { get; set; }
|
if (GlobalState.ModListPath == AbsolutePath.Empty) return;
|
||||||
private AbsolutePath InstallPath { get; set; }
|
|
||||||
private AbsolutePath DownloadPath { get; set; }
|
|
||||||
|
|
||||||
private string StatusText { get; set; }
|
ModListPath = GlobalState.ModListPath;
|
||||||
private LoggerProvider.ILogMessage CurrentLog { get; set; }
|
ModList = await StandardInstaller.LoadFromFile(_dtos, ModListPath);
|
||||||
|
GlobalState.ModList = ModList;
|
||||||
|
|
||||||
private const string InstallSettingsPrefix = "install-settings-";
|
string hex = (await ModListPath.ToString().Hash()).ToHex();
|
||||||
|
var prevSettings = await _settingsManager.Load<SavedInstallSettings>(InstallSettingsPrefix + hex);
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
if (prevSettings.ModListLocation == ModListPath)
|
||||||
{
|
{
|
||||||
// var Location = KnownFolders.EntryPoint.Combine("downloaded_mod_lists", machineURL).WithExtension(Ext.Wabbajack);
|
ModListPath = prevSettings.ModListLocation;
|
||||||
await CheckValidInstallPath();
|
InstallPath = prevSettings.InstallLocation;
|
||||||
await base.OnInitializedAsync();
|
DownloadPath = prevSettings.DownloadLoadction;
|
||||||
|
//ModlistMetadata = metadata ?? prevSettings.Metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CheckValidInstallPath()
|
Stream image = await StandardInstaller.ModListImageStream(ModListPath);
|
||||||
|
await using var reader = new MemoryStream();
|
||||||
|
await image.CopyToAsync(reader);
|
||||||
|
Image = $"data:image/png;base64,{Convert.ToBase64String(reader.ToArray())}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void SelectInstallFolder()
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (_installState.Value.CurrentModListPath == null) return;
|
AbsolutePath? thing = await Dialog.ShowDialogNonBlocking(true);
|
||||||
|
if (thing != null) InstallPath = (AbsolutePath)thing;
|
||||||
ModListPath = (AbsolutePath)_installState.Value.CurrentModListPath;
|
StateHasChanged();
|
||||||
ModList = await StandardInstaller.LoadFromFile(_dtos, ModListPath);
|
|
||||||
_dispatcher.Dispatch(new UpdateInstallState(InstallState.InstallStateEnum.Configuration, ModList, ModListPath, null, null));
|
|
||||||
|
|
||||||
string hex = (await ModListPath.ToString().Hash()).ToHex();
|
|
||||||
var prevSettings = await _settingsManager.Load<SavedInstallSettings>(InstallSettingsPrefix + hex);
|
|
||||||
|
|
||||||
if (prevSettings.ModListLocation == ModListPath)
|
|
||||||
{
|
|
||||||
ModListPath = prevSettings.ModListLocation;
|
|
||||||
InstallPath = prevSettings.InstallLocation;
|
|
||||||
DownloadPath = prevSettings.DownloadLoadction;
|
|
||||||
//ModlistMetadata = metadata ?? prevSettings.Metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream image = await StandardInstaller.ModListImageStream(ModListPath);
|
|
||||||
await using var reader = new MemoryStream();
|
|
||||||
await image.CopyToAsync(reader);
|
|
||||||
Image = $"data:image/png;base64,{Convert.ToBase64String(reader.ToArray())}";
|
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
private async void SelectInstallFolder()
|
|
||||||
{
|
{
|
||||||
try
|
Debug.Print(ex.Message);
|
||||||
{
|
|
||||||
AbsolutePath? thing = await Dialog.ShowDialogNonBlocking(true);
|
|
||||||
if (thing != null) InstallPath = (AbsolutePath)thing;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.Print(ex.Message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async void SelectDownloadFolder()
|
private async void SelectDownloadFolder()
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
try
|
AbsolutePath? thing = await Dialog.ShowDialogNonBlocking(true);
|
||||||
{
|
if (thing != null) DownloadPath = (AbsolutePath)thing;
|
||||||
AbsolutePath? thing = await Dialog.ShowDialogNonBlocking(true);
|
StateHasChanged();
|
||||||
if (thing != null) DownloadPath = (AbsolutePath)thing;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.Print(ex.Message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
private async Task Install()
|
|
||||||
{
|
{
|
||||||
_dispatcher.Dispatch(new UpdateInstallState(InstallState.InstallStateEnum.Installing, ModList, ModListPath, InstallPath, DownloadPath));
|
Debug.Print(ex.Message);
|
||||||
await Task.Run(BeginInstall);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task BeginInstall()
|
private async Task Install()
|
||||||
|
{
|
||||||
|
GlobalState.InstallState = GlobalState.InstallStateEnum.Installing;
|
||||||
|
await Task.Run(BeginInstall);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task BeginInstall()
|
||||||
|
{
|
||||||
|
string postfix = (await ModListPath.ToString().Hash()).ToHex();
|
||||||
|
await _settingsManager.Save(InstallSettingsPrefix + postfix, new SavedInstallSettings
|
||||||
{
|
{
|
||||||
string postfix = (await ModListPath.ToString().Hash()).ToHex();
|
ModListLocation = ModListPath,
|
||||||
await _settingsManager.Save(InstallSettingsPrefix + postfix, new SavedInstallSettings
|
InstallLocation = InstallPath,
|
||||||
|
DownloadLoadction = DownloadPath
|
||||||
|
});
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var installer = StandardInstaller.Create(_serviceProvider, new InstallerConfiguration
|
||||||
{
|
{
|
||||||
ModListLocation = ModListPath,
|
Game = ModList.GameType,
|
||||||
InstallLocation = InstallPath,
|
Downloads = DownloadPath,
|
||||||
DownloadLoadction = DownloadPath
|
Install = InstallPath,
|
||||||
|
ModList = ModList,
|
||||||
|
ModlistArchive = ModListPath,
|
||||||
|
SystemParameters = _parametersConstructor.Create(),
|
||||||
|
GameFolder = _gameLocator.GameLocation(ModList.GameType)
|
||||||
});
|
});
|
||||||
|
|
||||||
try
|
|
||||||
|
installer.OnStatusUpdate = update =>
|
||||||
{
|
{
|
||||||
var installer = StandardInstaller.Create(_serviceProvider, new InstallerConfiguration
|
if (StatusText != update.StatusText)
|
||||||
{
|
{
|
||||||
Game = ModList.GameType,
|
StatusText = update.StatusText;
|
||||||
Downloads = DownloadPath,
|
InvokeAsync(StateHasChanged);
|
||||||
Install = InstallPath,
|
}
|
||||||
ModList = ModList,
|
};
|
||||||
ModlistArchive = ModListPath,
|
|
||||||
SystemParameters = _parametersConstructor.Create(),
|
|
||||||
GameFolder = _gameLocator.GameLocation(ModList.GameType)
|
|
||||||
});
|
|
||||||
|
|
||||||
|
await installer.Begin(CancellationToken.None);
|
||||||
installer.OnStatusUpdate = update =>
|
}
|
||||||
{
|
catch (Exception ex)
|
||||||
if (StatusText != update.StatusText)
|
{
|
||||||
{
|
Debug.Print(ex.Message);
|
||||||
StatusText = update.StatusText;
|
|
||||||
InvokeAsync(StateHasChanged);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
await installer.Begin(CancellationToken.None);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.Print(ex.Message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
internal class SavedInstallSettings
|
|
||||||
{
|
internal class SavedInstallSettings
|
||||||
public AbsolutePath ModListLocation { get; set; }
|
{
|
||||||
public AbsolutePath InstallLocation { get; set; }
|
public AbsolutePath ModListLocation { get; set; }
|
||||||
public AbsolutePath DownloadLoadction { get; set; }
|
public AbsolutePath InstallLocation { get; set; }
|
||||||
public ModlistMetadata Metadata { get; set; }
|
public AbsolutePath DownloadLoadction { get; set; }
|
||||||
}
|
public ModlistMetadata Metadata { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,105 +0,0 @@
|
|||||||
@font-face {
|
|
||||||
font-family: "Raleway";
|
|
||||||
src: url("fonts/Raleway-Variable.ttf");
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "YanoneKaffeesatz";
|
|
||||||
src: url("fonts/YanoneKaffeesatz-Variable.ttf");
|
|
||||||
}
|
|
||||||
#content {
|
|
||||||
display: flex;
|
|
||||||
height: 100%;
|
|
||||||
align-content: center;
|
|
||||||
justify-content: space-around;
|
|
||||||
align-items: center;
|
|
||||||
color: white;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
#content .install-background {
|
|
||||||
position: absolute;
|
|
||||||
width: calc(100% - 75px);
|
|
||||||
height: calc(100% - 65px);
|
|
||||||
filter: blur(25px) brightness(50%);
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
#content .install-background img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
#content .list {
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
#content .list .left-side, #content .list .right-side {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
#content .logger-container {
|
|
||||||
height: 200px;
|
|
||||||
width: 100%;
|
|
||||||
padding: 0.5rem;
|
|
||||||
background: rgba(0, 0, 0, 0.2);
|
|
||||||
color: lightgrey;
|
|
||||||
border: solid 1px black;
|
|
||||||
}
|
|
||||||
#content .settings {
|
|
||||||
font-size: 0.85rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
padding: 1rem;
|
|
||||||
backdrop-filter: brightness(0.5);
|
|
||||||
}
|
|
||||||
#content .settings .locations {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
#content .settings .locations .labels span {
|
|
||||||
display: block;
|
|
||||||
height: 2rem;
|
|
||||||
padding: 0.25rem;
|
|
||||||
margin: 0.25rem;
|
|
||||||
white-space: pre;
|
|
||||||
cursor: pointer;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
#content .settings .locations .paths {
|
|
||||||
flex: 1;
|
|
||||||
margin-left: 1rem;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
#content .settings .locations .paths span {
|
|
||||||
display: block;
|
|
||||||
height: 2rem;
|
|
||||||
padding: 0.25rem;
|
|
||||||
margin: 0.25rem;
|
|
||||||
white-space: pre;
|
|
||||||
cursor: pointer;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
border: solid 1px rgba(255, 255, 255, 0.3);
|
|
||||||
}
|
|
||||||
#content .settings .options {
|
|
||||||
display: flex;
|
|
||||||
flex-flow: row wrap;
|
|
||||||
flex-direction: column;
|
|
||||||
margin-left: 2rem;
|
|
||||||
}
|
|
||||||
#content .settings .install {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
margin: 0.5rem;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
#content .settings .install img {
|
|
||||||
width: 5rem;
|
|
||||||
height: 5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=Configure.razor.css.map */
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["../Shared/Globals.scss","Configure.razor.scss"],"names":[],"mappings":"AAAC;EACC;EACA;;AAGF;EACE;EACA;;ACWF;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;;AAIR;EACI;EACA;EACA;EACA;;AAEA;EACI;;AAIR;EACI;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAGI;EApEZ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAkEQ;EACI;EACA;EACA;;AAEA;EA9EZ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAyEgB;;AAKZ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA","file":"Configure.razor.css"}
|
|
@ -6,109 +6,110 @@ $checkbox-background-checked: $accent-color;
|
|||||||
$checkbox-size: 0.75rem;
|
$checkbox-size: 0.75rem;
|
||||||
|
|
||||||
@mixin path-span {
|
@mixin path-span {
|
||||||
display: block;
|
display: block;
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
padding: 0.25rem;
|
padding: 0.25rem;
|
||||||
margin: 0.25rem;
|
margin: 0.25rem;
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#content {
|
#content {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
align-content: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
color: white;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.install-background {
|
||||||
|
position: absolute;
|
||||||
|
width: calc(100% - #{$sidebar-width});
|
||||||
|
height: calc(100% - #{$header-height});
|
||||||
|
filter: blur(25px) brightness(50%);
|
||||||
|
z-index: -1;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
flex: 1;
|
||||||
align-content: center;
|
overflow: hidden;
|
||||||
justify-content: space-around;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: white;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
.install-background {
|
.left-side, .right-side {
|
||||||
position: absolute;
|
flex: 1;
|
||||||
width: calc(100% - #{$sidebar-width});
|
margin: 1rem;
|
||||||
height: calc(100% - #{$header-height});
|
|
||||||
filter: blur(25px) brightness(50%);
|
|
||||||
z-index: -1;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.list {
|
.logger-container {
|
||||||
display: flex;
|
height: 200px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.5rem;
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
color: lightgrey;
|
||||||
|
border: solid 1px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
padding: 1rem;
|
||||||
|
backdrop-filter: brightness(0.5);
|
||||||
|
|
||||||
|
.locations {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.labels {
|
||||||
|
span {
|
||||||
|
@include path-span;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.paths {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
margin-left: 1rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.left-side, .right-side {
|
span {
|
||||||
flex: 1;
|
@include path-span;
|
||||||
|
border: solid 1px rgba(255, 255, 255, 0.3);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.logger-container {
|
.options {
|
||||||
height: 200px;
|
display: flex;
|
||||||
width: 100%;
|
flex-flow: row wrap;
|
||||||
padding: 0.5rem;
|
flex-direction: column;
|
||||||
background: rgb(0 0 0 / 20%);
|
margin-left: 2rem;
|
||||||
color: lightgrey;
|
|
||||||
border: solid 1px black;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings {
|
.install {
|
||||||
font-size: 0.85rem;
|
display: flex;
|
||||||
display: flex;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
margin: 0.5rem;
|
||||||
padding: 1rem;
|
cursor: pointer;
|
||||||
backdrop-filter: brightness(0.5);
|
|
||||||
|
|
||||||
.locations {
|
img {
|
||||||
display: flex;
|
width: 5rem;
|
||||||
flex-direction: row;
|
height: 5rem;
|
||||||
flex: 1;
|
}
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.labels {
|
|
||||||
span {
|
|
||||||
@include path-span;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.paths {
|
|
||||||
flex: 1;
|
|
||||||
margin-left: 1rem;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
span {
|
|
||||||
@include path-span;
|
|
||||||
border: solid 1px rgba(255, 255, 255, 0.3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.options {
|
|
||||||
display: flex;
|
|
||||||
flex-flow: row wrap;
|
|
||||||
flex-direction: column;
|
|
||||||
margin-left: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.install {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
margin: 0.5rem;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 5rem;
|
|
||||||
height: 5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
8
Wabbajack.App.Blazor/Pages/Create.razor
Normal file
8
Wabbajack.App.Blazor/Pages/Create.razor
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
@page "/Create"
|
||||||
|
@namespace Wabbajack.App.Blazor.Pages
|
||||||
|
|
||||||
|
<div id="content">
|
||||||
|
<div class="resources">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -1,47 +1,15 @@
|
|||||||
@page "/gallery"
|
@page "/Gallery"
|
||||||
@namespace Wabbajack.App.Blazor.Pages
|
|
||||||
@using Wabbajack.Networking.WabbajackClientApi;
|
|
||||||
@using Wabbajack.DTOs
|
|
||||||
@using System.Diagnostics
|
|
||||||
@using Microsoft.Extensions.Logging
|
|
||||||
@using Wabbajack.App.Blazor.Models
|
|
||||||
|
|
||||||
@inject Client _client
|
@using Wabbajack.DTOs
|
||||||
|
|
||||||
|
@namespace Wabbajack.App.Blazor.Pages
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
@foreach (ModlistMetadata item in _listItems)
|
@foreach (ModlistMetadata modlist in _listItems)
|
||||||
{
|
{
|
||||||
<ModlistItem Metadata=@item></ModlistItem>
|
<ModlistItem Metadata=@modlist>
|
||||||
|
<InteractionIcon Icon="images/icons/install.svg" Label="Install" Size="75px" OnClick="@(() => OnClickDownload(modlist))"/>
|
||||||
|
<InteractionIcon Icon="images/icons/info.svg" Label="Information" Size="75px" OnClick="@(() => OnClickInformation(modlist))"/>
|
||||||
|
</ModlistItem>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@code {
|
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private ILogger<Gallery> _logger { get; set; }
|
|
||||||
// [Inject]
|
|
||||||
// private LoggerProvider _loggerProvider { get; set; }
|
|
||||||
[Inject]
|
|
||||||
private Services.OSIntegrated.Configuration _configuration { get; set; }
|
|
||||||
|
|
||||||
private List<ModlistMetadata> _listItems { get; set; } = new() { };
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_logger.LogInformation("Getting modlists...");
|
|
||||||
ModlistMetadata[] modLists = await _client.LoadLists();
|
|
||||||
_listItems.AddRange(modLists.ToList());
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
//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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
86
Wabbajack.App.Blazor/Pages/Gallery.razor.cs
Normal file
86
Wabbajack.App.Blazor/Pages/Gallery.razor.cs
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Wabbajack.App.Blazor.State;
|
||||||
|
using Wabbajack.Common;
|
||||||
|
using Wabbajack.DTOs;
|
||||||
|
using Wabbajack.Networking.WabbajackClientApi;
|
||||||
|
using Wabbajack.Paths;
|
||||||
|
using Wabbajack.Paths.IO;
|
||||||
|
using Wabbajack.RateLimiter;
|
||||||
|
using Wabbajack.Services.OSIntegrated.Services;
|
||||||
|
|
||||||
|
namespace Wabbajack.App.Blazor.Pages;
|
||||||
|
|
||||||
|
public partial class Gallery
|
||||||
|
{
|
||||||
|
[Inject] private GlobalState GlobalState { get; set; }
|
||||||
|
[Inject] private NavigationManager NavigationManager { get; set; }
|
||||||
|
[Inject] private ILogger<Gallery> _logger { get; set; }
|
||||||
|
[Inject] private Client _client { get; set; }
|
||||||
|
[Inject] private ModListDownloadMaintainer _maintainer { get; set; }
|
||||||
|
|
||||||
|
public Percent DownloadProgress { get; set; }
|
||||||
|
|
||||||
|
private List<ModlistMetadata> _listItems { get; set; } = new();
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Getting modlists...");
|
||||||
|
ModlistMetadata[] modLists = await _client.LoadLists();
|
||||||
|
_listItems.AddRange(modLists.ToList());
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
//TODO: [Critical] Figure out why an exception is thrown on first navigation.
|
||||||
|
_logger.LogError(ex, "Error while loading lists");
|
||||||
|
}
|
||||||
|
|
||||||
|
await base.OnInitializedAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void OnClickDownload(ModlistMetadata metadata)
|
||||||
|
{
|
||||||
|
// GlobalState.NavigationAllowed = !GlobalState.NavigationAllowed;
|
||||||
|
await Download(metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void OnClickInformation(ModlistMetadata metadata)
|
||||||
|
{
|
||||||
|
// TODO: [High] Implement information modal.
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Download(ModlistMetadata metadata)
|
||||||
|
{
|
||||||
|
GlobalState.NavigationAllowed = false;
|
||||||
|
await using Timer timer = new(_ => InvokeAsync(StateHasChanged));
|
||||||
|
timer.Change(TimeSpan.FromMilliseconds(250), TimeSpan.FromMilliseconds(250));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
(IObservable<Percent> progress, Task task) = _maintainer.DownloadModlist(metadata);
|
||||||
|
IDisposable dispose = progress.Subscribe(p => DownloadProgress = p);
|
||||||
|
|
||||||
|
await task;
|
||||||
|
//await _wjClient.SendMetric("downloading", Metadata.Title);
|
||||||
|
dispose.Dispose();
|
||||||
|
|
||||||
|
AbsolutePath path = KnownFolders.EntryPoint.Combine("downloaded_mod_lists", metadata.Links.MachineURL).WithExtension(Ext.Wabbajack);
|
||||||
|
NavigationManager.NavigateTo("/Configure");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Print(e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
await timer.DisposeAsync();
|
||||||
|
GlobalState.NavigationAllowed = true;
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +0,0 @@
|
|||||||
#content {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-flow: row wrap;
|
|
||||||
justify-content: space-evenly;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=Gallery.razor.css.map */
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["Gallery.razor.scss"],"names":[],"mappings":"AAAC;EACC;EACA;EACA;EACA","file":"Gallery.razor.css"}
|
|
@ -1,7 +0,0 @@
|
|||||||
#content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=Home.razor.css.map */
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["Home.razor.scss"],"names":[],"mappings":"AAAC;EACC;EACA;EAEA","file":"Home.razor.css"}
|
|
@ -1,4 +1,5 @@
|
|||||||
@page "/SelectInstall"
|
@page "/Install"
|
||||||
|
|
||||||
@namespace Wabbajack.App.Blazor.Pages
|
@namespace Wabbajack.App.Blazor.Pages
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
@ -17,9 +18,9 @@
|
|||||||
<div class="modlist">
|
<div class="modlist">
|
||||||
<img src="https://i.imgur.com/9jnSPcX.png" alt="">
|
<img src="https://i.imgur.com/9jnSPcX.png" alt="">
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="title">Living Skyrim</div>
|
<div class="title">[Title]</div>
|
||||||
<div class="description">ForgottenGlory</div>
|
<div class="description">[Description]</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
28
Wabbajack.App.Blazor/Pages/Install.razor.cs
Normal file
28
Wabbajack.App.Blazor/Pages/Install.razor.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.WindowsAPICodePack.Dialogs;
|
||||||
|
using Wabbajack.App.Blazor.State;
|
||||||
|
using Wabbajack.Common;
|
||||||
|
using Wabbajack.Paths;
|
||||||
|
|
||||||
|
namespace Wabbajack.App.Blazor.Pages;
|
||||||
|
|
||||||
|
public partial class Install
|
||||||
|
{
|
||||||
|
[Inject] private NavigationManager NavigationManager { get; set; }
|
||||||
|
[Inject] private GlobalState GlobalState { get; set; }
|
||||||
|
|
||||||
|
private void SelectFile()
|
||||||
|
{
|
||||||
|
using (var dialog = new CommonOpenFileDialog())
|
||||||
|
{
|
||||||
|
dialog.Multiselect = false;
|
||||||
|
dialog.Filters.Add(new CommonFileDialogFilter("Wabbajack File", "*" + Ext.Wabbajack));
|
||||||
|
if (dialog.ShowDialog() != CommonFileDialogResult.Ok) return;
|
||||||
|
GlobalState.ModListPath = dialog.FileName.ToAbsolutePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigationManager.NavigateTo("/Configure");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void VerifyFile(AbsolutePath path) { }
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
@page "/"
|
@page "/"
|
||||||
|
|
||||||
@namespace Wabbajack.App.Blazor.Pages
|
@namespace Wabbajack.App.Blazor.Pages
|
||||||
|
|
||||||
<News/>
|
<News/>
|
||||||
<div id="content"></div>
|
<div id="content"></div>
|
||||||
|
|
||||||
@ -18,4 +20,4 @@
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
}
|
}
|
@ -4,6 +4,7 @@
|
|||||||
//height: inherit;
|
//height: inherit;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//.header {
|
//.header {
|
||||||
// flex: 2;
|
// flex: 2;
|
@ -1,73 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using DynamicData;
|
|
||||||
using Fluxor;
|
|
||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
using Microsoft.Win32;
|
|
||||||
using Microsoft.WindowsAPICodePack.Dialogs;
|
|
||||||
using Wabbajack.App.Blazor.Store;
|
|
||||||
using Wabbajack.Common;
|
|
||||||
using Wabbajack.DTOs;
|
|
||||||
using Wabbajack.DTOs.JsonConverters;
|
|
||||||
using Wabbajack.Installer;
|
|
||||||
using Wabbajack.Paths;
|
|
||||||
|
|
||||||
namespace Wabbajack.App.Blazor.Pages
|
|
||||||
{
|
|
||||||
public partial class SelectInstall
|
|
||||||
{
|
|
||||||
[Inject] private NavigationManager NavigationManager { get; set; }
|
|
||||||
[Inject] private IState<InstallState> _installState { get; set; }
|
|
||||||
[Inject] private IDispatcher _dispatcher { get; set; }
|
|
||||||
|
|
||||||
private AbsolutePath _modListPath { get; set; }
|
|
||||||
|
|
||||||
private void SelectFile()
|
|
||||||
{
|
|
||||||
using (var dialog = new CommonOpenFileDialog())
|
|
||||||
{
|
|
||||||
dialog.Multiselect = false;
|
|
||||||
dialog.Filters.Add(new CommonFileDialogFilter("Wabbajack File", "*" + Ext.Wabbajack));
|
|
||||||
if (dialog.ShowDialog() != CommonFileDialogResult.Ok) return;
|
|
||||||
_modListPath = dialog.FileName.ToAbsolutePath();
|
|
||||||
}
|
|
||||||
VerifyFile(_modListPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// private void SelectFile()
|
|
||||||
// {
|
|
||||||
// var file = new OpenFileDialog
|
|
||||||
// {
|
|
||||||
// Filter = "Wabbajack (*.wabbajack)|*.wabbajack",
|
|
||||||
// FilterIndex = 1,
|
|
||||||
// Multiselect = false,
|
|
||||||
// Title = "Wabbajack file for install"
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// if (file.ShowDialog() != true) return;
|
|
||||||
// var path = file.FileName.ToAbsolutePath();
|
|
||||||
// VerifyFile(path);
|
|
||||||
// }
|
|
||||||
// catch (Exception ex)
|
|
||||||
// {
|
|
||||||
// Debug.Print(ex.Message);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
private void VerifyFile(AbsolutePath path)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_dispatcher.Dispatch(new UpdateInstallState(InstallState.InstallStateEnum.Configuration, null, path, null, null));
|
|
||||||
NavigationManager.NavigateTo("/configure");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.Print(ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
#content {
|
|
||||||
display: flex;
|
|
||||||
height: 100%;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
#content .select {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-evenly;
|
|
||||||
}
|
|
||||||
#content .select div {
|
|
||||||
display: flex;
|
|
||||||
border: solid 1px red;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
#content .select div img {
|
|
||||||
width: 15rem;
|
|
||||||
height: 15rem;
|
|
||||||
}
|
|
||||||
#content .recent .title {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
font-weight: 100;
|
|
||||||
}
|
|
||||||
#content .recent .modlist img {
|
|
||||||
height: 4rem;
|
|
||||||
width: auto;
|
|
||||||
border: solid 1px red;
|
|
||||||
}
|
|
||||||
#content .recent .modlist .info {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=SelectInstall.razor.css.map */
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["SelectInstall.razor.scss"],"names":[],"mappings":"AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE,OAvBa;EAwBb,QAxBa;;AA8BjB;EACE;EACA;;AAIA;EACE;EACA;EACA;;AAGF;EACE;EACA","file":"SelectInstall.razor.css"}
|
|
8
Wabbajack.App.Blazor/Pages/Settings.razor
Normal file
8
Wabbajack.App.Blazor/Pages/Settings.razor
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
@page "/Settings"
|
||||||
|
@namespace Wabbajack.App.Blazor.Pages
|
||||||
|
|
||||||
|
<div id="content">
|
||||||
|
<div class="resources">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
23
Wabbajack.App.Blazor/Pages/Settings.razor.cs
Normal file
23
Wabbajack.App.Blazor/Pages/Settings.razor.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Wabbajack.App.Models;
|
||||||
|
|
||||||
|
namespace Wabbajack.App.Blazor.Pages;
|
||||||
|
|
||||||
|
public partial class Settings
|
||||||
|
{
|
||||||
|
[Inject] private ResourceSettingsManager _resourceSettingsManager { get; set; }
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ResourceSettingsManager.ResourceSetting resource = await _resourceSettingsManager.GetSettings("Downloads");
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
catch (Exception ex) { }
|
||||||
|
|
||||||
|
await base.OnInitializedAsync();
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +0,0 @@
|
|||||||
@font-face {
|
|
||||||
font-family: "Raleway";
|
|
||||||
src: url("fonts/Raleway-Variable.ttf");
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "YanoneKaffeesatz";
|
|
||||||
src: url("fonts/YanoneKaffeesatz-Variable.ttf");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=Globals.css.map */
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["Globals.scss"],"names":[],"mappings":"AAAC;EACC;EACA;;AAGF;EACE;EACA","file":"Globals.css"}
|
|
@ -1,13 +1,22 @@
|
|||||||
@inherits LayoutComponentBase
|
@inherits LayoutComponentBase
|
||||||
|
@namespace Wabbajack.App.Blazor.Shared
|
||||||
|
|
||||||
@* This is required because layout components can't access scoped CSS. *@
|
<CascadingValue Value="@(this)">
|
||||||
@* <link rel="stylesheet" href="MainLayout.Razor.css"> *@
|
<div id="background"></div>
|
||||||
|
<SideBar/>
|
||||||
<div id="background"></div>
|
<div id="wrapper">
|
||||||
<SideBar/>
|
<TopBar/>
|
||||||
<div id="wrapper">
|
<div id="page">
|
||||||
<TopBar/>
|
@Body
|
||||||
<div id="page">
|
</div>
|
||||||
@Body
|
@if (ShowFooter)
|
||||||
|
{
|
||||||
|
<BottomBar/>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</CascadingValue>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
public bool ShowFooter { get; set; } = false;
|
||||||
|
}
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
@font-face {
|
|
||||||
font-family: "Raleway";
|
|
||||||
src: url("fonts/Raleway-Variable.ttf");
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "YanoneKaffeesatz";
|
|
||||||
src: url("fonts/YanoneKaffeesatz-Variable.ttf");
|
|
||||||
}
|
|
||||||
#background {
|
|
||||||
position: fixed;
|
|
||||||
height: 100vh;
|
|
||||||
width: 100%;
|
|
||||||
background: linear-gradient(320deg, #151022, #1f0d2a, #100214);
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wrapper {
|
|
||||||
width: calc(100% - 75px);
|
|
||||||
float: right;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#page {
|
|
||||||
margin-top: 65px;
|
|
||||||
height: calc(100% - 65px);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=MainLayout.razor.css.map */
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["Globals.scss","MainLayout.razor.scss"],"names":[],"mappings":"AAAC;EACC;EACA;;AAGF;EACE;EACA;;ACLF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE,YDHc;ECId","file":"MainLayout.razor.css"}
|
|
77
Wabbajack.App.Blazor/State/GlobalState.cs
Normal file
77
Wabbajack.App.Blazor/State/GlobalState.cs
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using Wabbajack.DTOs;
|
||||||
|
using Wabbajack.Paths;
|
||||||
|
|
||||||
|
namespace Wabbajack.App.Blazor.State;
|
||||||
|
|
||||||
|
public class GlobalState
|
||||||
|
{
|
||||||
|
#region Navigation Allowed
|
||||||
|
|
||||||
|
private bool _navigationAllowed = true;
|
||||||
|
|
||||||
|
public event Action OnNavigationStateChange;
|
||||||
|
|
||||||
|
public bool NavigationAllowed
|
||||||
|
{
|
||||||
|
get => _navigationAllowed;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_navigationAllowed = value;
|
||||||
|
OnNavigationStateChange?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Install
|
||||||
|
|
||||||
|
private InstallStateEnum _installState;
|
||||||
|
private AbsolutePath _modListPath;
|
||||||
|
private ModList _modList;
|
||||||
|
|
||||||
|
public event Action OnModListPathChange;
|
||||||
|
public event Action OnModListChange;
|
||||||
|
public event Action OnInstallStateChange;
|
||||||
|
|
||||||
|
public AbsolutePath ModListPath
|
||||||
|
{
|
||||||
|
get => _modListPath;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_modListPath = value;
|
||||||
|
OnModListPathChange?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModList ModList
|
||||||
|
{
|
||||||
|
get => _modList;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_modList = value;
|
||||||
|
OnModListChange?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public InstallStateEnum InstallState
|
||||||
|
{
|
||||||
|
get => _installState;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_installState = value;
|
||||||
|
OnInstallStateChange?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum InstallStateEnum
|
||||||
|
{
|
||||||
|
Waiting,
|
||||||
|
Configuration,
|
||||||
|
Installing,
|
||||||
|
Success,
|
||||||
|
Failure
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
@ -1,47 +0,0 @@
|
|||||||
using Fluxor;
|
|
||||||
using Wabbajack.DTOs;
|
|
||||||
|
|
||||||
namespace Wabbajack.App.Blazor.Store;
|
|
||||||
|
|
||||||
[FeatureState]
|
|
||||||
public class DownloadState
|
|
||||||
{
|
|
||||||
public DownloadStateEnum CurrentDownloadState { get; }
|
|
||||||
public ModlistMetadata CurrentModlistMetadata { get; }
|
|
||||||
|
|
||||||
// Required for initial state.
|
|
||||||
private DownloadState() { }
|
|
||||||
|
|
||||||
public DownloadState(DownloadStateEnum newState, ModlistMetadata newModlist)
|
|
||||||
{
|
|
||||||
CurrentDownloadState = newState;
|
|
||||||
CurrentModlistMetadata = newModlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum DownloadStateEnum
|
|
||||||
{
|
|
||||||
Waiting,
|
|
||||||
Downloading,
|
|
||||||
Downloaded,
|
|
||||||
Failure
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class UpdateDownloadState
|
|
||||||
{
|
|
||||||
public DownloadState.DownloadStateEnum State { get; }
|
|
||||||
public ModlistMetadata Modlist { get; }
|
|
||||||
|
|
||||||
public UpdateDownloadState(DownloadState.DownloadStateEnum state, ModlistMetadata modlist)
|
|
||||||
{
|
|
||||||
State = state;
|
|
||||||
Modlist = modlist;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DownloadStateReducers
|
|
||||||
{
|
|
||||||
[ReducerMethod]
|
|
||||||
public static DownloadState ReduceChangeDownloadState(DownloadState state, UpdateDownloadState action) =>
|
|
||||||
new(action.State, action.Modlist);
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
using Fluxor;
|
|
||||||
using Wabbajack.DTOs;
|
|
||||||
using Wabbajack.Paths;
|
|
||||||
|
|
||||||
namespace Wabbajack.App.Blazor.Store;
|
|
||||||
|
|
||||||
[FeatureState]
|
|
||||||
public class InstallState
|
|
||||||
{
|
|
||||||
public InstallStateEnum CurrentInstallState { get; }
|
|
||||||
public ModList? CurrentModList { get; }
|
|
||||||
public AbsolutePath? CurrentModListPath { get; }
|
|
||||||
public AbsolutePath? CurrentInstallPath { get; }
|
|
||||||
public AbsolutePath? CurrentDownloadPath { get; }
|
|
||||||
|
|
||||||
// Required for initial state.
|
|
||||||
private InstallState() { }
|
|
||||||
|
|
||||||
public InstallState(InstallStateEnum newState, ModList? newModList, AbsolutePath? newModListPath, AbsolutePath? newInstallPath, AbsolutePath? newDownloadPath)
|
|
||||||
{
|
|
||||||
CurrentInstallState = newState;
|
|
||||||
CurrentModList = newModList ?? CurrentModList;
|
|
||||||
CurrentModListPath = newModListPath ?? CurrentModListPath;
|
|
||||||
CurrentInstallPath = newInstallPath ?? CurrentInstallPath;
|
|
||||||
CurrentDownloadPath = newDownloadPath ?? CurrentDownloadPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum InstallStateEnum
|
|
||||||
{
|
|
||||||
Waiting,
|
|
||||||
Configuration,
|
|
||||||
Installing,
|
|
||||||
Success,
|
|
||||||
Failure
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class UpdateInstallState
|
|
||||||
{
|
|
||||||
public InstallState.InstallStateEnum State { get; }
|
|
||||||
public ModList? ModList { get; }
|
|
||||||
public AbsolutePath? ModListPath { get; }
|
|
||||||
public AbsolutePath? InstallPath { get; }
|
|
||||||
public AbsolutePath? DownloadPath { get; }
|
|
||||||
|
|
||||||
public UpdateInstallState(InstallState.InstallStateEnum state, ModList? modlist, AbsolutePath? modlistPath, AbsolutePath? installPath, AbsolutePath? downloadPath)
|
|
||||||
{
|
|
||||||
State = state;
|
|
||||||
ModList = modlist;
|
|
||||||
ModListPath = modlistPath;
|
|
||||||
InstallPath = installPath;
|
|
||||||
DownloadPath = downloadPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class InstallStateReducers
|
|
||||||
{
|
|
||||||
[ReducerMethod]
|
|
||||||
public static InstallState ReduceChangeInstallState(InstallState state, UpdateInstallState action) => new(action.State, action.ModList, action.ModListPath, action.InstallPath, action.DownloadPath);
|
|
||||||
}
|
|
@ -14,143 +14,140 @@ using Wabbajack;
|
|||||||
using static PInvoke.User32;
|
using static PInvoke.User32;
|
||||||
using UnmanagedType = System.Runtime.InteropServices.UnmanagedType;
|
using UnmanagedType = System.Runtime.InteropServices.UnmanagedType;
|
||||||
|
|
||||||
namespace Wabbajack.App.Blazor.Utility
|
namespace Wabbajack.App.Blazor.Utility;
|
||||||
|
|
||||||
|
// Much of the GDI code here is taken from : https://github.com/ModOrganizer2/modorganizer/blob/master/src/envmetrics.cpp
|
||||||
|
// Thanks to MO2 for being good citizens and supporting OSS code
|
||||||
|
public class SystemParametersConstructor
|
||||||
{
|
{
|
||||||
// Much of the GDI code here is taken from : https://github.com/ModOrganizer2/modorganizer/blob/master/src/envmetrics.cpp
|
private readonly ILogger<SystemParametersConstructor> _logger;
|
||||||
// Thanks to MO2 for being good citizens and supporting OSS code
|
|
||||||
public class SystemParametersConstructor
|
public SystemParametersConstructor(ILogger<SystemParametersConstructor> logger)
|
||||||
{
|
{
|
||||||
private readonly ILogger<SystemParametersConstructor> _logger;
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
public SystemParametersConstructor(ILogger<SystemParametersConstructor> logger)
|
private IEnumerable<(int Width, int Height, bool IsPrimary)> GetDisplays()
|
||||||
|
{
|
||||||
|
// Needed to make sure we get the right values from this call
|
||||||
|
SetProcessDPIAware();
|
||||||
|
unsafe
|
||||||
{
|
{
|
||||||
_logger = logger;
|
List<(int Width, int Height, bool IsPrimary)>? col = new List<(int Width, int Height, bool IsPrimary)>();
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<(int Width, int Height, bool IsPrimary)> GetDisplays()
|
EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero,
|
||||||
{
|
delegate(IntPtr hMonitor, IntPtr hdcMonitor, RECT* lprcMonitor, void* dwData)
|
||||||
// Needed to make sure we get the right values from this call
|
|
||||||
SetProcessDPIAware();
|
|
||||||
unsafe
|
|
||||||
{
|
|
||||||
var col = new List<(int Width, int Height, bool IsPrimary)>();
|
|
||||||
|
|
||||||
EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero,
|
|
||||||
delegate(IntPtr hMonitor, IntPtr hdcMonitor, RECT* lprcMonitor, void* dwData)
|
|
||||||
{
|
|
||||||
MONITORINFOEX mi = new MONITORINFOEX();
|
|
||||||
mi.cbSize = Marshal.SizeOf(mi);
|
|
||||||
bool success = GetMonitorInfo(hMonitor, (MONITORINFO*)&mi);
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
col.Add(((mi.Monitor.right - mi.Monitor.left), (mi.Monitor.bottom - mi.Monitor.top),
|
|
||||||
mi.Flags == MONITORINFO_Flags.MONITORINFOF_PRIMARY));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}, IntPtr.Zero);
|
|
||||||
return col;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SystemParameters Create()
|
|
||||||
{
|
|
||||||
var (width, height, _) = GetDisplays().First(d => d.IsPrimary);
|
|
||||||
|
|
||||||
/*using var f = new SharpDX.DXGI.Factory1();
|
|
||||||
var video_memory = f.Adapters1.Select(a =>
|
|
||||||
Math.Max(a.Description.DedicatedSystemMemory, (long)a.Description.DedicatedVideoMemory)).Max();*/
|
|
||||||
|
|
||||||
var dxgiMemory = 0UL;
|
|
||||||
|
|
||||||
unsafe
|
|
||||||
{
|
|
||||||
using var api = DXGI.GetApi();
|
|
||||||
|
|
||||||
IDXGIFactory1* factory1 = default;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
//https://docs.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-createdxgifactory1
|
var mi = new MONITORINFOEX();
|
||||||
SilkMarshal.ThrowHResult(api.CreateDXGIFactory1(SilkMarshal.GuidPtrOf<IDXGIFactory1>(), (void**)&factory1));
|
mi.cbSize = Marshal.SizeOf(mi);
|
||||||
|
bool success = GetMonitorInfo(hMonitor, (MONITORINFO*)&mi);
|
||||||
|
if (success)
|
||||||
|
col.Add((mi.Monitor.right - mi.Monitor.left, mi.Monitor.bottom - mi.Monitor.top,
|
||||||
|
mi.Flags == MONITORINFO_Flags.MONITORINFOF_PRIMARY));
|
||||||
|
|
||||||
uint i = 0u;
|
return true;
|
||||||
while (true)
|
}, IntPtr.Zero);
|
||||||
{
|
return col;
|
||||||
IDXGIAdapter1* adapter1 = default;
|
|
||||||
|
|
||||||
//https://docs.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-idxgifactory1-enumadapters1
|
|
||||||
var res = factory1->EnumAdapters1(i, &adapter1);
|
|
||||||
|
|
||||||
var exception = Marshal.GetExceptionForHR(res);
|
|
||||||
if (exception != null) break;
|
|
||||||
|
|
||||||
AdapterDesc1 adapterDesc = default;
|
|
||||||
|
|
||||||
//https://docs.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-idxgiadapter1-getdesc1
|
|
||||||
SilkMarshal.ThrowHResult(adapter1->GetDesc1(&adapterDesc));
|
|
||||||
|
|
||||||
var systemMemory = (ulong)adapterDesc.DedicatedSystemMemory;
|
|
||||||
var videoMemory = (ulong)adapterDesc.DedicatedVideoMemory;
|
|
||||||
|
|
||||||
var maxMemory = Math.Max(systemMemory, videoMemory);
|
|
||||||
if (maxMemory > dxgiMemory)
|
|
||||||
dxgiMemory = maxMemory;
|
|
||||||
|
|
||||||
adapter1->Release();
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.LogError(e, "While getting SystemParameters");
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (factory1->LpVtbl != (void**)IntPtr.Zero)
|
|
||||||
factory1->Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var memory = GetMemoryStatus();
|
|
||||||
return new SystemParameters
|
|
||||||
{
|
|
||||||
ScreenWidth = width,
|
|
||||||
ScreenHeight = height,
|
|
||||||
VideoMemorySize = (long)dxgiMemory,
|
|
||||||
SystemMemorySize = (long)memory.ullTotalPhys,
|
|
||||||
SystemPageSize = (long)memory.ullTotalPageFile - (long)memory.ullTotalPhys
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
|
||||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
|
||||||
static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer);
|
|
||||||
|
|
||||||
public static MEMORYSTATUSEX GetMemoryStatus()
|
|
||||||
{
|
|
||||||
var mstat = new MEMORYSTATUSEX();
|
|
||||||
GlobalMemoryStatusEx(mstat);
|
|
||||||
return mstat;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
|
||||||
public class MEMORYSTATUSEX
|
|
||||||
{
|
|
||||||
public uint dwLength;
|
|
||||||
public uint dwMemoryLoad;
|
|
||||||
public ulong ullTotalPhys;
|
|
||||||
public ulong ullAvailPhys;
|
|
||||||
public ulong ullTotalPageFile;
|
|
||||||
public ulong ullAvailPageFile;
|
|
||||||
public ulong ullTotalVirtual;
|
|
||||||
public ulong ullAvailVirtual;
|
|
||||||
public ulong ullAvailExtendedVirtual;
|
|
||||||
|
|
||||||
public MEMORYSTATUSEX()
|
|
||||||
{
|
|
||||||
dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public SystemParameters Create()
|
||||||
|
{
|
||||||
|
(int width, int height, _) = GetDisplays().First(d => d.IsPrimary);
|
||||||
|
|
||||||
|
/*using var f = new SharpDX.DXGI.Factory1();
|
||||||
|
var video_memory = f.Adapters1.Select(a =>
|
||||||
|
Math.Max(a.Description.DedicatedSystemMemory, (long)a.Description.DedicatedVideoMemory)).Max();*/
|
||||||
|
|
||||||
|
ulong dxgiMemory = 0UL;
|
||||||
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
using DXGI? api = DXGI.GetApi();
|
||||||
|
|
||||||
|
IDXGIFactory1* factory1 = default;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//https://docs.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-createdxgifactory1
|
||||||
|
SilkMarshal.ThrowHResult(api.CreateDXGIFactory1(SilkMarshal.GuidPtrOf<IDXGIFactory1>(), (void**)&factory1));
|
||||||
|
|
||||||
|
uint i = 0u;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
IDXGIAdapter1* adapter1 = default;
|
||||||
|
|
||||||
|
//https://docs.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-idxgifactory1-enumadapters1
|
||||||
|
int res = factory1->EnumAdapters1(i, &adapter1);
|
||||||
|
|
||||||
|
Exception? exception = Marshal.GetExceptionForHR(res);
|
||||||
|
if (exception != null) break;
|
||||||
|
|
||||||
|
AdapterDesc1 adapterDesc = default;
|
||||||
|
|
||||||
|
//https://docs.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-idxgiadapter1-getdesc1
|
||||||
|
SilkMarshal.ThrowHResult(adapter1->GetDesc1(&adapterDesc));
|
||||||
|
|
||||||
|
ulong systemMemory = (ulong)adapterDesc.DedicatedSystemMemory;
|
||||||
|
ulong videoMemory = (ulong)adapterDesc.DedicatedVideoMemory;
|
||||||
|
|
||||||
|
ulong maxMemory = Math.Max(systemMemory, videoMemory);
|
||||||
|
if (maxMemory > dxgiMemory)
|
||||||
|
dxgiMemory = maxMemory;
|
||||||
|
|
||||||
|
adapter1->Release();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.LogError(e, "While getting SystemParameters");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (factory1->LpVtbl != (void**)IntPtr.Zero)
|
||||||
|
factory1->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MEMORYSTATUSEX? memory = GetMemoryStatus();
|
||||||
|
return new SystemParameters
|
||||||
|
{
|
||||||
|
ScreenWidth = width,
|
||||||
|
ScreenHeight = height,
|
||||||
|
VideoMemorySize = (long)dxgiMemory,
|
||||||
|
SystemMemorySize = (long)memory.ullTotalPhys,
|
||||||
|
SystemPageSize = (long)memory.ullTotalPageFile - (long)memory.ullTotalPhys
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
|
private static extern bool GlobalMemoryStatusEx([In] [Out] MEMORYSTATUSEX lpBuffer);
|
||||||
|
|
||||||
|
public static MEMORYSTATUSEX GetMemoryStatus()
|
||||||
|
{
|
||||||
|
var mstat = new MEMORYSTATUSEX();
|
||||||
|
GlobalMemoryStatusEx(mstat);
|
||||||
|
return mstat;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||||
|
public class MEMORYSTATUSEX
|
||||||
|
{
|
||||||
|
public uint dwLength;
|
||||||
|
public uint dwMemoryLoad;
|
||||||
|
public ulong ullTotalPhys;
|
||||||
|
public ulong ullAvailPhys;
|
||||||
|
public ulong ullTotalPageFile;
|
||||||
|
public ulong ullAvailPageFile;
|
||||||
|
public ulong ullTotalVirtual;
|
||||||
|
public ulong ullAvailVirtual;
|
||||||
|
public ulong ullAvailExtendedVirtual;
|
||||||
|
|
||||||
|
public MEMORYSTATUSEX()
|
||||||
|
{
|
||||||
|
dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -14,10 +14,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<!-- <PackageReference Include="LibSassBuilder" Version="2.0.1" />-->
|
|
||||||
<PackageReference Include="DynamicData" Version="7.4.9" />
|
<PackageReference Include="DynamicData" Version="7.4.9" />
|
||||||
<PackageReference Include="Fluxor" Version="4.2.2-Alpha" />
|
|
||||||
<PackageReference Include="Fluxor.Blazor.Web" Version="4.2.2-Alpha" />
|
|
||||||
<PackageReference Include="Microsoft-WindowsAPICodePack-Shell" Version="1.1.4" />
|
<PackageReference Include="Microsoft-WindowsAPICodePack-Shell" Version="1.1.4" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Wpf" Version="6.0.101-preview.11.2349" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Wpf" Version="6.0.101-preview.11.2349" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="6.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="6.0.0" />
|
||||||
@ -27,9 +24,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<!-- Required so updating the .scss files doesn't trigger a reload when using dotnet watch run. -->
|
|
||||||
<Content Remove="**\*.scss" />
|
|
||||||
<Content Include="**\*.scss" Watch="false" />
|
|
||||||
<Content Update="wwwroot\index.html">
|
<Content Update="wwwroot\index.html">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
@ -43,13 +37,14 @@
|
|||||||
<ProjectReference Include="..\Wabbajack.Services.OSIntegrated\Wabbajack.Services.OSIntegrated.csproj" />
|
<ProjectReference Include="..\Wabbajack.Services.OSIntegrated\Wabbajack.Services.OSIntegrated.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<!-- <Target Name="DeleteGeneratedCSSFiles" AfterTargets="Build">-->
|
<!-- dotnet tool install Excubo.WebCompiler -g -->
|
||||||
<!-- <ItemGroup>-->
|
<Target Name="TestWebCompiler" BeforeTargets="PreBuildEvent">
|
||||||
<!-- <FilesToDelete Include="$(ProjectDir)Components\**\*.css"/>-->
|
<Exec Command="webcompiler -h" ContinueOnError="true" StandardOutputImportance="low" StandardErrorImportance="low" LogStandardErrorAsError="false" IgnoreExitCode="true">
|
||||||
<!-- <FilesToDelete Include="$(ProjectDir)Pages\**\*.css"/>-->
|
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
|
||||||
<!-- <FilesToDelete Include="$(ProjectDir)Shared\**\*.css"/>-->
|
</Exec>
|
||||||
<!-- </ItemGroup>-->
|
</Target>
|
||||||
<!-- <Message Text="@(FilesToDelete, ', ')" Importance="High"/>-->
|
|
||||||
<!-- <Delete Files="@(FilesToDelete)"/>-->
|
<Target Name="CompileStaticAssets" AfterTargets="TestWebCompiler" Condition="'$(ErrorCode)' == '0'">
|
||||||
<!-- </Target>-->
|
<Exec Command="webcompiler -r .\ -c webcompilerconfiguration.json" StandardOutputImportance="high" StandardErrorImportance="high" />
|
||||||
|
</Target>
|
||||||
</Project>
|
</Project>
|
||||||
|
23
Wabbajack.App.Blazor/webcompilerconfiguration.json
Normal file
23
Wabbajack.App.Blazor/webcompilerconfiguration.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"Minifiers": {
|
||||||
|
"GZip": false,
|
||||||
|
"Enabled": false
|
||||||
|
},
|
||||||
|
"Autoprefix": {
|
||||||
|
"Enabled": false
|
||||||
|
},
|
||||||
|
"CompilerSettings": {
|
||||||
|
"Sass": {
|
||||||
|
"IndentType": "Space",
|
||||||
|
"IndentWidth": 2,
|
||||||
|
"OutputStyle": "Nested",
|
||||||
|
"Precision": 5,
|
||||||
|
"RelativeUrls": true,
|
||||||
|
"LineFeed": "Lf",
|
||||||
|
"SourceMap": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Output": {
|
||||||
|
"Preserve": true
|
||||||
|
}
|
||||||
|
}
|
9
Wabbajack.App.Blazor/wwwroot/images/icons/adjust.svg
Normal file
9
Wabbajack.App.Blazor/wwwroot/images/icons/adjust.svg
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img"
|
||||||
|
width="1024px" height="1024px" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32">
|
||||||
|
<path
|
||||||
|
d="M30 8h-4.1c-.5-2.3-2.5-4-4.9-4s-4.4 1.7-4.9 4H2v2h14.1c.5 2.3 2.5 4 4.9 4s4.4-1.7 4.9-4H30V8zm-9 4c-1.7 0-3-1.3-3-3s1.3-3 3-3s3 1.3 3 3s-1.3 3-3 3z"
|
||||||
|
fill="#FFF"/>
|
||||||
|
<path
|
||||||
|
d="M2 24h4.1c.5 2.3 2.5 4 4.9 4s4.4-1.7 4.9-4H30v-2H15.9c-.5-2.3-2.5-4-4.9-4s-4.4 1.7-4.9 4H2v2zm9-4c1.7 0 3 1.3 3 3s-1.3 3-3 3s-3-1.3-3-3s1.3-3 3-3z"
|
||||||
|
fill="#FFF"/>
|
||||||
|
</svg>
|
9
Wabbajack.App.Blazor/wwwroot/images/icons/settings.svg
Normal file
9
Wabbajack.App.Blazor/wwwroot/images/icons/settings.svg
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img"
|
||||||
|
width="1024px" height="1024px" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32">
|
||||||
|
<path
|
||||||
|
d="M27 16.76V16v-.77l1.92-1.68A2 2 0 0 0 29.3 11l-2.36-4a2 2 0 0 0-1.73-1a2 2 0 0 0-.64.1l-2.43.82a11.35 11.35 0 0 0-1.31-.75l-.51-2.52a2 2 0 0 0-2-1.61h-4.68a2 2 0 0 0-2 1.61l-.51 2.52a11.48 11.48 0 0 0-1.32.75l-2.38-.86A2 2 0 0 0 6.79 6a2 2 0 0 0-1.73 1L2.7 11a2 2 0 0 0 .41 2.51L5 15.24v1.53l-1.89 1.68A2 2 0 0 0 2.7 21l2.36 4a2 2 0 0 0 1.73 1a2 2 0 0 0 .64-.1l2.43-.82a11.35 11.35 0 0 0 1.31.75l.51 2.52a2 2 0 0 0 2 1.61h4.72a2 2 0 0 0 2-1.61l.51-2.52a11.48 11.48 0 0 0 1.32-.75l2.42.82a2 2 0 0 0 .64.1a2 2 0 0 0 1.73-1l2.28-4a2 2 0 0 0-.41-2.51zM25.21 24l-3.43-1.16a8.86 8.86 0 0 1-2.71 1.57L18.36 28h-4.72l-.71-3.55a9.36 9.36 0 0 1-2.7-1.57L6.79 24l-2.36-4l2.72-2.4a8.9 8.9 0 0 1 0-3.13L4.43 12l2.36-4l3.43 1.16a8.86 8.86 0 0 1 2.71-1.57L13.64 4h4.72l.71 3.55a9.36 9.36 0 0 1 2.7 1.57L25.21 8l2.36 4l-2.72 2.4a8.9 8.9 0 0 1 0 3.13L27.57 20z"
|
||||||
|
fill="#FFF"/>
|
||||||
|
<path
|
||||||
|
d="M16 22a6 6 0 1 1 6-6a5.94 5.94 0 0 1-6 6zm0-10a3.91 3.91 0 0 0-4 4a3.91 3.91 0 0 0 4 4a3.91 3.91 0 0 0 4-4a3.91 3.91 0 0 0-4-4z"
|
||||||
|
fill="#FFF"/>
|
||||||
|
</svg>
|
@ -126,9 +126,6 @@ EndProject
|
|||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "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
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{18E36813-CB53-4172-8FF3-EFE3B9B30A5F}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{18E36813-CB53-4172-8FF3-EFE3B9B30A5F}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
|
||||||
.editorconfig = .editorconfig
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Loading…
Reference in New Issue
Block a user