Compare commits

...

42 Commits

Author SHA1 Message Date
CodeDevMLH
2db3056511 Update manifest.json for release v1.4.0.1 [skip ci] 2026-02-04 15:01:50 +00:00
CodeDevMLH
2cc038e164 Bump version to 1.4.0.1 and update plugin configuration loading method
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-04 16:01:01 +01:00
CodeDevMLH
aa2df6e035 Update manifest.json for release v1.4.0.0 [skip ci] 2026-02-04 12:49:45 +00:00
CodeDevMLH
ff41618879 Fix localStorage key for loading screen preference (v1.4.0.0)
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 48s
2026-02-04 13:48:54 +01:00
CodeDevMLH
fbc03a28ea Update manifest.json for release v1.4.0.0 [skip ci] 2026-02-04 12:46:16 +00:00
CodeDevMLH
d2db678855 Bump version to 1.4.0.0
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-02-04 13:45:27 +01:00
CodeDevMLH
9259a0f487 Add client-side settings feature and support for SVG file type 2026-02-04 13:45:11 +01:00
CodeDevMLH
c391649884 add svg logo 2026-02-04 13:42:55 +01:00
CodeDevMLH
623e1d55b2 Update manifest.json for release v1.3.0.3 [skip ci] 2026-02-04 01:41:36 +00:00
CodeDevMLH
54b522101d Update configPage.html to emphasize note on item ID resolution feedback
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-04 02:40:47 +01:00
CodeDevMLH
dc92e8adba Bump version to 1.3.0.3
Some checks failed
Auto Release Plugin / build-and-release (push) Has been cancelled
2026-02-04 02:39:31 +01:00
CodeDevMLH
9de0d60bb8 Update configPage.html to clarify manual trailer override instructions 2026-02-04 02:39:07 +01:00
CodeDevMLH
5cd1f020fd Update manifest.json for release v1.3.0.2 [skip ci] 2026-02-04 01:27:56 +00:00
CodeDevMLH
1285d79538 Bump version to 1.3.0.2
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 56s
2026-02-04 02:27:04 +01:00
CodeDevMLH
05128ebc7e Update manifest.json for release v1.3.0.1 [skip ci] 2026-02-04 01:14:20 +00:00
CodeDevMLH
3bad812e96 Bump version to 1.3.0.1
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-04 02:13:29 +01:00
CodeDevMLH
1872a744a7 Update manifest.json for release v1.3.0.0 [skip ci] 2026-02-04 00:07:16 +00:00
CodeDevMLH
83441a3c4f Bump version to 1.3.0.0
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 1m0s
2026-02-04 01:06:22 +01:00
CodeDevMLH
49ad41c3f6 Enhance custom media ID functionality with manual trailer override 2026-02-04 01:06:12 +01:00
CodeDevMLH
984a41b180 Update manifest.json for release v1.2.3.7 [skip ci] 2026-01-28 22:39:54 +00:00
CodeDevMLH
c8421d12b0 Bump version to 1.2.3.7 and update changelog for release
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 57s
2026-01-28 23:39:03 +01:00
CodeDevMLH
b5d38629d2 Update manifest.json for release v1.2.3.6 [skip ci] 2026-01-28 21:31:54 +00:00
CodeDevMLH
8f4adece49 Bump version to 1.2.3.6 and update changelog for release
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 58s
2026-01-28 22:31:01 +01:00
CodeDevMLH
cfebccc289 Update manifest.json for release v1.2.3.5 [skip ci] 2026-01-28 20:21:21 +00:00
CodeDevMLH
2613fd7acf Update version to 1.2.3.5 in project file and manifest.json
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 1m20s
2026-01-28 21:20:06 +01:00
CodeDevMLH
bb10b9c15e Merge branch 'main' of ssh://git.mahom03-spacecloud.de:44322/CodeDevMLH/jellyfin-plugin-media-bar-enhanced 2026-01-28 21:16:52 +01:00
CodeDevMLH
a9ad8d65e4 Merge branch 'main' of ssh://git.mahom03-spacecloud.de:44322/CodeDevMLH/jellyfin-plugin-media-bar-enhanced [skip-ci] 2026-01-28 02:15:28 +01:00
CodeDevMLH
e7232da38b Update manifest.json for release v1.2.3.4 [skip ci] 2026-01-28 01:09:39 +00:00
CodeDevMLH
53bd1d23c7 Update manifest.json for release v1.2.3.4 with changelog and source URL adjustments
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 57s
2026-01-28 02:07:25 +01:00
CodeDevMLH
5643ebfd28 Update manifest.json for release v1.2.3.3 [skip ci] 2026-01-28 01:05:46 +00:00
CodeDevMLH
bed2fbaa76 Bump version to 1.2.3.4 and update release automation to generate commit log
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 58s
2026-01-28 02:04:45 +01:00
CodeDevMLH
05f64bc3d7 Update manifest.json for release v1.2.3.3 [skip ci] 2026-01-28 00:45:20 +00:00
CodeDevMLH
277433581c Bump version to 1.2.3.3 and update manifest with changelog for button positioning adjustments
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 58s
2026-01-28 01:44:23 +01:00
CodeDevMLH
44f0b1cb38 Update manifest.json for release v1.2.3.2 [skip ci] 2026-01-28 00:30:37 +00:00
CodeDevMLH
d31dcbabdc Bump version to 1.2.3.2 and update manifest with changelog for button adjustments on small screens
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 1m1s
2026-01-28 01:29:42 +01:00
CodeDevMLH
4ed6509505 Update manifest.json for release v1.2.3.1 [skip ci] 2026-01-28 00:17:29 +00:00
CodeDevMLH
6427b8422a Bump version to 1.2.3.1 and update manifest with changelog for button layout adjustments on small screens
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 56s
2026-01-28 01:16:38 +01:00
CodeDevMLH
ebfbe1d563 Update manifest.json for release v1.2.3.0 [skip ci] 2026-01-27 23:54:43 +00:00
CodeDevMLH
67e5d8e4d2 Bump version to 1.2.3.0 and update manifest with changelog for button display fixes on small screens
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 56s
2026-01-28 00:53:50 +01:00
CodeDevMLH
d68ba7e846 Update manifest.json for release v1.2.2.0 [skip ci] 2026-01-24 22:53:55 +00:00
CodeDevMLH
0444cf333d Bump version to 1.2.2.0 and update manifest with changelog for visibility fixes
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 1m0s
2026-01-24 23:52:59 +01:00
CodeDevMLH
10279e97d9 Comment out CHANGELOG body in release automation workflow 2026-01-23 01:18:22 +01:00
11 changed files with 521 additions and 36 deletions

View File

@@ -24,6 +24,8 @@ jobs:
uses: actions/checkout@v6 uses: actions/checkout@v6
with: with:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: Setup .NET - name: Setup .NET
uses: actions/setup-dotnet@v5 uses: actions/setup-dotnet@v5
@@ -94,16 +96,52 @@ jobs:
commit_message: "Update manifest.json for release v${{ env.VERSION }} [skip ci]" commit_message: "Update manifest.json for release v${{ env.VERSION }} [skip ci]"
file_pattern: manifest.json file_pattern: manifest.json
- name: Generate Commit Log
if: success()
shell: bash
run: |
echo "Generating commit log since last tag..."
# Get the previous tag
PREV_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -z "$PREV_TAG" ]; then
echo "No previous tag found. Getting all commits."
start_range=""
else
echo "Previous tag: $PREV_TAG"
start_range="$PREV_TAG.."
fi
echo "### What's Changed" > commit_log.md
echo "" >> commit_log.md
git log --pretty=format:"- %s (%h) by @%an" $start_range >> commit_log.md
# Combine Changelog from manifest (if exists) and commit log
if [ -n "${{ env.CHANGELOG }}" ]; then
echo "${{ env.CHANGELOG }}" > release_body.txt
echo "" >> release_body.txt
echo "" >> release_body.txt
cat commit_log.md >> release_body.txt
else
cat commit_log.md > release_body.txt
fi
# Debug output
cat release_body.txt
- name: Create Release - name: Create Release
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v2
with: with:
tag_name: "v${{ env.VERSION }}" tag_name: "v${{ env.VERSION }}"
name: "v${{ env.VERSION }}" name: "v${{ env.VERSION }}"
body: ${{ env.CHANGELOG }} # body: ${{ env.CHANGELOG }}
files: ${{ env.ZIP_PATH }} files: ${{ env.ZIP_PATH }}
draft: false draft: false
prerelease: false prerelease: false
generate_release_notes: true generate_release_notes: false
body_path: release_body.txt
# Update Message in Remote Repository # Update Message in Remote Repository
- name: Checkout Central Manifest Repo - name: Checkout Central Manifest Repo

View File

@@ -70,6 +70,7 @@ namespace Jellyfin.Plugin.MediaBarEnhanced.Api
if (path.EndsWith(".js", StringComparison.OrdinalIgnoreCase)) return "application/javascript"; if (path.EndsWith(".js", StringComparison.OrdinalIgnoreCase)) return "application/javascript";
if (path.EndsWith(".css", StringComparison.OrdinalIgnoreCase)) return "text/css"; if (path.EndsWith(".css", StringComparison.OrdinalIgnoreCase)) return "text/css";
if (path.EndsWith(".html", StringComparison.OrdinalIgnoreCase)) return "text/html"; if (path.EndsWith(".html", StringComparison.OrdinalIgnoreCase)) return "text/html";
if (path.EndsWith(".svg", StringComparison.OrdinalIgnoreCase)) return "image/svg+xml";
return "application/octet-stream"; return "application/octet-stream";
} }
} }

View File

@@ -34,5 +34,6 @@ namespace Jellyfin.Plugin.MediaBarEnhanced.Configuration
public string PreferredVideoQuality { get; set; } = "Auto"; public string PreferredVideoQuality { get; set; } = "Auto";
public bool EnableSeasonalContent { get; set; } = false; public bool EnableSeasonalContent { get; set; } = false;
public bool IsEnabled { get; set; } = true; public bool IsEnabled { get; set; } = true;
public bool EnableClientSideSettings { get; set; } = false;
} }
} }

View File

