Merge pull request #325 from LD-Reborn/319-feature-user-image-pre-loading

319 feature user image pre loading
This commit is contained in:
LD50
2025-11-20 20:08:48 +01:00
committed by GitHub
7 changed files with 105 additions and 0 deletions

View File

@@ -1,6 +1,7 @@
using SixLabors.ImageSharp; using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.Formats.Webp;
using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats;
using Berufsschule_HAM.Models;
namespace Berufsschule_HAM.Helpers; namespace Berufsschule_HAM.Helpers;
@@ -35,4 +36,19 @@ public static class ImageHelper
} }
return result; return result;
} }
public static async Task PreloadUsers(IEnumerable<UserModel> userModels, UserImagePreloadType? preloadType)
{
if (preloadType is null || preloadType == UserImagePreloadType.None) return;
foreach (UserModel user in userModels)
{
if (user.JpegPhoto is null) continue;
ResizeAndConvertToWebp(user.JpegPhoto, 48);
if (preloadType == UserImagePreloadType.FullSized)
{
ResizeAndConvertToWebp(user.JpegPhoto, 256);
}
}
}
} }

View File

@@ -11,9 +11,17 @@ public class AdminSettingsModel
public required string BarcodeText { get; set; } public required string BarcodeText { get; set; }
public required Dictionary<string, Preset> Presets { get; set; } public required Dictionary<string, Preset> Presets { get; set; }
public HashAlgorithm? hashAlgorithm; public HashAlgorithm? hashAlgorithm;
public UserImagePreloadType? UserImagePreloadType { get; set; } = Models.UserImagePreloadType.None;
} }
public class Preset public class Preset
{ {
public required Dictionary<string, string> Attribute { get; set; } public required Dictionary<string, string> Attribute { get; set; }
}
public enum UserImagePreloadType
{
None,
Icons,
FullSized
} }

View File

@@ -34,6 +34,7 @@ builder.Services.AddElmah<XmlFileErrorLog>(Options =>
builder.Services.AddSingleton<LdapService>(); builder.Services.AddSingleton<LdapService>();
builder.Services.AddHostedService<MigrationService>(); builder.Services.AddHostedService<MigrationService>();
builder.Services.AddHostedService<ImagePreloadService>();
builder.Services.AddHealthChecks() builder.Services.AddHealthChecks()
.AddCheck<DatabaseHealthCheck>("DatabaseHealthCheck"); .AddCheck<DatabaseHealthCheck>("DatabaseHealthCheck");

View File

@@ -88,4 +88,17 @@
<data name="Error contacting server" xml:space="preserve"> <data name="Error contacting server" xml:space="preserve">
<value>Fehler bei der Kommunikation mit dem Server</value> <value>Fehler bei der Kommunikation mit dem Server</value>
</data> </data>
<data name="User image preloading" xml:space="preserve">
<value>Benutzerprofilbilder im Voraus laden</value>
</data>
<data name="userImagePreloadType_None" xml:space="preserve">
<value>Benutzerprofilbilder nicht laden</value>
</data>
<data name="userImagePreloadType_Icons" xml:space="preserve">
<value>48x48 (empfohlen)</value>
</data>
<data name="userImagePreloadType_FullSized" xml:space="preserve">
<value>48x48 + 256x256</value>
</data>
</root> </root>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, ...</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, ...</value>
</resheader>
<data name="userImagePreloadType_None" xml:space="preserve">
<value>Do not preload user images</value>
</data>
<data name="userImagePreloadType_Icons" xml:space="preserve">
<value>48x48 (recommended)</value>
</data>
<data name="userImagePreloadType_FullSized" xml:space="preserve">
<value>48x48 + 256x256</value>
</data>
</root>

View File

@@ -0,0 +1,33 @@
using Berufsschule_HAM.Models;
using Berufsschule_HAM.Helpers;
namespace Berufsschule_HAM.Services;
public class ImagePreloadService : IHostedService
{
private readonly LdapService _ldap;
private readonly ILogger<HomeController> _logger;
public ImagePreloadService(LdapService ldap, ILogger<HomeController> logger)
{
_ldap = ldap ?? throw new ArgumentNullException(nameof(ldap));
_logger = logger;
}
public Task StartAsync(CancellationToken cancellationToken)
{
AdminSettingsModel adminSettingsModel = _ldap.GetAdminSettingsModelAsync().Result;
if (adminSettingsModel.UserImagePreloadType is not null && adminSettingsModel.UserImagePreloadType != UserImagePreloadType.None)
{
IEnumerable<UserModel> users = _ldap.ListUsersAsync().Result;
_logger.LogTrace("Preloading user images");
return ImageHelper.PreloadUsers(users, adminSettingsModel.UserImagePreloadType);
}
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}

View File

@@ -56,6 +56,15 @@
<label class="form-label" for="updateMaxDownloadableUserImageSize">@T["Max downloadable user image size"]</label> <label class="form-label" for="updateMaxDownloadableUserImageSize">@T["Max downloadable user image size"]</label>
<input type="number" id="updateMaxDownloadableUserImageSize" name="MaxDownloadableUserImageSize" class="form-control" value="@Model.MaxDownloadableUserImageSize" /> <input type="number" id="updateMaxDownloadableUserImageSize" name="MaxDownloadableUserImageSize" class="form-control" value="@Model.MaxDownloadableUserImageSize" />
</div> </div>
<div class="col-md-6">
<label class="form-label" for="updateUserImagePreloadType">@T["User image preloading"]</label>
<select type="text" name="UserImagePreloadType" id="updateUserImagePreloadType" class="form-control" />
@foreach (UserImagePreloadType userImagePreloadType in Enum.GetValues(typeof(UserImagePreloadType)))
{
<option selected="@(Model.UserImagePreloadType == userImagePreloadType)" value="@userImagePreloadType">@T["userImagePreloadType_" + userImagePreloadType.ToString()]</option>
}
</select>
</div>
</div> </div>
<div class="mt-3 p-2 bg border rounded d-flex justify-content-between align-items-center" <div class="mt-3 p-2 bg border rounded d-flex justify-content-between align-items-center"
data-bs-toggle="collapse" data-bs-toggle="collapse"