From fbf9b2189be52fe4464a24724ec9ed4b0f59868c Mon Sep 17 00:00:00 2001 From: CodeDevMLH <145071728+CodeDevMLH@users.noreply.github.com> Date: Wed, 17 Dec 2025 21:58:48 +0100 Subject: [PATCH] feat: enhance configuration page with seasonal options and improve user guidance --- .../Configuration/configPage.html | 326 ++++++++++++------ Jellyfin.Plugin.Seasonals/Web/santa.js | 2 +- feat/Jellyfin.Plugin.Seasonals.csproj | 34 -- feat/Plugin.cs | 50 --- feat/PluginServiceRegistrator.cs | 18 - feat/ScriptInjectionMiddleware.cs | 102 ------ feat/ScriptInjectionStartupFilter.cs | 21 -- 7 files changed, 218 insertions(+), 335 deletions(-) delete mode 100644 feat/Jellyfin.Plugin.Seasonals.csproj delete mode 100644 feat/Plugin.cs delete mode 100644 feat/PluginServiceRegistrator.cs delete mode 100644 feat/ScriptInjectionMiddleware.cs delete mode 100644 feat/ScriptInjectionStartupFilter.cs diff --git a/Jellyfin.Plugin.Seasonals/Configuration/configPage.html b/Jellyfin.Plugin.Seasonals/Configuration/configPage.html index 07dacfd..ac89a23 100644 --- a/Jellyfin.Plugin.Seasonals/Configuration/configPage.html +++ b/Jellyfin.Plugin.Seasonals/Configuration/configPage.html @@ -8,6 +8,16 @@
+
+

Seasonals

+ + + Help + +
+
+
+
-
-
-

Autumn

-
+
+ Advanced Configuration +

Configure specific settings for each seasonal theme below.

+

All symbol count settings add this number in addition to the standard 12 symbols (if random symbols is enabled).

+ +
+ Autumn +
+
Enable the autumn theme effects in general.
+
+
+ +
Displays leaves randomly distributed across the screen
+
+
+ +
Displays leaves randomly distributed across the screen on mobile devices. Warning: High values may affect performance.
+
Number of additional leaves displayed on screen (if enabled)
-
- -
-
- -
-
+
+
Randomize the falling speed of each leaf.
-
+
+
Rotate leaves as they fall. Notice: May affect performance
+
+
-

Snowflakes

-
+
+ Snowflakes +
+
Enable the snowflakes theme in general.
+
+
+ +
Displays snowflakes randomly distributed across the screen.
+
+
+ +
Displays snowflakes randomly distributed across the screen on mobile devices. Warning: High values may affect performance.
+
Number of additional snowflakes displayed (if enabled).
-
- -
-
- -
-
+
+
Display snowflakes in different colors/shapes.
-
+
+
Randomize the falling speed of snowflakes.
+
+
-

Snowfall

-
+
+ Snowfall +
+
Enable the snowfall effect in general.
+
Total number of snowflakes for the snowfall effect (recommended values: 300 - 600).
-
Warning: High values may affect performance
+
Total number of snowflakes on mobile devices. Warning: High values may affect performance.
+
The speed of the snowfall animation (recommended values: 0 - 5).
+
+
-

Snowstorm

-
+
+ Snowstorm +
+
Enable the snowstorm effect in general.
+
Total number of snowflakes in the storm (recommended values: 300 - 600).
-
Warning: High values may affect performance
+
Total number of snowflakes on mobile devices. Warning: High values may affect performance.
+
The speed of the snowstorm (falling).
+
Strength of the horizontal wind effect (recommended values: 3 - 6).
+
Amount of vertical movement variation (recommended values: 1 - 3).
+
+
-

Fireworks

-
+
+ Fireworks +
+
Enable the fireworks effect in general.
-
Warning: High values may affect performance
+
Number of particles per firework explosion. Warning: High values may affect performance.
+
Time in milliseconds between firework launches.
-
+
+
Allow fireworks to scroll with the page.
+
Minimum number of concurrent fireworks.
+
Maximum number of concurrent fireworks.
+
+
-

Halloween

-
+
+ Halloween +
+
Enable the Halloween theme in general.
+
+
+ +
Displays Halloween symbols randomly distributed across the screen.
+
+
+ +
Displays Halloween symbols randomly distributed across the screen on mobile devices. Warning: High values may affect performance.
+
Number of additional Halloween symbols (pumpkins, ghosts, etc.) on screen (if enabled).
-
- -
-
- -
-
+
+
Randomize the movement speed.
+
+
-

Hearts

-
+
+ Hearts +
+
Enable the Hearts theme in general.
+
+
+ +
Displays hearts randomly distributed across the screen.
+
+
+ +
Displays hearts randomly distributed across the screen. on mobile devices. Warning: High values may affect performance.
+
Number of additional floating hearts.
-
- -
-
- -
-
+
+
Randomize the floating speed.
+
+
-

