Merge pull request #156 from Moonlight-Panel/AddServerBackgroundImage

Add dynamic background images for servers
This commit is contained in:
Marcel Baumgartner
2023-06-11 16:28:03 +02:00
committed by GitHub
14 changed files with 1526 additions and 334 deletions

View File

@@ -20,4 +20,5 @@ public class Image
public List<DockerImage> DockerImages { get; set; } = new();
public List<ImageVariable> Variables { get; set; } = new();
public string TagsJson { get; set; } = "";
public string BackgroundImageUrl { get; set; } = "";
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Moonlight.App.Database.Migrations
{
/// <inheritdoc />
public partial class AddBackgroundImageUrlImage : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "BackgroundImageUrl",
table: "Images",
type: "longtext",
nullable: false)
.Annotation("MySql:CharSet", "utf8mb4");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "BackgroundImageUrl",
table: "Images");
}
}
}

View File

@@ -132,6 +132,10 @@ namespace Moonlight.App.Database.Migrations
b.Property<int>("Allocations")
.HasColumnType("int");
b.Property<string>("BackgroundImageUrl")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("ConfigFiles")
.IsRequired()
.HasColumnType("longtext");

View File

@@ -47,6 +47,29 @@ public class ResourcesController : Controller
return NotFound();
}
[HttpGet("background/{name}")]
public async Task<ActionResult> GetBackground([FromRoute] string name)
{
if (name.Contains(".."))
{
await SecurityLogService.Log(SecurityLogType.PathTransversal, x =>
{
x.Add<string>(name);
});
return NotFound();
}
if (System.IO.File.Exists(PathBuilder.File("storage", "resources", "public", "background", name)))
{
var fs = new FileStream(PathBuilder.File("storage", "resources", "public", "background", name), FileMode.Open);
return File(fs, MimeTypes.GetMimeType(name), name);
}
return NotFound();
}
[HttpGet("bucket/{bucket}/{name}")]
public async Task<ActionResult> GetBucket([FromRoute] string bucket, [FromRoute] string name)
{

View File

@@ -16,6 +16,11 @@ public class ResourceService
return $"{AppUrl}/api/moonlight/resources/images/{name}";
}
public string BackgroundImage(string name)
{
return $"{AppUrl}/api/moonlight/resources/background/{name}";
}
public string Avatar(User user)
{
return $"{AppUrl}/api/moonlight/avatar/{user.Id}";

View File

@@ -0,0 +1,39 @@
using Logging.Net;
using Moonlight.App.Services.Files;
namespace Moonlight.App.Services.Sessions;
public class DynamicBackgroundService
{
public EventHandler OnBackgroundImageChanged { get; set; }
public string BackgroundImageUrl { get; private set; }
private string DefaultBackgroundImageUrl;
public DynamicBackgroundService(ResourceService resourceService)
{
DefaultBackgroundImageUrl = resourceService.BackgroundImage("main.jpg");
BackgroundImageUrl = DefaultBackgroundImageUrl;
}
public Task Change(string url)
{
if(BackgroundImageUrl == url) // Prevent unnecessary updates
return Task.CompletedTask;
BackgroundImageUrl = url;
OnBackgroundImageChanged?.Invoke(this, null!);
return Task.CompletedTask;
}
public Task Reset()
{
if(BackgroundImageUrl == DefaultBackgroundImageUrl) // Prevent unnecessary updates
return Task.CompletedTask;
BackgroundImageUrl = DefaultBackgroundImageUrl;
OnBackgroundImageChanged?.Invoke(this, null!);
return Task.CompletedTask;
}
}

View File

@@ -74,6 +74,7 @@
<Folder Include="App\ApiClients\CloudPanel\Resources\" />
<Folder Include="App\Http\Middleware" />
<Folder Include="storage\backups\" />
<Folder Include="storage\resources\public\background\" />
</ItemGroup>
</Project>

View File

@@ -134,6 +134,7 @@ namespace Moonlight
builder.Services.AddScoped<ReCaptchaService>();
builder.Services.AddScoped<IpBanService>();
builder.Services.AddSingleton<OAuth2Service>();
builder.Services.AddScoped<DynamicBackgroundService>();
builder.Services.AddScoped<SubscriptionService>();
builder.Services.AddScoped<SubscriptionAdminService>();

View File

@@ -20,6 +20,7 @@
@inject ToastService ToastService
@inject SmartTranslateService SmartTranslateService
@inject IpBanService IpBanService
@inject DynamicBackgroundService DynamicBackgroundService
<GlobalErrorBoundary>
@{
@@ -56,7 +57,7 @@
<Sidebar></Sidebar>
<div class="app-main flex-column flex-row-fluid" id="kt_app_main">
<div class="d-flex flex-column flex-column-fluid">
<div id="kt_app_content" class="app-content flex-column-fluid">
<div id="kt_app_content" class="app-content flex-column-fluid" style="background-position: center; background-size: cover; background-repeat: no-repeat; background-attachment: fixed; background-image: url('@(DynamicBackgroundService.BackgroundImageUrl)')">
<div id="kt_app_content_container" class="app-container container-fluid">
<div class="mt-10">
<SoftErrorBoundary>
@@ -189,6 +190,11 @@
{
try
{
DynamicBackgroundService.OnBackgroundImageChanged += async (_, _) =>
{
await InvokeAsync(StateHasChanged);
};
IsIpBanned = await IpBanService.IsBanned();
if(IsIpBanned)
@@ -211,7 +217,13 @@
await SessionService.Register();
NavigationManager.LocationChanged += (sender, args) => { SessionService.Refresh(); };
NavigationManager.LocationChanged += async (_, _) =>
{
SessionService.Refresh();
if (!NavigationManager.Uri.Contains("/server/"))
await DynamicBackgroundService.Reset();
};
if (User != null)
{

View File

@@ -38,6 +38,16 @@
</label>
<textarea @bind="Image.Description" type="text" class="form-control"></textarea>
</div>
<div class="mb-10">
<label class="form-label">
<TL>Background image url</TL>
</label>
<input
@bind="Image.BackgroundImageUrl"
type="text"
class="form-control"
placeholder="@(SmartTranslateService.Translate("Leave empty for the default background image"))">
</div>
</div>
</div>
<div class="col-xl-6 mb-5 mb-xl-10">

View File

@@ -125,7 +125,8 @@
</div>
</div>
<!--d-flex flex-row mb-5-->
<div class="row">
<div class="col">
<div class="card mb-5">
<div class="card-header card-header-stretch">
<div class="card-title d-flex align-items-center">
@@ -173,14 +174,15 @@
<TL>Create a domain</TL>
</a>
<span class="text-gray-400 fw-semibold d-block fs-6">
<TL>Make your servvices accessible throught your own domain</TL>
<TL>Make your services accessible through your own domain</TL>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col">
<div class="card mb-5">
<div class="card-header card-header-stretch">
<div class="card-title d-flex align-items-center">
@@ -235,6 +237,8 @@
</div>
</div>
</div>
</div>
</div>
</LazyLoader>
@code

View File

@@ -10,6 +10,7 @@
@using Moonlight.App.Helpers.Wings.Enums
@using Moonlight.App.Repositories
@using Moonlight.App.Services
@using Moonlight.App.Services.Sessions
@using Moonlight.Shared.Components.Xterm
@using Moonlight.Shared.Components.ServerControl
@using Newtonsoft.Json
@@ -20,6 +21,7 @@
@inject EventSystem Event
@inject ServerService ServerService
@inject NavigationManager NavigationManager
@inject DynamicBackgroundService DynamicBackgroundService
@implements IDisposable
@@ -291,6 +293,11 @@
return Task.CompletedTask;
});
if (string.IsNullOrEmpty(Image.BackgroundImageUrl))
await DynamicBackgroundService.Reset();
else
await DynamicBackgroundService.Change(Image.BackgroundImageUrl);
}
}
else

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB