Serve slideshowpure.js/css from the plugin instead of jsDelivr

The injected index.html loaded both files from cdn.jsdelivr.net at
{{Config.VersionString}}, default "main". A branch ref is not a version:
jsDelivr re-resolves it at request time, so browser-side changes reach
every install the day they land, with no release and no way to decline,
and the code in the browser drifts from the installed plugin version. It
also leaves the media bar broken on servers without internet access.

Embed the files in the assembly and serve them from the existing
/MediaBar/{file} route:

- slideshowpure.js/css become EmbeddedResource under the Inject namespace
- Inject/index.html templates an asset base URL instead of a bare ref
- VersionString defaults to "embedded", which resolves to ../MediaBar
  (relative, so it works when Jellyfin is hosted under a base path)

Any other value is still treated as a git ref and fetched from jsDelivr.
This commit is contained in:
Skyler Shaw committed 2026-08-26 05:32:44 -07:00
1 parent f8b52288db
commit c7a4a47735
5 files changed
+20 -10

No files matched your search

@@ -10,10 +10,12 @@ namespace Jellyfin.Plugin.MediaBar.Configuration
public class PluginConfiguration : BasePluginConfiguration
{
public const string EmbeddedVersion = "embedded";
public MediaBarState Enabled { get; set; } = MediaBarState.Enabled;
public string VersionString { get; set; } = "main";
public string VersionString { get; set; } = EmbeddedVersion;
public bool UseAvatarsFile { get; set; } = true;
public string AvatarsPlaylist { get; set; } = string.Empty;
@@ -37,7 +37,7 @@
<label class="inputLabel inputLabelUnfocused" for="txtVersionString">Version</label>
<label class="inputLabel inputLabel-float inputLabelUnfocused" for="txtVersionString"></label>
<input id="txtVersionString" type="text" is="emby-input" class="emby-input" data-id="txtVersionString" />
<div class="fieldDescription">Which version of the jsdelivr'd plugin should be used.</div>
<div class="fieldDescription">Where the web assets are loaded from. Leave as <code>embedded</code> to serve the copies shipped inside this plugin, which always match the installed version and need no internet access. Set a git ref (branch, tag or commit) to load that version from jsDelivr instead.</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label class="emby-checkbox-label">
@@ -98,17 +98,24 @@ namespace Jellyfin.Plugin.MediaBar.Helpers
string importedHtml = reader
.ReadToEnd()
.Replace("{{Config.VersionString}}", ResolveVersion());
.Replace("{{AssetBaseUrl}}", ResolveAssetBaseUrl());
string regex = Regex.Replace(payload.Contents!, "(</head>)", $"{importedHtml}$1");
return regex;
}
private static string ResolveVersion()
private static string ResolveAssetBaseUrl()
{
string version = MediaBarPlugin.Instance.Configuration.VersionString;
if (string.IsNullOrWhiteSpace(version) ||
string.Equals(version, PluginConfiguration.EmbeddedVersion, StringComparison.OrdinalIgnoreCase))
{
// Relative to /web/ so it resolves when Jellyfin is hosted under a base path
return "../MediaBar";
}
if (version == "latest")
{
version = "main";
@@ -120,7 +127,7 @@ namespace Jellyfin.Plugin.MediaBar.Helpers
version = "10.11";
}
return version;
return $"https://cdn.jsdelivr.net/gh/IAmParadox27/jellyfin-plugin-media-bar@{version}";
}
public static string HomeHtmlChunk(PatchRequestPayload payload)
@@ -1,5 +1,5 @@
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/IAmParadox27/jellyfin-plugin-media-bar@{{Config.VersionString}}/slideshowpure.css" />
<script defer src="https://cdn.jsdelivr.net/gh/IAmParadox27/jellyfin-plugin-media-bar@{{Config.VersionString}}/slideshowpure.js"></script>
<link rel="stylesheet" href="{{AssetBaseUrl}}/slideshowpure.css" />
<script defer src="{{AssetBaseUrl}}/slideshowpure.js"></script>
<script defer>
if (typeof MediaBarConfigHandler == 'undefined') {
const MediaBarConfigHandler = {
@@ -53,8 +53,9 @@
<ItemGroup>
<None Include="..\..\README.md" />
<None Include="..\logo.png" CopyToOutputDirectory="Always" />
<None Include="..\..\slideshowpure.js" />
<None Include="..\..\slideshowpure.css" />
<!-- Served by MediaBarController at /MediaBar/slideshowpure.{js,css} -->
<EmbeddedResource Include="..\..\slideshowpure.js" LogicalName="Jellyfin.Plugin.MediaBar.Inject.slideshowpure.js" />
<EmbeddedResource Include="..\..\slideshowpure.css" LogicalName="Jellyfin.Plugin.MediaBar.Inject.slideshowpure.css" />
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="Exists('C:\ProgramData\Jellyfin\Server_10_11\plugins\MediaBar')">