mirror of
https://github.com/Maassoft/ColorControl.git
synced 2026-10-22 00:22:18 -05:00
upgrade to .NET, fix webOS 26 compatibility, run new UI in separate process
This commit is contained in:
1 parent
8cb427f0b0
commit
d0d3bb4682
80 files changed
+1517
-912
No files matched your search
+70
-23
@@ -1,7 +1,10 @@
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.UI.Pages.Generic;
|
||||
using ColorControl.UI.Services;
|
||||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using NStandard;
|
||||
using System.Net;
|
||||
|
||||
namespace ColorControl.UI;
|
||||
@@ -9,17 +12,15 @@ namespace ColorControl.UI;
|
||||
public static class Blazor
|
||||
{
|
||||
private static WebApplication? CurrentApplication;
|
||||
private static int Port;
|
||||
private static bool AllowRemoteConnections;
|
||||
|
||||
public static bool IsRunning(Config config) => CurrentApplication != null && Port == config.UiPort && AllowRemoteConnections == config.UiAllowRemoteConnections;
|
||||
public static CustomComponentBase? CurrentComponent { get; private set; }
|
||||
|
||||
public static async Task Start(Config config)
|
||||
public static async Task Start(string[] args)
|
||||
{
|
||||
if (IsRunning(config))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var mutexId = args.GetValueOrDefault(0);
|
||||
var useDarkMode = args.GetValueOrDefault(1) == "True";
|
||||
var uiPort = Utils.ParseInt(args.GetValueOrDefault(2));
|
||||
var allowRemoteConnections = args.GetValueOrDefault(3) == "True";
|
||||
|
||||
await Stop();
|
||||
|
||||
@@ -29,7 +30,7 @@ public static class Blazor
|
||||
builder.Services.AddRazorComponents()
|
||||
.AddInteractiveServerComponents();
|
||||
|
||||
builder.Services.AddSingleton<AppState>(new AppState { SelectedTheme = config.UseDarkMode ? "dark" : "light" });
|
||||
builder.Services.AddSingleton(new AppState { SelectedTheme = useDarkMode ? "dark" : "light" });
|
||||
builder.Services.AddTransient<RpcUiClientService>();
|
||||
builder.Services.AddTransient<JSHelper>();
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
@@ -37,11 +38,11 @@ public static class Blazor
|
||||
|
||||
builder.Services.Configure<HostOptions>(opts => opts.ShutdownTimeout = TimeSpan.FromSeconds(3));
|
||||
|
||||
var listenPort = config.UiPort > 0 ? config.UiPort : 0;
|
||||
var listenPort = uiPort > 0 ? uiPort : 0;
|
||||
|
||||
builder.WebHost.ConfigureKestrel(options =>
|
||||
{
|
||||
if (config.UiAllowRemoteConnections)
|
||||
if (allowRemoteConnections)
|
||||
{
|
||||
options.ListenAnyIP(listenPort);
|
||||
}
|
||||
@@ -51,6 +52,8 @@ public static class Blazor
|
||||
}
|
||||
});
|
||||
|
||||
builder.WebHost.UseStaticWebAssets();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
@@ -61,17 +64,56 @@ public static class Blazor
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true);
|
||||
//app.UseHttpsRedirection();
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseAntiforgery();
|
||||
|
||||
app.MapStaticAssets();
|
||||
//app.UsePathBase("/");
|
||||
|
||||
app.MapRazorComponents<Components.App>()
|
||||
.AddInteractiveServerRenderMode();
|
||||
|
||||
CurrentApplication = app;
|
||||
Port = config.UiPort;
|
||||
AllowRemoteConnections = config.UiAllowRemoteConnections;
|
||||
|
||||
var _ = Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(500);
|
||||
|
||||
var port = GetCurrentPort();
|
||||
|
||||
if (port == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var rpcServer = app.Services.GetRequiredService<RpcUiClientService>();
|
||||
|
||||
await rpcServer.CallAsync<bool>("OptionsService", "SetCurrentUiSettings", port, allowRemoteConnections);
|
||||
|
||||
if (!mutexId.IsNullOrWhiteSpace())
|
||||
{
|
||||
Console.WriteLine("Waiting for mutex: " + mutexId);
|
||||
var mutex = new Mutex(false, mutexId, out var createdNew);
|
||||
if (createdNew)
|
||||
{
|
||||
Console.WriteLine("Mutex was created, skipping.");
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
mutex.WaitOne();
|
||||
Console.WriteLine("Waiting done.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Wait completed: " + ex.Message);
|
||||
}
|
||||
|
||||
Environment.Exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
await app.RunAsync();
|
||||
}
|
||||
@@ -85,14 +127,7 @@ public static class Blazor
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetCurrentUrl()
|
||||
{
|
||||
var port = GetCurrentPort();
|
||||
|
||||
return $"http://localhost:{port}";
|
||||
}
|
||||
|
||||
public static int GetCurrentPort()
|
||||
public static int GetCurrentPort(Config? config = null)
|
||||
{
|
||||
if (CurrentApplication == null)
|
||||
{
|
||||
@@ -115,4 +150,16 @@ public static class Blazor
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static void SetCurrentComponent(CustomComponentBase? customComponentBase)
|
||||
{
|
||||
CurrentComponent = customComponentBase;
|
||||
}
|
||||
|
||||
public static void ClearCurrentComponent(CustomComponentBase customComponentBase)
|
||||
{
|
||||
if (CurrentComponent == customComponentBase)
|
||||
{
|
||||
CurrentComponent = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0-windows</TargetFramework>
|
||||
<TargetFramework>net10.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<OutputType>Library</OutputType>
|
||||
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
|
||||
<BlazorDisableThrowNavigationException>true</BlazorDisableThrowNavigationException>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.3.4" />
|
||||
<PackageReference Include="NLog" Version="6.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@using ColorControl.Shared.Common
|
||||
@using ColorControl.Shared.Contracts
|
||||
@using ColorControl.UI.Pages.Generic
|
||||
@using ColorControl.UI.Services
|
||||
@using ColorControl.UI.Components.Pages.Generic
|
||||
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
|
||||
@@ -9,6 +10,7 @@
|
||||
@inject NavigationManager _navigationManager
|
||||
@inject NotificationService _notificationService
|
||||
@inject ProtectedSessionStorage _sessionStorage
|
||||
@inject JSHelper _jsHelper
|
||||
|
||||
@implements IDisposable
|
||||
@attribute [StreamRendering]
|
||||
@@ -20,19 +22,26 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<base href="/" />
|
||||
<ResourcePreloader />
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||
<link rel="stylesheet" href="app.css" />
|
||||
<link rel="stylesheet" href="ColorControl.UI.styles.css" />
|
||||
<ImportMap />
|
||||
<link rel="icon" type="image/png" href="favicon.png" />
|
||||
|
||||
<HeadOutlet />
|
||||
<HeadOutlet @rendermode="InteractiveServer" />
|
||||
<script>
|
||||
addEventListener('focus', (event) => {
|
||||
var isModalShown = document.getElementsByClassName("modal show").length > 0;
|
||||
DotNet.invokeMethodAsync("ColorControl.UI", "RefreshSummary", isModalShown);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<Routes />
|
||||
<script src="_framework/blazor.web.js"></script>
|
||||
<Routes @rendermode="InteractiveServer" />
|
||||
<script src="@Assets["_framework/blazor.web.js"]"></script>
|
||||
<NotificationsComponent></NotificationsComponent>
|
||||
</body>
|
||||
|
||||
@@ -59,4 +68,13 @@
|
||||
{
|
||||
AppState.OnChange -= StateHasChanged;
|
||||
}
|
||||
|
||||
[JSInvokable]
|
||||
public static async Task RefreshSummary(bool isModalShown)
|
||||
{
|
||||
if (Blazor.CurrentComponent is SummaryComponentBase summaryComponent && !isModalShown)
|
||||
{
|
||||
await summaryComponent.RefreshExternal();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,12 @@
|
||||
@using ColorControl.Shared.Common
|
||||
@using ColorControl.Shared.Contracts
|
||||
@using ColorControl.Shared.Contracts.AMD
|
||||
@using ColorControl.UI.Pages.Generic
|
||||
@using ColorControl.UI.Services;
|
||||
@using ColorControl.UI.Components.Pages.Generic
|
||||
@using ColorControl.UI.Generics
|
||||
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
|
||||
@inherits SummaryComponentBase
|
||||
|
||||
@rendermode Constants.RenderMode
|
||||
|
||||
@@ -144,6 +146,13 @@ else
|
||||
private PresetOrder PresetOrder;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
|
||||
await Refresh();
|
||||
}
|
||||
|
||||
protected override async Task Refresh()
|
||||
{
|
||||
await RefreshPresets();
|
||||
DisplayPresets = await _rpcClientService.CallAsync<List<AmdPreset>>("AmdService", "GetDisplayPresets");
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
@using ColorControl.Shared.Contracts.DisplayInfo
|
||||
@using ColorControl.UI.Components.Pages.Generic
|
||||
@using ColorControl.UI.Generics
|
||||
@using ColorControl.UI.Pages.Generic
|
||||
@using ColorControl.UI.Services
|
||||
@inherits SummaryComponentBase
|
||||
|
||||
@rendermode Constants.RenderMode
|
||||
|
||||
@@ -190,7 +192,15 @@ else
|
||||
|
||||
private FieldDefinition AskHdrAssociationField = new FieldDefinition { Label = "Associate as HDR profile", FieldType = FieldType.CheckBox, Value = false };
|
||||
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
|
||||
await Refresh();
|
||||
}
|
||||
|
||||
protected override async Task Refresh()
|
||||
{
|
||||
await RefreshDisplays();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
@using ColorControl.Shared.Contracts.Game
|
||||
@using ColorControl.UI.Services
|
||||
@using ColorControl.UI.Components.Pages.Generic
|
||||
@using NvAPIWrapper.Native.Display
|
||||
@using ColorControl.Shared.Common
|
||||
|
||||
@rendermode Constants.RenderMode
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace ColorControl.UI.Pages.Generic;
|
||||
|
||||
public abstract class CustomComponentBase : ComponentBase, IDisposable
|
||||
{
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
|
||||
Blazor.ClearCurrentComponent(this);
|
||||
}
|
||||
|
||||
protected override Task OnInitializedAsync()
|
||||
{
|
||||
Blazor.SetCurrentComponent(this);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -44,9 +44,9 @@
|
||||
try
|
||||
{
|
||||
var options = new RpcUiClientOptions
|
||||
{
|
||||
Timeout = 60000
|
||||
};
|
||||
{
|
||||
Timeout = 60000
|
||||
};
|
||||
|
||||
var result = await _rpcClientService.CallWithOptionsAsync<string>("GameService", "SelectPath", options);
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace ColorControl.UI.Pages.Generic;
|
||||
|
||||
public abstract class SummaryComponentBase : CustomComponentBase
|
||||
{
|
||||
protected abstract Task Refresh();
|
||||
|
||||
public async Task RefreshExternal()
|
||||
{
|
||||
await Refresh();
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
@@ -7,16 +7,20 @@
|
||||
|
||||
@if (Triggers != null)
|
||||
{
|
||||
if (!Triggers.Any())
|
||||
if (Triggers.Count < 2)
|
||||
{
|
||||
<div>
|
||||
<label class="form-label">No triggers found. Click to add:</label>
|
||||
<label class="form-label">Add trigger:</label>
|
||||
<button class="btn btn-primary btn-sm" type="button" @onclick="() => Triggers.Add(new PresetTrigger())">Add</button>
|
||||
</div>
|
||||
}
|
||||
|
||||
foreach (var trigger in Triggers)
|
||||
{
|
||||
<div class="clearfix">
|
||||
<label class="form-label">Trigger @(Triggers.IndexOf(trigger) + 1)</label>
|
||||
<button class="btn btn-danger btn-sm float-end" type="button" @onclick="() => Triggers.Remove(trigger)">Remove</button>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label" for="triggerType">Trigger type</label>
|
||||
<select class="form-select" id="triggerType" @bind="trigger.Trigger">
|
||||
@@ -26,7 +30,7 @@
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<FlagsInput Label="Conditions" Value="@((uint)trigger.Conditions)" Labels="ConditionLabels" Col="6" ValueChanged="ConditionsChanged"></FlagsInput>
|
||||
<FlagsInput Label="Conditions" Value="@((uint)trigger.Conditions)" Labels="ConditionLabels" Col="6" ValueChanged="value => ConditionsChanged(value, trigger)"></FlagsInput>
|
||||
<div class="mb-2">
|
||||
<label class="form-label" for="includedProcesses">Included processes</label>
|
||||
<input class="form-control" type="text" @bind="trigger.IncludedProcessesAsString" />
|
||||
@@ -40,6 +44,11 @@
|
||||
<input class="form-control" type="text" @bind="trigger.ConnectedDisplaysRegex"
|
||||
title="The preset will be executed only if the supplied Regular Expression matches the device name of at least one of the displays that are connected at the moment the trigger is fired." />
|
||||
</div>
|
||||
|
||||
@if (Triggers.IndexOf(trigger) < Triggers.Count - 1)
|
||||
{
|
||||
<div class="border-bottom mb-2"></div>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,14 +58,8 @@
|
||||
|
||||
private List<string> ConditionLabels = Utils.GetDescriptions<PresetConditionType>(fromValue: 1).ToList();
|
||||
|
||||
public void ConditionsChanged(uint value)
|
||||
public void ConditionsChanged(uint value, PresetTrigger trigger)
|
||||
{
|
||||
if (Triggers == null || !Triggers.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var trigger = Triggers.First();
|
||||
trigger.Conditions = (PresetConditionType)value;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
@using ColorControl.Shared.Contracts
|
||||
@using ColorControl.Shared.Contracts.LG
|
||||
@using ColorControl.UI.Services
|
||||
@using NvAPIWrapper.Native.Display
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using ColorControl.Shared.Common
|
||||
@using ColorControl.UI.Components.Pages.Generic
|
||||
|
||||
@@ -154,6 +154,10 @@
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="checkUseSecureConnection" @bind="Device.Options.UseSecureConnection">
|
||||
<label class="form-check-label" for="checkUseSecureConnection">Use secure connection</label>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="checkUseNewHandshake" @bind="Device.Options.UseNewHandshake">
|
||||
<label class="form-check-label" for="checkUseNewHandshake">Enable webOS 26 compatibility</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
@using ColorControl.Shared.Contracts.LG
|
||||
@using ColorControl.UI.Services
|
||||
@using ColorControl.UI.Components.Pages.Generic
|
||||
@using NvAPIWrapper.Native.Display
|
||||
@using ColorControl.Shared.Common
|
||||
@using static ColorControl.UI.Components.Pages.Generic.StepsInput<ColorControl.Shared.Contracts.LG.LgPreset>
|
||||
|
||||
|
||||
@@ -5,10 +5,12 @@
|
||||
@using ColorControl.Shared.Contracts.NVIDIA
|
||||
@using ColorControl.Shared.Contracts.LG
|
||||
@using ColorControl.UI.Components.Pages.RemoteControl
|
||||
@using ColorControl.UI.Pages.Generic
|
||||
@using ColorControl.UI.Services;
|
||||
@using ColorControl.UI.Components.Pages.Generic
|
||||
@using ColorControl.UI.Generics
|
||||
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
|
||||
@inherits SummaryComponentBase
|
||||
|
||||
@rendermode Constants.RenderMode
|
||||
|
||||
@@ -239,6 +241,13 @@ else
|
||||
private List<LgPreset> RcPresets = [LgPresets.InStartPreset, LgPresets.EzAdjustPreset];
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
|
||||
await Refresh();
|
||||
}
|
||||
|
||||
protected override async Task Refresh()
|
||||
{
|
||||
Config = await _rpcClientService.CallAsync<LgServiceConfigDto>("LgService", "GetConfig");
|
||||
await RefreshPresets();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
@using ColorControl.Shared.Contracts
|
||||
@using ColorControl.Shared.Contracts.NVIDIA
|
||||
@using ColorControl.UI.Services;
|
||||
@using NvAPIWrapper.Native.Display
|
||||
@using ColorControl.Shared.Common;
|
||||
|
||||
@rendermode Constants.RenderMode
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
@using ColorControl.Shared.Contracts.NVIDIA
|
||||
@using ColorControl.UI.Components.Pages.Generic
|
||||
@using ColorControl.UI.Services;
|
||||
@using NvAPIWrapper.Native.Display
|
||||
@using ColorControl.Shared.Common;
|
||||
|
||||
@rendermode Constants.RenderMode
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
@using ColorControl.Shared.Contracts.NVIDIA
|
||||
@using ColorControl.UI.Components.Pages.Generic
|
||||
@using ColorControl.UI.Services;
|
||||
@using NvAPIWrapper.Native.Display
|
||||
@using ColorControl.Shared.Common;
|
||||
|
||||
@rendermode Constants.RenderMode
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
@using ColorControl.Shared.Contracts
|
||||
@using ColorControl.Shared.Contracts.NVIDIA
|
||||
@using ColorControl.UI.Services;
|
||||
@using NvAPIWrapper.Native.Display
|
||||
@using ColorControl.Shared.Common;
|
||||
@using static ColorControl.Shared.Common.NestedItemsBuilder
|
||||
|
||||
|
||||
@@ -45,50 +45,62 @@
|
||||
}
|
||||
<div class="accordion accordion-flush" id="presetAccordion">
|
||||
|
||||
@if (!Preset.IsDisplayPreset)
|
||||
{
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<span class="d-flex align-items-baseline">
|
||||
@if (!Preset.IsDisplayPreset)
|
||||
{
|
||||
<input class="form-check-input me-1" style="font-size: 1rem; visibility: hidden" type="checkbox">
|
||||
}
|
||||
<button class="accordion-button collapsed py-2" type="button" data-bs-toggle="collapse" data-bs-target="#displaySettings">
|
||||
Display
|
||||
</button>
|
||||
</span>
|
||||
</h2>
|
||||
<div id="displaySettings" class="accordion-collapse collapse" data-bs-parent="#presetAccordion">
|
||||
<div class="accordion-body">
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<span class="d-flex align-items-baseline">
|
||||
@if (!Preset.IsDisplayPreset)
|
||||
{
|
||||
<input class="form-check-input me-1" style="font-size: 1rem; visibility: hidden" type="checkbox">
|
||||
}
|
||||
<button class="accordion-button collapsed py-2" type="button" data-bs-toggle="collapse" data-bs-target="#displaySettings">
|
||||
Display
|
||||
</button>
|
||||
</span>
|
||||
</h2>
|
||||
<div id="displaySettings" class="accordion-collapse collapse" data-bs-parent="#presetAccordion">
|
||||
<div class="accordion-body">
|
||||
@if (!Preset.IsDisplayPreset)
|
||||
{
|
||||
<div class="mb-2">
|
||||
<input class="form-check-input" type="checkbox" @bind="Preset.primaryDisplay" id="primaryDisplay">
|
||||
<label class="form-check-label" for="primaryDisplay">
|
||||
Primary display
|
||||
</label>
|
||||
</div>
|
||||
@if (displayPresets != null)
|
||||
}
|
||||
@if (displayPresets != null)
|
||||
{
|
||||
if (!Preset.IsDisplayPreset)
|
||||
{
|
||||
<div class="mb-2">
|
||||
<label class="form-label" for="mode">Display</label>
|
||||
<select class="form-select" id="mode" @bind="Preset.DisplayId" disabled="@(Preset.primaryDisplay)">
|
||||
<select class="form-select" id="mode" @bind="Preset.DisplayId" disabled="@Preset.primaryDisplay">
|
||||
@foreach (var display in displayPresets)
|
||||
{
|
||||
<option value="@display.DisplayId">@display.displayName</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<input class="form-check-input" type="checkbox" @bind="Preset.DisplayConfig.IsPrimary" id="setAsPrimaryDisplay" disabled="@(Preset.primaryDisplay)">
|
||||
<label class="form-check-label" for="setAsPrimaryDisplay">
|
||||
Set display as primary display
|
||||
</label>
|
||||
</div>
|
||||
}
|
||||
<div class="mb-2">
|
||||
<input class="form-check-input" type="checkbox" @bind="Preset.DisplayConfig.IsPrimary" id="setAsPrimaryDisplay" disabled="@(Preset.IsDisplayPreset && displayPresets.Count == 1)">
|
||||
<label class="form-check-label" for="setAsPrimaryDisplay">
|
||||
Set display as primary display
|
||||
</label>
|
||||
</div>
|
||||
}
|
||||
<div class="mb-2">
|
||||
<label class="form-label" for="connectivity">Connectivity</label>
|
||||
<select class="form-select" id="scaling" @bind="Preset.DisplayConfig.Connectivity">
|
||||
@foreach (var connectivity in Enum.GetValues<Shared.Contracts.DisplayConnectivity>())
|
||||
{
|
||||
<option value="@connectivity.ToString()">@connectivity.ToString()</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@if (resolutions != null)
|
||||
{
|
||||
@@ -745,7 +757,7 @@
|
||||
|
||||
ApplyImmediately = false;
|
||||
|
||||
Preset = PresetParam == null ? null : PresetParam.CloneWithId();
|
||||
Preset = PresetParam?.CloneWithId();
|
||||
|
||||
displayPresets = await _rpcClientService.CallAsync<List<NvPreset>>("NvService", "GetDisplayPresets");
|
||||
if (Preset?.IsDisplayPreset == true)
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
@using ColorControl.Shared.Contracts
|
||||
@using ColorControl.Shared.Contracts.NVIDIA
|
||||
@using ColorControl.UI.Pages.Generic
|
||||
@using ColorControl.UI.Services;
|
||||
@using ColorControl.UI.Components.Pages.Generic
|
||||
@using ColorControl.Shared.Common;
|
||||
@using ColorControl.UI.Generics
|
||||
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
|
||||
@inherits SummaryComponentBase
|
||||
|
||||
@rendermode Constants.RenderMode
|
||||
|
||||
@@ -276,6 +278,13 @@ else
|
||||
private PresetOrder PresetOrder;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
|
||||
await Refresh();
|
||||
}
|
||||
|
||||
protected override async Task Refresh()
|
||||
{
|
||||
NvConfig = await _rpcClientService.CallAsync<NvServiceConfig>("NvService", "GetConfig");
|
||||
await RefreshPresets();
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
@using ColorControl.Shared.Contracts.Base
|
||||
@using ColorControl.Shared.Contracts.RemoteControl
|
||||
@using ColorControl.UI.Services
|
||||
@using NvAPIWrapper.Native.Display
|
||||
@using ColorControl.Shared.Common
|
||||
@using System.Globalization
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
@using ColorControl.Shared.Contracts.Samsung
|
||||
@using ColorControl.UI.Components.Pages.Generic
|
||||
@using ColorControl.UI.Services
|
||||
@using NvAPIWrapper.Native.Display
|
||||
@using ColorControl.Shared.Common
|
||||
|
||||
@rendermode Constants.RenderMode
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
@using ColorControl.Shared.Contracts.Samsung
|
||||
@using ColorControl.UI.Services
|
||||
@using ColorControl.UI.Components.Pages.Generic
|
||||
@using NvAPIWrapper.Native.Display
|
||||
@using ColorControl.Shared.Common
|
||||
@using static ColorControl.UI.Components.Pages.Generic.StepsInput<ColorControl.Shared.Contracts.Samsung.SamsungPreset>
|
||||
|
||||
|
||||
@@ -102,8 +102,8 @@
|
||||
SecondaryAction = FactoryMenuSecondStepEnterWithoutExecute;
|
||||
Fields =
|
||||
[
|
||||
AddField("Service Menu - Advanced", null, FieldType.Label, "If the service menu opened and you want to access the Advanced settings, click 'Next >' or click 'Skip' to skip"),
|
||||
AddField("Advanced Unlock Type", AdvancedUnlockType.TV, subLabel: "Select the desired unlock type for the Advanced section. If the target is a TV choose TV, otherwise choose Monitor")
|
||||
AddField("Service Menu - Advanced", null, FieldType.Label, "If the service menu opened and you want to access the Advanced settings, click 'Next >' or click 'Skip' to skip. You can also manually enter the unlock codes 0098 (for TV's) and 0038 (for monitors) while the 'Advanced' item is highlighted."),
|
||||
AddField("Advanced Unlock Type", AdvancedUnlockType.TV, subLabel: "Select the desired unlock type for the Advanced section. If the target is a TV choose TV, otherwise choose Monitor")
|
||||
];
|
||||
|
||||
StateHasChanged();
|
||||
|
||||
@@ -5,10 +5,12 @@
|
||||
@using ColorControl.Shared.Contracts.NVIDIA
|
||||
@using ColorControl.Shared.Contracts.Samsung
|
||||
@using ColorControl.UI.Components.Pages.RemoteControl
|
||||
@using ColorControl.UI.Pages.Generic
|
||||
@using ColorControl.UI.Services;
|
||||
@using ColorControl.UI.Components.Pages.Generic
|
||||
@using ColorControl.UI.Generics
|
||||
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
|
||||
@inherits SummaryComponentBase
|
||||
|
||||
@rendermode Constants.RenderMode
|
||||
|
||||
@@ -220,6 +222,13 @@ else
|
||||
private PresetOrder PresetOrder;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
|
||||
await Refresh();
|
||||
}
|
||||
|
||||
protected override async Task Refresh()
|
||||
{
|
||||
Config = await _rpcClientService.CallAsync<SamsungServiceConfigDto>("SamsungService", "GetConfig");
|
||||
await RefreshPresets();
|
||||
|
||||
@@ -12,7 +12,5 @@ public static class Constants
|
||||
public const string Light = "light";
|
||||
public const string Dark = "dark";
|
||||
|
||||
|
||||
public static IComponentRenderMode RenderMode = new InteractiveServerRenderMode(prerender: false);
|
||||
|
||||
}
|
||||
+16
-28
@@ -1,32 +1,20 @@
|
||||
//using ColorControl.UI;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.UI;
|
||||
using ColorControl.UI.Services;
|
||||
using System.Diagnostics;
|
||||
|
||||
//Blazor.Start();
|
||||
var arguments = args;
|
||||
|
||||
//var builder = WebApplication.CreateBuilder(args);
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
var rpcServer = new RpcUiClientService(null);
|
||||
var options = new RpcUiClientOptions
|
||||
{
|
||||
Timeout = 10000
|
||||
};
|
||||
|
||||
//// Add services to the container.
|
||||
//builder.Services.AddRazorComponents()
|
||||
// .AddInteractiveServerComponents();
|
||||
var config = await rpcServer.CallWithOptionsAsync<Config>("OptionsService", "GetConfig", options);
|
||||
arguments = ["", config.UseDarkMode.ToString(), config.UiPort.ToString(), config.UiAllowRemoteConnections.ToString()];
|
||||
}
|
||||
|
||||
//builder.Services.AddSingleton<AppState>();
|
||||
//builder.Services.AddSingleton<OptionsService>();
|
||||
|
||||
//var app = builder.Build();
|
||||
|
||||
//// Configure the HTTP request pipeline.
|
||||
//if (!app.Environment.IsDevelopment())
|
||||
//{
|
||||
// app.UseExceptionHandler("/Error", createScopeForErrors: true);
|
||||
// // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||
// app.UseHsts();
|
||||
//}
|
||||
|
||||
//app.UseHttpsRedirection();
|
||||
|
||||
//app.UseStaticFiles();
|
||||
//app.UseAntiforgery();
|
||||
|
||||
//app.MapRazorComponents<App>()
|
||||
// .AddInteractiveServerRenderMode();
|
||||
|
||||
//app.Run();
|
||||
await Blazor.Start(arguments);
|
||||
@@ -1,13 +1,5 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:31433",
|
||||
"sslPort": 44330
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
@@ -26,13 +18,6 @@
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,11 @@ public class JSHelper(IJSRuntime jsRuntime)
|
||||
await InvokeVoidAsync("CloseModal", id);
|
||||
}
|
||||
|
||||
public async Task<bool> IsModalShown()
|
||||
{
|
||||
return await InvokeAsync<bool>("IsModalShown");
|
||||
}
|
||||
|
||||
public async Task ShowToast(string id)
|
||||
{
|
||||
await InvokeVoidAsync("ShowToast", id);
|
||||
|
||||
@@ -10,7 +10,7 @@ public class RpcUiClientOptions
|
||||
public int Timeout { get; set; } = PipeUtils.DefaultTimeout;
|
||||
}
|
||||
|
||||
public class RpcUiClientService(NotificationService notificationService)
|
||||
public class RpcUiClientService(NotificationService? notificationService)
|
||||
{
|
||||
public string? LastErrorMessage { get; private set; }
|
||||
|
||||
@@ -46,7 +46,7 @@ public class RpcUiClientService(NotificationService notificationService)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (result?.ErrorMessages.Count > 0)
|
||||
if (result?.ErrorMessages.Count > 0 && notificationService != null)
|
||||
{
|
||||
await notificationService.SendNotificationDirect(new NotificationDto(result.ErrorMessages.First(), Constants.Danger));
|
||||
}
|
||||
@@ -74,7 +74,7 @@ public class RpcUiClientService(NotificationService notificationService)
|
||||
|
||||
if (resultJson == null)
|
||||
{
|
||||
notificationService.SendNotification(new NotificationDto("Unknown communication error", Constants.Danger));
|
||||
notificationService?.SendNotification(new NotificationDto("Unknown communication error", Constants.Danger));
|
||||
|
||||
return default;
|
||||
}
|
||||
@@ -85,7 +85,10 @@ public class RpcUiClientService(NotificationService notificationService)
|
||||
{
|
||||
LastErrorMessage = resultMessage?.ErrorMessage ?? "Unknown communication error";
|
||||
|
||||
await notificationService.SendNotificationDirect(new NotificationDto(LastErrorMessage, Constants.Danger));
|
||||
if (notificationService != null)
|
||||
{
|
||||
await notificationService.SendNotificationDirect(new NotificationDto(LastErrorMessage, Constants.Danger));
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
@@ -26,4 +26,8 @@ export function GetElementClassName(elementId) {
|
||||
|
||||
export function NavigateTo(uri, timeout = 0) {
|
||||
setTimeout(() => window.location = uri, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
export function IsModalShown() {
|
||||
return document.getElementsByClassName("modal show").length > 0;
|
||||
}
|
||||
Reference in new issue
Block a user