diff --git a/Jellyfin.Plugin.MediaBarEnhanced/Api/OverlayImageController.cs b/Jellyfin.Plugin.MediaBarEnhanced/Api/OverlayImageController.cs new file mode 100644 index 0000000..31a8a49 --- /dev/null +++ b/Jellyfin.Plugin.MediaBarEnhanced/Api/OverlayImageController.cs @@ -0,0 +1,89 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using MediaBrowser.Common.Configuration; + +namespace Jellyfin.Plugin.MediaBarEnhanced.Api +{ + /// + /// Controller for handling custom overlay image uploads and retrieval. + /// + [ApiController] + [Route("MediaBarEnhanced")] + public class OverlayImageController : ControllerBase + { + private readonly IApplicationPaths _applicationPaths; + private readonly string _imageDirectory; + private readonly string _imagePath; + + public OverlayImageController(IApplicationPaths applicationPaths) + { + _applicationPaths = applicationPaths; + + // We use the plugin's data folder to store the image + _imageDirectory = Path.Combine(_applicationPaths.PluginConfigurationPath, "MediaBarEnhanced"); + + // We'll just overwrite this single file each time + _imagePath = Path.Combine(_imageDirectory, "custom_overlay_image.dat"); + } + + /// + /// Uploads a new custom overlay image. + /// + [HttpPost("OverlayImage")] + [Consumes("multipart/form-data")] + public async Task UploadImage([FromForm] IFormFile file) + { + if (file == null || file.Length == 0) + { + return BadRequest("No file uploaded."); + } + + try + { + if (!Directory.Exists(_imageDirectory)) + { + Directory.CreateDirectory(_imageDirectory); + } + + // Delete the old one if it exists to ensure freshness + if (System.IO.File.Exists(_imagePath)) + { + System.IO.File.Delete(_imagePath); + } + + using (var stream = new FileStream(_imagePath, FileMode.Create)) + { + await file.CopyToAsync(stream).ConfigureAwait(false); + } + + // Return the GET URL that the frontend can use + var getUrl = "/MediaBarEnhanced/OverlayImage?t=" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + return Ok(new { url = getUrl }); + } + catch (Exception ex) + { + return StatusCode(500, $"Internal server error: {ex.Message}"); + } + } + + /// + /// Retrieves the custom overlay image. + /// + [HttpGet("OverlayImage")] + public IActionResult GetImage() + { + if (!System.IO.File.Exists(_imagePath)) + { + return NotFound(); + } + + // Read the file and return as a generic octet stream, since we don't strictly track the mime type + // The browser will figure out it's an image + var stream = new FileStream(_imagePath, FileMode.Open, FileAccess.Read, FileShare.Read); + return File(stream, "image/*"); + } + } +} diff --git a/Jellyfin.Plugin.MediaBarEnhanced/Configuration/PluginConfiguration.cs b/Jellyfin.Plugin.MediaBarEnhanced/Configuration/PluginConfiguration.cs index 3e75b62..11e1026 100644 --- a/Jellyfin.Plugin.MediaBarEnhanced/Configuration/PluginConfiguration.cs +++ b/Jellyfin.Plugin.MediaBarEnhanced/Configuration/PluginConfiguration.cs @@ -53,5 +53,6 @@ namespace Jellyfin.Plugin.MediaBarEnhanced.Configuration public bool EnableCustomOverlay { get; set; } = false; public string CustomOverlayText { get; set; } = ""; public string CustomOverlayImageUrl { get; set; } = ""; + public string CustomOverlayStyle { get; set; } = "Shadowed"; } } diff --git a/Jellyfin.Plugin.MediaBarEnhanced/Configuration/configPage.html b/Jellyfin.Plugin.MediaBarEnhanced/Configuration/configPage.html index a450d08..752af7c 100644 --- a/Jellyfin.Plugin.MediaBarEnhanced/Configuration/configPage.html +++ b/Jellyfin.Plugin.MediaBarEnhanced/Configuration/configPage.html @@ -210,10 +210,10 @@ - -