1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Compare commits

...

2 Commits

Author SHA1 Message Date
Robert
37b8c2c3e9 Webserver - Add option to enable remote access 2025-02-16 12:05:26 +01:00
Robert
3367280576 Startup wizard - Correctly remember wizard was compelted
Settings - Fix double navigation occuring when opening settings
Settings - Fix double navigation occuring when opening releases
2025-02-16 11:15:52 +01:00
8 changed files with 43 additions and 32 deletions

View File

@ -33,7 +33,7 @@ public abstract class PluginEndPoint
/// <summary> /// <summary>
/// Gets the full URL of the end point /// Gets the full URL of the end point
/// </summary> /// </summary>
public string Url => $"{_pluginsHandler.ServerUrl}{_pluginsHandler.BaseRoute}/{PluginFeature.Plugin.Guid}/{Name}"; public string Url => $"/{_pluginsHandler.BaseRoute}/{PluginFeature.Plugin.Guid}/{Name}";
/// <summary> /// <summary>
/// Gets the plugin the end point is associated with /// Gets the plugin the end point is associated with

View File

@ -97,8 +97,6 @@ public class PluginsHandler : IHandler
#region Overrides of WebModuleBase #region Overrides of WebModuleBase
internal string? ServerUrl { get; set; }
/// <summary> /// <summary>
/// Gets a read only collection containing all current plugin end points /// Gets a read only collection containing all current plugin end points
/// </summary> /// </summary>

View File

@ -28,6 +28,7 @@ internal class WebServerService : IWebServerService, IDisposable
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly ICoreService _coreService; private readonly ICoreService _coreService;
private readonly PluginSetting<bool> _webServerEnabledSetting; private readonly PluginSetting<bool> _webServerEnabledSetting;
private readonly PluginSetting<bool> _webServerRemoteAccessSetting;
private readonly PluginSetting<int> _webServerPortSetting; private readonly PluginSetting<int> _webServerPortSetting;
private readonly SemaphoreSlim _webserverSemaphore = new(1, 1); private readonly SemaphoreSlim _webserverSemaphore = new(1, 1);
@ -45,9 +46,11 @@ internal class WebServerService : IWebServerService, IDisposable
_controllers = new List<WebApiControllerRegistration>(); _controllers = new List<WebApiControllerRegistration>();
_webServerEnabledSetting = settingsService.GetSetting("WebServer.Enabled", true); _webServerEnabledSetting = settingsService.GetSetting("WebServer.Enabled", true);
_webServerRemoteAccessSetting = settingsService.GetSetting("WebServer.RemoteAccess", false);
_webServerPortSetting = settingsService.GetSetting("WebServer.Port", 9696); _webServerPortSetting = settingsService.GetSetting("WebServer.Port", 9696);
_webServerEnabledSetting.SettingChanged += WebServerEnabledSettingOnSettingChanged; _webServerEnabledSetting.SettingChanged += WebServerSettingsOnSettingChanged;
_webServerPortSetting.SettingChanged += WebServerPortSettingOnSettingChanged; _webServerRemoteAccessSetting.SettingChanged += WebServerSettingsOnSettingChanged;
_webServerPortSetting.SettingChanged += WebServerSettingsOnSettingChanged;
pluginManagementService.PluginFeatureDisabled += PluginManagementServiceOnPluginFeatureDisabled; pluginManagementService.PluginFeatureDisabled += PluginManagementServiceOnPluginFeatureDisabled;
PluginsHandler = new PluginsHandler("plugins"); PluginsHandler = new PluginsHandler("plugins");
@ -75,12 +78,7 @@ internal class WebServerService : IWebServerService, IDisposable
WebServerStarted?.Invoke(this, EventArgs.Empty); WebServerStarted?.Invoke(this, EventArgs.Empty);
} }
private void WebServerEnabledSettingOnSettingChanged(object? sender, EventArgs e) private void WebServerSettingsOnSettingChanged(object? sender, EventArgs e)
{
_ = StartWebServer();
}
private void WebServerPortSettingOnSettingChanged(object? sender, EventArgs e)
{ {
_ = StartWebServer(); _ = StartWebServer();
} }
@ -102,7 +100,6 @@ internal class WebServerService : IWebServerService, IDisposable
public void Dispose() public void Dispose()
{ {
Server?.DisposeAsync(); Server?.DisposeAsync();
_webServerPortSetting.SettingChanged -= WebServerPortSettingOnSettingChanged;
} }
public IServer? Server { get; private set; } public IServer? Server { get; private set; }
@ -121,8 +118,6 @@ internal class WebServerService : IWebServerService, IDisposable
Server = null; Server = null;
} }
PluginsHandler.ServerUrl = $"http://localhost:{_webServerPortSetting.Value}/";
LayoutBuilder serverLayout = Layout.Create() LayoutBuilder serverLayout = Layout.Create()
.Add(PluginsHandler) .Add(PluginsHandler)
.Add(new StatusHandler()) .Add(new StatusHandler())
@ -138,12 +133,12 @@ internal class WebServerService : IWebServerService, IDisposable
IServer server = Host.Create() IServer server = Host.Create()
.Handler(serverLayout.Build()) .Handler(serverLayout.Build())
.Bind(IPAddress.Loopback, (ushort) _webServerPortSetting.Value) .Bind(_webServerRemoteAccessSetting.Value ? IPAddress.Any : IPAddress.Loopback, (ushort) _webServerPortSetting.Value)
.Defaults() .Defaults()
.Build(); .Build();
// Store the URL in a webserver.txt file so that remote applications can find it // Store the URL in a webserver.txt file so that remote applications can find it
await File.WriteAllTextAsync(Path.Combine(Constants.DataFolder, "webserver.txt"), PluginsHandler.ServerUrl); await File.WriteAllTextAsync(Path.Combine(Constants.DataFolder, "webserver.txt"), $"http://localhost:{_webServerPortSetting.Value}/");
return server; return server;
} }

