Recreated plugin with new project template. Started implementing server system daemon

This commit is contained in:
2026-03-01 21:09:29 +01:00
parent f6b71f4de6
commit 52dbd13fb5
350 changed files with 2795 additions and 21553 deletions

View File

@@ -0,0 +1,6 @@
<Project>
<ItemGroup>
<!-- Put your plugin references here -->
<!-- E.g. <PackageReference Include="MoonlightServers.Api" Version="2.1.0" /> -->
</ItemGroup>
</Project>

View File

@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="10.0.1"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SimplePlugin" Version="1.0.2"/>
<PackageReference Include="SimplePlugin.Abstractions" Version="1.0.2"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\MoonlightServers.Api\MoonlightServers.Api.csproj" />
<ProjectReference Include="..\MoonlightServers.Frontend.Host\MoonlightServers.Frontend.Host.csproj" />
</ItemGroup>
<Import Project="Api.props"/>
</Project>

View File

@@ -0,0 +1,9 @@
using Moonlight.Api;
using SimplePlugin.Generated;
var plugins = PluginRegistry
.Modules
.OfType<MoonlightPlugin>()
.ToArray();
await StartupHandler.RunAsync(args, plugins);

View File

@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5031",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:7240;http://localhost:5031",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,23 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Moonlight": {
"Database": {
"Host": "your-db.host",
"Username": "change_me",
"Password": "change_me",
"Database": "change_me"
},
"Oidc": {
"Authority": "http://localhost:8092",
"RequireHttpsMetadata": false,
"ClientId": "clientId",
"ClientSecret": "clientSecret"
}
}
}

View File

@@ -0,0 +1,6 @@
<Project>
<ItemGroup>
<!-- Put your plugin references here -->
<!-- E.g. <PackageReference Include="MoonlightServers.Frontend" Version="2.1.0" /> -->
</ItemGroup>
</Project>

View File

@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<OverrideHtmlAssetPlaceholders>true</OverrideHtmlAssetPlaceholders>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.1"/>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.1" PrivateAssets="all"/>
<PackageReference Include="SimplePlugin" Version="1.0.2"/>
<PackageReference Include="SimplePlugin.Abstractions" Version="1.0.2"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\MoonlightServers.Frontend\MoonlightServers.Frontend.csproj" />
</ItemGroup>
<Import Project="Frontend.props"/>
</Project>

View File

@@ -0,0 +1,9 @@
using Moonlight.Frontend;
using SimplePlugin.Generated;
var plugins = PluginRegistry
.Modules
.OfType<MoonlightPlugin>()
.ToArray();
await StartupHandler.RunAsync(args, plugins);

View File

@@ -0,0 +1,25 @@
import fs from 'fs';
import selectorParser from 'postcss-selector-parser';
export default function extractTailwindClasses(opts = {}) {
const classSet = new Set();
return {
postcssPlugin: 'extract-tailwind-classes',
Rule(rule) {
selectorParser(selectors => {
selectors.walkClasses(node => {
classSet.add(node.value);
});
}).processSync(rule.selector);
},
OnceExit() {
const classArray = Array.from(classSet).sort();
fs.mkdirSync('../../../Servers.Frontend/Styles', { recursive: true });
fs.writeFileSync('../../../Servers.Frontend/Styles/Servers.Frontend.map', classArray.join('\n'));
console.log(`Extracted classes ${classArray.length}`);
}
};
}
extractTailwindClasses.postcss = true;

View File

@@ -0,0 +1,19 @@
{
"scripts": {
"dev": "npx postcss styles.css -o ../wwwroot/style.min.css --watch",
"dev-build": "npx postcss styles.css -o ../wwwroot/style.min.css",
"build": "cross-env EXTRACT_CLASSES=true npx postcss styles.css -o ../wwwroot/style.min.css"
},
"dependencies": {
"@tailwindcss/postcss": "^4.1.18",
"cssnano": "^7.1.2",
"postcss": "^8.5.6",
"postcss-cli": "^11.0.1",
"postcss-selector-parser": "^7.1.1",
"tailwindcss": "^4.1.18",
"tw-animate-css": "^1.4.0"
},
"devDependencies": {
"cross-env": "^10.1.0"
}
}

View File

@@ -0,0 +1,18 @@
import tailwindcss from '@tailwindcss/postcss';
import cssnano from 'cssnano';
import extractTailwindClasses from './extract-classes.mjs';
const plugins = [
tailwindcss,
cssnano({
preset: 'default'
})
];
if (process.env.EXTRACT_CLASSES === "true") {
plugins.push(extractTailwindClasses());
}
export default {
plugins
};

View File

@@ -0,0 +1,31 @@
@import "tailwindcss";
@import "tw-animate-css";
@import "../bin/ShadcnBlazor/scrollbar.css";
@import "../bin/ShadcnBlazor/default-theme.css";
@import "./theme.css";
@source "../bin/Moonlight.Frontend/*.map";
@source "../../../Moonlight.Api/**/*.razor";
@source "../../../Moonlight.Api/**/*.cs";
@source "../../../Moonlight.Api/**/*.html";
@source "../../../Moonlight.Frontend/**/*.razor";
@source "../../../Moonlight.Frontend/**/*.cs";
@source "../../../Moonlight.Frontend/**/*.html";
@custom-variant dark (&:is(.dark *));
#blazor-error-ui {
display: none;
}
@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
}

View File