@@ -16,7 +16,7 @@
<a is="emby-linkbutton" class="raised raised-mini emby-button" style="margin-left: 2em;" <a is="emby-linkbutton" class="raised raised-mini emby-button" style="margin-left: 2em;"
target="_blank" href="https://github.com/CodeDevMLH/jellyfin-plugin-media-bar-enhanced"> target="_blank" href="https://github.com/CodeDevMLH/jellyfin-plugin-media-bar-enhanced">
<i class="md-icon button-icon button-icon-left secondaryText"></i> <i class="md-icon button-icon button-icon-left secondaryText"></i>
<span>Help</span> <span>${Help}</span>
</a> </a>
</div> </div>
<hr style="max-width: 800px; margin: 1em 0;"> <hr style="max-width: 800px; margin: 1em 0;">
@@ -109,20 +109,27 @@
<div class="inputContainer"> <div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="CustomMediaIds">Media/Collection/Playlist <label class="inputLabel inputLabelUnfocused" for="CustomMediaIds">Media/Collection/Playlist
IDs IDs
(Comma or Newline separated)</label> (Newline or Comma separated)</label>
<textarea is="emby-textarea" id="CustomMediaIds" name="CustomMediaIds" <textarea is="emby-textarea" id="CustomMediaIds" name="CustomMediaIds"
style="width: 100%; height: 150px; font-family: monospace;"></textarea> style="width: 100%; height: 150px; font-family: monospace;"></textarea>
<div class="fieldDescription" id="customMediaIdsDesc">Enter the IDs of the items you want to <div class="fieldDescription" id="customMediaIdsDesc">Enter the IDs of the items you want to show in the slideshow.
show in the slideshow. You can separate them by new line or comma.
You can separate them by comma or new line. <br><br>
<b>Manual Trailer Override:</b> You can specify a YouTube URL for an item by adding it in
brackets: <br> <code>e.g. ID DESCRIPTION [https://youtu.be/...]</code> or <code>ID [https://youtu.be/...] DESCRIPTION</code>
<br><br>
You can also add a description after the ID using any separator like space, pipe You can also add a description after the ID using any separator like space, pipe
(|) or dash (-) (e.g. <code>ID | Description</code>). (|) or dash (-): <br>e.g. <code>ID DESCRIPTION</code> or <code>ID | DESCRIPTION</code>
Note: The separator MUST NOT be a hex character (0-9, a-f).</div> <br><br>
<b>Note:</b> If using a <b>Collection Name</b> (instead of an ID) combined with a description, you <b>MUST</b> use
the pipe (|) separator.
<br>
<b>Note:</b> The separator <b>MUST NOT</b> be a hex character (0-9, a-f).</div>
<div class="fieldDescription" id="seasonalMediaIdsDesc" style="display: none;"> <div class="fieldDescription" id="seasonalMediaIdsDesc" style="display: none;">
<b>Seasonal Mode Enabled:</b> Define lines with date ranges (Format: DD.MM-DD.MM | <b>Seasonal Mode Enabled:</b> Define lines with date ranges (Format: DD.MM-DD.MM |
<i>name</i> | <i>IDs</i>).<br> <i>name</i> | <i>IDs</i>).<br>
Example:<br> Example:<br>
<code>20.10-31.10 | Halloween | ID1, ID2</code><br> <code>20.10-31.10 | Halloween | ID1, ID2 [https://youtu.be/...]</code><br>
<code>01.12-26.12 | Christmas | ID3, ID4</code><br> <code>01.12-26.12 | Christmas | ID3, ID4</code><br>
<i>Only lines matching the current date will be used. If no line matches, it will try to <i>Only lines matching the current date will be used. If no line matches, it will try to
fetch the list.txt or use random items.</i> fetch the list.txt or use random items.</i>
@@ -131,7 +138,7 @@
Example: Example:
<code>https://your-jellyfin-url/web/#/details?id=<b style="color:red;">your-item-id</b>&serverId=your-server-id</code><br><br> <code>https://your-jellyfin-url/web/#/details?id=<b style="color:red;">your-item-id</b>&serverId=your-server-id</code><br><br>
You can also insert a name of a collection or playlist to fetch the IDs of all items in You can also insert a name of a collection or playlist to fetch the IDs of all items in
it (will take the first hit.<br>Note: there is currently no feedback if the name it (will take the first hit.<br><b>Note:</b> there is currently no feedback if the name
resolution succeeded, you will have to look if the bar displays the correct items.). resolution succeeded, you will have to look if the bar displays the correct items.).
</p> </p>
</div> </div>
@@ -214,6 +221,15 @@
Space (pause), M (mute/unmute)) for Space (pause), M (mute/unmute)) for
the slideshow.</div> the slideshow.</div>
</div> </div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="EnableClientSideSettings"
name="EnableClientSideSettings" />
<span>Enable Client-Side Settings</span>
</label>
<div class="fieldDescription">If enabled, users will see a media bar icon in the header to
override settings (like disabling the bar or video backdrops) locally on their device.</div>
</div>
<h2 class="sectionTitle">Time Settings</h2> <h2 class="sectionTitle">Time Settings</h2>
<p>Leave a setting blank to use the default value.</p> <p>Leave a setting blank to use the default value.</p>
@@ -354,7 +370,7 @@
'WaitForTrailerToEnd', 'StartMuted', 'FullWidthVideo', 'EnableMobileVideo', 'WaitForTrailerToEnd', 'StartMuted', 'FullWidthVideo', 'EnableMobileVideo',
'ShowTrailerButton', 'AlwaysShowArrows', 'EnableKeyboardControls', 'ShowTrailerButton', 'AlwaysShowArrows', 'EnableKeyboardControls',
'EnableCustomMediaIds', 'CustomMediaIds', 'EnableLoadingScreen', 'EnableCustomMediaIds', 'CustomMediaIds', 'EnableLoadingScreen',
'EnableSeasonalContent' 'EnableSeasonalContent', 'EnableClientSideSettings'
]; ];
keys.forEach(function (key) { keys.forEach(function (key) {
@@ -403,7 +419,7 @@
'WaitForTrailerToEnd', 'StartMuted', 'FullWidthVideo', 'EnableMobileVideo', 'WaitForTrailerToEnd', 'StartMuted', 'FullWidthVideo', 'EnableMobileVideo',
'ShowTrailerButton', 'AlwaysShowArrows', 'EnableKeyboardControls', 'ShowTrailerButton', 'AlwaysShowArrows', 'EnableKeyboardControls',
'EnableCustomMediaIds', 'CustomMediaIds', 'EnableLoadingScreen', 'EnableCustomMediaIds', 'CustomMediaIds', 'EnableLoadingScreen',
'EnableSeasonalContent' 'EnableSeasonalContent', 'EnableClientSideSettings'
]; ];
keys.forEach(function (key) { keys.forEach(function (key) {

View File

@@ -12,7 +12,7 @@
<!-- <TreatWarningsAsErrors>false</TreatWarningsAsErrors> --> <!-- <TreatWarningsAsErrors>false</TreatWarningsAsErrors> -->
<Title>Jellyfin Media Bar Enhanced Plugin</Title> <Title>Jellyfin Media Bar Enhanced Plugin</Title>
<Authors>CodeDevMLH</Authors> <Authors>CodeDevMLH</Authors>
<Version>1.2.1.0</Version> <Version>1.4.0.1</Version>
<RepositoryUrl>https://github.com/CodeDevMLH/jellyfin-plugin-media-bar-enhanced</RepositoryUrl> <RepositoryUrl>https://github.com/CodeDevMLH/jellyfin-plugin-media-bar-enhanced</RepositoryUrl>
</PropertyGroup> </PropertyGroup>

View File

@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
id="Layer_1"
x="0px"
y="0px"
width="100%"
viewBox="0 0 1350 614"
enable-background="new 0 0 1350 614"
xml:space="preserve"
sodipodi:docname="file.svg"
inkscape:version="1.4.3 (0d15f75, 2025-12-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs12" /><sodipodi:namedview
id="namedview12"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="0.6577778"
inkscape:cx="949.40875"
inkscape:cy="353.46283"
inkscape:window-width="1920"
inkscape:window-height="1057"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" />
<path
fill="#FFFFFF"
opacity="1.000000"
stroke="none"
d=" M498.548157,519.821655 C508.235687,521.444031 517.517883,522.883118 526.789673,524.386841 C536.062744,525.890869 545.290039,527.733582 554.600769,528.937012 C569.316772,530.839050 584.077454,532.410095 598.836426,533.957336 C604.395325,534.539978 609.999268,534.894470 615.587463,534.962463 C649.167603,535.371338 682.751465,536.051270 716.329163,535.842651 C733.921753,535.733337 751.570740,534.638367 769.072815,532.819946 C786.970642,530.960388 804.773499,527.980896 822.517700,524.912109 C837.109558,522.388550 851.563538,519.058533 866.055603,515.977478 C868.387451,515.481689 870.928345,514.879272 872.806641,513.535217 C879.726013,508.583801 887.504639,508.919464 895.403381,508.953278 C923.388123,509.073120 951.373596,509.000000 979.719482,509.000000 C982.161377,520.378662 984.893127,531.637695 981.961182,543.227234 C979.976440,551.072632 973.778442,555.828491 967.460266,559.698853 C953.314880,568.364014 937.162048,571.950806 921.308411,575.872864 C904.270447,580.087952 887.066101,583.750244 869.788757,586.839539 C856.508240,589.214233 842.995605,590.277039 829.598083,592.014893 C817.345276,593.604248 805.122803,595.434509 792.859192,596.931213 C785.386536,597.843262 777.873047,598.539368 770.356934,598.946899 C760.284119,599.493164 750.191467,599.679504 740.106567,599.996582 C729.022766,600.345154 717.940002,600.757629 706.853455,600.980286 C686.771912,601.383606 666.685425,602.025940 646.605713,601.887451 C630.265808,601.774658 613.922607,600.848145 597.599915,599.941284 C584.830078,599.231812 572.043884,598.388062 559.347107,596.902161 C542.894592,594.976624 526.524048,592.351746 510.117493,590.032715 C498.219177,588.351013 486.247437,587.069946 474.439728,584.896851 C460.666870,582.362061 446.959656,579.361694 433.368530,575.981812 C421.710663,573.082764 410.121399,569.759766 398.757050,565.877136 C390.349060,563.004578 382.063538,559.402710 375.940796,552.427185 C368.723480,544.204651 369.426941,534.276978 370.326233,524.483704 C370.763611,519.720825 372.250519,515.054382 373.336273,510.000000 C379.597778,510.000000 385.905701,510.000000 392.213623,510.000000 C416.043518,510.000000 439.873474,509.974213 463.703278,510.020355 C468.857361,510.030334 473.744324,509.818298 478.814545,512.700806 C484.680084,516.035461 491.648621,517.429932 498.548157,519.821655 z"
id="path2" />
<path
fill="#c8c8c8"
opacity="1"
stroke="none"
d="m 330.93526,188.95459 c 0.0532,1.16148 0.0581,2.32297 0.0581,3.48445 0.002,83.55873 -0.0386,167.75573 -0.57327,251.76418 -44.6889,0.44479 -88.81469,-0.19785 -132.97407,-0.2035 -13.11818,-0.002 -20.44468,-7.24185 -20.44509,-20.21618 -0.002,-70.32166 0.28149,-140.64545 -0.24711,-210.96311 -0.10208,-13.57908 11.89072,-24.0623 24.10976,-23.96327 43.32297,0.35117 86.74576,0.11257 130.07169,0.0974 z"
id="path3"
sodipodi:nodetypes="cccsssscc" />
<path
fill="#cacaca"
opacity="1"
stroke="none"
d="m 1022.16,444.04364 c -0.053,-1.16144 -0.1533,-2.32288 -0.1533,-3.48431 0,-83.22391 0,-167.06543 0.5397,-250.74024 44.4984,-0.44619 88.4667,0.17002 132.435,0.20091 1.9751,10e-4 4.0287,2e-5 5.9117,0.50249 9.4167,2.51288 15.1069,10.15306 15.1069,20.00441 0,70.78233 -0.01,141.56468 0.01,212.34703 0,11.71546 -8.3125,21.49304 -20.9484,21.33988 -44.2946,-0.53681 -88.6475,0.5279 -132.9487,0.54246 z"
id="path4"
sodipodi:nodetypes="cccssssscc" />
<path
fill="#FFFFFF"
opacity="1.000000"
stroke="none"
d=" M395.009064,492.000000 C388.373993,491.343384 382.134369,491.180939 376.119720,489.933716 C360.581818,486.711700 348.845917,469.578186 348.888336,452.941223 C349.121979,361.276459 348.856903,269.610443 349.117371,177.945831 C349.171234,158.979095 361.452057,145.815338 378.579987,141.080048 C381.670135,140.225739 385.026764,140.042633 388.260437,140.041855 C580.424316,139.995056 772.588196,140.032410 964.752075,139.947540 C983.056519,139.939468 999.484863,152.050247 1002.960144,170.649078 C1003.555847,173.837250 1003.955872,177.116028 1003.957764,180.353241 C1004.010315,271.518555 1003.995422,362.683899 1004.003967,453.849243 C1004.005615,471.728058 992.793335,486.960602 974.694824,490.930511 C971.377319,491.658203 967.901123,491.956940 964.498047,491.957794 C774.834351,492.005280 585.170715,492.000000 395.009064,492.000000 M366.000000,444.473267 C366.000000,445.473083 366.077789,446.479889 365.988403,447.471649 C364.525879,463.702362 376.379547,474.760803 392.373016,474.218567 C416.907867,473.386719 441.491730,474.000000 466.054779,474.000000 C631.708801,474.000000 797.362976,473.895935 963.016418,474.208832 C975.500122,474.232391 987.143127,463.686707 987.110474,450.109283 C986.896118,360.949951 986.935608,271.789764 987.060913,182.630081 C987.082764,167.068771 976.391968,156.885590 961.346191,156.898560 C779.693542,157.055176 598.040710,157.000000 416.387909,157.000015 C407.555267,157.000015 398.721680,156.919998 389.890198,157.021133 C379.513062,157.139969 369.799591,164.361786 367.516266,174.235321 C366.373566,179.176605 366.064880,184.403137 366.059814,189.501343 C365.975830,274.161438 366.000000,358.821686 366.000000,444.473267 z"
id="path5" />
<path
fill="#FFFFFF"
opacity="1.000000"
stroke="none"
d=" M1022.085632,444.503815 C1066.461182,444.029083 1110.766602,443.677002 1155.061157,444.213806 C1167.697144,444.366974 1176.012939,434.589386 1176.009644,422.873932 C1175.990234,352.091583 1176.000000,281.309235 1176.000000,210.526901 C1176.000000,200.675552 1170.309814,193.035370 1160.893066,190.522491 C1159.010132,190.020020 1156.956543,190.021393 1154.981445,190.020004 C1111.013062,189.989136 1067.044800,189.990509 1022.618164,189.970871 C1022.159912,185.153610 1022.159912,180.351242 1022.159912,175.223175 C1023.488647,175.146652 1024.761597,175.009567 1026.034424,175.009247 C1069.847046,174.998154 1113.660400,174.850555 1157.471680,175.086029 C1171.636108,175.162170 1181.810181,182.166565 1188.159180,194.986008 C1188.953613,196.590164 1192.106445,197.862457 1194.174561,197.874329 C1225.658569,198.055084 1257.144043,198.000000 1288.629150,198.000000 C1296.625366,198.000000 1304.621582,198.006012 1312.617798,197.998688 C1327.143555,197.985397 1341.007446,211.825241 1341.004761,226.425781 C1340.993286,287.063751 1341.126831,347.702118 1340.917603,408.339386 C1340.859741,425.102753 1334.462280,432.430908 1319.805664,438.607025 C1318.373657,439.210449 1316.552856,438.985443 1314.912476,438.986176 C1274.764771,439.003845 1234.617065,439.049438 1194.469727,438.913055 C1190.980713,438.901215 1189.458252,440.058899 1187.874390,443.116028 C1182.058105,454.342072 1172.220093,460.703491 1159.901367,460.820709 C1114.260986,461.255157 1068.613892,460.968658 1022.969238,460.944519 C1022.828308,460.944427 1022.687500,460.819489 1022.011292,460.499634 C1022.011292,455.500580 1022.011292,450.232269 1022.085632,444.503815 M1247.500000,211.000000 C1231.341675,211.000000 1215.183350,210.992218 1199.025024,211.003860 C1192.604980,211.008499 1191.005493,212.565262 1191.004761,218.862900 C1190.997070,284.995239 1190.996216,351.127563 1191.005737,417.259918 C1191.006714,423.998322 1192.925781,425.988373 1199.485962,425.991455 C1236.799927,426.009003 1274.113892,425.976929 1311.427856,426.022675 C1317.619751,426.030273 1322.117432,423.150269 1324.465454,417.754608 C1326.001587,414.224365 1326.887695,410.114258 1326.897217,406.260986 C1327.044556,346.958801 1327.000488,287.656097 1326.999512,228.353546 C1326.999390,217.144135 1320.810547,211.008224 1309.468384,211.002762 C1289.145630,210.992966 1268.822754,211.000000 1247.500000,211.000000 z"
id="path6" />
<path
fill="#ffffff"
opacity="1"
stroke="none"
d="m 330.91425,188.95955 c -43.39994,0.47338 -86.72771,0.24878 -130.05068,-0.10239 -12.21904,-0.099 -24.21184,10.38419 -24.10976,23.96327 0.5286,70.31766 0.24494,140.64145 0.24711,210.96311 4.1e-4,12.97433 7.32691,20.21451 20.44509,20.21618 44.15938,0.006 88.31876,0.01 132.93637,0.0304 0.45826,5.48407 0.45826,10.95264 0.45826,16.96985 h -5.38221 c -43.31478,0 -86.6306,0.16705 -129.94372,-0.10172 -13.00781,-0.0807 -23.54056,-5.59921 -29.7357,-17.6466 -1.61699,-3.14444 -3.63599,-4.35541 -7.30498,-4.34201 -39.64915,0.1448 -79.29908,0.0573 -118.948685,0.1159 -8.759545,0.0129 -15.254898,-4.23486 -20.405224,-10.70178 -5.312873,-6.67105 -7.246366,-14.40582 -7.218926,-23.05365 0.188187,-59.30734 0.09876,-118.61557 0.09882,-177.92351 1.1e-5,-11.41679 8.002948,-23.41223 18.672981,-27.12843 3.893362,-1.35602 8.201628,-2.10867 12.324739,-2.12553 38.316288,-0.15668 76.63382,-0.16838 114.94993,0.008 4.54648,0.0209 6.93851,-1.56689 9.02278,-5.48947 5.92766,-11.15582 15.14014,-17.58424 28.12126,-17.59602 C 238.40646,174.97557 281.72125,175 325.03604,175 h 5.95221 c 0,4.49806 -0.0475,6.53519 -0.12151,11.26344 M 75.5,426 c 25.9955,0 51.991,0.002 77.9865,-0.002 7.14871,-0.001 8.51109,-1.33438 8.51145,-8.35559 0.003,-66.15506 0.004,-132.31012 -7.3e-4,-198.46518 -4.9e-4,-6.96535 -1.18309,-8.17265 -8.02932,-8.17404 -37.32679,-0.008 -74.653577,-0.0119 -111.980363,0.002 -9.938388,0.004 -15.978248,6.1517 -15.984113,16.22824 -0.01154,19.82986 -0.0034,39.65971 -0.0034,59.48958 0,39.6597 0.195755,79.32095 -0.116185,118.97821 -0.09684,12.31097 8.311491,21.3251 20.131846,20.44104 C 55.46117,425.43628 65.001663,426 75.5,426 Z"
id="path7"
sodipodi:nodetypes="cssssccssssssssssssssccsssssssssss" />
<path
fill="#FFFFFF"
opacity="1.000000"
stroke="none"
d=" M752.998535,122.000000 C697.384888,122.000000 642.270752,122.000031 587.156677,121.999809 C585.991150,121.999802 584.755127,122.248329 583.674011,121.945503 C581.040527,121.207886 579.301270,119.989822 581.538269,116.943802 C595.221191,98.312027 608.645996,79.486267 622.579712,61.044662 C631.013855,49.881832 639.965149,39.081825 649.147034,28.521265 C655.735779,20.943233 663.853149,14.640454 674.239014,14.266470 C682.228760,13.978765 690.355103,15.915215 696.482056,22.029982 C710.278809,35.799351 722.732300,50.695175 734.200928,66.471100 C745.246033,81.664513 756.752502,96.522255 768.020935,111.553917 C769.170105,113.086906 770.086121,114.795883 771.095093,116.432625 C773.244812,119.919868 772.167419,121.913857 767.983948,121.981750 C763.156494,122.060104 758.326782,121.999985 752.998535,122.000000 z"
id="path8" />
<path
fill="#B9B9B9"
opacity="1.000000"
stroke="none"
d=" M366.000000,443.977570 C366.000000,358.821686 365.975830,274.161438 366.059814,189.501343 C366.064880,184.403137 366.373566,179.176605 367.516266,174.235321 C369.799591,164.361786 379.513062,157.139969 389.890198,157.021133 C398.721680,156.919998 407.555267,157.000015 416.387909,157.000015 C598.040710,157.000000 779.693542,157.055176 961.346191,156.898560 C976.391968,156.885590 987.082764,167.068771 987.060913,182.630081 C986.935608,271.789764 986.896118,360.949951 987.110474,450.109283 C987.143127,463.686707 975.500122,474.232391 963.016418,474.208832 C797.362976,473.895935 631.708801,474.000000 466.054779,474.000000 C441.491730,474.000000 416.907867,473.386719 392.373016,474.218567 C376.379547,474.760803 364.525879,463.702362 365.988403,447.471649 C366.077789,446.479889 366.000000,445.473083 366.000000,443.977570 M612.844971,237.388443 C611.896790,239.785782 610.129822,242.180267 610.121521,244.580856 C609.958679,291.555145 609.984619,338.530182 610.022644,385.505005 C610.026978,390.825134 613.298340,395.021606 618.073486,396.969757 C622.378906,398.726318 626.389282,397.628296 629.872437,395.474457 C644.906433,386.178070 659.816589,376.677917 674.674377,367.100769 C694.658508,354.219269 714.593994,341.261017 734.470093,328.213562 C745.839661,320.750214 745.924316,311.287506 734.653076,303.900543 C710.193420,287.870148 685.640808,271.981476 661.117188,256.048767 C651.003967,249.478363 640.900208,242.892380 630.730652,236.409973 C623.383179,231.726349 619.020142,231.866287 612.844971,237.388443 z"
id="path9" />
<path
fill="#CFCFCF"
opacity="1.000000"
stroke="none"
d=" M1248.000000,211.000000 C1268.822754,211.000000 1289.145630,210.992966 1309.468384,211.002762 C1320.810547,211.008224 1326.999390,217.144135 1326.999512,228.353546 C1327.000488,287.656097 1327.044556,346.958801 1326.897217,406.260986 C1326.887695,410.114258 1326.001587,414.224365 1324.465454,417.754608 C1322.117432,423.150269 1317.619751,426.030273 1311.427856,426.022675 C1274.113892,425.976929 1236.799927,426.009003 1199.485962,425.991455 C1192.925781,425.988373 1191.006714,423.998322 1191.005737,417.259918 C1190.996216,351.127563 1190.997070,284.995239 1191.004761,218.862900 C1191.005493,212.565262 1192.604980,211.008499 1199.025024,211.003860 C1215.183350,210.992218 1231.341675,211.000000 1248.000000,211.000000 z"
id="path10" />
<path
fill="#C0C0C0"
opacity="1.000000"
stroke="none"
d=" M75.000000,426.000000 C65.001663,426.000000 55.461170,425.436279 46.015667,426.142670 C34.195312,427.026733 25.786983,418.012604 25.883821,405.701630 C26.195761,366.044373 26.000006,326.383118 26.000006,286.723419 C26.000004,266.893555 25.991882,247.063705 26.003424,227.233841 C26.009289,217.157303 32.049149,211.009308 41.987537,211.005600 C79.314323,210.991669 116.641106,210.996048 153.967896,211.003571 C160.814133,211.004959 161.996735,212.212265 161.997223,219.177612 C162.001892,285.332672 162.001419,351.487732 161.997955,417.642792 C161.997589,424.664001 160.635208,425.997284 153.486496,425.998383 C127.490997,426.002441 101.495499,426.000000 75.000000,426.000000 z"
id="path11" />
<path
fill="#FFFFFF"
opacity="1.000000"
stroke="none"
d=" M612.987183,237.031128 C619.020142,231.866287 623.383179,231.726349 630.730652,236.409973 C640.900208,242.892380 651.003967,249.478363 661.117188,256.048767 C685.640808,271.981476 710.193420,287.870148 734.653076,303.900543 C745.924316,311.287506 745.839661,320.750214 734.470093,328.213562 C714.593994,341.261017 694.658508,354.219269 674.674377,367.100769 C659.816589,376.677917 644.906433,386.178070 629.872437,395.474457 C626.389282,397.628296 622.378906,398.726318 618.073486,396.969757 C613.298340,395.021606 610.026978,390.825134 610.022644,385.505005 C609.984619,338.530182 609.958679,291.555145 610.121521,244.580856 C610.129822,242.180267 611.896790,239.785782 612.987183,237.031128 z"
id="path12" />
</svg>

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,5 +1,5 @@
/* /*
* Jellyfin Slideshow by M0RPH3US v3.0.8 * Jellyfin Slideshow by M0RPH3US v3.0.9
* Modified by CodeDevMLH v1.1.0.0 * Modified by CodeDevMLH v1.1.0.0
* *
* New features: * New features:
@@ -13,6 +13,7 @@
* - option to set a maximum for the pagination dots (will turn into a counter style if exceeded) * - option to set a maximum for the pagination dots (will turn into a counter style if exceeded)
* - option to disable loading screen * - option to disable loading screen
* - option to put collection (boxsets) IDs into the slideshow to display their items * - option to put collection (boxsets) IDs into the slideshow to display their items
* - option to enable client-side settings (allow users to override settings locally on their device)
*/ */
@import url(https://fonts.googleapis.com/css2?family=Archivo+Narrow:ital,wght@0,400..700;1,400..700&display=swap); @import url(https://fonts.googleapis.com/css2?family=Archivo+Narrow:ital,wght@0,400..700;1,400..700&display=swap);
@@ -170,6 +171,12 @@
height: 90%; height: 90%;
overflow: hidden; overflow: hidden;
margin: 0 auto; margin: 0 auto;
pointer-events: auto;
}
#slides-container[style*="display: none"],
#slides-container[style*="visibility: hidden"] {
pointer-events: none !important;
} }
.arrow { .arrow {
@@ -784,6 +791,41 @@
left: 50%; left: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
} }
@media (max-width: 400px) {
.button-container {
gap: 10px;
}
.play-button,
.trailer-button {
padding: 8px 14px;
}
.misc-info {
flex-wrap: wrap;
justify-content: center;
gap: 0px 10px;
}
.runTime {
width: 100%;
justify-content: center;
margin-top: 0.5vh;
}
.misc-info .separator-icon:last-of-type {
display: none;
}
.genre {
top: calc(50% + 16vh);
}
.button-container {
top: calc(50% + 27vh);
}
}
} }
/*Landscape Mode Phones*/ /*Landscape Mode Phones*/

View File

@@ -1,5 +1,5 @@
/* /*
* Jellyfin Slideshow by M0RPH3US v3.0.8 * Jellyfin Slideshow by M0RPH3US v3.0.9
* Modified by CodeDevMLH v1.1.0.0 * Modified by CodeDevMLH v1.1.0.0
* *
* New features: * New features:
@@ -13,6 +13,7 @@
* - option to set a maximum for the pagination dots (will turn into a counter style if exceeded) * - option to set a maximum for the pagination dots (will turn into a counter style if exceeded)
* - option to disable loading screen * - option to disable loading screen
* - option to put collection (boxsets) IDs into the slideshow to display their items * - option to put collection (boxsets) IDs into the slideshow to display their items
* - option to enable client-side settings (allow users to override settings locally on their device)
*/ */
//Core Module Configuration //Core Module Configuration
@@ -49,6 +50,7 @@ const CONFIG = {
enableSeasonalContent: false, enableSeasonalContent: false,
customMediaIds: "", customMediaIds: "",
enableLoadingScreen: true, enableLoadingScreen: true,
enableClientSideSettings: false,
}; };
// State management // State management
@@ -78,6 +80,7 @@ const STATE = {
videoPlayers: {}, videoPlayers: {},
sponsorBlockInterval: null, sponsorBlockInterval: null,
isMuted: CONFIG.startMuted, isMuted: CONFIG.startMuted,
customTrailerUrls: {},
}, },
}; };
@@ -206,7 +209,7 @@ const initLoadingScreen = () => {
if (!isHomePage) return; if (!isHomePage) return;
// Check LocalStorage for cached preference to avoid flash // Check LocalStorage for cached preference to avoid flash
const cachedSetting = localStorage.getItem('mediaBarEnhanced_enableLoadingScreen'); const cachedSetting = localStorage.getItem('mediaBarEnhanced-enableLoadingScreen');
if (cachedSetting === 'false') { if (cachedSetting === 'false') {
return; return;
} }
@@ -344,6 +347,7 @@ const resetSlideshowState = () => {
STATE.slideshow.itemIds = []; STATE.slideshow.itemIds = [];
STATE.slideshow.loadedItems = {}; STATE.slideshow.loadedItems = {};
STATE.slideshow.createdSlides = {}; STATE.slideshow.createdSlides = {};
STATE.slideshow.customTrailerUrls = {};
STATE.slideshow.totalItems = 0; STATE.slideshow.totalItems = 0;
STATE.slideshow.isLoading = false; STATE.slideshow.isLoading = false;
}; };
@@ -439,7 +443,7 @@ const fetchPluginConfig = async () => {
} }
// Sync to LocalStorage for next load // Sync to LocalStorage for next load
localStorage.setItem('mediaBarEnhanced_enableLoadingScreen', CONFIG.enableLoadingScreen); localStorage.setItem('mediaBarEnhanced-enableLoadingScreen', CONFIG.enableLoadingScreen);
console.log("✅ MediaBarEnhanced config loaded", CONFIG); console.log("✅ MediaBarEnhanced config loaded", CONFIG);
} }
@@ -843,29 +847,64 @@ const LocalizationUtils = {
throw new Error(`Failed to fetch translations: ${response.statusText}`); throw new Error(`Failed to fetch translations: ${response.statusText}`);
} }
/**
* @example
* Standard version
* ```js
* "use strict";
* (self.webpackChunk = self.webpackChunk || []).push([[62634], {
* 30985: function(e) {
* e.exports = JSON.parse('{"Absolute":"..."}')
* }
* }]);
* ```
*
* Minified version
* ```js
* "use strict";(self.webpackChunk=self.webpackChunk||[]).push([[24072],{60715:function(e){e.exports=JSON.parse('{"Absolute":"..."}')}}]);
* ```
*/
const chunkText = await response.text(); const chunkText = await response.text();
const replaceEscaped = (text) =>
text.replace(/\\"/g, '"').replace(/\\n/g, '\n').replace(/\\\\/g, '\\').replace(/\\'/g, "'");
// 1. Try to remove start and end wrappers first
try {
// Matches from start of file to the beginning of JSON.parse('
const START = /^(.*)JSON\.parse\(['"]/gms;
// Matches from the end of the JSON string to the end of the file
const END = /['"]?\)?\s*}?(\r\n|\r|\n)?}?]?\)?;(\r\n|\r|\n)?$/gms;
const jsonString = replaceEscaped(chunkText.replace(START, '').replace(END, ''));
this.translations[locale] = JSON.parse(jsonString);
return;
} catch (e) {
console.error('Failed to parse JSON from standard extraction.');
// Try alternative extraction below
}
// 2. Try to extract only the JSON string directly
let jsonMatch = chunkText.match(/JSON\.parse\(['"](.*?)['"]\)/); let jsonMatch = chunkText.match(/JSON\.parse\(['"](.*?)['"]\)/);
if (jsonMatch) { if (jsonMatch) {
let jsonString = jsonMatch[1]
.replace(/\\"/g, '"')
.replace(/\\n/g, '\n')
.replace(/\\\\/g, '\\')
.replace(/\\'/g, "'");
try { try {
const jsonString = replaceEscaped(jsonMatch[1]);
this.translations[locale] = JSON.parse(jsonString); this.translations[locale] = JSON.parse(jsonString);
return; return;
} catch (e) { } catch (e) {
console.error('Failed to parse JSON from direct extraction.');
// Try direct extraction // Try direct extraction
} }
} }
// 3. Fallback: extract everything between the first { and the last }
const jsonStart = chunkText.indexOf('{'); const jsonStart = chunkText.indexOf('{');
const jsonEnd = chunkText.lastIndexOf('}') + 1; const jsonEnd = chunkText.lastIndexOf('}') + 1;
if (jsonStart !== -1 && jsonEnd > jsonStart) { if (jsonStart !== -1 && jsonEnd > jsonStart) {
const jsonString = chunkText.substring(jsonStart, jsonEnd); const jsonString = chunkText.substring(jsonStart, jsonEnd);
try { try {
this.translations[locale] = JSON.parse(jsonString); this.translations[locale] = JSON.parse(jsonString);
return;
} catch (e) { } catch (e) {
console.error("Failed to parse JSON from chunk:", e); console.error("Failed to parse JSON from chunk:", e);
} }
@@ -1275,9 +1314,12 @@ const VisibilityObserver = {
const isVisible = const isVisible =
(window.location.hash === "#/home.html" || (window.location.hash === "#/home.html" ||
window.location.hash === "#/home") && window.location.hash === "#/home") &&
activeTab &&
activeTab.getAttribute("data-index") === "0"; activeTab.getAttribute("data-index") === "0";
container.style.display = isVisible ? "block" : "none"; container.style.display = isVisible ? "block" : "none";
container.style.visibility = isVisible ? "visible" : "hidden";
container.style.pointerEvents = isVisible ? "auto" : "none";
if (isVisible) { if (isVisible) {
if (STATE.slideshow.slideInterval && !STATE.slideshow.isPaused) { if (STATE.slideshow.slideInterval && !STATE.slideshow.isPaused) {
@@ -1296,11 +1338,11 @@ const VisibilityObserver = {
* Initializes visibility observer * Initializes visibility observer
*/ */
init() { init() {
const observer = new MutationObserver(this.updateVisibility); const observer = new MutationObserver(() => this.updateVisibility());
observer.observe(document.body, { childList: true, subtree: true }); observer.observe(document.body, { childList: true, subtree: true });
document.body.addEventListener("click", this.updateVisibility); document.body.addEventListener("click", () => this.updateVisibility());
window.addEventListener("hashchange", this.updateVisibility); window.addEventListener("hashchange", () => this.updateVisibility());
this.updateVisibility(); this.updateVisibility();
}, },
@@ -1391,12 +1433,21 @@ const SlideCreator = {
let trailerUrl = null; let trailerUrl = null;
// 1. Check for Remote Trailers (YouTube) // 1. Check for Remote Trailers (YouTube)
if (item.RemoteTrailers && item.RemoteTrailers.length > 0) { // Priority: Custom Config URL > Metadata RemoteTrailer
if (STATE.slideshow.customTrailerUrls && STATE.slideshow.customTrailerUrls[itemId]) {
trailerUrl = STATE.slideshow.customTrailerUrls[itemId];
console.log(`Using custom trailer URL for ${itemId}: ${trailerUrl}`);
} else if (item.RemoteTrailers && item.RemoteTrailers.length > 0) {
trailerUrl = item.RemoteTrailers[0].Url; trailerUrl = item.RemoteTrailers[0].Url;
} }
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
const shouldPlayVideo = CONFIG.enableVideoBackdrop && (!isMobile || CONFIG.enableMobileVideo);
// Client Setting Overrides
const enableVideo = SettingsManager.getSetting('videoBackdrops', CONFIG.enableVideoBackdrop);
const enableMobileVideo = SettingsManager.getSetting('mobileVideo', CONFIG.enableMobileVideo);
const shouldPlayVideo = enableVideo && (!isMobile || enableMobileVideo);
if (trailerUrl && shouldPlayVideo) { if (trailerUrl && shouldPlayVideo) {
let isYoutube = false; let isYoutube = false;
@@ -2537,10 +2588,25 @@ const SlideshowManager = {
*/ */
parseCustomIds() { parseCustomIds() {
if (!CONFIG.enableSeasonalContent) { if (!CONFIG.enableSeasonalContent) {
return CONFIG.customMediaIds return CONFIG.customMediaIds
.split(/[\n,]/) // Split by comma or newline .split(/[\n,]/).map((line) => {
.map((id) => id.trim()) // Remove whitespace const urlMatch = line.match(/\[(.*?)\]/);
.filter((id) => id); // Remove empty strings let id = line;
if (urlMatch) {
const url = urlMatch[1];
id = line.replace(/\[.*?\]/, '').trim();
const guidMatch = id.match(/([0-9a-f]{32})/i);
if (guidMatch) {
id = guidMatch[1];
} else {
id = id.split('|')[0].trim();
}
STATE.slideshow.customTrailerUrls[id] = url;
}
return id.trim();
})
.map((id) => id.trim())
.filter((id) => id);
} else { } else {
return this.parseSeasonalIds(); return this.parseSeasonalIds();
} }
@@ -2597,7 +2663,22 @@ const SlideshowManager = {
if (isInRange) { if (isInRange) {
console.log(`Seasonal match found: ${line}`); console.log(`Seasonal match found: ${line}`);
const ids = idsPart.split(/[,]/).map(id => id.trim()).filter(id => id); const ids = idsPart.split(/[,]/).map(line => {
const urlMatch = line.match(/\[(.*?)\]/);
let id = line;
if (urlMatch) {
const url = urlMatch[1];
id = line.replace(/\[.*?\]/, '').trim();
const guidMatch = id.match(/([0-9a-f]{32})/i);
if (guidMatch) {
id = guidMatch[1];
} else {
id = id.split('|')[0].trim();
}
STATE.slideshow.customTrailerUrls[id] = url;
}
return id.trim();
}).filter(id => id);
rawIds.push(...ids); rawIds.push(...ids);
} }
} }
@@ -2700,7 +2781,10 @@ const SlideshowManager = {
this.nextSlide(); this.nextSlide();
}, CONFIG.shuffleInterval); }, CONFIG.shuffleInterval);
if (CONFIG.waitForTrailerToEnd && STATE.slideshow.slideInterval) { // Check if we should wait for trailer
const waitForTrailer = SettingsManager.getSetting('waitForTrailer', CONFIG.waitForTrailerToEnd);
if (waitForTrailer && STATE.slideshow.slideInterval) {
const activeSlide = document.querySelector('.slide.active'); const activeSlide = document.querySelector('.slide.active');
const hasActiveVideo = !!(activeSlide && activeSlide.querySelector('.video-backdrop')); const hasActiveVideo = !!(activeSlide && activeSlide.querySelector('.video-backdrop'));
if (hasActiveVideo) { if (hasActiveVideo) {
@@ -2845,6 +2929,158 @@ const initArrowNavigation = () => {
); );
}; };
const SettingsManager = {
initialized: false,
init() {
if (this.initialized) return;
if (!CONFIG.enableClientSideSettings) return;
this.initialized = true;
this.injectSettingsIcon();
console.log("MediaBarEnhanced: Client-Side Settings Manager initialized.");
},
getSetting(key, defaultValue) {
if (!CONFIG.enableClientSideSettings) return defaultValue;
const value = localStorage.getItem(`mediaBarEnhanced-${key}`);
return value !== null ? value === 'true' : defaultValue;
},
setSetting(key, value) {
localStorage.setItem(`mediaBarEnhanced-${key}`, value);
},
createIcon() {
const button = document.createElement('button');
button.type = 'button';
button.className = 'paper-icon-button-light headerButton media-bar-settings-button';
button.title = 'Media Bar Settings';
// button.innerHTML = '<span class="material-icons">tune</span>';
button.innerHTML = '<img src="/MediaBarEnhanced/Resources/assets/logo_SW.svg" style="width: 24px; height: 24px; vertical-align: middle;">';
button.style.verticalAlign = 'middle';
button.addEventListener('click', (e) => {
e.stopPropagation();
this.toggleSettingsPopup(button);
});
return button;
},
injectSettingsIcon() {
const observer = new MutationObserver((mutations, obs) => {
const headerRight = document.querySelector('.headerRight');
if (headerRight && !document.querySelector('.media-bar-settings-button')) {
const icon = this.createIcon();
headerRight.prepend(icon);
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
},
createPopup(anchorElement) {
const existing = document.querySelector('.media-bar-settings-popup');
if (existing) existing.remove();
const popup = document.createElement('div');
popup.className = 'media-bar-settings-popup dialog';
Object.assign(popup.style, {
position: 'fixed',
zIndex: '10000',
backgroundColor: '#202020',
padding: '1em',
borderRadius: '0.3em',
boxShadow: '0 0 20px rgba(0,0,0,0.5)',
minWidth: '250px',
color: '#fff',
});
const rect = anchorElement.getBoundingClientRect();
let rightPos = window.innerWidth - rect.right;
if (window.innerWidth < 450 || (window.innerWidth - rightPos) < 260) {
popup.style.right = '1rem';
popup.style.left = 'auto';
} else {
popup.style.right = `${rightPos}px`;
popup.style.left = 'auto';
}
popup.style.top = `${rect.bottom + 10}px`;
const settings = [
{ key: 'enabled', label: 'Enable Media Bar', default: true },
{ key: 'videoBackdrops', label: 'Enable Video Backdrops', default: CONFIG.enableVideoBackdrop },
{ key: 'trailerButton', label: 'Show Trailer Button', default: CONFIG.showTrailerButton },
{ key: 'mobileVideo', label: 'Enable Mobile Video', default: CONFIG.enableMobileVideo },
{ key: 'waitForTrailer', label: 'Wait For Trailer To End', default: CONFIG.waitForTrailerToEnd },
{ key: 'slideAnimations', label: 'Enable Slide Animations', default: CONFIG.slideAnimationEnabled },
];
let html = '<h3 style="margin-top:0; margin-bottom:1em; border-bottom:1px solid #444; padding-bottom:0.5em;">Media Bar Settings</h3>';
settings.forEach(setting => {
const isChecked = this.getSetting(setting.key, setting.default);
html += `
<div class="checkboxContainer checkboxContainer-withDescription" style="margin-bottom: 0.5em;">
<label class="emby-checkbox-label">
<input id="mb-setting-${setting.key}" type="checkbox" is="emby-checkbox" class="emby-checkbox" ${isChecked ? 'checked' : ''} />
<span class="checkboxLabel">${setting.label}</span>
</label>
</div>
`;
});
// Reload button
html += `
<div style="margin-top:1em; text-align:right;">
<button is="emby-button" type="button" class="raised button-submit emby-button" id="mb-settings-save">
<span>Reload</span>
</button>
</div>
`;
popup.innerHTML = html;
// Add Listeners
settings.forEach(setting => {
const checkbox = popup.querySelector(`#mb-setting-${setting.key}`);
checkbox.addEventListener('change', (e) => {
this.setSetting(setting.key, e.target.checked);
});
});
popup.querySelector('#mb-settings-save').addEventListener('click', () => {
location.reload();
});
const closeHandler = (e) => {
if (!popup.contains(e.target) && e.target !== anchorElement && !anchorElement.contains(e.target)) {
popup.remove();
document.removeEventListener('click', closeHandler);
}
};
setTimeout(() => document.addEventListener('click', closeHandler), 0);
document.body.appendChild(popup);
},
toggleSettingsPopup(anchorElement) {
const existing = document.querySelector('.media-bar-settings-popup');
if (existing) {
existing.remove();
} else {
this.createPopup(anchorElement);
}
}
};
/** /**
* Initialize the slideshow * Initialize the slideshow
*/ */
@@ -2853,6 +3089,16 @@ const slidesInit = async () => {
console.log("⚠️ Slideshow already initialized, skipping"); console.log("⚠️ Slideshow already initialized, skipping");
return; return;
} }
if (CONFIG.enableClientSideSettings) {
SettingsManager.init();
const isEnabled = SettingsManager.getSetting('enabled', true);
if (!isEnabled) {
console.log("MediaBarEnhanced: Disabled by client-side setting.");
return;
}
}
STATE.slideshow.hasInitialized = true; STATE.slideshow.hasInitialized = true;
/** /**
@@ -2970,6 +3216,6 @@ window.mediaBarEnhanced = {
initLoadingScreen(); initLoadingScreen();
loadPluginConfig().then(() => { fetchPluginConfig().then(() => {
startLoginStatusWatcher(); startLoginStatusWatcher();
}); });

View File

@@ -144,6 +144,9 @@ Configure the plugin via **Dashboard** > **Plugins** > **Media Bar Enhanced**.
Define exactly what shows up in your bar. Define exactly what shows up in your bar.
* **Enable Custom Media IDs**: Restrict the slideshow to a specific list of IDs. * **Enable Custom Media IDs**: Restrict the slideshow to a specific list of IDs.
* **Manual Trailer Override**: Add `[YouTube_URL]` after an ID to force a specific trailer.
* Example ID: `a1b2c3d4e5... [https://www.youtube.com/watch?v=VIDEO_ID]`
* Example Collection Name: `Halloween Collection [https://...] | My Description` (Note: Use `|` to separate description from name if using a name instead of an ID)
* **Enable Seasonal Content Mode**: Advanced date-based scheduling. * **Enable Seasonal Content Mode**: Advanced date-based scheduling.
* Format: `DD.MM-DD.MM | Name | ID1, ID2, ID3` * Format: `DD.MM-DD.MM | Name | ID1, ID2, ID3`
* Example: `20.10-31.10 | Halloween | <ID_OF_HALLOWEEN_COLLECTION>` * Example: `20.10-31.10 | Halloween | <ID_OF_HALLOWEEN_COLLECTION>`

View File

@@ -27,7 +27,8 @@ Setzt deine Commits neu auf die Spitze eines anderen Branches. Die Commit-IDs we
```bash ```bash
git checkout dev git checkout dev
git rebase main git fetch origin
git rebase origin/main
``` ```
| Details | | | Details | |

View File

@@ -8,6 +8,38 @@
"category": "General", "category": "General",
"imageUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/raw/branch/main/logo.png", "imageUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/raw/branch/main/logo.png",
"versions": [ "versions": [
{
"version": "1.4.0.1",
"changelog": "- feat: Add client-side settings feature for selected media bar settings",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.4.0.1/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "4068c03b1ab809906d64d4faed1c1b0e",
"timestamp": "2026-02-04T15:01:50Z"
},
{
"version": "1.3.0.3",
"changelog": "- feat: Enhance custom media ID functionality with manual trailer override support",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.3.0.3/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "1d9e0a8342d46f84aed3f7bd1bee32d3",
"timestamp": "2026-02-04T01:41:35Z"
},
{
"version": "1.2.3.7",
"changelog": "- Fixes the issue where buttons were cut off on smaller screens such as on S24/S25.\n- Update mediaBarEnhanced.js and mediaBarEnhanced.css with version 3.0.9 from original repo",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.2.3.7/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "fa1bf48cff159cc7dbf0aab48511a37c",
"timestamp": "2026-01-28T22:39:54Z"
},
{
"version": "1.2.2.0",
"changelog": "- Fixes issues with persistent slides-container visibility",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.2.2.0/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "3362f93815845c4e85b66b31bcd0f52c",
"timestamp": "2026-01-24T22:53:55Z"
},
{ {
"version": "1.2.1.0", "version": "1.2.1.0",
"changelog": "- Update mediaBarEnhanced.js and mediaBarEnhanced.css with version 3.0.8 from original repo", "changelog": "- Update mediaBarEnhanced.js and mediaBarEnhanced.css with version 3.0.8 from original repo",