Merge branch 'v2_ChangeArchitecture' into v2_ChangeArchitecture_AddDiagnose
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using Moonlight.Client.Interfaces;
|
||||
using Moonlight.Client.Plugins;
|
||||
|
||||
namespace Moonlight.Client.Implementations;
|
||||
|
||||
public class CoreStartup : IPluginStartup
|
||||
{
|
||||
public Task BuildApplication(WebAssemblyHostBuilder builder)
|
||||
public Task BuildApplication(IServiceProvider serviceProvider, WebAssemblyHostBuilder builder)
|
||||
{
|
||||
builder.Services.AddSingleton<ISidebarItemProvider, DefaultSidebarItemProvider>();
|
||||
builder.Services.AddSingleton<IOverviewElementProvider, DefaultOverviewElementProvider>();
|
||||
@@ -13,6 +14,6 @@ public class CoreStartup : IPluginStartup
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task ConfigureApplication(WebAssemblyHost app)
|
||||
public Task ConfigureApplication(IServiceProvider serviceProvider, WebAssemblyHost app)
|
||||
=> Task.CompletedTask;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
|
||||
namespace Moonlight.Client.Interfaces;
|
||||
|
||||
public interface IPluginStartup
|
||||
{
|
||||
public Task BuildApplication(WebAssemblyHostBuilder builder);
|
||||
public Task ConfigureApplication(WebAssemblyHost app);
|
||||
}
|
||||
@@ -1,71 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<PublishTrimmed>false</PublishTrimmed>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
<DefaultItemExcludes>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<DefaultItemExcludes>
|
||||
**\bin\**;**\obj\**;**\node_modules\**;**\Styles\*.json
|
||||
</DefaultItemExcludes>
|
||||
<StaticWebAssetsEnabled>True</StaticWebAssetsEnabled>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<PropertyGroup>
|
||||
<PackageId>Moonlight.Client</PackageId>
|
||||
<Version>2.1.0</Version>
|
||||
<Authors>Moonlight Panel</Authors>
|
||||
<Description>A build of the client for moonlight development</Description>
|
||||
<PackageProjectUrl>https://github.com/Moonlight-Panel/Moonlight</PackageProjectUrl>
|
||||
<DevelopmentDependency>true</DevelopmentDependency>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<IsPackable>true</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Blazor-ApexCharts" Version="4.0.1"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.10"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.10" PrivateAssets="all"/>
|
||||
<PackageReference Include="MoonCore" Version="1.8.5"/>
|
||||
<PackageReference Include="MoonCore.Blazor" Version="1.2.9"/>
|
||||
<PackageReference Include="MoonCore.PluginFramework" Version="1.0.5"/>
|
||||
<PackageReference Include="MoonCore.Blazor.Tailwind" Version="1.4.2"/>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="**\*.cs" Exclude="storage\**\*;bin\**\*;obj\**\*">
|
||||
<Pack>true</Pack>
|
||||
<PackagePath>src</PackagePath>
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Styles\**\*" Exclude="storage\**\*;bin\**\*;obj\**\*;Styles\node_modules\**\*">
|
||||
<Pack>true</Pack>
|
||||
<PackagePath>styles</PackagePath>
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Compile Remove="storage\**\*"/>
|
||||
<Content Remove="storage\**\*"/>
|
||||
<None Remove="storage\**\*"/>
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
Specify the /p:BuildPWA=true flag to build moonlight as a PWA.
|
||||
This flag is by default disabled to allow nuget package generation
|
||||
-->
|
||||
|
||||
<PropertyGroup Condition="'$(BuildPWA)' == 'true'">
|
||||
<ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(BuildPWA)' == 'true'">
|
||||
<ServiceWorker Include="wwwroot\service-worker.js" PublishedContent="wwwroot\service-worker.published.js"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Moonlight.Shared\Moonlight.Shared.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
<StaticWebAssetsEnabled>True</StaticWebAssetsEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PackageTags>frontend</PackageTags>
|
||||
<PackageId>Moonlight.Client</PackageId>
|
||||
<Version>2.1.0</Version>
|
||||
<Authors>Moonlight Panel</Authors>
|
||||
<Description>A build of the client for moonlight development</Description>
|
||||
<PackageProjectUrl>https://github.com/Moonlight-Panel/Moonlight</PackageProjectUrl>
|
||||
<DevelopmentDependency>true</DevelopmentDependency>
|
||||
<IsPackable>true</IsPackable>
|
||||
<CompressionEnabled>false</CompressionEnabled>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Blazor-ApexCharts" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.5" PrivateAssets="all" />
|
||||
<PackageReference Include="MoonCore" Version="1.8.6" />
|
||||
<PackageReference Include="MoonCore.Blazor" Version="1.3.0" />
|
||||
<PackageReference Include="MoonCore.Blazor.Tailwind" Version="1.4.3" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="**\*.cs" Exclude="storage\**\*;bin\**\*;obj\**\*">
|
||||
<Pack>true</Pack>
|
||||
<PackagePath>src</PackagePath>
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Styles\**\*" Exclude="storage\**\*;bin\**\*;obj\**\*;Styles\node_modules\**\*">
|
||||
<Pack>true</Pack>
|
||||
<PackagePath>styles</PackagePath>
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Compile Remove="storage\**\*" />
|
||||
<Content Remove="storage\**\*" />
|
||||
<None Remove="storage\**\*" />
|
||||
</ItemGroup>
|
||||
<!--
|
||||
Specify the /p:BuildPWA=true flag to build moonlight as a PWA.
|
||||
This flag is by default disabled to allow nuget package generation
|
||||
-->
|
||||
<PropertyGroup Condition="'$(BuildPWA)' == 'true'">
|
||||
<ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition="'$(BuildPWA)' == 'true'">
|
||||
<ServiceWorker Include="wwwroot\service-worker.js" PublishedContent="wwwroot\service-worker.published.js" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Moonlight.Shared\Moonlight.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
9
Moonlight.Client/Plugins/IPluginStartup.cs
Normal file
9
Moonlight.Client/Plugins/IPluginStartup.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
|
||||
namespace Moonlight.Client.Plugins;
|
||||
|
||||
public interface IPluginStartup
|
||||
{
|
||||
public Task BuildApplication(IServiceProvider serviceProvider, WebAssemblyHostBuilder builder);
|
||||
public Task ConfigureApplication(IServiceProvider serviceProvider, WebAssemblyHost app);
|
||||
}
|
||||
7
Moonlight.Client/Plugins/PluginStartupAttribute.cs
Normal file
7
Moonlight.Client/Plugins/PluginStartupAttribute.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Moonlight.Client.Plugins;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class PluginStartupAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
@@ -9,7 +9,9 @@ using MoonCore.Blazor.Tailwind.Extensions;
|
||||
using MoonCore.Blazor.Tailwind.Auth;
|
||||
using MoonCore.Extensions;
|
||||
using MoonCore.Helpers;
|
||||
using Moonlight.Client.Implementations;
|
||||
using Moonlight.Client.Interfaces;
|
||||
using Moonlight.Client.Plugins;
|
||||
using Moonlight.Client.Services;
|
||||
using Moonlight.Shared.Misc;
|
||||
using Moonlight.Client.UI;
|
||||
@@ -33,15 +35,14 @@ public class Startup
|
||||
private WebAssemblyHost WebAssemblyHost;
|
||||
|
||||
// Plugin Loading
|
||||
private AssemblyLoadContext PluginLoadContext;
|
||||
private Assembly[] AdditionalAssemblies;
|
||||
|
||||
private IPluginStartup[] AdditionalPlugins;
|
||||
private IPluginStartup[] PluginStartups;
|
||||
private IServiceProvider PluginLoadServiceProvider;
|
||||
|
||||
public async Task Run(string[] args, Assembly[]? additionalAssemblies = null)
|
||||
public async Task Run(string[] args, IPluginStartup[]? additionalPlugins = null)
|
||||
{
|
||||
Args = args;
|
||||
AdditionalAssemblies = additionalAssemblies ?? [];
|
||||
AdditionalPlugins = additionalPlugins ?? [];
|
||||
|
||||
await PrintVersion();
|
||||
await SetupLogging();
|
||||
@@ -49,7 +50,6 @@ public class Startup
|
||||
await CreateWebAssemblyHostBuilder();
|
||||
|
||||
await LoadConfiguration();
|
||||
await LoadPlugins();
|
||||
await InitializePlugins();
|
||||
|
||||
await RegisterLogging();
|
||||
@@ -94,7 +94,7 @@ public class Startup
|
||||
httpClient.BaseAddress = new Uri(WebAssemblyHostBuilder.HostEnvironment.BaseAddress);
|
||||
|
||||
var jsonText = await httpClient.GetStringAsync("frontend.json");
|
||||
|
||||
|
||||
Configuration = JsonSerializer.Deserialize<FrontendConfiguration>(jsonText, new JsonSerializerOptions()
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
@@ -120,7 +120,7 @@ public class Startup
|
||||
BaseAddress = new Uri(Configuration.ApiUrl)
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
WebAssemblyHostBuilder.Services.AddScoped(sp =>
|
||||
{
|
||||
var httpClient = sp.GetRequiredService<HttpClient>();
|
||||
@@ -146,7 +146,7 @@ public class Startup
|
||||
WebAssemblyHostBuilder.Services.AddScoped<LocalStorageService>();
|
||||
|
||||
WebAssemblyHostBuilder.Services.AddScoped<ThemeService>();
|
||||
|
||||
|
||||
WebAssemblyHostBuilder.Services.AutoAddServices<Program>();
|
||||
|
||||
return Task.CompletedTask;
|
||||
@@ -160,39 +160,15 @@ public class Startup
|
||||
|
||||
foreach (var scriptName in Configuration.Scripts)
|
||||
await jsRuntime.InvokeVoidAsync("moonlight.assets.loadJavascript", scriptName);
|
||||
|
||||
foreach (var styleName in Configuration.Styles)
|
||||
await jsRuntime.InvokeVoidAsync("moonlight.assets.loadStylesheet", styleName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Plugins
|
||||
|
||||
private async Task LoadPlugins()
|
||||
{
|
||||
// Create everything required to stream plugins
|
||||
using var clientForStreaming = new HttpClient();
|
||||
|
||||
clientForStreaming.BaseAddress = new Uri(Configuration.HostEnvironment == "ApiServer"
|
||||
? Configuration.ApiUrl
|
||||
: WebAssemblyHostBuilder.HostEnvironment.BaseAddress
|
||||
);
|
||||
|
||||
PluginLoadContext = new AssemblyLoadContext(null);
|
||||
|
||||
foreach (var assembly in Configuration.Assemblies)
|
||||
{
|
||||
var assemblyStream = await clientForStreaming.GetStreamAsync($"plugins/{assembly}");
|
||||
PluginLoadContext.LoadFromStream(assemblyStream);
|
||||
}
|
||||
|
||||
// Add application assembly service
|
||||
var appAssemblyService = new ApplicationAssemblyService();
|
||||
|
||||
appAssemblyService.Assemblies.AddRange(AdditionalAssemblies);
|
||||
appAssemblyService.Assemblies.AddRange(PluginLoadContext.Assemblies);
|
||||
|
||||
WebAssemblyHostBuilder.Services.AddSingleton(appAssemblyService);
|
||||
}
|
||||
|
||||
private Task InitializePlugins()
|
||||
{
|
||||
// Define minimal service collection
|
||||
@@ -205,38 +181,31 @@ public class Startup
|
||||
builder.AddProviders(LoggerProviders);
|
||||
});
|
||||
|
||||
//
|
||||
var startupSp = startupSc.BuildServiceProvider();
|
||||
|
||||
// Initialize plugin startups
|
||||
var startups = new List<IPluginStartup>();
|
||||
var startupType = typeof(IPluginStartup);
|
||||
|
||||
var assembliesToScan = new List<Assembly>();
|
||||
|
||||
assembliesToScan.Add(typeof(Startup).Assembly);
|
||||
assembliesToScan.AddRange(AdditionalAssemblies);
|
||||
assembliesToScan.AddRange(PluginLoadContext.Assemblies);
|
||||
PluginLoadServiceProvider = startupSc.BuildServiceProvider();
|
||||
|
||||
foreach (var pluginAssembly in assembliesToScan)
|
||||
{
|
||||
var startupTypes = pluginAssembly
|
||||
.ExportedTypes
|
||||
.Where(x => !x.IsAbstract && !x.IsInterface && x.IsAssignableTo(startupType))
|
||||
.ToArray();
|
||||
// Collect startups
|
||||
var pluginStartups = new List<IPluginStartup>();
|
||||
|
||||
foreach (var type in startupTypes)
|
||||
{
|
||||
var startup = ActivatorUtilities.CreateInstance(startupSp, type) as IPluginStartup;
|
||||
|
||||
if(startup == null)
|
||||
continue;
|
||||
|
||||
startups.Add(startup);
|
||||
}
|
||||
}
|
||||
pluginStartups.Add(new CoreStartup());
|
||||
|
||||
PluginStartups = startups.ToArray();
|
||||
pluginStartups.AddRange(AdditionalPlugins); // Used by the development server
|
||||
|
||||
// Do NOT remove the following comment, as its used to place the plugin startup register calls
|
||||
// MLBUILD_PLUGIN_STARTUP_HERE
|
||||
|
||||
|
||||
PluginStartups = pluginStartups.ToArray();
|
||||
|
||||
// Add application assembly service
|
||||
var appAssemblyService = new ApplicationAssemblyService();
|
||||
|
||||
appAssemblyService.Assemblies.AddRange(
|
||||
PluginStartups
|
||||
.Select(x => x.GetType().Assembly)
|
||||
.Distinct()
|
||||
);
|
||||
|
||||
WebAssemblyHostBuilder.Services.AddSingleton(appAssemblyService);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
@@ -249,7 +218,7 @@ public class Startup
|
||||
{
|
||||
try
|
||||
{
|
||||
await pluginAppStartup.BuildApplication(WebAssemblyHostBuilder);
|
||||
await pluginAppStartup.BuildApplication(PluginLoadServiceProvider, WebAssemblyHostBuilder);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -268,7 +237,7 @@ public class Startup
|
||||
{
|
||||
try
|
||||
{
|
||||
await pluginAppStartup.ConfigureApplication(WebAssemblyHost);
|
||||
await pluginAppStartup.ConfigureApplication(PluginLoadServiceProvider, WebAssemblyHost);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -336,9 +305,9 @@ public class Startup
|
||||
{
|
||||
WebAssemblyHostBuilder.Services.AddAuthorizationCore();
|
||||
WebAssemblyHostBuilder.Services.AddCascadingAuthenticationState();
|
||||
|
||||
|
||||
WebAssemblyHostBuilder.Services.AddAuthenticationStateManager<RemoteAuthStateManager>();
|
||||
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,15 @@ window.moonlight = {
|
||||
scriptElement.type = 'text/javascript';
|
||||
|
||||
(document.head || document.documentElement).appendChild(scriptElement);
|
||||
},
|
||||
loadStylesheet: function (url) {
|
||||
let linkElement = document.createElement('link');
|
||||
|
||||
linkElement.href = url;
|
||||
linkElement.type = 'text/css';
|
||||
linkElement.rel = 'stylesheet';
|
||||
|
||||
(document.head || document.documentElement).appendChild(linkElement);
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user