@@ -0,0 +1,132 @@
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.129 0.042 264.695);
--card: oklch(1 0 0);
--card-foreground: oklch(0.129 0.042 264.695);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.129 0.042 264.695);
--primary: oklch(0.208 0.042 265.755);
--primary-foreground: oklch(0.984 0.003 247.858);
--secondary: oklch(0.968 0.007 247.896);
--secondary-foreground: oklch(0.208 0.042 265.755);
--muted: oklch(0.968 0.007 247.896);
--muted-foreground: oklch(0.554 0.046 257.417);
--accent: oklch(0.968 0.007 247.896);
--accent-foreground: oklch(0.208 0.042 265.755);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.929 0.013 255.508);
--input: oklch(0.929 0.013 255.508);
--ring: oklch(0.704 0.04 256.788);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--sidebar: var(--background);
--sidebar-foreground: var(--foreground);
--sidebar-primary: var(--primary);
--sidebar-primary-foreground: var(--primary-foreground);
--sidebar-accent: var(--accent);
--sidebar-accent-foreground: var(--accent-foreground);
--sidebar-border: var(--border);
--sidebar-ring: var(--ring);
--font-sans: Inter, sans-serif;
--font-serif: Georgia, serif;
}
.dark {
/* Deep blue-slate background with purple undertones */
--background: oklch(0.16 0.028 260);
--foreground: oklch(0.98 0.008 260);
/* Cards with slightly lighter blue-slate */
--card: oklch(0.21 0.032 260);
--card-foreground: oklch(0.98 0.008 260);
/* Popovers with medium depth */
--popover: oklch(0.24 0.035 260);
--popover-foreground: oklch(0.98 0.008 260);
/* Vibrant blue-purple primary */
--primary: oklch(0.62 0.18 270);
--primary-foreground: oklch(0.99 0.005 260);
/* Secondary with blue-slate tone */
--secondary: oklch(0.27 0.038 260);
--secondary-foreground: oklch(0.98 0.008 260);
/* Muted elements */
--muted: oklch(0.25 0.035 260);
--muted-foreground: oklch(0.66 0.025 260);
/* Accent with purple-blue blend */
--accent: oklch(0.36 0.065 268);
--accent-foreground: oklch(0.98 0.008 260);
/* Destructive red with good contrast */
--destructive: oklch(0.62 0.22 25);
--destructive-foreground: oklch(0.99 0.005 260);
/* Subtle borders and inputs */
--border: oklch(0.32 0.025 260);
--input: oklch(0.30 0.030 260);
--ring: oklch(0.62 0.18 270);
/* Chart colors with blue-purple harmony */
--chart-1: oklch(0.58 0.18 270);
--chart-2: oklch(0.62 0.16 245);
--chart-3: oklch(0.68 0.15 290);
--chart-4: oklch(0.60 0.20 260);
--chart-5: oklch(0.65 0.14 280);
/* Sidebar with slightly different depth */
--sidebar: oklch(0.18 0.030 260);
--sidebar-foreground: oklch(0.97 0.008 260);
--sidebar-primary: oklch(0.60 0.17 270);
--sidebar-primary-foreground: oklch(0.99 0.005 260);
--sidebar-accent: oklch(0.26 0.038 260);
--sidebar-accent-foreground: oklch(0.98 0.008 260);
--sidebar-border: oklch(0.30 0.025 260);
--sidebar-ring: oklch(0.58 0.17 270);
}
@theme inline {
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
}

View File

@@ -0,0 +1,108 @@
<!DOCTYPE html>
<html lang="en" class="dark">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Moonlight</title>
<base href="/" />
<link rel="preload" id="webassembly" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=fallback" />
<link rel="stylesheet" href="style.min.css" />
<script type="importmap"></script>
<script>
window.frontendConfig = {
STYLE_TAG_ID: 'theme-variables',
configuration: {},
applyTheme: function(cssContent) {
// Find or create the style tag
let styleTag = document.getElementById(this.STYLE_TAG_ID);
if (!styleTag) {
styleTag = document.createElement('style');
styleTag.id = this.STYLE_TAG_ID;
document.head.appendChild(styleTag);
}
// Update the style tag content
styleTag.textContent = cssContent;
},
reloadConfiguration: function (){
try {
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/frontend/config', false);
xhr.send(null);
if (xhr.status === 200) {
this.configuration = JSON.parse(xhr.responseText);
}
} catch (error) {
console.error('Failed to load initial theme:', error);
}
},
getConfiguration: function (){
return this.configuration;
},
reload: function () {
this.reloadConfiguration();
document.title = this.configuration.name;
this.applyTheme(this.configuration.themeCss);
}
};
window.frontendConfig.reload();
</script>
</head>
<body class="bg-background text-foreground">
<div id="app">
<div class="h-screen w-full flex items-center justify-center">
<div class="flex min-w-0 flex-1 flex-col items-center justify-center gap-3 rounded-lg border-dashed p-6 text-center text-balance md:p-12">
<div class="flex max-w-sm flex-col items-center gap-2 text-center">
<div class="flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-muted text-foreground size-10 rounded-lg [&_svg:not([class*='size-'])]:size-6">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="lucide lucide-zap-icon lucide-zap size-6">
<path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"/>
</svg>
</div>
</div>
<div class="text-lg font-medium tracking-tight">
Loading application
</div>
<div class="flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance">
<div class="bg-primary/20 w-full relative h-2 overflow-hidden rounded-full">
<div class="bg-primary h-full w-[var(--blazor-load-percentage,0)] flex-1 transition-all">
</div>
</div>
</div>
</div>
</div>
</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="." class="reload">Reload</a>
<span class="dismiss">🗙</span>
</div>
<script src="/_content/ShadcnBlazor/interop.js" defer></script>
<script src="/_content/ShadcnBlazor.Extras/interop.js" defer></script>
<script src="/_content/ShadcnBlazor.Extras/codemirror-bundle.js" defer></script>
<script src="_framework/blazor.webassembly#[.{fingerprint}].js"></script>
</body>
</html>