Christmas

-
+
+ Christmas +
+
Enable the Christmas theme in general.
+
+
+ +
Displays Christmas-themed icons randomly distributed across the screen.
+
+
+ +
Displays Christmas-themed icons randomly distributed across the screen on mobile devices. Warning: High values may affect performance.
+
Number of additional Christmas symbols.
-
- -
-
- -
-
+
+
Randomize the movement speed.
+
+
-

Santa

-
+
+ Santa +
+
Enable the Santa theme in general.
+
Number of snowflakes accompanying Santa (recommended values: 300-600).
-
Warning: High values may affect performance
+
Number of snowflakes accompanying Santa on mobile devices. Warning: High values may affect performance.
+
Time in seconds for Santa to cross the screen (recommended values: 5 - 15).
+
Time in seconds for Santa to cross the screen on mobile (recommended values: 3 - 12).
+
Speed of the falling snow (recommended values: 0-5).
+
Maximum time Santa waits before appearing again.
+
Minimum time Santa waits before appearing again.
+
Maximum speed of falling presents.
+
Minimum speed of falling presents.
+
+
-

Easter

-
+
+ Easter +
+
Enable the Easter theme in general.
+
+
+ +
Displays easter eggs randomly distributed across the screen.
+
+
+ +
Displays easter eggs randomly distributed across the screen on mobile devices. Warning: High values may affect performance.
+
Number of additional Easter eggs (if enabled).
-
- -
-
- -
-
+
+
Randomize the movement speed.
-
+
+
Show the Easter Bunny hopping across the screen.
+
Time in milliseconds for one hop cycle.
+
Height of the bunny's hop in pixels.
+
Minimum time the bunny waits before appearing again.
+
Maximum time the bunny waits before appearing again.
+
+
+ +
+ info +
+ All changes require a page refresh (ctrl + r or F5) after saving for changes to take effect.
+ If old settings persist, please force clear browser cache.
@@ -385,7 +494,6 @@ -
Please reload the page (F5) after saving for changes to take effect.
diff --git a/Jellyfin.Plugin.Seasonals/Web/santa.js b/Jellyfin.Plugin.Seasonals/Web/santa.js index d6577a7..6bf75c1 100644 --- a/Jellyfin.Plugin.Seasonals/Web/santa.js +++ b/Jellyfin.Plugin.Seasonals/Web/santa.js @@ -4,7 +4,7 @@ const santaIsFlying = config.enableSanta !== undefined ? config.enableSanta : tr let snowflakesCount = config.snowflakesCount || 500; // count of snowflakes (recommended values: 300-600) const snowflakesCountMobile = config.snowflakesCountMobile || 250; // count of snowflakes on mobile devices (Warning: High values may affect performance) const snowFallSpeed = config.snowFallSpeed || 3; // speed of snowfall (recommended values: 0-5) -const santaSpeed = config.santaSpeed || 10; // speed of santa in seconds (recommended values: 5000-15000) +const santaSpeed = config.santaSpeed || 10; // speed of santa in seconds (recommended values: 5-15) const santaSpeedMobile = config.santaSpeedMobile || 8; // speed of santa on mobile devices in seconds const maxSantaRestTime = config.maxSantaRestTime || 8; // maximum time santa rests in seconds const minSantaRestTime = config.minSantaRestTime || 3; // minimum time santa rests in seconds diff --git a/feat/Jellyfin.Plugin.Seasonals.csproj b/feat/Jellyfin.Plugin.Seasonals.csproj deleted file mode 100644 index a42bea4..0000000 --- a/feat/Jellyfin.Plugin.Seasonals.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - 10.11.0 - net9.0 - net8.0 - Jellyfin.Plugin.Seasonals - enable - - - - - Jellyfin Seasonals Plugin - CodeDevMLH - 1.1.0.0 - https://github.com/CodeDevMLH/jellyfin-plugin-seasonals - - - - - - - - - - - - - - - - - - diff --git a/feat/Plugin.cs b/feat/Plugin.cs deleted file mode 100644 index a4b513d..0000000 --- a/feat/Plugin.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Collections.Generic; -using Jellyfin.Plugin.Seasonals.Configuration; -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Plugins; -using MediaBrowser.Model.Plugins; -using MediaBrowser.Model.Serialization; - -namespace Jellyfin.Plugin.Seasonals; - -/// -/// The main plugin. -/// -public class Plugin : BasePlugin, IHasWebPages -{ - /// - /// Initializes a new instance of the class. - /// - /// Instance of the interface. - /// Instance of the interface. - public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer) - : base(applicationPaths, xmlSerializer) - { - Instance = this; - } - - /// - public override string Name => "Seasonals"; - - /// - public override Guid Id => Guid.Parse("ef1e863f-cbb0-4e47-9f23-f0cbb1826ad4"); - - /// - /// Gets the current plugin instance. - /// - public static Plugin? Instance { get; private set; } - - /// - public IEnumerable GetPages() - { - return - [ - new PluginPageInfo - { - Name = "seasonals", - EmbeddedResourcePath = GetType().Namespace + ".Configuration.configPage.html" - } - ]; - } -} diff --git a/feat/PluginServiceRegistrator.cs b/feat/PluginServiceRegistrator.cs deleted file mode 100644 index f3363b0..0000000 --- a/feat/PluginServiceRegistrator.cs +++ /dev/null @@ -1,18 +0,0 @@ -using MediaBrowser.Controller; -using MediaBrowser.Controller.Plugins; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; - -namespace Jellyfin.Plugin.Seasonals; - -/// -/// Registers plugin services. -/// -public class PluginServiceRegistrator : IPluginServiceRegistrator -{ - /// - public void RegisterServices(IServiceCollection serviceCollection, IServerApplicationHost applicationHost) - { - serviceCollection.AddTransient(); - } -} diff --git a/feat/ScriptInjectionMiddleware.cs b/feat/ScriptInjectionMiddleware.cs deleted file mode 100644 index 9f61642..0000000 --- a/feat/ScriptInjectionMiddleware.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.IO; -using System.Text; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Logging; - -namespace Jellyfin.Plugin.Seasonals; - -/// -/// Middleware to inject the Seasonals script into the Jellyfin web interface. -/// -public class ScriptInjectionMiddleware -{ - private readonly RequestDelegate _next; - private readonly ILogger _logger; - private const string ScriptTag = ""; - private const string Marker = ""; - - /// - /// Initializes a new instance of the class. - /// - /// The next delegate in the pipeline. - /// The logger. - public ScriptInjectionMiddleware(RequestDelegate next, ILogger logger) - { - _next = next; - _logger = logger; - } - - /// - /// Invokes the middleware. - /// - /// The HTTP context. - /// A task representing the asynchronous operation. - public async Task InvokeAsync(HttpContext context) - { - if (IsIndexRequest(context.Request.Path)) - { - var originalBodyStream = context.Response.Body; - using var responseBody = new MemoryStream(); - context.Response.Body = responseBody; - - try - { - await _next(context); - - context.Response.Body = originalBodyStream; - responseBody.Seek(0, SeekOrigin.Begin); - - if (context.Response.StatusCode == 200 && - context.Response.ContentType != null && - context.Response.ContentType.Contains("text/html", StringComparison.OrdinalIgnoreCase)) - { - using var reader = new StreamReader(responseBody); - var content = await reader.ReadToEndAsync(); - - if (!content.Contains(ScriptTag, StringComparison.Ordinal) && content.Contains(Marker, StringComparison.Ordinal)) - { - var newContent = content.Replace(Marker, $"{ScriptTag}\n{Marker}", StringComparison.Ordinal); - var bytes = Encoding.UTF8.GetBytes(newContent); - - context.Response.ContentLength = bytes.Length; - await context.Response.Body.WriteAsync(bytes, 0, bytes.Length); - return; - } - } - - responseBody.Seek(0, SeekOrigin.Begin); - await responseBody.CopyToAsync(originalBodyStream); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error injecting Seasonals script via middleware."); - // Ensure we try to write back the original response if something failed - if (responseBody.Length > 0 && context.Response.Body == originalBodyStream) - { - responseBody.Seek(0, SeekOrigin.Begin); - await responseBody.CopyToAsync(originalBodyStream); - } - } - } - else - { - await _next(context); - } - } - - private static bool IsIndexRequest(PathString path) - { - if (!path.HasValue) - { - return false; - } - - var p = path.Value; - // Check for root, index.html, or web/index.html - return p.Equals("/", StringComparison.OrdinalIgnoreCase) || - p.Equals("/index.html", StringComparison.OrdinalIgnoreCase) || - p.EndsWith("/web/index.html", StringComparison.OrdinalIgnoreCase); - } -} diff --git a/feat/ScriptInjectionStartupFilter.cs b/feat/ScriptInjectionStartupFilter.cs deleted file mode 100644 index fc2e7c5..0000000 --- a/feat/ScriptInjectionStartupFilter.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; - -namespace Jellyfin.Plugin.Seasonals; - -/// -/// Startup filter to register the ScriptInjectionMiddleware. -/// -public class ScriptInjectionStartupFilter : IStartupFilter -{ - /// - public Action Configure(Action next) - { - return builder => - { - builder.UseMiddleware(); - next(builder); - }; - } -}