using System; using System.IO; using MediaBrowser.Common.Configuration; using Microsoft.Extensions.Logging; namespace Jellyfin.Plugin.JRay.Services; /// /// Injects (or removes) a script tag in the web client's index.html /// that loads JRay's pause-overlay script. This follows the pattern used by /// other Jellyfin plugins (e.g. Intro Skipper) since there is no official /// plugin hook for player-overlay UI. /// public static class WebClientPatchService { private const string Marker = ""; private const string ScriptTag = ""; private const string Injected = ScriptTag + Marker + "\n"; /// /// Ensures the web client's index.html either has or does not have the /// JRay overlay script injected, matching . /// /// The Jellyfin application paths. /// Whether the overlay script should be present. /// The logger. public static void Apply(IApplicationPaths applicationPaths, bool enableOverlay, ILogger logger) { var indexPath = Path.Combine(applicationPaths.WebPath, "index.html"); try { if (!File.Exists(indexPath)) { logger.LogDebug("JRay: web client index.html not found at {Path}", indexPath); return; } var html = File.ReadAllText(indexPath); var hasMarker = html.Contains(Marker, StringComparison.Ordinal); if (enableOverlay && !hasMarker) { var patched = ReplaceLast(html, "", Injected); File.WriteAllText(indexPath, patched); logger.LogInformation("JRay: injected pause-overlay script into {Path}", indexPath); } else if (!enableOverlay && hasMarker) { var patched = html.Replace(ScriptTag + Marker + "\n", string.Empty, StringComparison.Ordinal) .Replace(ScriptTag + Marker, string.Empty, StringComparison.Ordinal); File.WriteAllText(indexPath, patched); logger.LogInformation("JRay: removed pause-overlay script from {Path}", indexPath); } } catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) { logger.LogWarning(ex, "JRay: failed to patch web client index.html at {Path}", indexPath); } } private static string ReplaceLast(string source, string find, string replace) { var index = source.LastIndexOf(find, StringComparison.Ordinal); if (index < 0) { return source; } return source[..index] + replace + source[(index + find.Length)..]; } }