View File

@ -2,6 +2,7 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Artemis.UI.Routing; using Artemis.UI.Routing;
@ -42,14 +43,11 @@ public partial class SettingsViewModel : RoutableHostScreen<RoutableScreen>, IMa
public ViewModelBase? TitleBarViewModel => null; public ViewModelBase? TitleBarViewModel => null;
/// <inheritdoc /> /// <inheritdoc />
public override async Task OnNavigating(NavigationArguments args, CancellationToken cancellationToken) public override Task OnNavigating(NavigationArguments args, CancellationToken cancellationToken)
{ {
// Display tab change on navigate // Display tab change on navigate, if there is none forward to the first
SelectedTab = SettingTabs.FirstOrDefault(t => t.Matches(args.Path)); SelectedTab = SettingTabs.FirstOrDefault(t => t.Matches(args.Path)) ?? SettingTabs.FirstOrDefault();
return Task.CompletedTask;
// Always show a tab, if there is none forward to the first
if (SelectedTab == null)
await _router.Navigate(SettingTabs.First().Path);
} }
public void GoBack() public void GoBack()

View File

@ -146,6 +146,22 @@
</Grid> </Grid>
<Border Classes="card-separator" /> <Border Classes="card-separator" />
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0">
<TextBlock>Enable remote access</TextBlock>
<TextBlock Classes="subtitle" TextWrapping="Wrap">
By default the web server can only be accessed by applications running on your own computer, e.g. supported games.
</TextBlock>
<TextBlock Classes="subtitle warning" TextWrapping="Wrap">
Enabling remote access allows you to access Artemis from other devices on your network, depending on your router even the outside world.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ToggleSwitch IsChecked="{CompiledBinding WebServerRemoteAccess.Value}" OnContent="Yes" OffContent="No" MinWidth="0" Margin="0 -10" />
</StackPanel>
</Grid>
<Border Classes="card-separator" />
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto"> <Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0"> <StackPanel Grid.Column="0">
<TextBlock> <TextBlock>

View File

@ -167,6 +167,7 @@ public class GeneralTabViewModel : RoutableScreen
public PluginSetting<double> CoreRenderScale => _settingsService.GetSetting("Core.RenderScale", 0.5); public PluginSetting<double> CoreRenderScale => _settingsService.GetSetting("Core.RenderScale", 0.5);
public PluginSetting<int> CoreTargetFrameRate => _settingsService.GetSetting("Core.TargetFrameRate", 30); public PluginSetting<int> CoreTargetFrameRate => _settingsService.GetSetting("Core.TargetFrameRate", 30);
public PluginSetting<bool> WebServerEnabled => _settingsService.GetSetting("WebServer.Enabled", true); public PluginSetting<bool> WebServerEnabled => _settingsService.GetSetting("WebServer.Enabled", true);
public PluginSetting<bool> WebServerRemoteAccess => _settingsService.GetSetting("WebServer.RemoteAccess", false);
public PluginSetting<int> WebServerPort => _settingsService.GetSetting("WebServer.Port", 9696); public PluginSetting<int> WebServerPort => _settingsService.GetSetting("WebServer.Port", 9696);
private void ExecuteShowLogs() private void ExecuteShowLogs()

View File

@ -109,10 +109,6 @@ public partial class ReleasesTabViewModel : RoutableHostScreen<ReleaseDetailsVie
SelectedReleaseViewModel = ReleaseViewModels.FirstOrDefault(vm => vm.Release.Id == releaseId); SelectedReleaseViewModel = ReleaseViewModels.FirstOrDefault(vm => vm.Release.Id == releaseId);
// Otherwise forward to the last release // Otherwise forward to the last release
else else
{ SelectedReleaseViewModel = ReleaseViewModels.FirstOrDefault(r => r.IsCurrentVersion) ?? ReleaseViewModels.FirstOrDefault();
ReleaseViewModel? lastRelease = ReleaseViewModels.FirstOrDefault(r => r.IsCurrentVersion) ?? ReleaseViewModels.FirstOrDefault();
if (lastRelease != null)
await _router.Navigate($"settings/releases/{lastRelease.Release.Id}");
}
} }
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using Artemis.Core; using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Screens.StartupWizard.Steps; using Artemis.UI.Screens.StartupWizard.Steps;
using Artemis.UI.Shared; using Artemis.UI.Shared;
using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services;
@ -11,11 +12,13 @@ namespace Artemis.UI.Screens.StartupWizard;
public partial class StartupWizardViewModel : DialogViewModelBase<bool> public partial class StartupWizardViewModel : DialogViewModelBase<bool>
{ {
private readonly IContainer _container; private readonly IContainer _container;
private readonly ISettingsService _settingsService;
[Notify] private WizardStepViewModel _screen; [Notify] private WizardStepViewModel _screen;
public StartupWizardViewModel(IContainer container, IWindowService windowService) public StartupWizardViewModel(IContainer container, IWindowService windowService, ISettingsService settingsService)
{ {
_container = container; _container = container;
_settingsService = settingsService;
_screen = _container.Resolve<WelcomeStepViewModel>(); _screen = _container.Resolve<WelcomeStepViewModel>();
_screen.Wizard = this; _screen.Wizard = this;
@ -41,6 +44,10 @@ public partial class StartupWizardViewModel : DialogViewModelBase<bool>
public void SkipOrFinishWizard() public void SkipOrFinishWizard()
{ {
PluginSetting<bool> setting = _settingsService.GetSetting("UI.SetupWizardCompleted", false);
setting.Value = true;
setting.Save();
Close(true); Close(true);
} }
} }