Added AssetService. Added command line handling for assets. Added asset streaming on the client

This commit is contained in:
2024-12-01 18:34:08 +01:00
parent 2e98d166ec
commit 0a76e64d2f
5 changed files with 134 additions and 1 deletions

View File

@@ -0,0 +1,27 @@
using Microsoft.AspNetCore.Mvc;
using Moonlight.ApiServer.Services;
using Moonlight.Shared.Http.Responses.Assets;
namespace Moonlight.ApiServer.Http.Controllers;
[ApiController]
[Route("api/assets")]
public class AssetsController : Controller
{
private readonly AssetService AssetService;
public AssetsController(AssetService assetService)
{
AssetService = assetService;
}
[HttpGet]
public async Task<FrontendAssetResponse> Get()
{
return new FrontendAssetResponse()
{
CssFiles = AssetService.CssFiles.ToArray(),
JavascriptFiles = AssetService.JavascriptFiles.ToArray(),
};
}
}

View File

@@ -0,0 +1,10 @@
using MoonCore.Attributes;
namespace Moonlight.ApiServer.Services;
[Singleton]
public class AssetService
{
public readonly List<string> CssFiles = new();
public readonly List<string> JavascriptFiles = new();
}

View File

@@ -78,9 +78,11 @@ public class Startup
await RegisterOAuth2(); await RegisterOAuth2();
await RegisterCaching(); await RegisterCaching();
await HookPluginBuild(); await HookPluginBuild();
await HandleConfigureArguments();
await BuildWebApplication(); await BuildWebApplication();
await HandleServiceArguments();
await PrepareDatabase(); await PrepareDatabase();
await UseBase(); await UseBase();
@@ -124,6 +126,73 @@ public class Startup
return Task.CompletedTask; return Task.CompletedTask;
} }
#region Command line arguments
private Task HandleConfigureArguments()
{
return Task.CompletedTask;
}
private Task HandleServiceArguments()
{
// Handle manual asset loading arguments
if (Args.Any(x => x.StartsWith("--frontend-asset")))
{
if (!Configuration.Client.Enable)
{
Logger.LogWarning("The hosting of the moonlight frontend is disabled. Ignoring all --frontend-asset options");
return Task.CompletedTask; // TODO: Change this when adding more service argument handling functions
}
if (!WebApplicationBuilder.Environment.IsDevelopment())
Logger.LogWarning("Using the --frontend-asset option is not meant to be used in production. Plugin assets will be loaded automaticly");
var assetService = WebApplication.Services.GetRequiredService<AssetService>();
for (int i = 0; i < Args.Length; i++)
{
var currentArg = Args[i];
// Ignore all args without relation to our frontend assets
if(!currentArg.Equals("--frontend-asset", StringComparison.InvariantCultureIgnoreCase))
continue;
if (i + 1 >= Args.Length)
{
Logger.LogWarning("You need to specify an asset path after the --frontend-asset option");
continue;
}
var nextArg = Args[i + 1];
if (nextArg.StartsWith("--"))
{
Logger.LogWarning("You need to specify an asset path after the --frontend-asset option");
continue;
}
var extension = Path.GetExtension(nextArg);
switch (extension)
{
case ".css":
assetService.CssFiles.Add(nextArg);
break;
case ".js":
assetService.JavascriptFiles.Add(nextArg);
break;
default:
Logger.LogWarning("Unknown asset extension {extension}. Ignoring it", extension);
break;
}
}
}
return Task.CompletedTask;
}
#endregion
#region Base #region Base
private Task RegisterBase() private Task RegisterBase()

View File

@@ -15,6 +15,7 @@ using Moonlight.Client.Interfaces;
using Moonlight.Client.Services; using Moonlight.Client.Services;
using Moonlight.Client.UI; using Moonlight.Client.UI;
using Moonlight.Client.UI.Forms; using Moonlight.Client.UI.Forms;
using Moonlight.Shared.Http.Responses.Assets;
using Moonlight.Shared.Http.Responses.PluginsStream; using Moonlight.Shared.Http.Responses.PluginsStream;
namespace Moonlight.Client; namespace Moonlight.Client;
@@ -62,6 +63,7 @@ public class Startup
await BuildWebAssemblyHost(); await BuildWebAssemblyHost();
await LoadPluginAssets(); await LoadPluginAssets();
await LoadAssets();
await WebAssemblyHost.RunAsync(); await WebAssemblyHost.RunAsync();
} }
@@ -124,6 +126,24 @@ public class Startup
return Task.CompletedTask; return Task.CompletedTask;
} }
#region Asset Loading
private async Task LoadAssets()
{
var apiClient = WebAssemblyHost.Services.GetRequiredService<HttpApiClient>();
var assetManifest = await apiClient.GetJson<FrontendAssetResponse>("api/assets");
var jsRuntime = WebAssemblyHost.Services.GetRequiredService<IJSRuntime>();
foreach (var cssFile in assetManifest.CssFiles)
await jsRuntime.InvokeVoidAsync("moonlight.assets.loadCss", cssFile);
foreach (var javascriptFile in assetManifest.JavascriptFiles)
await jsRuntime.InvokeVoidAsync("moonlight.assets.loadJavascript", javascriptFile);
}
#endregion
#region Interfaces #region Interfaces
private Task RegisterInterfaces() private Task RegisterInterfaces()

View File

@@ -0,0 +1,7 @@
namespace Moonlight.Shared.Http.Responses.Assets;
public class FrontendAssetResponse
{
public string[] CssFiles { get; set; }
public string[] JavascriptFiles { get; set; }
}