Compare commits

...

405 Commits

Author SHA1 Message Date
CodeDevMLH
518fd5640e Bump version to 1.7.1.15 and update changelog for new features and fixes
Some checks failed
Auto Release Plugin / build-and-release (push) Failing after 51s
2026-03-09 03:40:38 +01:00
CodeDevMLH
a57f3db009 Add custom overlay image upload feature with style options 2026-03-09 03:40:13 +01:00
CodeDevMLH
8ff4f081f3 Update manifest.json for release v1.7.1.14 [skip ci] 2026-03-09 01:29:55 +00:00
CodeDevMLH
4a07c22091 Bump version to 1.7.1.14 in project file and manifest for release
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 43s
2026-03-09 02:29:11 +01:00
CodeDevMLH
4d1d442746 Add custom overlay feature with configuration options for text and image 2026-03-09 02:28:46 +01:00
CodeDevMLH
1df2b341e5 Refactor mask-image properties for improved readability in mediaBarEnhanced.css 2026-03-09 01:57:21 +01:00
CodeDevMLH
b2dbd6df45 Update manifest.json for release v1.7.1.13 [skip ci] 2026-03-08 22:50:48 +00:00
CodeDevMLH
60c72a01b1 Bump version to 1.7.1.13 in project file and manifest for release
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 44s
2026-03-08 23:50:03 +01:00
CodeDevMLH
9f7ef3c96b Refactor button background colors for improved visibility and update YouTube iframe attributes for better playback control 2026-03-08 23:49:49 +01:00
CodeDevMLH
7ffcfa68c1 Update manifest.json for release v1.7.1.12 [skip ci] 2026-03-08 22:15:28 +00:00
CodeDevMLH
aaf21d3c33 Bump version to 1.7.1.12 in project file and manifest for release
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 45s
2026-03-08 23:14:42 +01:00
CodeDevMLH
9758ecd417 Add background color to detail and favorite buttons for improved visibility 2026-03-08 23:14:09 +01:00
CodeDevMLH
a4547d80b1 Update manifest.json for release v1.7.1.11 [skip ci] 2026-03-08 22:06:37 +00:00
CodeDevMLH
671e38ff32 Bump version to 1.7.1.11 in project file and manifest for release
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 45s
2026-03-08 23:05:51 +01:00
CodeDevMLH
0e9d0f9d09 Remove appearance properties from button styles and add background color and text color to button for improved visibility 2026-03-08 23:05:38 +01:00
CodeDevMLH
5f296f3c88 Update manifest.json for release v1.7.1.10 [skip ci] 2026-03-08 21:36:22 +00:00
CodeDevMLH
a14b3ca8b5 Bump version to 1.7.1.10 in project file and manifest
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 45s
2026-03-08 22:35:35 +01:00
CodeDevMLH
4d12e34d01 Enhance CSS styles for buttons and overlays, improving appearance and consistency 2026-03-08 22:35:31 +01:00
CodeDevMLH
59fe6f7083 Update manifest.json for release v1.7.1.9 [skip ci] 2026-03-08 20:58:25 +00:00
CodeDevMLH
dcb2164ea1 Bump version to 1.7.1.9
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 44s
2026-03-08 21:57:41 +01:00
CodeDevMLH
2f71f7b46b Improve null checks and conditionals for better stability in localization and slideshow management
Some checks failed
Auto Release Plugin / build-and-release (push) Has been cancelled
2026-03-08 21:57:22 +01:00
CodeDevMLH
70b0a2a192 Update manifest.json for release v1.7.1.8 [skip ci] 2026-03-08 19:29:25 +00:00
CodeDevMLH
300c76890b Bump version to 1.7.1.8 in project file and manifest
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 46s
2026-03-08 20:28:38 +01:00
CodeDevMLH
64e5441aff Optimize slideshow distance calculation for circular navigation 2026-03-08 20:28:20 +01:00
CodeDevMLH
f47c9dde88 Update manifest.json for release v1.7.1.7 [skip ci] 2026-03-08 19:15:10 +00:00
CodeDevMLH
9d42b5af8d Merge branch 'main' of ssh://git.mahom03-spacecloud.de:44322/CodeDevMLH/jellyfin-plugin-media-bar-enhanced
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 46s
2026-03-08 20:14:23 +01:00
CodeDevMLH
8c5f66716f Update version to 1.7.1.7 and enhance changelog with new features and fixes 2026-03-08 20:09:58 +01:00
CodeDevMLH
41e6c1032d Add Hide Arrows on Mobile option to configuration and update related logic 2026-03-08 20:09:47 +01:00
CodeDevMLH
fe07fe9f5e Update manifest.json for release v1.7.1.6 [skip ci] 2026-03-08 18:33:15 +00:00
CodeDevMLH
22a7eb8dcb Update version to 1.7.1.6 and enhance changelog with new features and fixes
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 46s
2026-03-08 19:32:27 +01:00
CodeDevMLH
07658f4fbc Add Exclude Seasonal Content option to configuration and update related logic 2026-03-08 19:32:15 +01:00
CodeDevMLH
25ee5b73b4 Update field descriptions for Max Parental Rating and Max Days Recent inputs to clarify no limit options 2026-03-08 19:21:04 +01:00
CodeDevMLH
8f8e251054 Add max parental rating and max days recent filters to configuration 2026-03-08 19:19:20 +01:00
CodeDevMLH
05529e5627 add new tests 2026-03-08 19:18:30 +01:00
CodeDevMLH
b3e00e8ad6 Update manifest.json for release v1.7.1.5 [skip ci] 2026-03-08 16:17:52 +00:00
CodeDevMLH
39649a6dd3 Bump version to 1.7.1.5 in project file and manifest
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 49s
2026-03-08 17:17:04 +01:00
CodeDevMLH
11aca32158 Enhance mobile layout by adjusting button container and adding styles for misc-info and genre 2026-03-08 17:17:00 +01:00
CodeDevMLH
9bcb2f984a Update manifest.json for release v1.7.1.4 [skip ci] 2026-03-08 15:58:12 +00:00
CodeDevMLH
c23a614f9f Bump version to 1.7.1.4 and update changelog for new features and fixes
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-03-08 16:57:21 +01:00
CodeDevMLH
3a367cb2be Add ShowPaginationDots configuration option and update related UI elements 2026-03-08 16:57:16 +01:00
CodeDevMLH
2993bfe3f2 del old tmp 2026-03-08 16:56:18 +01:00
CodeDevMLH
3ffa2c262a Update manifest.json for release v1.7.1.3 [skip ci] 2026-03-08 15:20:14 +00:00
CodeDevMLH
dc88110e9c Bump version to 1.7.1.3 in project file and manifest for release
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 56s
2026-03-08 16:19:17 +01:00
CodeDevMLH
f9ae62a459 Refactor button-container styles for improved layout and responsiveness 2026-03-08 16:19:07 +01:00
CodeDevMLH
9e2f861213 Update manifest.json for release v1.7.1.2 [skip ci] 2026-03-08 15:08:30 +00:00
CodeDevMLH
4781618a52 Bump version to 1.7.1.2 in project file and manifest for release
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-03-08 16:07:39 +01:00
CodeDevMLH
2bed81c1f8 Refactor button-container styles for improved layout and responsiveness 2026-03-08 16:07:32 +01:00
CodeDevMLH
292fcfc389 Update manifest.json for release v1.7.1.1 [skip ci] 2026-03-08 14:48:17 +00:00
CodeDevMLH
da718a0e57 Bump version to 1.7.1.1 in project file and manifest for release
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 49s
2026-03-08 15:47:26 +01:00
CodeDevMLH
95a8907496 test2 2026-03-08 15:47:09 +01:00
CodeDevMLH
0498756529 Update manifest.json for release v1.7.1.0 [skip ci] 2026-03-08 14:32:40 +00:00
CodeDevMLH
f1d92080b2 Bump version to 1.7.1.0 and update changelog for mobile button fix
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 48s
2026-03-08 15:31:52 +01:00
CodeDevMLH
586b57d23e Enhance button layout in button-container for better responsiveness 2026-03-08 15:30:21 +01:00
CodeDevMLH
47b05a82ba Update changelog for version 1.7.0.14: enhance iframe security, fix playback issues on iOS/MacOS, disable animations for TV layout, remove list.txt functionality, and improve logging. [skip ci] 2026-03-06 04:30:04 +01:00
CodeDevMLH
cb45e0cb43 Update manifest.json for release v1.7.0.14 [skip ci] 2026-03-06 03:13:48 +00:00
CodeDevMLH
19246c3a19 Bump version to 1.7.0.14
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-03-06 04:12:58 +01:00
CodeDevMLH
99b4b09306 Disable animations and backdrop filters for TV layout on high pixel density screens 2026-03-06 04:12:52 +01:00
CodeDevMLH
563a1e5484 Update manifest.json for release v1.7.0.13 [skip ci] 2026-03-06 03:10:54 +00:00
CodeDevMLH
788708370d Bump version to 1.7.0.13
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-03-06 04:10:04 +01:00
CodeDevMLH
4bb0de11da Remove fetchItemIdsFromList function and related logic for item ID retrieval 2026-03-06 04:09:36 +01:00
CodeDevMLH
d2abfc6b46 Enhance logging in media bar with contextual messages 2026-03-06 04:06:18 +01:00
CodeDevMLH
8ba14d4df0 Update manifest.json for release v1.7.0.12 [skip ci] 2026-03-06 02:26:17 +00:00
CodeDevMLH
538138fcf3 Bump version to 1.7.0.12
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-03-06 03:25:23 +01:00
CodeDevMLH
08efb11d95 Remove picture-in-picture support from YouTube player integration 2026-03-06 03:25:08 +01:00
CodeDevMLH
de62c794f9 Update manifest.json for release v1.7.0.11 [skip ci] 2026-03-06 02:19:18 +00:00
CodeDevMLH
fc2491a4ef Bump version to 1.7.0.11
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-03-06 03:18:26 +01:00
CodeDevMLH
03276d7722 Enhance YouTube player integration with fullscreen and picture-in-picture support 2026-03-06 03:18:13 +01:00
CodeDevMLH
8676160e7b Update manifest.json for release v1.7.0.10 [skip ci] 2026-03-06 02:02:52 +00:00
CodeDevMLH
c562560bc0 Bump version to 1.7.0.10
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-03-06 03:02:01 +01:00
CodeDevMLH
98474d4ff6 Refactor YouTube player integration to use iframe for improved performance and security 2026-03-06 03:01:34 +01:00
CodeDevMLH
14c0eb43ed Update manifest.json for release v1.7.0.9 [skip ci] 2026-03-06 01:24:40 +00:00
CodeDevMLH
c4cbeda2b8 Bump version to 1.7.0.9
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-03-06 02:23:50 +01:00
CodeDevMLH
53ad568be4 Fix active slide detection logic in SlideCreator for improved video playback handling 2026-03-06 02:23:13 +01:00
CodeDevMLH
fba64bd0f6 Update manifest.json for release v1.7.0.8 [skip ci] 2026-03-06 01:17:19 +00:00
CodeDevMLH
3da16c4c5c Bump version to 1.7.0.8
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-03-06 02:16:28 +01:00
CodeDevMLH
c7cd7be3ee Add low-power device detection and adjust video playback settings 2026-03-06 02:16:09 +01:00
CodeDevMLH
6d90523eef Update manifest.json for release v1.7.0.7 [skip ci] 2026-03-06 00:45:38 +00:00
CodeDevMLH
2a3e8057a1 Bump version to 1.7.0.7
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-03-06 01:44:24 +01:00
CodeDevMLH
42026b0ee8 test revert 2026-03-06 01:44:04 +01:00
CodeDevMLH
64dbc3cfd3 Update manifest.json for release v1.7.0.6 [skip ci] 2026-03-06 00:25:04 +00:00
CodeDevMLH
c998266dd7 Bump version to 1.7.0.6
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-03-06 01:24:11 +01:00
CodeDevMLH
9b941e5a77 test again 2026-03-06 01:23:49 +01:00
CodeDevMLH
1d70d7166d Update manifest.json for release v1.7.0.5 [skip ci] 2026-03-05 23:59:06 +00:00
CodeDevMLH
5331f0faf1 Bump version to 1.7.0.5
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-03-06 00:58:15 +01:00
CodeDevMLH
0508188705 test nochmal
Some checks failed
Auto Release Plugin / build-and-release (push) Has been cancelled
2026-03-06 00:57:58 +01:00
CodeDevMLH
cc861f4263 Update manifest.json for release v1.7.0.4 [skip ci] 2026-03-05 23:35:23 +00:00
CodeDevMLH
10e6cdc4a2 Bump version to 1.7.0.4
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-03-06 00:34:32 +01:00
CodeDevMLH
a8c7faab6b Add Safari support for YouTube video playback using plain iframe embed 2026-03-06 00:34:19 +01:00
CodeDevMLH
6df390fa18 Update manifest.json for release v1.7.0.3 [skip ci] 2026-03-05 23:23:07 +00:00
CodeDevMLH
d0c3d7ee4d Bump version to 1.7.0.3 (test 3)
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-03-06 00:22:14 +01:00
CodeDevMLH
bc621aacdf test 2026-03-06 00:21:54 +01:00
CodeDevMLH
73eb30d671 Update manifest.json for release v1.7.0.2 [skip ci] 2026-03-05 22:44:56 +00:00
CodeDevMLH
2cfbec95c9 Bump version to 1.7.0.2
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-03-05 23:44:05 +01:00
CodeDevMLH
08fc29cba3 Improve video backdrop handling: optimize autoplay logic for fresh loads and enhance Safari compatibility with loadedmetadata event 2026-03-05 23:43:52 +01:00
CodeDevMLH
0d6b835486 Update manifest.json for release v1.7.0.1 [skip ci] 2026-03-05 21:43:51 +00:00
CodeDevMLH
bf620e447f Bump version to 1.7.0.1
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-03-05 22:42:58 +01:00
CodeDevMLH
3117d627dd Enhance video playback handling: enable autoplay, adjust mute settings for Safari compatibility, and improve navigation checks during autoplay. 2026-03-05 22:42:40 +01:00
CodeDevMLH
71402f7e86 Update manifest.json for release v1.7.0.0 [skip ci] 2026-03-05 01:05:37 +00:00
CodeDevMLH
cce202b88d Bump version to 1.7.0.0
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 55s
2026-03-05 02:04:43 +01:00
CodeDevMLH
1d334e4d95 Add YouTube no-cookie host and referrer policy for iframe security 2026-03-05 02:00:54 +01:00
CodeDevMLH
142063ce63 Update configPage.html to add warning about autoplay failure when disabling start muted option 2026-03-05 02:00:19 +01:00
CodeDevMLH
1a0050ae1a Update manifest.json for release v1.6.6.4 [skip ci] 2026-02-19 17:21:41 +00:00
CodeDevMLH
46ebfdbafc Bump version to 1.6.6.4
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 58s
2026-02-19 18:20:41 +01:00
CodeDevMLH
14d2bb957b Remove server configuration check for plugin enablement 2026-02-19 18:20:25 +01:00
CodeDevMLH
7a0c1e4488 Enhance script injection by removing legacy tags and improving logging 2026-02-19 18:20:17 +01:00
CodeDevMLH
ec0e686e00 Update manifest.json for release v1.6.6.3 [skip ci] 2026-02-19 15:50:04 +00:00
CodeDevMLH
54395896b3 Bump version to 1.6.6.3
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 56s
2026-02-19 16:49:08 +01:00
CodeDevMLH
8b2fe59f5a Add server configuration check to disable plugin if necessary 2026-02-19 16:49:00 +01:00
CodeDevMLH
a44bf7ebf4 Update manifest.json for release v1.6.6.2 [skip ci] 2026-02-19 02:36:42 +00:00
CodeDevMLH
1f273906bf Bump version to 1.6.6.2
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-02-19 03:35:50 +01:00
CodeDevMLH
0534d0458e Add delay before stopping other video players during slideshow transitions 2026-02-19 03:35:38 +01:00
CodeDevMLH
8b0d6f137d Update manifest.json for release v1.6.6.1 [skip ci] 2026-02-19 02:25:34 +00:00
CodeDevMLH
2208b86a47 Bump version to 1.6.6.1
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-02-19 03:24:42 +01:00
CodeDevMLH
5a1048687c Enhance video backdrop handling with opacity transitions for smoother playback 2026-02-19 03:24:27 +01:00
CodeDevMLH
d3f6641158 Update manifest.json for release v1.6.6.0 [skip ci] 2026-02-19 01:01:21 +00:00
CodeDevMLH
c214a620e4 Bump version to 1.6.6.0
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-19 01:52:31 +01:00
CodeDevMLH
f0c9462878 Implement manual mapping for MediaBarIsEnabled and enhance video backdrop handling 2026-02-19 01:52:17 +01:00
CodeDevMLH
e12a5b56a2 Update manifest.json for release v1.6.5.2 [skip ci] 2026-02-16 23:57:58 +00:00
CodeDevMLH
51ff0f2623 Bump version to 1.6.5.2
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-02-17 00:57:07 +01:00
CodeDevMLH
2c907debc8 Enhance video handling: release HTTP connections and manage lazy loading for trailers 2026-02-17 00:56:47 +01:00
CodeDevMLH
7b30f8c9e9 typos [skip ci] 2026-02-16 23:06:45 +01:00
CodeDevMLH
3a90605112 Update manifest.json for release v1.6.5.1 [skip ci] 2026-02-16 21:49:25 +00:00
CodeDevMLH
5772d670ff Bump version to 1.6.5.1
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-16 22:48:33 +01:00
CodeDevMLH
e558594c52 Enhance seasonal section layout and adjust input field width in configuration 2026-02-16 22:48:14 +01:00
CodeDevMLH
343436ac56 Update manifest.json for release v1.6.5.0 [skip ci] 2026-02-16 18:38:41 +00:00
CodeDevMLH
6075e20a11 Update version to 1.6.5.0
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-16 19:37:46 +01:00
CodeDevMLH
8b7def809b Refactor configuration tabs and enhance seasonal section functionality 2026-02-16 19:36:46 +01:00
CodeDevMLH
43950eac60 Add release existence check to automation workflow 2026-02-16 00:06:15 +01:00
CodeDevMLH
c09f265b26 Update manifest.json for release v1.6.4.1 [skip ci] 2026-02-15 22:56:18 +00:00
CodeDevMLH
379c370b4a ..
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-15 23:55:28 +01:00
CodeDevMLH
b567307003 Update manifest.json for release v1.6.4.0 [skip ci] 2026-02-15 22:53:31 +00:00
CodeDevMLH
ff9ea9eff0 Bump version to 1.6.4.1
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-02-15 23:52:41 +01:00
CodeDevMLH
9427e3e535 Remove autoplay and loop attributes from video backdrop configuration 2026-02-15 23:52:34 +01:00
CodeDevMLH
19318a916d Update manifest.json for release v1.6.4.0 [skip ci] 2026-02-15 22:39:48 +00:00
CodeDevMLH
5d85284df8 Merge branch 'main' of ssh://git.mahom03-spacecloud.de:44322/CodeDevMLH/jellyfin-plugin-media-bar-enhanced
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-15 23:38:58 +01:00
CodeDevMLH
2382f850b6 Bump version to 1.6.4.0 2026-02-15 23:38:56 +01:00
CodeDevMLH
22041293f6 Update manifest.json for release v1.6.3.0 [skip ci] 2026-02-15 22:38:19 +00:00
CodeDevMLH
5595158f9d Update field description for Prefer Local Backdrops setting
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-02-15 23:25:01 +01:00
CodeDevMLH
39f85e0c9b fix backdrop issue? 2026-02-15 23:24:56 +01:00
CodeDevMLH
18a9980a0a Update manifest.json for release v1.6.3.0 [skip ci] 2026-02-15 01:21:08 +00:00
CodeDevMLH
deb426833d Bump version to 1.6.3.0
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-02-15 02:19:47 +01:00
CodeDevMLH
bf4b6da0f0 fix path issue on subpath installations 2026-02-15 02:19:37 +01:00
CodeDevMLH
2bc7d90254 Update manifest.json for release v1.6.2.3 [skip ci] 2026-02-15 00:38:08 +00:00
CodeDevMLH
3f302d4c64 Bump version to 1.6.2.3
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-15 01:37:17 +01:00
CodeDevMLH
13a1cc7885 Add option to include watched content in the Media Bar configuration 2026-02-15 01:37:05 +01:00
CodeDevMLH
a62900f96e Add options for theme video support, randomization, and including watched content in the Media Bar 2026-02-15 01:36:56 +01:00
CodeDevMLH
9d90a29a40 Update build command in RELEASE_GUIDE.md for enhanced plugin structure 2026-02-15 01:36:52 +01:00
CodeDevMLH
cd3973088e [skip ci] 2026-02-15 01:08:21 +01:00
CodeDevMLH
4112cfad4a Update manifest.json for release v1.6.2.1 [skip ci] 2026-02-14 23:52:43 +00:00
CodeDevMLH
2618b18df1 Bump version to 1.6.2.1
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-15 00:51:54 +01:00
CodeDevMLH
ef378c5e87 Add option to include watched content in random selection 2026-02-15 00:51:00 +01:00
CodeDevMLH
b8d0dd9f1a Update description for random backdrop video option in configPage.html [skip ci] 2026-02-15 00:36:42 +01:00
CodeDevMLH
d7c44061cb Update manifest.json for release v1.6.2.0 [skip ci] 2026-02-14 23:34:47 +00:00
CodeDevMLH
9acb05d19e Update version to 1.6.2.0
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 49s
2026-02-15 00:33:58 +01:00
CodeDevMLH
619d8533d2 Add configuration options for local backdrops and randomization features 2026-02-15 00:31:01 +01:00
CodeDevMLH
a4b39ae3bf Add check_backdrop_fields script for testing item details and theme media 2026-02-15 00:30:44 +01:00
CodeDevMLH
74a367584b Add fetch_specific_items_with_fields script to retrieve extended item details 2026-02-15 00:30:36 +01:00
CodeDevMLH
06407f9121 Update manifest.json for release v1.6.1.32 [skip ci] 2026-02-14 16:34:33 +00:00
CodeDevMLH
0926493391 Update manifest.json with new seasonal UI logic and custom ID limits
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-14 17:33:39 +01:00
CodeDevMLH
6dbb33be96 remove tests
Some checks failed
Auto Release Plugin / build-and-release (push) Has been cancelled
2026-02-14 17:33:04 +01:00
CodeDevMLH
211d9d316a Update README.md to include new sections for content sorting, limits, and credits 2026-02-14 17:32:46 +01:00
CodeDevMLH
329733246d Update field description for seasonal content configuration to clarify fallback behavior 2026-02-14 17:32:42 +01:00
CodeDevMLH
6110e1cdd8 Remove commented-out code for previous slide handling and play/pause button state management 2026-02-14 17:32:38 +01:00
CodeDevMLH
31c8a209a5 add test
Some checks failed
Auto Release Plugin / build-and-release (push) Has been cancelled
2026-02-14 17:32:25 +01:00
CodeDevMLH
ad2e761bbd Update manifest.json for release v1.6.1.32 [skip ci] 2026-02-14 15:57:28 +00:00
CodeDevMLH
85f90e8fbb Bump version to 1.6.1.32
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-14 16:56:39 +01:00
CodeDevMLH
9f5f607168 Refactor video playback handling for active slides and improve mute functionality 2026-02-14 16:56:23 +01:00
CodeDevMLH
108a644983 Update manifest.json for release v1.6.1.31 [skip ci] 2026-02-14 15:41:38 +00:00
CodeDevMLH
ab778f774f Bump version to 1.6.1.31
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-02-14 16:40:48 +01:00
CodeDevMLH
5dcb60487e Implement dynamic mute/unmute functionality based on slideshow state 2026-02-14 16:40:40 +01:00
CodeDevMLH
9a6997f1da Update manifest.json for release v1.6.1.30 [skip ci] 2026-02-14 15:32:46 +00:00
CodeDevMLH
31d315ed8f Bump version to 1.6.1.30
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-14 16:31:55 +01:00
CodeDevMLH
2b1301ea0b Refactor video playback management in SlideshowManager for improved performance and auto-unpause functionality 2026-02-14 16:31:38 +01:00
CodeDevMLH
ee8c0b8888 Update manifest.json for release v1.6.1.29 [skip ci] 2026-02-14 15:04:22 +00:00
CodeDevMLH
64ef4915b8 Bump version to 1.6.1.29
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-14 16:03:30 +01:00
CodeDevMLH
1f655ed7b6 Enhance SponsorBlock data fetching with caching and improve slide transition logic 2026-02-14 16:03:14 +01:00
CodeDevMLH
0682967591 Update manifest.json for release v1.6.1.28 [skip ci] 2026-02-14 14:38:41 +00:00
CodeDevMLH
7938728f8e Bump version to 1.6.1.28 in project file and manifest
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-14 15:37:50 +01:00
CodeDevMLH
a0773c66eb Refactor video playback logic to manage mute state more effectively and improve autoplay handling 2026-02-14 15:37:44 +01:00
CodeDevMLH
10f2a38add Update manifest.json for release v1.6.1.27 [skip ci] 2026-02-14 14:22:59 +00:00
CodeDevMLH
9bfa3ba5ea Bump version to 1.6.1.26
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-02-14 15:22:09 +01:00
CodeDevMLH
5c00c07b8a Refactor video playback logic and enhance slide management 2026-02-14 15:21:32 +01:00
CodeDevMLH
773c49a228 Update manifest.json for release v1.6.1.25 [skip ci] 2026-02-14 02:21:15 +00:00
CodeDevMLH
41a309e0d1 Bump version to 1.6.1.25
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-02-14 03:20:25 +01:00
CodeDevMLH
43797fbb98 Refactor video playback handling and improve tab visibility management 2026-02-14 03:20:04 +01:00
CodeDevMLH
f13a1ba1af test [skip ci] 2026-02-14 02:18:13 +01:00
CodeDevMLH
d489c22f28 Update manifest.json for release v1.6.1.24 [skip ci] 2026-02-14 01:12:45 +00:00
CodeDevMLH
7816c87543 Bump version to 1.6.1.24
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 1m19s
2026-02-14 02:11:09 +01:00
CodeDevMLH
720567bafc Enhance video playback logic with improved state handling and retry mechanism for YouTube players 2026-02-14 02:10:55 +01:00
CodeDevMLH
2289a1f83e Update manifest.json for release v1.6.1.23 [skip ci] 2026-02-14 00:58:27 +00:00
CodeDevMLH
a269318f58 Bump version to 1.6.1.23
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-02-14 01:57:36 +01:00
CodeDevMLH
fdb409fd3b Merge branch 'main' of ssh://git.mahom03-spacecloud.de:44322/CodeDevMLH/jellyfin-plugin-media-bar-enhanced 2026-02-14 01:57:18 +01:00
CodeDevMLH
9bb4b9d355 Refactor video playback logic to improve handling of active slides and paused state 2026-02-14 01:57:14 +01:00
CodeDevMLH
1e18c22937 Update manifest.json for release v1.6.1.22 [skip ci] 2026-02-14 00:43:45 +00:00
CodeDevMLH
a83913d15c Bump version to 1.6.1.22
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-14 01:42:53 +01:00
CodeDevMLH
2f50931beb Fix YouTube player readiness checks and improve polling logic for video playback 2026-02-14 01:42:42 +01:00
CodeDevMLH
5b14bdba35 Update manifest.json for release v1.6.1.21 [skip ci] 2026-02-14 00:35:03 +00:00
CodeDevMLH
9ba3b1e49f Bump version to 1.6.1.21
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-14 01:34:12 +01:00
CodeDevMLH
bf7c7fb8e8 Enhance video backdrop handling to support YouTube iframe integration and improve video playback logic 2026-02-14 01:33:54 +01:00
CodeDevMLH
39e29046de Update manifest.json for release v1.6.1.20 [skip ci] 2026-02-14 00:10:58 +00:00
CodeDevMLH
18260f8eac Bump version to 1.6.1.20
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-14 01:10:09 +01:00
CodeDevMLH
59c07f3c45 Merge branch 'main' of ssh://git.mahom03-spacecloud.de:44322/CodeDevMLH/jellyfin-plugin-media-bar-enhanced
Some checks failed
Auto Release Plugin / build-and-release (push) Has been cancelled
2026-02-14 01:09:50 +01:00
CodeDevMLH
b06d1e9375 Enhance video playback logic to handle pending play state and improve pause behavior for video backdrops 2026-02-14 01:09:48 +01:00
CodeDevMLH
e5bf23a7bc Enhance README with detailed configuration options for Custom Media IDs, Content Sorting, and Content Limits 2026-02-14 01:09:29 +01:00
CodeDevMLH
0d7113969b Improve clarity and consistency in configuration page labels and descriptions 2026-02-14 01:09:16 +01:00
CodeDevMLH
f69f676a68 Update manifest.json for release v1.6.1.19 [skip ci] 2026-02-13 18:44:00 +00:00
CodeDevMLH
f448c89ef2 Bump version to 1.6.1.19
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-13 19:43:04 +01:00
CodeDevMLH
daf26fe53a Refactor slide playback logic to remove redundant checks and improve clarity 2026-02-13 19:42:49 +01:00
CodeDevMLH
26ef307838 Update manifest.json for release v1.6.1.18 [skip ci] 2026-02-13 18:35:24 +00:00
CodeDevMLH
c296483583 Bump version to 1.6.1.18
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-13 19:34:31 +01:00
CodeDevMLH
7992e20715 Refactor slide playback logic to improve active slide checks and remove commented code 2026-02-13 19:34:13 +01:00
CodeDevMLH
1ae59f5da5 Update manifest.json for release v1.6.1.17 [skip ci] 2026-02-13 13:49:23 +00:00
CodeDevMLH
92eaf91173 Bump version to 1.6.1.17
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 1m2s
2026-02-13 14:48:24 +01:00
CodeDevMLH
e7410ec22a Fix slideshow preloading logic to prevent redundant slide creation 2026-02-13 14:48:07 +01:00
CodeDevMLH
bb43d1e679 Update manifest.json for release v1.6.1.16 [skip ci] 2026-02-13 02:53:20 +00:00
CodeDevMLH
b6609d23a2 Bump version to 1.6.1.16
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-02-13 03:52:27 +01:00
CodeDevMLH
9d4cbf37d3 Refactor slideshow state management and improve video playback logic 2026-02-13 03:52:07 +01:00
CodeDevMLH
b5e63ef3b7 Update manifest.json for release v1.6.1.15 [skip ci] 2026-02-13 02:41:24 +00:00
CodeDevMLH
22f9906188 Bump version to 1.6.1.15
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-13 03:40:35 +01:00
CodeDevMLH
ae54ab41a8 Refactor video playback logic to simplify conditions for active slides 2026-02-13 03:40:23 +01:00
CodeDevMLH
9663ab78d2 Update manifest.json for release v1.6.1.14 [skip ci] 2026-02-13 02:23:29 +00:00
CodeDevMLH
f633e4273f Bump version to 1.6.1.14
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-13 03:22:39 +01:00
CodeDevMLH
c0895fd8d7 Fix slideshow current slide index update logic 2026-02-13 03:22:21 +01:00
CodeDevMLH
002ccdb08b Enhance label styling and adjust layout in configuration form 2026-02-13 03:11:53 +01:00
CodeDevMLH
7cb03410ee Update manifest.json for release v1.6.1.13 [skip ci] 2026-02-13 02:02:19 +00:00
CodeDevMLH
17c8681e93 Bump version to 1.6.1.13 in project files and manifest
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-13 03:01:29 +01:00
CodeDevMLH
3a4c663c0e Enhance configuration layout and improve seasonal section handling 2026-02-13 03:01:17 +01:00
CodeDevMLH
3385196611 Update manifest.json for release v1.6.1.12 [skip ci] 2026-02-13 01:41:56 +00:00
CodeDevMLH
2538556f7c Bump version to 1.6.1.12
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-02-13 02:41:06 +01:00
CodeDevMLH
550ebed942 Update manifest.json for release v1.6.1.11 [skip ci] 2026-02-13 01:19:07 +00:00
CodeDevMLH
21d55711d4 Enhance configuration layout for season name input and update select appearance
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-02-13 02:18:18 +01:00
CodeDevMLH
81a0d375be Update manifest.json for release v1.6.1.11 [skip ci] 2026-02-13 01:12:47 +00:00
CodeDevMLH
23cbc0a85a Bump version to 1.6.1.11
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-13 02:11:58 +01:00
CodeDevMLH
2de066cca8 Merge branch 'main' of ssh://git.mahom03-spacecloud.de:44322/CodeDevMLH/jellyfin-plugin-media-bar-enhanced 2026-02-13 02:11:46 +01:00
CodeDevMLH
138e50ff15 Enhance configuration layout and add disablePictureInPicture option for video playback 2026-02-13 02:11:20 +01:00
CodeDevMLH
bf72dc08a3 Update manifest.json for release v1.6.1.10 [skip ci] 2026-02-13 00:41:36 +00:00
CodeDevMLH
65a63b4aa0 Bump version to 1.6.1.10
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-13 01:40:48 +01:00
CodeDevMLH
a1df756c56 Enhance seasonal section input fields with improved layout and descriptions 2026-02-13 01:40:33 +01:00
CodeDevMLH
f2d383ec61 Refactor video playback logic in SlideshowManager for improved fallback handling 2026-02-13 01:36:26 +01:00
CodeDevMLH
b85f52d8d3 Update manifest.json for release v1.6.1.9 [skip ci] 2026-02-13 00:16:40 +00:00
CodeDevMLH
ad18acb011 Bump version to 1.6.1.9
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-13 01:15:47 +01:00
CodeDevMLH
2ae147ac01 Add seasonal content support and enhance custom media ID handling 2026-02-13 01:15:33 +01:00
CodeDevMLH
9896044988 Update manifest.json for release v1.6.1.8 [skip ci] 2026-02-12 23:51:47 +00:00
CodeDevMLH
93e91e2e60 Bump version to 1.6.1.8 in project file and manifest
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 58s
2026-02-13 00:50:52 +01:00
CodeDevMLH
b613b028d0 Add configuration options for custom ID limits 2026-02-13 00:50:34 +01:00
CodeDevMLH
9906784845 Enhance visibility change handling to manage video playback more effectively when tab visibility changes 2026-02-12 21:35:29 +01:00
CodeDevMLH
009a3c4720 Update manifest.json for release v1.6.1.7 [skip ci] 2026-02-12 15:57:17 +00:00
CodeDevMLH
595056230a Bump version to 1.6.1.7 in project file and manifest
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 59s
2026-02-12 16:54:36 +01:00
CodeDevMLH
b18060dfd7 Refactor visibility observer initialization and remove debounce logic 2026-02-12 16:54:20 +01:00
CodeDevMLH
ebb2af9d24 Update manifest.json for release v1.6.1.6 [skip ci] 2026-02-12 02:03:10 +00:00
CodeDevMLH
743af20b8e Bump version to 1.6.1.6
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-12 03:02:17 +01:00
CodeDevMLH
9844b186d7 Enhance focus management in TV mode by delaying focus call after iframe removal 2026-02-12 03:02:10 +01:00
CodeDevMLH
104b76aa41 Update manifest.json for release v1.6.1.5 [skip ci] 2026-02-12 01:51:53 +00:00
CodeDevMLH
7493c8fa93 Bump version to 1.6.1.5
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-12 02:51:04 +01:00
CodeDevMLH
77c03157a1 Enhance slide pruning logic to restore focus in TV mode after pruning slides 2026-02-12 02:50:50 +01:00
CodeDevMLH
a7929e1ff6 Update manifest.json for release v1.6.1.4 [skip ci] 2026-02-12 01:29:37 +00:00
CodeDevMLH
c78e07de62 Bump version to 1.6.1.4
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-12 02:28:47 +01:00
CodeDevMLH
a90f805ea8 Refactor visibility management in slideshow and video playback; optimize state updates and debounce observer for improved performance. 2026-02-12 02:28:32 +01:00
CodeDevMLH
ccba1857e1 Update manifest.json for release v1.6.1.3 [skip ci] 2026-02-12 00:43:53 +00:00
CodeDevMLH
ff56c9370b Bump version to 1.6.1.3
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 49s
2026-02-12 01:43:05 +01:00
CodeDevMLH
162600c43f Enhance TV mode support by preventing iframe focus stealing and ensuring container focus continuity; refactor video playback management for improved clarity and functionality. 2026-02-12 01:42:22 +01:00
CodeDevMLH
a21549af47 Update manifest.json for release v1.6.1.2 [skip ci] 2026-02-11 23:50:41 +00:00
CodeDevMLH
1b319ade40 Merge branch 'main' of ssh://git.mahom03-spacecloud.de:44322/CodeDevMLH/jellyfin-plugin-media-bar-enhanced
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-02-12 00:49:49 +01:00
CodeDevMLH
75757d67e7 Adjust backdrop container positioning for TV layout 2026-02-11 20:15:17 +01:00
CodeDevMLH
92fc8d72f7 Update manifest.json for release v1.6.1.2 [skip ci] 2026-02-11 19:13:25 +00:00
CodeDevMLH
cfe9dec550 Bump version to 1.6.1.2
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-11 20:12:30 +01:00
CodeDevMLH
1bef573aaf Enhance video playback handling and improve slide preloading logic 2026-02-11 20:12:16 +01:00
CodeDevMLH
29a365b690 Update manifest.json for release v1.6.1.1 [skip ci] 2026-02-11 18:57:36 +00:00
CodeDevMLH
0ee0a65309 Bump version to 1.6.1.1
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-11 19:56:42 +01:00
CodeDevMLH
152d22b709 Refine video playback logic in slideshow and update preload description 2026-02-11 19:56:20 +01:00
CodeDevMLH
216dddad94 Update manifest.json for release v1.6.1.0 [skip ci] 2026-02-11 17:24:36 +00:00
CodeDevMLH
a6de148ca1 Bump version to 1.6.1.0
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 56s
2026-02-11 18:23:42 +01:00
CodeDevMLH
1f9378d74d Enhance video backdrop styling for TV layout and improve focus management in slideshow 2026-02-11 18:22:44 +01:00
CodeDevMLH
cc025779dc Update manifest.json for release v1.6.0.2 [skip ci] 2026-02-10 22:07:34 +00:00
CodeDevMLH
3d10fd59b5 Enhance manual trailer/video override instructions to support Jellyfin Item IDs and clarify usage
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-10 23:06:40 +01:00
CodeDevMLH
bf261eba96 Update manifest.json for release v1.6.0.2 [skip ci] 2026-02-10 21:44:36 +00:00
CodeDevMLH
e3116c30cf Bump version to 1.6.0.2
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-10 22:43:47 +01:00
CodeDevMLH
bb39c91d32 Enhance custom trailer URL handling to support Jellyfin Item IDs and standard URLs 2026-02-10 22:43:40 +01:00
CodeDevMLH
4e0c74614a Update manifest.json for release v1.6.0.1 [skip ci] 2026-02-10 21:27:25 +00:00
CodeDevMLH
b61bf92437 Bump version to 1.6.0.1 in project files and manifest
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-10 22:26:32 +01:00
CodeDevMLH
dfbd6ce964 Enable autoplay for video playback in SlideUtils 2026-02-10 22:26:28 +01:00
CodeDevMLH
f1cbcad177 Update manifest.json for release v1.6.0.0 [skip ci] 2026-02-10 21:18:26 +00:00
CodeDevMLH
feedd5d95f Bump version to 1.6.0.0
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-10 22:17:36 +01:00
CodeDevMLH
87d82cca15 Enhance trailer handling: support object format for trailer URLs and add widget referrer for YouTube embeds 2026-02-10 22:17:24 +01:00
CodeDevMLH
a70746e095 Update manifest.json for release v1.5.1.3 [skip ci] 2026-02-10 20:12:59 +00:00
CodeDevMLH
f32283e0bf Bump version to 1.5.1.3 and update changelog for release
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-10 21:12:05 +01:00
CodeDevMLH
8f3985f307 Update manifest.json for release v1.5.1.2 [skip ci] 2026-02-10 17:39:23 +00:00
CodeDevMLH
0b2817ecff Bump version to 1.5.1.2 and update changelog for release
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-02-10 18:38:31 +01:00
CodeDevMLH
84faee2db4 Update manifest.json for release v1.5.1.1 [skip ci] 2026-02-10 16:58:48 +00:00
CodeDevMLH
3efa07ec51 Bump version to 1.5.1.1 and update changelog for release
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 55s
2026-02-10 17:57:54 +01:00
CodeDevMLH
af603e8803 Enhance options in mediaBarEnhanced for seasonal content, local trailers, and sorting criteria [skip ci] 2026-02-10 01:57:51 +01:00
CodeDevMLH
fe63414e4b Update manifest.json for release v1.5.1.0 [skip ci] 2026-02-10 00:51:17 +00:00
CodeDevMLH
614c86083f Bump version to 1.5.1.0 and update changelog for iOS/MacOS playback fix
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-02-10 01:50:27 +01:00
CodeDevMLH
17b9e8921e Update manifest.json for release v1.5.0.28 [skip ci] 2026-02-10 00:35:42 +00:00
CodeDevMLH
5075226ba8 fix wording
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 56s
2026-02-10 01:34:47 +01:00
CodeDevMLH
443fb1008b Update version to 1.5.0.28 and enhance changelog with new features and fixes [skip ci] 2026-02-10 01:32:33 +01:00
CodeDevMLH
8f12140aad Update manifest.json for release v1.5.0.28 [skip ci] 2026-02-10 00:22:00 +00:00
CodeDevMLH
1469712bb5 reverted to 25
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-10 01:21:08 +01:00
CodeDevMLH
76ff03ac17 Update manifest.json for release v1.5.0.27 [skip ci] 2026-02-10 00:16:23 +00:00
CodeDevMLH
25b1ba5f2b Bump version to 1.5.0.26 and update changelog for recent changes
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-10 01:15:33 +01:00
CodeDevMLH
eed3ca1860 Update manifest.json for release v1.5.0.25 [skip ci] 2026-02-10 00:07:06 +00:00
CodeDevMLH
0f14577f5d Bump version to 1.5.0.25 and update changelog for recent changes
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-02-10 01:06:15 +01:00
CodeDevMLH
9999d6a633 Update manifest.json for release v1.5.0.24 [skip ci] 2026-02-09 23:53:21 +00:00
CodeDevMLH
a935fd7d5d Bump version to 1.5.0.24 and update changelog for recent changes
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-02-10 00:52:29 +01:00
CodeDevMLH
60293e81e1 Update manifest.json for release v1.5.0.23 [skip ci] 2026-02-09 23:34:11 +00:00
CodeDevMLH
f54e55fe04 Bump version to 1.5.0.23 and update changelog for recent changes
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-02-10 00:33:19 +01:00
CodeDevMLH
b3c42e2100 Update manifest.json for release v1.5.0.22 [skip ci] 2026-02-09 23:08:41 +00:00
CodeDevMLH
20ddbb32c7 Bump version to 1.5.0.22 and update changelog for recent changes
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-10 00:07:51 +01:00
CodeDevMLH
14a5075e22 Update manifest.json for release v1.5.0.21 [skip ci] 2026-02-09 22:29:09 +00:00
CodeDevMLH
accb316a81 Bump version to 1.5.0.21 and update changelog for recent changes
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 55s
2026-02-09 23:28:15 +01:00
CodeDevMLH
51c5cdf5bf Update manifest.json for release v1.5.0.20 [skip ci] 2026-02-09 16:53:01 +00:00
CodeDevMLH
306eff757b Update changelog formatting for version 1.5.0.20
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-02-09 17:52:10 +01:00
CodeDevMLH
b8f28a5735 Bump version to 1.5.0.20 and update changelog for recent changes
Some checks failed
Auto Release Plugin / build-and-release (push) Has been cancelled
2026-02-09 17:49:36 +01:00
CodeDevMLH
0932d9611d Update manifest.json for release v1.5.0.19 [skip ci] 2026-02-09 16:33:56 +00:00
CodeDevMLH
5e616db0ae Bump version to 1.5.0.19 and update changelog for recent changes
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 57s
2026-02-09 17:32:59 +01:00
CodeDevMLH
538b0f2110 Update manifest.json for release v1.5.0.18 [skip ci] 2026-02-09 16:21:43 +00:00
CodeDevMLH
e717c07c54 Bump version to 1.5.0.18 and update changelog for recent changes
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 1m2s
2026-02-09 17:20:40 +01:00
CodeDevMLH
0fa2d01ca3 Update manifest.json for release v1.5.0.17 [skip ci] 2026-02-09 16:05:12 +00:00
CodeDevMLH
5299b2a9d5 Bump version to 1.5.0.17 and update changelog for recent changes
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 57s
2026-02-09 17:04:15 +01:00
CodeDevMLH
4f244988b9 Update manifest.json for release v1.5.0.16 [skip ci] 2026-02-09 15:54:25 +00:00
CodeDevMLH
5635a8f05e Bump version to 1.5.0.16 and update changelog for keyboard controls and sorting options
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-02-09 16:53:33 +01:00
CodeDevMLH
c901da4b0c Update manifest.json for release v1.5.0.15 [skip ci] 2026-02-09 15:41:45 +00:00
CodeDevMLH
c45cd0281f Bump version to 1.5.0.15 in project file and manifest.json
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-02-09 16:40:24 +01:00
CodeDevMLH
0c3e74829a Remove upstream trailer layout feature from configuration and UI 2026-02-09 16:40:01 +01:00
CodeDevMLH
e6b769f099 Update manifest.json for release v1.5.0.14 [skip ci] 2026-02-09 15:30:53 +00:00
CodeDevMLH
77371f7b98 Bump version to 1.5.0.14 and update changelog in manifest.json
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 58s
2026-02-09 16:29:56 +01:00
CodeDevMLH
988b800b6d Update manifest.json for release v1.5.0.13 [skip ci] 2026-02-09 15:21:45 +00:00
CodeDevMLH
4c6514ba9f Bump version to 1.5.0.13 and update changelog in manifest.json
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-02-09 16:20:52 +01:00
CodeDevMLH
6910eba7d6 Update manifest.json for release v1.5.0.12 [skip ci] 2026-02-09 15:10:07 +00:00
CodeDevMLH
3585b47b6c Bump version to 1.5.0.12 and update changelog in manifest.json
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 56s
2026-02-09 16:09:10 +01:00
CodeDevMLH
8170abdc94 Update manifest.json for release v1.5.0.11 [skip ci] 2026-02-09 14:56:05 +00:00
CodeDevMLH
535c0e17bf Add upstream trailer layout feature and update version to 1.5.0.11
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-02-09 15:55:14 +01:00
CodeDevMLH
df1cee0eeb Update manifest.json for release v1.5.0.10 [skip ci] 2026-02-09 13:31:00 +00:00
CodeDevMLH
16cc56030f Bump version to 1.5.0.10 in project file and manifest
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 55s
2026-02-09 14:30:05 +01:00
CodeDevMLH
13ecbac96e Update manifest.json for release v1.5.0.9 [skip ci] 2026-02-09 13:18:30 +00:00
CodeDevMLH
8bca6f9052 Bump version to 1.5.0.9 in project file and manifest
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-09 14:17:38 +01:00
CodeDevMLH
217db2a66d Fix video backdrop styling for full coverage and pointer events 2026-02-09 14:17:22 +01:00
CodeDevMLH
5fd7bcb8b6 Update manifest.json for release v1.5.0.8 [skip ci] 2026-02-09 13:11:30 +00:00
CodeDevMLH
0b0e41a9f9 Bump version to 1.5.0.8 in project file and manifest
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 56s
2026-02-09 14:10:35 +01:00
CodeDevMLH
370db55714 Enhance slideshow video styling for better positioning and responsiveness 2026-02-09 14:06:18 +01:00
CodeDevMLH
e5d4800ef1 Update manifest.json for release v1.5.0.7 [skip ci] 2026-02-09 12:28:45 +00:00
CodeDevMLH
b910e92364 Add spotlight.html: Initial implementation of Seth's Spotlight UI enhancement for Jellyfin with movie slideshow and trailer functionality
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 55s
2026-02-09 13:27:51 +01:00
CodeDevMLH
82283b1faf Merge branch 'main' of ssh://git.mahom03-spacecloud.de:44322/CodeDevMLH/jellyfin-plugin-media-bar-enhanced
Some checks failed
Auto Release Plugin / build-and-release (push) Has been cancelled
2026-02-09 13:27:36 +01:00
CodeDevMLH
1588b1a6b2 Add option to prefer local trailers over remote ones; update configuration and UI 2026-02-09 03:31:05 +01:00
CodeDevMLH
de19466341 Add script to fetch specific item details from Jellyfin API 2026-02-09 02:56:53 +01:00
CodeDevMLH
15054e314c refine sorting options description 2026-02-09 02:42:23 +01:00
CodeDevMLH
3877f96b09 Add sorting options for Production Year and Critic Rating; remove Date Created sorting 2026-02-09 02:39:42 +01:00
CodeDevMLH
abca7cb3b6 Refactor random item fetching logic and enhance error handling; add JSON download feature 2026-02-09 02:39:32 +01:00
CodeDevMLH
998a0cfc68 Add scripts to fetch random items from Jellyfin API with detailed logging [skip ci] 2026-02-09 02:21:12 +01:00
CodeDevMLH
63be8214d0 Update manifest.json for release v1.5.0.6 [skip ci] 2026-02-09 00:31:35 +00:00
CodeDevMLH
99411afffd Bump version to 1.5.0.6; update changelog and fix keyboard controls in TV mode
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 58s
2026-02-09 01:30:36 +01:00
CodeDevMLH
9510ae6ba7 Add sorting options for content in configuration and update sorting logic 2026-02-09 01:30:28 +01:00
CodeDevMLH
2030538acc Update manifest.json for release v1.5.0.5 [skip ci] 2026-02-08 02:20:04 +00:00
CodeDevMLH
463e9ef424 Bump version to 1.5.0.5; update keyboard controls and changelog
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 51s
2026-02-08 03:19:12 +01:00
CodeDevMLH
dbe9ce97d2 Update manifest.json for release v1.5.0.4 [skip ci] 2026-02-08 01:32:40 +00:00
CodeDevMLH
45c780c018 Bump version to 1.5.0.4 and update changelog for mediaBarEnhanced.js and manifest.json; enhance keyboard navigation controls
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-08 02:31:49 +01:00
CodeDevMLH
9de268caa7 , 2026-02-08 02:28:06 +01:00
CodeDevMLH
a8298461f9 Update manifest.json for release v1.5.0.3 [skip ci] 2026-02-08 00:41:45 +00:00
CodeDevMLH
aa369e5c7b Merge branch 'main' of ssh://git.mahom03-spacecloud.de:44322/CodeDevMLH/jellyfin-plugin-media-bar-enhanced
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-08 01:40:53 +01:00
CodeDevMLH
f62dc853be Bump version to 1.5.0.3 and update changelog for mediaBarEnhanced.js and manifest.json; improve keyboard controls in TV mode 2026-02-08 01:40:50 +01:00
CodeDevMLH
d0a7f5da8c Update manifest.json for release v1.5.0.2 [skip ci] 2026-02-08 00:10:29 +00:00
CodeDevMLH
1f140fd3c1 Bump version to 1.5.0.2 and update changelog for mediaBarEnhanced.js and manifest.json; enhance keyboard controls in TV mode
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-02-08 01:09:38 +01:00
CodeDevMLH
18474d4537 Update manifest.json for release v1.5.0.1 [skip ci] 2026-02-08 00:00:01 +00:00
CodeDevMLH
839424a960 Bump version to 1.5.0.1 and update changelog for mediaBarEnhanced.js and manifest.json; fix keyboard controls in TV mode
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 57s
2026-02-08 00:59:04 +01:00
CodeDevMLH
8050aa8e76 Update manifest.json for release v1.5.0.0 [skip ci] 2026-02-07 23:50:07 +00:00
CodeDevMLH
0c173b9685 Bump version to 1.5.0.0 and update changelog for mediaBarEnhanced.js and mediaBarEnhanced.css
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 56s
2026-02-08 00:49:12 +01:00
CodeDevMLH
90ecc7c0ef add without list.txt 2026-02-08 00:48:48 +01:00
CodeDevMLH
c80d3726a6 Enhance README.md with new features: added custom trailer URL option, client settings, and updated client platform support details. 2026-02-04 21:11:52 +01:00
CodeDevMLH
a8e63c935f Comment out seasonal manifest update steps in release automation workflow [skip ci] 2026-02-04 19:47:03 +01:00
CodeDevMLH
d931a5d589 Merge branch 'main' of ssh://git.mahom03-spacecloud.de:44322/CodeDevMLH/jellyfin-plugin-media-bar-enhanced 2026-02-04 19:08:14 +01:00
CodeDevMLH
629f13ab58 Comment out seasonal manifest update steps in release automation workflow 2026-02-04 19:08:13 +01:00
CodeDevMLH
6a91784401 Update manifest.json for release v1.4.0.12 [skip ci] 2026-02-04 18:07:40 +00:00
CodeDevMLH
3f8777db9f Bump version to 1.4.0.12
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-04 19:06:47 +01:00
CodeDevMLH
4ec337a893 Update button layout and text for improved clarity in settings UI 2026-02-04 19:05:27 +01:00
CodeDevMLH
7366f2ca30 Update button text for clarity in settings UI 2026-02-04 19:04:19 +01:00
CodeDevMLH
faabf13870 Update manifest.json for release v1.4.0.11 [skip ci] 2026-02-04 17:58:14 +00:00
CodeDevMLH
3e584fa419 Bump version to 1.4.0.11
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-04 18:57:23 +01:00
CodeDevMLH
13889c3c68 Enhance button layout in settings UI for better alignment and clarity 2026-02-04 18:57:09 +01:00
CodeDevMLH
7af9eb5004 Update manifest.json for release v1.4.0.10 [skip ci] 2026-02-04 17:51:26 +00:00
CodeDevMLH
1e57d8acef Bump version to 1.4.0.10
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-04 18:50:36 +01:00
CodeDevMLH
5964d2cb34 Enhance settings UI with reset functionality and improved button layout 2026-02-04 18:50:20 +01:00
CodeDevMLH
6f3fd23879 Update manifest.json for release v1.4.0.9 [skip ci] 2026-02-04 17:39:12 +00:00
CodeDevMLH
47949e9820 Bump version to 1.4.0.9
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-04 18:38:21 +01:00
CodeDevMLH
5fe8da8347 Update configuration descriptions for clarity and accuracy 2026-02-04 18:38:05 +01:00
CodeDevMLH
a8842f8415 Update manifest.json for release v1.4.0.8 [skip ci] 2026-02-04 17:27:23 +00:00
CodeDevMLH
3ecaf5fae6 Bump version to 1.4.0.8
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-04 18:26:30 +01:00
CodeDevMLH
9d13d61e77 Update configuration labels and descriptions for clarity 2026-02-04 18:26:16 +01:00
CodeDevMLH
0e441b751b Update manifest.json for release v1.4.0.7 [skip ci] 2026-02-04 17:09:29 +00:00
CodeDevMLH
4f14c00636 Bump version to 1.4.0.7
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 55s
2026-02-04 18:08:37 +01:00
CodeDevMLH
2dbb4dcfea Add minimal logo SVG and update mediaBarEnhanced.js to use it 2026-02-04 18:08:24 +01:00
CodeDevMLH
1982511374 Update manifest.json for release v1.4.0.6 [skip ci] 2026-02-04 16:40:22 +00:00
CodeDevMLH
3d7c1ec2cb Bump version to 1.4.0.6
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-04 17:39:30 +01:00
CodeDevMLH
bf7762f4d8 Add short logo SVG and update mediaBarEnhanced.js to use it 2026-02-04 17:39:17 +01:00
CodeDevMLH
9ba4bae6a8 Update manifest.json for release v1.4.0.5 [skip ci] 2026-02-04 16:23:15 +00:00
CodeDevMLH
f7388d8c25 Bump version to 1.4.0.5
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-04 17:22:25 +01:00
CodeDevMLH
7097c49773 Fix logo image source in MediaBar settings button for correct display 2026-02-04 17:21:18 +01:00
CodeDevMLH
0dce0c1551 Update manifest.json for release v1.4.0.4 [skip ci] 2026-02-04 16:17:16 +00:00
CodeDevMLH
386c5f9d7d Bump version to 1.4.0.4
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 56s
2026-02-04 17:16:23 +01:00
CodeDevMLH
2bd1a7a8b4 Update logo image source in MediaBar settings button for improved display and drag handling 2026-02-04 17:16:07 +01:00
CodeDevMLH
61eeed78b8 Update logo image source in MediaBar settings button for improved display 2026-02-04 17:13:12 +01:00
CodeDevMLH
5a844f4d57 Update manifest.json for release v1.4.0.3 [skip ci] 2026-02-04 15:52:12 +00:00
CodeDevMLH
4127a2e20c Bump version to 1.4.0.3
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-04 16:51:22 +01:00
CodeDevMLH
f6b56a6f65 Refactor settings management to use MediaBarEnhancedSettingsManager for consistency 2026-02-04 16:51:03 +01:00
CodeDevMLH
4e8af02ab4 Update manifest.json for release v1.4.0.2 [skip ci] 2026-02-04 15:45:39 +00:00
CodeDevMLH
22d15748d9 Bump version to 1.4.0.2 and enhance client-side settings with descriptions for media bar options
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 55s
2026-02-04 16:44:47 +01:00
24 changed files with 3415 additions and 680 deletions

View File

@@ -51,7 +51,31 @@ jobs:
echo "$CHANGELOG" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- name: Check if Release Already Exists
id: check_release
shell: bash
run: |
REPO_OWNER="${{ github.repository_owner }}"
REPO_NAME="${{ github.event.repository.name }}"
VERSION="${{ env.VERSION }}"
TAG="v$VERSION"
SERVER_URL="https://git.mahom03-spacecloud.de"
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" "$SERVER_URL/api/v1/repos/$REPO_OWNER/$REPO_NAME/releases/tags/$TAG")
if [ "$HTTP_STATUS" -eq 200 ]; then
echo "Release $TAG already exists. Skipping release-related steps."
echo "release_exists=true" >> $GITHUB_OUTPUT
elif [ "$HTTP_STATUS" -eq 404 ]; then
echo "No existing release for $TAG. Continuing."
echo "release_exists=false" >> $GITHUB_OUTPUT
else
echo "Unexpected response when checking release: $HTTP_STATUS"
exit 1
fi
- name: Build and Zip
if: steps.check_release.outputs.release_exists == 'false'
shell: bash
run: |
# Inject version from manifest into the build
@@ -71,6 +95,7 @@ jobs:
echo "ZIP_PATH=bin/Publish/Jellyfin.Plugin.MediaBarEnhanced.zip" >> $GITHUB_ENV
- name: Update manifest.json
if: steps.check_release.outputs.release_exists == 'false'
shell: bash
run: |
REPO_OWNER="${{ github.repository_owner }}"
@@ -90,12 +115,14 @@ jobs:
manifest.json > manifest.json.tmp && mv manifest.json.tmp manifest.json
- name: Commit manifest.json
if: steps.check_release.outputs.release_exists == 'false'
uses: stefanzweifel/git-auto-commit-action@v7
with:
commit_message: "Update manifest.json for release v${{ env.VERSION }} [skip ci]"
file_pattern: manifest.json
- name: Create Release
if: steps.check_release.outputs.release_exists == 'false'
uses: akkuman/gitea-release-action@v1
with:
server_url: "https://git.mahom03-spacecloud.de"
@@ -109,6 +136,7 @@ jobs:
# Update Message in Remote Repository
- name: Checkout Central Manifest Repo
if: steps.check_release.outputs.release_exists == 'false'
uses: actions/checkout@v6
with:
repository: ${{ github.repository_owner }}/jellyfin-plugin-manifest
@@ -116,6 +144,7 @@ jobs:
token: ${{ secrets.JELLYFIN_PLUGIN_MANIFEST_UPDATER_PAT }}
- name: Update Central Manifest
if: steps.check_release.outputs.release_exists == 'false'
shell: bash
run: |
cd central-manifest
@@ -171,6 +200,7 @@ jobs:
manifest.json > manifest.json.tmp && mv manifest.json.tmp manifest.json
- name: Commit and Push Central Manifest
if: steps.check_release.outputs.release_exists == 'false'
run: |
cd central-manifest
git config user.name "CodeDevMLH"
@@ -186,79 +216,79 @@ jobs:
fi
# Update Message in Seasonals Repository
- name: Checkout Seasonal Manifest Repo
uses: actions/checkout@v6
with:
repository: ${{ github.repository_owner }}/Jellyfin-Seasonals-Plugin
path: seasonal-manifest
token: ${{ secrets.JELLYFIN_PLUGIN_MANIFEST_UPDATER_PAT }}
# - name: Checkout Seasonal Manifest Repo
# uses: actions/checkout@v6
# with:
# repository: ${{ github.repository_owner }}/Jellyfin-Seasonals-Plugin
# path: seasonal-manifest
# token: ${{ secrets.JELLYFIN_PLUGIN_MANIFEST_UPDATER_PAT }}
- name: Update Seasonal Manifest
shell: bash
run: |
cd seasonal-manifest
# - name: Update Seasonal Manifest
# shell: bash
# run: |
# cd seasonal-manifest
REPO_OWNER="${{ github.repository_owner }}"
REPO_NAME="${{ github.event.repository.name }}"
# REPO_OWNER="${{ github.repository_owner }}"
# REPO_NAME="${{ github.event.repository.name }}"
# 1. Get info from previous steps
VERSION="${{ env.VERSION }}"
HASH="${{ env.ZIP_HASH }}"
TIME="${{ env.BUILD_TIME }}"
DOWNLOAD_URL="https://git.mahom03-spacecloud.de/$REPO_OWNER/$REPO_NAME/releases/download/v$VERSION/Jellyfin.Plugin.MediaBarEnhanced.zip"
# # 1. Get info from previous steps
# VERSION="${{ env.VERSION }}"
# HASH="${{ env.ZIP_HASH }}"
# TIME="${{ env.BUILD_TIME }}"
# DOWNLOAD_URL="https://git.mahom03-spacecloud.de/$REPO_OWNER/$REPO_NAME/releases/download/v$VERSION/Jellyfin.Plugin.MediaBarEnhanced.zip"
# 2. Get info from env
PLUGIN_GUID="${{ env.PLUGIN_GUID }}"
CHANGELOG="${{ env.CHANGELOG }}"
TARGET_ABI="${{ env.TARGET_ABI }}"
# # 2. Get info from env
# PLUGIN_GUID="${{ env.PLUGIN_GUID }}"
# CHANGELOG="${{ env.CHANGELOG }}"
# TARGET_ABI="${{ env.TARGET_ABI }}"
echo "Updating Seasonal Manifest for Plugin GUID: $PLUGIN_GUID"
# echo "Updating Seasonal Manifest for Plugin GUID: $PLUGIN_GUID"
# 3. Update/Prepend entry in seasonal manifest.json
# Logic:
# - If array is empty or new version != old version: PREPEND new entry
# - If new version == old version: OVERWRITE (update) existing entry (re-release)
# # 3. Update/Prepend entry in seasonal manifest.json
# # Logic:
# # - If array is empty or new version != old version: PREPEND new entry
# # - If new version == old version: OVERWRITE (update) existing entry (re-release)
jq --arg guid "$PLUGIN_GUID" \
--arg hash "$HASH" \
--arg time "$TIME" \
--arg url "$DOWNLOAD_URL" \
--arg ver "$VERSION" \
--arg changelog "$CHANGELOG" \
--arg abi "$TARGET_ABI" \
'map(if .guid == $guid then
if .versions[0].version != $ver then
# New Version -> Prepend
.versions = [{
"version": $ver,
"changelog": $changelog,
"targetAbi": $abi,
"sourceUrl": $url,
"checksum": $hash,
"timestamp": $time
}] + .versions
else
# Same Version -> Update existing (overwrite top)
.versions[0].changelog = $changelog |
.versions[0].targetAbi = $abi |
.versions[0].sourceUrl = $url |
.versions[0].checksum = $hash |
.versions[0].timestamp = $time
end
else . end)' \
manifest.json > manifest.json.tmp && mv manifest.json.tmp manifest.json
# jq --arg guid "$PLUGIN_GUID" \
# --arg hash "$HASH" \
# --arg time "$TIME" \
# --arg url "$DOWNLOAD_URL" \
# --arg ver "$VERSION" \
# --arg changelog "$CHANGELOG" \
# --arg abi "$TARGET_ABI" \
# 'map(if .guid == $guid then
# if .versions[0].version != $ver then
# # New Version -> Prepend
# .versions = [{
# "version": $ver,
# "changelog": $changelog,
# "targetAbi": $abi,
# "sourceUrl": $url,
# "checksum": $hash,
# "timestamp": $time
# }] + .versions
# else
# # Same Version -> Update existing (overwrite top)
# .versions[0].changelog = $changelog |
# .versions[0].targetAbi = $abi |
# .versions[0].sourceUrl = $url |
# .versions[0].checksum = $hash |
# .versions[0].timestamp = $time
# end
# else . end)' \
# manifest.json > manifest.json.tmp && mv manifest.json.tmp manifest.json
- name: Commit and Push Seasonal Manifest
run: |
cd seasonal-manifest
git config user.name "CodeDevMLH"
git config user.email "145071728+CodeDevMLH@users.noreply.github.com"
# - name: Commit and Push Seasonal Manifest
# run: |
# cd seasonal-manifest
# git config user.name "CodeDevMLH"
# git config user.email "145071728+CodeDevMLH@users.noreply.github.com"
# Check if there are changes
if [[ -n $(git status -s) ]]; then
git add manifest.json
git commit -m "Auto-Update MediaBar Enhanced to v${{ env.VERSION }}"
git push
else
echo "No changes to seasonal manifest."
fi
# # Check if there are changes
# if [[ -n $(git status -s) ]]; then
# git add manifest.json
# git commit -m "Auto-Update MediaBar Enhanced to v${{ env.VERSION }}"
# git push
# else
# echo "No changes to seasonal manifest."
# fi

View File

@@ -52,7 +52,32 @@ jobs:
echo "$CHANGELOG" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- name: Check if Release Already Exists
id: check_release
shell: bash
run: |
REPO_OWNER="${{ github.repository_owner }}"
REPO_NAME="${{ github.event.repository.name }}"
VERSION="${{ env.VERSION }}"
TAG="v$VERSION"
API_URL="https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/releases/tags/$TAG"
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" "$API_URL")
if [ "$HTTP_STATUS" -eq 200 ]; then
echo "Release $TAG already exists. Skipping release-related steps."
echo "release_exists=true" >> $GITHUB_OUTPUT
elif [ "$HTTP_STATUS" -eq 404 ]; then
echo "No existing release for $TAG. Continuing."
echo "release_exists=false" >> $GITHUB_OUTPUT
else
echo "Unexpected response when checking release: $HTTP_STATUS"
exit 1
fi
- name: Build and Zip
if: steps.check_release.outputs.release_exists == 'false'
shell: bash
run: |
# Inject version from manifest into the build
@@ -72,6 +97,7 @@ jobs:
echo "ZIP_PATH=bin/Publish/Jellyfin.Plugin.MediaBarEnhanced.zip" >> $GITHUB_ENV
- name: Update manifest.json
if: steps.check_release.outputs.release_exists == 'false'
shell: bash
run: |
REPO_OWNER="${{ github.repository_owner }}"
@@ -91,13 +117,14 @@ jobs:
manifest.json > manifest.json.tmp && mv manifest.json.tmp manifest.json
- name: Commit manifest.json
if: steps.check_release.outputs.release_exists == 'false'
uses: stefanzweifel/git-auto-commit-action@v7
with:
commit_message: "Update manifest.json for release v${{ env.VERSION }} [skip ci]"
file_pattern: manifest.json
- name: Generate Commit Log
if: success()
if: success() && steps.check_release.outputs.release_exists == 'false'
shell: bash
run: |
echo "Generating commit log since last tag..."
@@ -131,6 +158,7 @@ jobs:
cat release_body.txt
- name: Create Release
if: steps.check_release.outputs.release_exists == 'false'
uses: softprops/action-gh-release@v2
with:
tag_name: "v${{ env.VERSION }}"
@@ -145,6 +173,7 @@ jobs:
# Update Message in Remote Repository
- name: Checkout Central Manifest Repo
if: steps.check_release.outputs.release_exists == 'false'
uses: actions/checkout@v6
with:
repository: ${{ github.repository_owner }}/jellyfin-plugin-manifest
@@ -152,6 +181,7 @@ jobs:
token: ${{ secrets.JELLYFIN_PLUGIN_MANIFEST_UPDATER_PAT }}
- name: Update Central Manifest
if: steps.check_release.outputs.release_exists == 'false'
shell: bash
run: |
cd central-manifest
@@ -207,6 +237,7 @@ jobs:
manifest.json > manifest.json.tmp && mv manifest.json.tmp manifest.json
- name: Commit and Push Central Manifest
if: steps.check_release.outputs.release_exists == 'false'
run: |
cd central-manifest
git config user.name "CodeDevMLH"
@@ -222,79 +253,79 @@ jobs:
fi
# Update Message in Seasonals Repository
- name: Checkout Seasonal Manifest Repo
uses: actions/checkout@v6
with:
repository: ${{ github.repository_owner }}/Jellyfin-Seasonals
path: seasonal-manifest
token: ${{ secrets.JELLYFIN_PLUGIN_MANIFEST_UPDATER_PAT }}
# - name: Checkout Seasonal Manifest Repo
# uses: actions/checkout@v6
# with:
# repository: ${{ github.repository_owner }}/Jellyfin-Seasonals
# path: seasonal-manifest
# token: ${{ secrets.JELLYFIN_PLUGIN_MANIFEST_UPDATER_PAT }}
- name: Update Seasonal Manifest
shell: bash
run: |
cd seasonal-manifest
# - name: Update Seasonal Manifest
# shell: bash
# run: |
# cd seasonal-manifest
REPO_OWNER="${{ github.repository_owner }}"
REPO_NAME="${{ github.event.repository.name }}"
# REPO_OWNER="${{ github.repository_owner }}"
# REPO_NAME="${{ github.event.repository.name }}"
# 1. Get info from previous steps
VERSION="${{ env.VERSION }}"
HASH="${{ env.ZIP_HASH }}"
TIME="${{ env.BUILD_TIME }}"
DOWNLOAD_URL="https://github.com/$REPO_OWNER/$REPO_NAME/releases/download/v$VERSION/Jellyfin.Plugin.MediaBarEnhanced.zip"
# # 1. Get info from previous steps
# VERSION="${{ env.VERSION }}"
# HASH="${{ env.ZIP_HASH }}"
# TIME="${{ env.BUILD_TIME }}"
# DOWNLOAD_URL="https://github.com/$REPO_OWNER/$REPO_NAME/releases/download/v$VERSION/Jellyfin.Plugin.MediaBarEnhanced.zip"
# 2. Get info from env
PLUGIN_GUID="${{ env.PLUGIN_GUID }}"
CHANGELOG="${{ env.CHANGELOG }}"
TARGET_ABI="${{ env.TARGET_ABI }}"
# # 2. Get info from env
# PLUGIN_GUID="${{ env.PLUGIN_GUID }}"
# CHANGELOG="${{ env.CHANGELOG }}"
# TARGET_ABI="${{ env.TARGET_ABI }}"
echo "Updating Seasonal Manifest for Plugin GUID: $PLUGIN_GUID"
# echo "Updating Seasonal Manifest for Plugin GUID: $PLUGIN_GUID"
# 3. Update/Prepend entry in seasonal manifest.json
# Logic:
# - If array is empty or new version != old version: PREPEND new entry
# - If new version == old version: OVERWRITE (update) existing entry (re-release)
# # 3. Update/Prepend entry in seasonal manifest.json
# # Logic:
# # - If array is empty or new version != old version: PREPEND new entry
# # - If new version == old version: OVERWRITE (update) existing entry (re-release)
jq --arg guid "$PLUGIN_GUID" \
--arg hash "$HASH" \
--arg time "$TIME" \
--arg url "$DOWNLOAD_URL" \
--arg ver "$VERSION" \
--arg changelog "$CHANGELOG" \
--arg abi "$TARGET_ABI" \
'map(if .guid == $guid then
if .versions[0].version != $ver then
# New Version -> Prepend
.versions = [{
"version": $ver,
"changelog": $changelog,
"targetAbi": $abi,
"sourceUrl": $url,
"checksum": $hash,
"timestamp": $time
}] + .versions
else
# Same Version -> Update existing (overwrite top)
.versions[0].changelog = $changelog |
.versions[0].targetAbi = $abi |
.versions[0].sourceUrl = $url |
.versions[0].checksum = $hash |
.versions[0].timestamp = $time
end
else . end)' \
manifest.json > manifest.json.tmp && mv manifest.json.tmp manifest.json
# jq --arg guid "$PLUGIN_GUID" \
# --arg hash "$HASH" \
# --arg time "$TIME" \
# --arg url "$DOWNLOAD_URL" \
# --arg ver "$VERSION" \
# --arg changelog "$CHANGELOG" \
# --arg abi "$TARGET_ABI" \
# 'map(if .guid == $guid then
# if .versions[0].version != $ver then
# # New Version -> Prepend
# .versions = [{
# "version": $ver,
# "changelog": $changelog,
# "targetAbi": $abi,
# "sourceUrl": $url,
# "checksum": $hash,
# "timestamp": $time
# }] + .versions
# else
# # Same Version -> Update existing (overwrite top)
# .versions[0].changelog = $changelog |
# .versions[0].targetAbi = $abi |
# .versions[0].sourceUrl = $url |
# .versions[0].checksum = $hash |
# .versions[0].timestamp = $time
# end
# else . end)' \
# manifest.json > manifest.json.tmp && mv manifest.json.tmp manifest.json
- name: Commit and Push Seasonal Manifest
run: |
cd seasonal-manifest
git config user.name "CodeDevMLH"
git config user.email "145071728+CodeDevMLH@users.noreply.github.com"
# - name: Commit and Push Seasonal Manifest
# run: |
# cd seasonal-manifest
# git config user.name "CodeDevMLH"
# git config user.email "145071728+CodeDevMLH@users.noreply.github.com"
# Check if there are changes
if [[ -n $(git status -s) ]]; then
git add manifest.json
git commit -m "Auto-Update MediaBar Enhanced to v${{ env.VERSION }}"
git push
else
echo "No changes to seasonal manifest."
fi
# # Check if there are changes
# if [[ -n $(git status -s) ]]; then
# git add manifest.json
# git commit -m "Auto-Update MediaBar Enhanced to v${{ env.VERSION }}"
# git push
# else
# echo "No changes to seasonal manifest."
# fi

246
Injector_new.cs Normal file
View File

@@ -0,0 +1,246 @@
using System;
using System.Reflection;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Loader;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using MediaBrowser.Common.Configuration;
using Jellyfin.Plugin.MediaBarEnhanced.Helpers;
namespace Jellyfin.Plugin.MediaBarEnhanced
{
/// <summary>
/// Handles the injection of the MediaBarEnhanced script into the Jellyfin web interface.
/// </summary>
public class ScriptInjector
{
private readonly IApplicationPaths _appPaths;
private readonly ILogger<ScriptInjector> _logger;
public const string ScriptTag = "<script src=\"../MediaBarEnhanced/Resources/mediaBarEnhanced.js\" defer></script>";
public const string CssTag = "<link rel=\"stylesheet\" href=\"../MediaBarEnhanced/Resources/mediaBarEnhanced.css\" />";
public const string ScriptMarker = "</body>";
public const string CssMarker = "</head>";
/// <summary>
/// Initializes a new instance of the <see cref="ScriptInjector"/> class.
/// </summary>
/// <param name="appPaths">The application paths.</param>
/// <param name="logger">The logger.</param>
public ScriptInjector(IApplicationPaths appPaths, ILogger<ScriptInjector> logger)
{
_appPaths = appPaths;
_logger = logger;
}
/// <summary>
/// Injects the script tag into index.html if it's not already present.
/// </summary>
public void Inject()
{
try
{
var webPath = GetWebPath();
if (string.IsNullOrEmpty(webPath))
{
_logger.LogWarning("Could not find Jellyfin web path. Script injection skipped. Attempting fallback.");
RegisterFileTransformation();
return;
}
var indexPath = Path.Combine(webPath, "index.html");
if (!File.Exists(indexPath))
{
_logger.LogWarning("index.html not found at {Path}. Script injection skipped. Attempting fallback.", indexPath);
RegisterFileTransformation();
return;
}
var content = File.ReadAllText(indexPath);
var injectedJS = false;
var injectedCSS = false;
if (!content.Contains(ScriptTag))
{
var index = content.IndexOf(ScriptMarker, StringComparison.OrdinalIgnoreCase);
if (index != -1)
{
content = content.Insert(index, ScriptTag + Environment.NewLine);
injectedJS = true;
}
}
if (!content.Contains(CssTag))
{
var index = content.IndexOf(CssMarker, StringComparison.OrdinalIgnoreCase);
if (index != -1)
{
content = content.Insert(index, CssTag + Environment.NewLine);
injectedCSS = true;
}
}
if (injectedJS && injectedCSS)
{
File.WriteAllText(indexPath, content);
_logger.LogInformation("MediaBarEnhanced script injected into index.html.");
} else if (injectedJS)
{
File.WriteAllText(indexPath, content);
_logger.LogInformation("MediaBarEnhanced JS script injected into index.html. But CSS was already present or could not be injected.");
}
else if (injectedCSS)
{
File.WriteAllText(indexPath, content);
_logger.LogInformation("MediaBarEnhanced CSS injected into index.html. But JS script was already present or could not be injected.");
}
else
{
_logger.LogInformation("MediaBarEnhanced script and CSS already present in index.html. Or could not be injected.");
}
}
catch (UnauthorizedAccessException)
{
_logger.LogWarning("Unauthorized access when attempting to inject script into index.html. Automatic injection failed. Attempting fallback now...");
RegisterFileTransformation();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error injecting MediaBarEnhanced resources. Attempting fallback.");
RegisterFileTransformation();
}
}
/// <summary>
/// Removes the script tag from index.html.
/// </summary>
public void Remove()
{
UnregisterFileTransformation();
try
{
var webPath = GetWebPath();
if (string.IsNullOrEmpty(webPath))
{
return;
}
var indexPath = Path.Combine(webPath, "index.html");
if (!File.Exists(indexPath))
{
return;
}
var content = File.ReadAllText(indexPath);
var modified = false;
if (content.Contains(ScriptTag))
{
content = content.Replace(ScriptTag + Environment.NewLine, "").Replace(ScriptTag, "");
modified = true;
}
if (content.Contains(CssTag))
{
content = content.Replace(CssTag + Environment.NewLine, "").Replace(CssTag, "");
modified = true;
}
if (modified)
{
File.WriteAllText(indexPath, content);
_logger.LogInformation("MediaBarEnhanced script removed from index.html.");
} else
{
_logger.LogInformation("MediaBarEnhanced script not found in index.html. No removal necessary.");
}
}
catch (UnauthorizedAccessException uaEx)
{
_logger.LogError(uaEx, "Unauthorized access when trying to remove MediaBarEnhanced script. Check file permissions.");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error removing MediaBarEnhanced script.");
}
}
private string? GetWebPath()
{
var prop = _appPaths.GetType().GetProperty("WebPath", BindingFlags.Instance | BindingFlags.Public);
return prop?.GetValue(_appPaths) as string;
}
private void RegisterFileTransformation()
{
_logger.LogInformation("MediaBarEnhanced Fallback. Registering file transformations.");
List<JObject> payloads = new List<JObject>();
{
JObject payload = new JObject();
payload.Add("id", "0dfac9d7-d898-4944-900b-1c1837707279");
payload.Add("fileNamePattern", "index.html");
payload.Add("callbackAssembly", GetType().Assembly.FullName);
payload.Add("callbackClass", typeof(TransformationPatches).FullName);
payload.Add("callbackMethod", nameof(TransformationPatches.IndexHtml));
payloads.Add(payload);
}
Assembly? fileTransformationAssembly =
AssemblyLoadContext.All.SelectMany(x => x.Assemblies).FirstOrDefault(x =>
x.FullName?.Contains(".FileTransformation") ?? false);
if (fileTransformationAssembly != null)
{
Type? pluginInterfaceType = fileTransformationAssembly.GetType("Jellyfin.Plugin.FileTransformation.PluginInterface");
if (pluginInterfaceType != null)
{
foreach (JObject payload in payloads)
{
pluginInterfaceType.GetMethod("RegisterTransformation")?.Invoke(null, new object?[] { payload });
}
_logger.LogInformation("File transformations registered successfully.");
}
else
{
_logger.LogWarning("FileTransformation plugin found but PluginInterface type missing.");
}
}
else
{
_logger.LogWarning("FileTransformation plugin assembly not found. Fallback failed.");
}
}
private void UnregisterFileTransformation()
{
try
{
Assembly? fileTransformationAssembly =
AssemblyLoadContext.All.SelectMany(x => x.Assemblies).FirstOrDefault(x =>
x.FullName?.Contains(".FileTransformation") ?? false);
if (fileTransformationAssembly != null)
{
Type? pluginInterfaceType = fileTransformationAssembly.GetType("Jellyfin.Plugin.FileTransformation.PluginInterface");
if (pluginInterfaceType != null)
{
Guid id = Guid.Parse("0dfac9d7-d898-4944-900b-1c1837707279");
pluginInterfaceType.GetMethod("RemoveTransformation")?.Invoke(null, new object?[] { id });
_logger.LogInformation("File transformation unregistered successfully.");
}
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Error attempting to unregister file transformation. It might not have been registered.");
}
}
}
}

View File

@@ -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
{
/// <summary>
/// Controller for handling custom overlay image uploads and retrieval.
/// </summary>
[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");
}
/// <summary>
/// Uploads a new custom overlay image.
/// </summary>
[HttpPost("OverlayImage")]
[Consumes("multipart/form-data")]
public async Task<IActionResult> 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}");
}
}
/// <summary>
/// Retrieves the custom overlay image.
/// </summary>
[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/*");
}
}
}

View File

@@ -15,12 +15,19 @@ namespace Jellyfin.Plugin.MediaBarEnhanced.Configuration
public int MaxMovies { get; set; } = 15;
public int MaxTvShows { get; set; } = 15;
public int MaxItems { get; set; } = 500;
public int MaxParentalRating { get; set; } = 0;
public int MaxDaysRecent { get; set; } = 0;
public int PreloadCount { get; set; } = 3;
public int FadeTransitionDuration { get; set; } = 500;
public int MaxPaginationDots { get; set; } = 15;
public bool ShowPaginationDots { get; set; } = true;
public bool SlideAnimationEnabled { get; set; } = true;
public bool EnableVideoBackdrop { get; set; } = true;
public bool UseSponsorBlock { get; set; } = true;
public bool PreferLocalTrailers { get; set; } = false;
public bool RandomizeLocalTrailers { get; set; } = false;
public bool PreferLocalBackdrops { get; set; } = false;
public bool RandomizeThemeVideos { get; set; } = false;
public bool WaitForTrailerToEnd { get; set; } = true;
public bool StartMuted { get; set; } = true;
public bool FullWidthVideo { get; set; } = true;
@@ -29,11 +36,23 @@ namespace Jellyfin.Plugin.MediaBarEnhanced.Configuration
public bool EnableLoadingScreen { get; set; } = true;
public bool EnableKeyboardControls { get; set; } = true;
public bool AlwaysShowArrows { get; set; } = false;
public bool HideArrowsOnMobile { get; set; } = true;
public string CustomMediaIds { get; set; } = "";
public bool EnableCustomMediaIds { get; set; } = true;
public string PreferredVideoQuality { get; set; } = "Auto";
public bool EnableSeasonalContent { get; set; } = false;
public bool ExcludeSeasonalContent { get; set; } = true;
public string SeasonalSections { get; set; } = "[]";
public bool IsEnabled { get; set; } = true;
public bool EnableClientSideSettings { get; set; } = false;
public bool ApplyLimitsToCustomIds { get; set; } = false;
public bool IncludeWatchedContent { get; set; } = false;
public string SortBy { get; set; } = "Random";
public string SortOrder { get; set; } = "Ascending";
public bool EnableCustomOverlay { get; set; } = false;
public string CustomOverlayText { get; set; } = "";
public string CustomOverlayImageUrl { get; set; } = "";
public string CustomOverlayStyle { get; set; } = "Shadowed";
}
}

View File

@@ -22,15 +22,15 @@
<hr style="max-width: 800px; margin: 1em 0;">
<div style="margin-bottom: 1.5em;">
<button class="jellyfin-tab-button active" onclick="showTab('basic', this)"
<button class="jellyfin-tab-button active" onclick="showTab('media-bar-enhanced-basic', this)"
style="background: none; border: none; color: #fff; cursor: pointer; transition: color 0.3s, border-bottom 0.3s; padding: 0.5em 1em; border-bottom: 2px solid #00a4dc;">
<h3>General Settings</h3>
</button>
<button class="jellyfin-tab-button" onclick="showTab('custom', this)"
<button class="jellyfin-tab-button" onclick="showTab('media-bar-enhanced-custom', this)"
style="background: none; border: none; color: #ccc; cursor: pointer; transition: color 0.3s, border-bottom 0.3s; padding: 0.5em 1em; border-bottom: 2px solid transparent;">
<h3>Custom Content</h3>
</button>
<button class="jellyfin-tab-button" onclick="showTab('advanced', this)"
<button class="jellyfin-tab-button" onclick="showTab('media-bar-enhanced-advanced', this)"
style="background: none; border: none; color: #ccc; cursor: pointer; transition: color 0.3s, border-bottom 0.3s; padding: 0.5em 1em; border-bottom: 2px solid transparent;">
<h3>Advanced Settings</h3>
</button>
@@ -39,11 +39,12 @@
<form id="mediaBarEnhancedConfigForm">
<!-- BASIC TAB -->
<div id="basic" class="tab-content">
<div id="media-bar-enhanced-basic" class="tab-content">
<h2 class="sectionTitle">Main Plugin Settings</h2>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="IsEnabled" name="IsEnabled" />
<input is="emby-checkbox" type="checkbox" id="MediaBarIsEnabled"
name="MediaBarIsEnabled" />
<span>Enable Media Bar Enhanced Plugin</span>
</label>
<div class="fieldDescription">Enable or disable the entire plugin functionality.</div>
@@ -52,12 +53,32 @@
<label>
<input is="emby-checkbox" type="checkbox" id="EnableVideoBackdrop"
name="EnableVideoBackdrop" />
<span>Enable Video Backdrops</span>
<span>Enable Trailer Backdrops</span>
</label>
<div class="fieldDescription">Show video trailers as background if available.<br>Adds a
<div class="fieldDescription">Show trailers as background if available.<br>Adds a
mute/unmute and pause/play button to control the video in the right top corner.</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<div class="checkboxContainer checkboxContainer-withDescription"
id="PreferLocalTrailersContainer">
<label>
<input is="emby-checkbox" type="checkbox" id="PreferLocalTrailers"
name="PreferLocalTrailers" />
<span>Prefer Local Trailers</span>
</label>
<div class="fieldDescription">If enabled, local trailers will be preferred over remote
(YouTube) trailers.</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription"
id="PreferLocalBackdropsContainer">
<label>
<input is="emby-checkbox" type="checkbox" id="PreferLocalBackdrops"
name="PreferLocalBackdrops" />
<span>Prefer Local Backdrops / Theme Videos</span>
</label>
<div class="fieldDescription">If enabled, local backdrop videos (Theme Videos) will be
preferred over remote and local trailers.</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription" id="WaitForTrailerToEndContainer">
<label>
<input is="emby-checkbox" type="checkbox" id="WaitForTrailerToEnd"
name="WaitForTrailerToEnd" />
@@ -65,11 +86,11 @@
</label>
<div class="fieldDescription">Delay slide transition until trailer finishes.</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<div class="checkboxContainer checkboxContainer-withDescription" id="EnableMobileVideoContainer">
<label>
<input is="emby-checkbox" type="checkbox" id="EnableMobileVideo"
name="EnableMobileVideo" />
<span>Enable Mobile Video</span>
<span>Enable Trailer On Mobile</span>
</label>
<div class="fieldDescription">Allow video playback on mobile devices.</div>
</div>
@@ -79,13 +100,14 @@
name="ShowTrailerButton" />
<span>Show Trailer Button</span>
</label>
<div class="fieldDescription">Display a button to open trailer in modal. Only visible if
trailer is not set as backdrop.</div>
<div class="fieldDescription">Display a button to open trailer in modal. Button only
visible if trailer is not set as backdrop.</div>
</div>
</div>
<!-- CUSTOM CONTENT TAB -->
<div id="custom" class="tab-content" style="display:none;">
<div id="media-bar-enhanced-custom" class="tab-content" style="display:none;">
<!-- Default Custom Media IDs -->
<h2 class="sectionTitle">Custom Media IDs</h2>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
@@ -93,59 +115,159 @@
name="EnableCustomMediaIds" />
<span>Enable Custom Media IDs</span>
</label>
<div class="fieldDescription">If enabled, the slideshow will try to show the items listed
below. If the list is empty, default behavior (random items) is used. Disable this
to temporarily ignore your custom list without deleting it.</div>
<div class="fieldDescription">If enabled, the slideshow will show the items listed
below as the default content. If the list is empty, random items from your library are
used.</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="ApplyLimitsToCustomIds"
name="ApplyLimitsToCustomIds" />
<span>Apply Limits to Custom IDs</span>
</label>
<div class="fieldDescription">If enabled, the Max Items limit (Advanced &rarr; Content
Limits) will also apply to Custom Media IDs and Collections. By default, custom lists
are not limited.</div>
</div>
<div id="customMediaIdsContainer">
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="CustomMediaIds">Default
Media/Collection/Playlist IDs (Newline or Comma-separated)</label>
<textarea class="emby-textarea" is="emby-textarea" id="CustomMediaIds"
name="CustomMediaIds"
style="width: 100%; height: 150px; font-family: monospace;"></textarea>
<div class="fieldDescription">Enter the IDs of the items you want to show in the
slideshow as your default content. You can separate them by new line or comma.
<br><br>
<b>Manual Trailer/Video Override:</b> You can specify a YouTube URL <b>OR</b> a
Jellyfin Item ID (e.g. for a Theme Video) for an item by adding it in
brackets: <br> <code>e.g. ID DESCRIPTION [https://youtu.be/...]</code> or
<code>ID [JellyfinItemId] DESCRIPTION</code>.
<br>
Methods:
<ul>
<li><b>YouTube URL:</b> Play a remote trailer from YouTube.</li>
<li><b>Jellyfin Item ID (GUID):</b> Play the video of another library item (e.g.
a Theme Video or Backdrop Video) using the native player.</li>
</ul>
You can also add a description after the ID using any separator like space, pipe (|)
or dash (-): <br>e.g. <code>ID DESCRIPTION</code> or <code>ID | DESCRIPTION</code>
<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>
<p>You can find the IDs of your items in the URL of the item page in the web
interface.<br>
Example:
<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 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).
</p>
</div>
</div>
<!-- Seasonal Content -->
<h2 class="sectionTitle" style="margin-top: 2em;">Seasonal Content</h2>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="EnableSeasonalContent"
name="EnableSeasonalContent" />
<span>Enable Seasonal Content Mode</span>
<span>Enable Seasonal Content</span>
</label>
<div class="fieldDescription">Enable this to define time-based lists in the field below.
</div>
<div class="fieldDescription">When enabled, seasonal sections below will override the
default list or random selection
during their active date ranges. If no season matches the current date, the default
Custom Media IDs above or random selection are used as fallback.</div>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="CustomMediaIds">Media/Collection/Playlist
IDs
(Newline or Comma separated)</label>
<textarea is="emby-textarea" id="CustomMediaIds" name="CustomMediaIds"
style="width: 100%; height: 150px; font-family: monospace;"></textarea>
<div class="fieldDescription" id="customMediaIdsDesc">Enter the IDs of the items you want to show in the slideshow.
You can separate them by new line or comma.
<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
(|) or dash (-): <br>e.g. <code>ID DESCRIPTION</code> or <code>ID | DESCRIPTION</code>
<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;">
<b>Seasonal Mode Enabled:</b> Define lines with date ranges (Format: DD.MM-DD.MM |
<i>name</i> | <i>IDs</i>).<br>
Example:<br>
<code>20.10-31.10 | Halloween | ID1, ID2 [https://youtu.be/...]</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
fetch the list.txt or use random items.</i>
<div id="seasonalContentContainer" style="display: none;">
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="ExcludeSeasonalContent"
name="ExcludeSeasonalContent" />
<span>Exclude Seasonal Content from Random Lists</span>
</label>
<div class="fieldDescription">When enabled, any items defined in your Seasonal Sections below will be explicitly excluded from being shown when the plugin pulls random items from your library.</div>
</div>
<p>You can find the IDs of your items in the URL of the item page in the web interface.<br>
Example:
<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
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.).
</p>
<div
style="background-color: rgba(255, 255, 255, 0.05); border-left: 4px solid #00a4dc; border-radius: 4px; padding: 1em 1.5em; margin: 1.5em 0; display: flex; align-items: center; gap: 1em;">
<i class="material-icons" style="color: #00a4dc; font-size: 24px;">info</i>
<div>Define seasonal rules to automatically select a selection of items based on the
date. Rules are evaluated from top to bottom. The first matching rule wins.</div>
</div>
<div id="seasonalSectionsList"></div>
<button is="emby-button" type="button" id="addSeasonBtn" class="raised emby-button"
style="margin-top: 1em; display: inline-flex; align-items: center; gap: 0.4em;">
<i class="material-icons" style="font-size: 24px;">add</i>
<span>Add Season</span>
</button>
</div>
<input type="hidden" id="SeasonalSections" name="SeasonalSections" value="[]" />
</div>
<!-- CUSTOM OVERLAY TAB -->
<div id="media-bar-enhanced-overlay" class="tab-content" style="display:none;">
<h2 class="sectionTitle">Custom Slideshow Overlay</h2>
<p>Inject a custom text or floating image over the slideshow. This can be overridden by specific Seasonal Sections in the Custom Filters tab.</p>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="EnableCustomOverlay" name="EnableCustomOverlay" />
<span>Enable Custom Overlay</span>
</label>
<div class="fieldDescription">If enabled, the text or image below will hover over the slideshow globally.</div>
</div>
<div class="selectContainer">
<label class="selectLabel" for="CustomOverlayStyle">Overlay Style</label>
<select is="emby-select" id="CustomOverlayStyle" name="CustomOverlayStyle"
class="selectLayout emby-select-withcolor emby-select"
style="width: 100%; -webkit-appearance: menulist; appearance: menulist;">
<option value="Shadowed">Classic Shadowed</option>
<option value="Frosted">Frosted Glass Pill</option>
<option value="Cinematic">Cinematic Golden Glow</option>
<option value="Pulse">Animated Pulse</option>
</select>
<div class="fieldDescription">Choose the visual styling animation for your custom text.</div>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="CustomOverlayText">Global Overlay Text</label>
<input is="emby-input" type="text" id="CustomOverlayText" name="CustomOverlayText" />
<div class="fieldDescription">Text to display on the overlay (e.g. "Movie Night!"). Leave blank to use an image instead.</div>
</div>
<h3 class="inputLabel" style="margin-top: 2em;">Global Overlay Image</h3>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="CustomOverlayImageUrl">Global Overlay Image URL</label>
<input is="emby-input" type="text" id="CustomOverlayImageUrl" name="CustomOverlayImageUrl" />
<div class="fieldDescription">Absolute URL to an image to display on the overlay. If provided, this overrides the text above.</div>
</div>
<!-- Image Upload Dropzone -->
<div class="inputContainer" style="margin-top: 1em;">
<label class="inputLabel">Or Upload Local Image</label>
<div id="overlayImageDropzone" style="border: 2px dashed rgba(255,255,255,0.2); border-radius: 8px; padding: 2em; text-align: center; cursor: pointer; background: rgba(0,0,0,0.2); transition: all 0.2s ease; position: relative; min-height: 120px; display: flex; flex-direction: column; align-items: center; justify-content: center;">
<i class="material-icons" style="font-size: 40px; color: rgba(255,255,255,0.4); margin-bottom: 10px;">cloud_upload</i>
<span style="font-size: 1.1em; color: rgba(255,255,255,0.7);">Drag and drop an image here, or click to select</span>
<input type="file" id="overlayImageInput" accept="image/png, image/jpeg, image/gif, image/webp" style="display: none;">
<img id="overlayImagePreview" style="display: none; max-width: 100%; max-height: 150px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); border-radius: 4px; z-index: 2;" />
<!-- A semi-transparent overlay to clear the image -->
<button type="button" id="clearOverlayImageBtn" is="paper-icon-button-light" style="display: none; position: absolute; top: 10px; right: 10px; z-index: 3; background: rgba(0,0,0,0.6); border-radius: 50%; padding: 5px;" title="Clear Image">
<i class="material-icons" style="color: white;">close</i>
</button>
</div>
<div class="fieldDescription">Uploading an image will securely save it to the server and automatically update the URL field above.</div>
</div>
</div>
<!-- ADVANCED TAB -->
<div id="advanced" class="tab-content" style="display:none;">
<div id="media-bar-enhanced-advanced" class="tab-content" style="display:none;">
<h2 class="sectionTitle">Features</h2>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
@@ -153,20 +275,51 @@
name="SlideAnimationEnabled" />
<span>Enable Slide Animations</span>
</label>
<div class="fieldDescription">Enable the zooming-in effect when a new slide is
shown. Attention: This may cause performance issues on weaker client hardware.</div>
<div class="fieldDescription">Enable the zooming-in effect on background images when a new
slide is shown (does not affect trailer backdrops). Attention: This may cause
performance issues on weaker client hardware.</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 trailer backdrops) locally on their device.
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="RandomizeThemeVideos"
name="RandomizeThemeVideos" />
<span>Randomize Backdrop Video</span>
</label>
<div class="fieldDescription">If enabled, a random video from the backdrops/theme videos
will be selected instead of the first one (if multiple exist).</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="RandomizeLocalTrailers"
name="RandomizeLocalTrailers" />
<span>Randomize Local Trailer</span>
</label>
<div class="fieldDescription">If enabled, a random local trailer will be selected instead of
the first one (if multiple exist).</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="UseSponsorBlock" name="UseSponsorBlock" />
<span>Use SponsorBlock</span>
</label>
<div class="fieldDescription">Skip intro/outro segments in YouTube trailers.</div>
<div class="fieldDescription">Skip intro/outro segments in YouTube trailers (if data is
available).</div>
</div>
<div class="selectContainer">
<label class="selectLabel" for="PreferredVideoQuality">Preferred YouTube Quality</label>
<select is="emby-select" id="PreferredVideoQuality" name="PreferredVideoQuality"
class="emby-select-withcolor emby-select">
class="selectLayout emby-select-withcolor emby-select"
style="width: 100%; -webkit-appearance: menulist; appearance: menulist;">
<option value="Auto">Auto (Smart)</option>
<option value="Maximum">Maximum (4K+)</option>
<option value="1080p">1080p</option>
@@ -181,7 +334,9 @@
<span>Start Muted</span>
</label>
<div class="fieldDescription">Start trailer video playback muted. (Known issue: In the
Android/IOS app, backdrop trailers are always muted.)</div>
Android/IOS app, backdrop trailers are always muted.)<br>
<b style="color:#ffcc00">Warning:</b> Disabling this may cause autoplay to fail on
certain browsers due to strict autoplay policies.</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
@@ -200,16 +355,23 @@
<span>Enable Loading Screen</span>
</label>
<div class="fieldDescription">Show a loading screen while the slideshow initializes. (You
may have to reload the page twice)</div>
may have to reload the page twice (after changing this setting) to take effect)</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="AlwaysShowArrows"
name="AlwaysShowArrows" />
<span>Always Show Arrows</span>
<span>Always Show Arrow Navigation Buttons</span>
</label>
<div class="fieldDescription">If enabled, navigation arrows will always be visible instead
of only on hover.</div>
<div class="fieldDescription">Force the UI arrow navigation buttons to always be visible instead of only when hovered.</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="HideArrowsOnMobile"
name="HideArrowsOnMobile" />
<span>Hide Arrows on Mobile</span>
</label>
<div class="fieldDescription">Completely disable the navigation arrows on mobile devices (since swiping is available).</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
@@ -221,15 +383,7 @@
Space (pause), M (mute/unmute)) for
the slideshow.</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>
<hr style="max-width: 800px; margin: 1em 0;">
<h2 class="sectionTitle">Time Settings</h2>
<p>Leave a setting blank to use the default value.</p>
@@ -273,6 +427,59 @@
<div class="fieldDescription">Minimum distance in pixels for a swipe to be registered (for
mobile).</div>
</div>
<hr style="max-width: 800px; margin: 1em 0;">
<h2 class="sectionTitle">Content Sorting and Filtering</h2>
<div class="selectContainer">
<label class="selectLabel" for="SortBy">Sort By</label>
<select is="emby-select" id="SortBy" name="SortBy"
class="selectLayout emby-select-withcolor emby-select"
style="width: 100%; -webkit-appearance: menulist; appearance: menulist;">
<option value="Random">Random</option>
<option value="Original">Original (Custom List Order)</option>
<option value="PremiereDate">Premiere Date</option>
<option value="ProductionYear">Production Year</option>
<option value="CriticRating">Critic Rating</option>
<option value="CommunityRating">Community Rating</option>
<option value="Name">Name</option>
<option value="Runtime">Runtime</option>
</select>
<div class="fieldDescription">Sort items by the selected criteria.</div>
</div>
<div class="selectContainer">
<label class="selectLabel" for="SortOrder">Sort Order</label>
<select is="emby-select" id="SortOrder" name="SortOrder"
class="selectLayout emby-select-withcolor emby-select"
style="width: 100%; -webkit-appearance: menulist; appearance: menulist;">
<option value="Ascending">Ascending</option>
<option value="Descending">Descending</option>
</select>
<div class="fieldDescription">Sort items in Ascending or Descending order.</div>
</div>
<div class="fieldDescription" style="margin-bottom: 2em; color: #ffcc00;">
<b>Note:</b> Sorting settings apply to both Server content and Custom IDs. 'Original'
preserves Custom List order.
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="MaxParentalRating">Max Parental Rating (Age Limit)</label>
<input is="emby-input" type="number" id="MaxParentalRating" name="MaxParentalRating" />
<div class="fieldDescription">Items exceeding this age rating will not be shown. Leave blank or set to 0 for no limit. Examples: 12, 16, 18.</div>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="MaxDaysRecent">Max Days Recent</label>
<input is="emby-input" type="number" id="MaxDaysRecent" name="MaxDaysRecent" />
<div class="fieldDescription">Only show items added in the last X days. Leave blank or set to 0 for no limit. Example: 30.</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="IncludeWatchedContent"
name="IncludeWatchedContent" />
<span>Include Watched Content</span>
</label>
<div class="fieldDescription">If enabled, watched content will be included in the random
selection results.</div>
</div>
<hr style="max-width: 800px; margin: 1em 0;">
<h2 class="sectionTitle">Content Limits</h2>
<p>Leave a setting blank to use the default value.</p>
@@ -297,7 +504,16 @@
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="PreloadCount">Preload Count</label>
<input is="emby-input" type="number" id="PreloadCount" name="PreloadCount" />
<div class="fieldDescription">Number of images to preload.</div>
<div class="fieldDescription">Number of slides to preload.</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="ShowPaginationDots"
name="ShowPaginationDots" />
<span>Show Pagination Dots/Counter</span>
</label>
<div class="fieldDescription">Show or hide the pagination dots/counter navigation at the
bottom of the slideshow.</div>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="MaxPaginationDots">Max Pagination
@@ -363,16 +579,28 @@
ApiClient.getPluginConfiguration(MediaBarEnhancedConfigurationPage.pluginId).then(function (config) {
var keys = [
'IsEnabled', 'ShuffleInterval', 'RetryInterval', 'MinSwipeDistance',
'ShuffleInterval', 'RetryInterval', 'MinSwipeDistance',
'LoadingCheckInterval', 'MaxPlotLength', 'MaxMovies', 'MaxTvShows',
'MaxItems', 'PreloadCount', 'FadeTransitionDuration', 'MaxPaginationDots',
'SlideAnimationEnabled', 'EnableVideoBackdrop', 'UseSponsorBlock',
'WaitForTrailerToEnd', 'StartMuted', 'FullWidthVideo', 'EnableMobileVideo',
'ShowTrailerButton', 'AlwaysShowArrows', 'EnableKeyboardControls',
'EnableCustomMediaIds', 'CustomMediaIds', 'EnableLoadingScreen',
'EnableSeasonalContent', 'EnableClientSideSettings'
'EnableSeasonalContent', 'EnableClientSideSettings', 'SortBy', 'SortOrder',
'PreferLocalTrailers', 'ApplyLimitsToCustomIds', 'SeasonalSections',
'PreferLocalBackdrops', 'RandomizeThemeVideos', 'RandomizeLocalTrailers',
'IncludeWatchedContent', 'ShowPaginationDots', 'MaxParentalRating',
'MaxDaysRecent', 'ExcludeSeasonalContent', 'HideArrowsOnMobile',
'EnableCustomOverlay', 'CustomOverlayText', 'CustomOverlayImageUrl',
'CustomOverlayStyle'
];
// Manual mapping for MediaBarIsEnabled -> IsEnabled, to avoid conflicts with other plugins
var mediaBarEnabledCheckbox = page.querySelector('#MediaBarIsEnabled');
if (mediaBarEnabledCheckbox) {
mediaBarEnabledCheckbox.checked = config.IsEnabled;
}
keys.forEach(function (key) {
var el = page.querySelector('#' + key);
if (el) {
@@ -384,42 +612,202 @@
}
});
// Handle Seasonal UI logic
var seasonalCheckbox = page.querySelector('#EnableSeasonalContent');
var normalDesc = page.querySelector('#customMediaIdsDesc');
var seasonalDesc = page.querySelector('#seasonalMediaIdsDesc');
// Render Seasonal Sections
try {
var sections = JSON.parse(config.SeasonalSections || "[]");
MediaBarEnhancedConfigurationPage.renderSeasonalSections(page, sections);
} catch (e) {
console.error("Error parsing SeasonalSections", e);
}
function updateDesc() {
if (seasonalCheckbox && seasonalCheckbox.checked) {
if (normalDesc) normalDesc.style.display = 'none';
if (seasonalDesc) seasonalDesc.style.display = 'block';
} else {
if (normalDesc) normalDesc.style.display = 'block';
if (seasonalDesc) seasonalDesc.style.display = 'none';
// Handle Seasonal UI visibility
var seasonalCheckbox = page.querySelector('#EnableSeasonalContent');
var seasonalContainer = page.querySelector('#seasonalContentContainer');
function updateSeasonalVisibility() {
if (seasonalContainer) {
seasonalContainer.style.display = seasonalCheckbox && seasonalCheckbox.checked ? 'block' : 'none';
}
}
if (seasonalCheckbox) {
seasonalCheckbox.addEventListener('change', updateDesc);
updateDesc();
seasonalCheckbox.addEventListener('change', updateSeasonalVisibility);
updateSeasonalVisibility();
}
// Add Season Button
var addSeasonBtn = page.querySelector('#addSeasonBtn');
if (addSeasonBtn) {
// Remove existing listeners to avoid duplicates if re-attached
var newBtn = addSeasonBtn.cloneNode(true);
addSeasonBtn.parentNode.replaceChild(newBtn, addSeasonBtn);
newBtn.addEventListener('click', function () {
MediaBarEnhancedConfigurationPage.addSeasonalSection(page);
});
}
// Handle Prefer Local Trailers visibility
var enableVideoBackdropCheckbox = page.querySelector('#EnableVideoBackdrop');
var preferLocalContainer = page.querySelector('#PreferLocalTrailersContainer');
var preferLocalBackdropsContainer = page.querySelector('#PreferLocalBackdropsContainer');
var waitForTrailerContainer = page.querySelector('#WaitForTrailerToEndContainer');
var enableMobileVideoContainer = page.querySelector('#EnableMobileVideoContainer');
function updatePreferLocalVisibility() {
if (enableVideoBackdropCheckbox && enableVideoBackdropCheckbox.checked) {
if (preferLocalContainer) preferLocalContainer.style.display = 'block';
if (preferLocalBackdropsContainer) preferLocalBackdropsContainer.style.display = 'block';
if (waitForTrailerContainer) waitForTrailerContainer.style.display = 'block';
if (enableMobileVideoContainer) enableMobileVideoContainer.style.display = 'block';
} else {
if (preferLocalContainer) preferLocalContainer.style.display = 'none';
if (preferLocalBackdropsContainer) preferLocalBackdropsContainer.style.display = 'none';
if (waitForTrailerContainer) waitForTrailerContainer.style.display = 'none';
if (enableMobileVideoContainer) enableMobileVideoContainer.style.display = 'none';
}
}
if (enableVideoBackdropCheckbox) {
enableVideoBackdropCheckbox.addEventListener('change', updatePreferLocalVisibility);
updatePreferLocalVisibility();
}
// Overlay Image Upload Logic
var dropzone = page.querySelector('#overlayImageDropzone');
var fileInput = page.querySelector('#overlayImageInput');
var urlInput = page.querySelector('#CustomOverlayImageUrl');
var previewImg = page.querySelector('#overlayImagePreview');
var clearBtn = page.querySelector('#clearOverlayImageBtn');
function updatePreview() {
if (urlInput.value && urlInput.value.trim() !== '') {
previewImg.src = urlInput.value;
previewImg.style.display = 'block';
clearBtn.style.display = 'block';
} else {
previewImg.style.display = 'none';
clearBtn.style.display = 'none';
}
}
// Initial check
updatePreview();
// Listen to manual URL input changes
urlInput.addEventListener('input', updatePreview);
clearBtn.addEventListener('click', function(e) {
e.stopPropagation(); // prevent triggering file dialog
urlInput.value = '';
fileInput.value = '';
updatePreview();
});
dropzone.addEventListener('click', function() {
fileInput.click();
});
dropzone.addEventListener('dragover', function(e) {
e.preventDefault();
dropzone.style.borderColor = '#00a4dc';
dropzone.style.background = 'rgba(0, 164, 220, 0.2)';
});
dropzone.addEventListener('dragleave', function(e) {
e.preventDefault();
dropzone.style.borderColor = 'rgba(255,255,255,0.2)';
dropzone.style.background = 'rgba(0,0,0,0.2)';
});
dropzone.addEventListener('drop', function(e) {
e.preventDefault();
dropzone.style.borderColor = 'rgba(255,255,255,0.2)';
dropzone.style.background = 'rgba(0,0,0,0.2)';
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
fileInput.files = e.dataTransfer.files;
uploadImage(e.dataTransfer.files[0]);
}
});
fileInput.addEventListener('change', function() {
if (this.files && this.files.length > 0) {
uploadImage(this.files[0]);
}
});
function uploadImage(file) {
// Validate it's an image
if (!file.type.match('image.*')) {
Dashboard.alert('Please select a valid image file.');
return;
}
Dashboard.showLoadingMsg();
var formData = new FormData();
formData.append('file', file);
// The Endpoint we created in C#
fetch(ApiClient.serverAddress() + '/MediaBarEnhanced/OverlayImage', {
method: 'POST',
body: formData,
headers: {
'Authorization': 'MediaBrowser Client="' + ApiClient.appName() + '", Device="' + ApiClient.deviceName() + '", DeviceId="' + ApiClient.deviceId() + '", Version="' + ApiClient.appVersion() + '", Token="' + ApiClient.accessToken() + '"'
}
})
.then(response => {
if (response.ok) return response.json();
throw new Error('Network response was not ok.');
})
.then(data => {
// Update URL input
urlInput.value = ApiClient.serverAddress() + data.url;
updatePreview();
Dashboard.hideLoadingMsg();
})
.catch(error => {
console.error('Upload error:', error);
Dashboard.alert('Image upload failed. Please verify API controller is active.');
Dashboard.hideLoadingMsg();
});
}
Dashboard.hideLoadingMsg();
});
},
saveConfiguration: function (page) {
Dashboard.showLoadingMsg();
var sections = MediaBarEnhancedConfigurationPage.getSeasonalSectionsFromUI(page);
var sectionsJson = JSON.stringify(sections);
var seasonalInput = page.querySelector('#SeasonalSections');
if (seasonalInput) seasonalInput.value = sectionsJson;
var config = {};
// Manual mapping for MediaBarIsEnabled -> IsEnabled, to avoid conflicts with other plugins
var mediaBarEnabledCheckbox = page.querySelector('#MediaBarIsEnabled');
if (mediaBarEnabledCheckbox) {
config.IsEnabled = mediaBarEnabledCheckbox.checked;
}
var keys = [
'IsEnabled', 'ShuffleInterval', 'RetryInterval', 'MinSwipeDistance',
'ShuffleInterval', 'RetryInterval', 'MinSwipeDistance',
'LoadingCheckInterval', 'MaxPlotLength', 'MaxMovies', 'MaxTvShows',
'MaxItems', 'PreloadCount', 'FadeTransitionDuration', 'MaxPaginationDots',
'SlideAnimationEnabled', 'EnableVideoBackdrop', 'UseSponsorBlock',
'WaitForTrailerToEnd', 'StartMuted', 'FullWidthVideo', 'EnableMobileVideo',
'ShowTrailerButton', 'AlwaysShowArrows', 'EnableKeyboardControls',
'EnableCustomMediaIds', 'CustomMediaIds', 'EnableLoadingScreen',
'EnableSeasonalContent', 'EnableClientSideSettings'
'EnableSeasonalContent', 'EnableClientSideSettings', 'SortBy', 'SortOrder',
'PreferLocalTrailers', 'ApplyLimitsToCustomIds', 'SeasonalSections',
'PreferLocalBackdrops', 'RandomizeThemeVideos', 'RandomizeLocalTrailers',
'IncludeWatchedContent', 'ShowPaginationDots', 'MaxParentalRating',
'MaxDaysRecent', 'ExcludeSeasonalContent', 'HideArrowsOnMobile',
'EnableCustomOverlay', 'CustomOverlayText', 'CustomOverlayImageUrl',
'CustomOverlayStyle'
];
keys.forEach(function (key) {
@@ -436,6 +824,146 @@
ApiClient.updatePluginConfiguration(MediaBarEnhancedConfigurationPage.pluginId, config).then(function (result) {
Dashboard.processPluginConfigurationUpdateResult(result);
});
},
renderSeasonalSections: function (page, sections) {
var container = page.querySelector('#seasonalSectionsList');
if (!container) return;
container.innerHTML = '';
sections.forEach(function (section, index) {
MediaBarEnhancedConfigurationPage.createSectionElement(container, section, index + 1);
});
},
addSeasonalSection: function (page) {
var container = page.querySelector('#seasonalSectionsList');
if (!container) return;
var index = container.children.length + 1;
MediaBarEnhancedConfigurationPage.createSectionElement(container, {
Name: 'New Season',
StartDay: 1, StartMonth: 1,
EndDay: 1, EndMonth: 1,
MediaIds: '',
OverlayText: '',
OverlayImageUrl: ''
}, index);
},
createSectionElement: function (container, data, index) {
var div = document.createElement('div');
div.className = 'seasonal-section';
div.style.cssText = 'background: rgba(0,0,0,0.2); padding: 1em; margin-bottom: 1em; border-radius: 4px; border: 1px solid rgba(255,255,255,0.1);';
var days = [];
for (var i = 1; i <= 31; i++) days.push(i);
var months = [
{ v: 1, n: 'Jan' }, { v: 2, n: 'Feb' }, { v: 3, n: 'Mar' }, { v: 4, n: 'Apr' },
{ v: 5, n: 'May' }, { v: 6, n: 'Jun' }, { v: 7, n: 'Jul' }, { v: 8, n: 'Aug' },
{ v: 9, n: 'Sep' }, { v: 10, n: 'Oct' }, { v: 11, n: 'Nov' }, { v: 12, n: 'Dec' }
];
function mkSelect(val, opts, cls) {
var h = '<select class="emby-select emby-select-withcolor ' + cls + '" style="width: auto; display: inline-block; margin-right: 5px; -webkit-appearance: menulist; appearance: menulist;">';
opts.forEach(function (o) {
var v = o.v || o;
var n = o.n || o;
h += '<option value="' + v + '" ' + (v == val ? 'selected' : '') + '>' + n + '</option>';
});
h += '</select>';
return h;
}
var labelText = 'Season list #' + (index || 1);
div.innerHTML =
'<div class="inputContainer" style="margin-bottom: 0.5em;">' +
' <div style="display: flex; align-items: center; justify-content: space-between;">' +
' <label class="inputLabel section-title" style="font-size: 1.2em; font-weight: bold; margin-bottom:0.5em; display:block;">' + labelText + '</label>' +
' <div style="display: flex; gap: 0.5em;">' +
' <button type="button" is="paper-icon-button-light" class="btn-move-up" title="Move Up"><i class="material-icons">arrow_upward</i></button>' +
' <button type="button" is="paper-icon-button-light" class="btn-move-down" title="Move Down"><i class="material-icons">arrow_downward</i></button>' +
' <button type="button" is="paper-icon-button-light" class="btn-remove" title="Remove" style="color: #a94442;"><i class="material-icons">delete</i></button>' +
' </div>' +
' </div>' +
' <div class="inputContainer">' +
' <input is="emby-input" type="text" class="emby-input section-name" style="width: 60%;" value="' + (data.Name || '') + '" />' +
' <div class="fieldDescription">Name of the season</div>' +
' </div>' +
'</div>' +
'<div class="inputContainer" style="margin-bottom: 1em;">' +
' <label class="inputLabel" style="margin-bottom:0.5em; display:block;">Active Period</label>' +
' <div style="display: flex; align-items: center; flex-wrap: wrap; gap: 0.5em;">' +
' <span>From:</span>' +
mkSelect(data.StartDay, days, 'start-day') +
mkSelect(data.StartMonth, months, 'start-month') +
' <span style="margin-left: 1em;">To:</span>' +
mkSelect(data.EndDay, days, 'end-day') +
mkSelect(data.EndMonth, months, 'end-month') +
' </div>' +
' <div class="fieldDescription">Date range (inclusive) when this content is active.</div>' +
'</div>' +
'<div class="inputContainer">' +
' <label class="inputLabel" style="margin-bottom:0.5em; display:block;">Media IDs</label>' +
' <textarea is="emby-textarea" class="emby-textarea section-ids" style="width: 100%; height: 80px; font-family: monospace;">' + (data.MediaIds || '') + '</textarea>' +
' <div class="fieldDescription">Comma-separated or Newline separated list of Movie/Series/Collection IDs to show during this season.<br>Same options available as for the default media IDs.</div>' +
'</div>' +
'<div class="inputContainer" style="margin-top: 1em;">' +
' <input is="emby-input" type="text" class="emby-input section-overlay-text" style="width: 100%;" value="' + (data.OverlayText ? data.OverlayText.replace(/"/g, '&quot;') : '') + '" placeholder="Seasonal Custom Overlay Text (e.g. Oscars Time!)" />' +
' <div class="fieldDescription">Optional: Override the global custom overlay text during this season.</div>' +
'</div>' +
'<div class="inputContainer">' +
' <input is="emby-input" type="text" class="emby-input section-overlay-image" style="width: 100%;" value="' + (data.OverlayImageUrl ? data.OverlayImageUrl.replace(/"/g, '&quot;') : '') + '" placeholder="Seasonal Custom Overlay Image URL" />' +
' <div class="fieldDescription">Optional: Override the global custom overlay image during this season. Overrides the text if provided.</div>' +
'</div>';
div.querySelector('.btn-remove').addEventListener('click', function () {
div.remove();
MediaBarEnhancedConfigurationPage.updateSectionTitles(container);
});
div.querySelector('.btn-move-up').addEventListener('click', function () {
if (div.previousElementSibling) {
container.insertBefore(div, div.previousElementSibling);
MediaBarEnhancedConfigurationPage.updateSectionTitles(container);
}
});
div.querySelector('.btn-move-down').addEventListener('click', function () {
if (div.nextElementSibling) {
container.insertBefore(div.nextElementSibling, div);
MediaBarEnhancedConfigurationPage.updateSectionTitles(container);
}
});
container.appendChild(div);
},
updateSectionTitles: function (container) {
var sections = container.querySelectorAll('.seasonal-section');
sections.forEach(function (section, index) {
var title = section.querySelector('.section-title');
if (title) {
title.innerText = 'Season list #' + (index + 1);
}
});
},
getSeasonalSectionsFromUI: function (page) {
var sections = [];
var els = page.querySelectorAll('.seasonal-section');
els.forEach(function (el) {
sections.push({
Name: el.querySelector('.section-name').value,
StartDay: parseInt(el.querySelector('.start-day').value),
StartMonth: parseInt(el.querySelector('.start-month').value),
EndDay: parseInt(el.querySelector('.end-day').value),
EndMonth: parseInt(el.querySelector('.end-month').value),
MediaIds: el.querySelector('.section-ids').value,
OverlayText: el.querySelector('.section-overlay-text').value,
OverlayImageUrl: el.querySelector('.section-overlay-image').value
});
});
return sections;
}
};

View File

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

View File

@@ -18,8 +18,8 @@ namespace Jellyfin.Plugin.MediaBarEnhanced
{
private readonly IApplicationPaths _appPaths;
private readonly ILogger<ScriptInjector> _logger;
public const string ScriptTag = "<script src=\"/MediaBarEnhanced/Resources/mediaBarEnhanced.js\" defer></script>";
public const string CssTag = "<link rel=\"stylesheet\" href=\"/MediaBarEnhanced/Resources/mediaBarEnhanced.css\" />";
public const string ScriptTag = "<script src=\"../MediaBarEnhanced/Resources/mediaBarEnhanced.js\" defer></script>";
public const string CssTag = "<link rel=\"stylesheet\" href=\"../MediaBarEnhanced/Resources/mediaBarEnhanced.css\" />";
public const string ScriptMarker = "</body>";
public const string CssMarker = "</head>";
@@ -60,6 +60,11 @@ namespace Jellyfin.Plugin.MediaBarEnhanced
var content = File.ReadAllText(indexPath);
var injectedJS = false;
var injectedCSS = false;
var modified = false;
// Cleanup legacy tags first to avoid duplicates or conflicts
content = RemoveLegacyTags(content, ref modified);
if (!content.Contains(ScriptTag))
{
@@ -81,19 +86,26 @@ namespace Jellyfin.Plugin.MediaBarEnhanced
}
}
if (injectedJS && injectedCSS)
if (injectedJS || injectedCSS || modified)
{
File.WriteAllText(indexPath, content);
_logger.LogInformation("MediaBarEnhanced script injected into index.html.");
} else if (injectedJS)
{
File.WriteAllText(indexPath, content);
_logger.LogInformation("MediaBarEnhanced JS script injected into index.html. But CSS was already present or could not be injected.");
}
else if (injectedCSS)
{
File.WriteAllText(indexPath, content);
_logger.LogInformation("MediaBarEnhanced CSS injected into index.html. But JS script was already present or could not be injected.");
if (injectedJS && injectedCSS)
{
_logger.LogInformation("MediaBarEnhanced script injected into index.html.");
}
else if (injectedJS)
{
_logger.LogInformation("MediaBarEnhanced JS script injected into index.html. But CSS was already present or could not be injected.");
}
else if (injectedCSS)
{
_logger.LogInformation("MediaBarEnhanced CSS injected into index.html. But JS script was already present or could not be injected.");
}
else
{
_logger.LogInformation("MediaBarEnhanced script and CSS already present. Legacy tags removed if found.");
}
}
else
{
@@ -148,6 +160,9 @@ namespace Jellyfin.Plugin.MediaBarEnhanced
modified = true;
}
// Remove legacy tags
content = RemoveLegacyTags(content, ref modified);
if (modified)
{
File.WriteAllText(indexPath, content);
@@ -242,5 +257,33 @@ namespace Jellyfin.Plugin.MediaBarEnhanced
_logger.LogWarning(ex, "Error attempting to unregister file transformation. It might not have been registered.");
}
}
/// <summary>
/// Removes legacy script and css tags from the content.
/// </summary>
/// <param name="content">The file content.</param>
/// <param name="modified">Ref bool to track if changes were made.</param>
/// <returns>The modified content.</returns>
private string RemoveLegacyTags(string content, ref bool modified)
{
// Legacy tags (used in versions prior to 1.6.3.0 where paths started with / instead of ../)
const string LegacyScriptTag = "<script src=\"/MediaBarEnhanced/Resources/mediaBarEnhanced.js\" defer></script>";
const string LegacyCssTag = "<link rel=\"stylesheet\" href=\"/MediaBarEnhanced/Resources/mediaBarEnhanced.css\" />";
if (content.Contains(LegacyScriptTag))
{
content = content.Replace(LegacyScriptTag + Environment.NewLine, "").Replace(LegacyScriptTag, "");
modified = true;
_logger.LogInformation("Legacy MediaBarEnhanced script tag removed.");
}
if (content.Contains(LegacyCssTag))
{
content = content.Replace(LegacyCssTag + Environment.NewLine, "").Replace(LegacyCssTag, "");
modified = true;
_logger.LogInformation("Legacy MediaBarEnhanced CSS tag removed.");
}
return content;
}
}
}

View File

@@ -0,0 +1,66 @@
<?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 661 614"
enable-background="new 0 0 661 614"
xml:space="preserve"
sodipodi:docname="logo.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="defs6" /><sodipodi:namedview
id="namedview6"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="1.3925081"
inkscape:cx="330.33918"
inkscape:cy="307"
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=" M327.000000,536.000000 C342.496460,536.000000 357.498688,536.258484 372.487610,535.922241 C385.664062,535.626770 398.866150,535.102905 411.983582,533.888245 C428.681671,532.341858 445.408508,530.610413 461.935608,527.840759 C481.796478,524.512451 501.467499,520.042786 521.199707,515.965698 C523.529053,515.484375 526.041382,514.803894 527.927551,513.457397 C534.700745,508.622009 542.319885,508.932159 550.045410,508.959991 C578.189880,509.061340 606.334900,509.000000 634.740234,509.000000 C637.186890,520.472595 639.957642,531.779480 636.933289,543.351501 C634.903503,551.117737 628.718933,555.934631 622.355957,559.773132 C608.164856,568.333984 592.050842,571.987366 576.187866,575.886841 C559.302490,580.037537 542.257751,583.610168 525.170837,586.844788 C514.799194,588.808228 504.204498,589.571716 493.731018,591.025574 C485.218262,592.207336 476.759888,593.799255 468.234467,594.866150 C460.604767,595.821045 452.927185,596.476501 445.251709,596.965637 C427.840851,598.075317 410.418152,598.998474 393.000580,600.003540 C387.415436,600.325806 381.835144,600.855774 376.246216,600.966370 C355.166992,601.383362 334.085815,601.853882 313.004028,601.930115 C300.255890,601.976196 287.500092,601.463989 274.757141,600.963013 C262.081879,600.464600 249.388809,600.007324 236.757446,598.910950 C221.974625,597.627930 207.229050,595.838806 192.505737,593.967224 C175.589020,591.816711 158.624741,589.840515 141.845245,586.863647 C122.976410,583.516113 104.227318,579.411011 85.549820,575.099731 C74.786339,572.615234 64.115028,569.507751 53.686581,565.866333 C45.305603,562.939758 36.992039,559.384155 30.888775,552.377869 C23.703732,544.129883 24.449305,534.207397 25.353891,524.421143 C25.793415,519.666260 27.276276,515.007690 28.352476,510.000000 C31.826927,510.000000 35.304031,510.000000 38.781136,510.000000 C64.774979,510.000000 90.768852,509.977386 116.762634,510.017090 C122.732361,510.026184 128.391159,510.172974 134.351212,512.686401 C143.412094,516.507568 153.202728,518.885010 162.889816,520.866455 C176.838547,523.719727 190.930084,525.975830 205.039062,527.917175 C219.893982,529.961182 234.816391,531.620972 249.755615,532.913391 C262.386749,534.006165 275.078796,534.468628 287.753540,534.962585 C300.662903,535.465698 313.584015,535.666687 327.000000,536.000000 z"
id="path2" />
<path
fill="#FFFFFF"
opacity="1.000000"
stroke="none"
d=" M606.999634,140.000000 C616.128296,140.706787 625.146667,140.066467 633.298218,142.423615 C646.862671,146.345963 654.950256,156.523895 657.932922,170.401443 C658.647095,173.724014 658.955444,177.196487 658.957458,180.600327 C659.010925,271.765411 659.009338,362.930511 658.991943,454.095612 C658.988525,471.780304 647.686096,487.160645 629.451294,490.947906 C626.281982,491.606171 622.988159,491.957306 619.751709,491.958099 C427.255005,492.004913 234.758301,491.987091 42.261608,492.021698 C24.730577,492.024841 8.072522,479.153046 5.027515,461.896179 C4.492155,458.862152 4.043763,455.761963 4.042027,452.692047 C3.990298,361.193634 3.871316,269.694855 4.104546,178.197021 C4.153368,159.043365 16.296051,146.063629 33.331520,141.092468 C36.402164,140.196411 39.775433,140.042984 43.009106,140.042160 C230.839310,139.994934 418.669525,140.000000 606.999634,140.000000 M359.500000,157.000000 C289.517120,157.000000 219.534225,157.000000 149.551346,157.000000 C114.893280,157.000000 80.235199,156.980255 45.577160,157.011627 C34.607761,157.021545 24.557083,164.368423 22.403088,174.518036 C21.314177,179.648972 21.059866,185.035080 21.055122,190.306381 C20.977442,276.618225 21.132351,362.930573 20.868862,449.241699 C20.825279,463.518036 31.508949,474.175995 45.628529,474.158508 C236.414246,473.922333 427.200470,473.908447 617.986023,474.208954 C630.511597,474.228729 642.140198,463.677826 642.108398,450.146484 C641.898560,360.835785 642.000916,271.524384 641.999146,182.213196 C641.998840,166.797821 632.262817,157.001709 616.936340,157.001236 C531.457581,156.998657 445.978790,157.000000 359.500000,157.000000 z"
id="path3" />
<path
fill="#FFFFFF"
opacity="1.000000"
stroke="none"
d=" M410.281616,93.782341 C415.291992,100.787689 420.140594,107.470741 424.713318,114.337517 C425.884766,116.096649 426.184479,118.436256 426.884674,120.509186 C424.913452,121.006126 422.942780,121.934616 420.970886,121.937248 C363.000671,122.014679 305.030334,122.011337 247.060028,121.969559 C243.859818,121.967247 240.659912,121.524078 236.054047,121.181580 C238.077652,116.962379 239.199081,113.266785 241.360825,110.339432 C254.448532,92.616531 267.699677,75.012611 281.049347,57.485538 C288.331970,47.924042 295.607147,38.325375 303.457062,29.236992 C310.346344,21.260773 318.726776,14.498528 329.750397,14.243196 C337.574341,14.061975 345.864899,15.756383 351.433380,22.105671 C364.247803,36.716980 376.755737,51.604027 389.124115,66.596909 C396.351105,75.357414 403.069855,84.537186 410.281616,93.782341 z"
id="path4" />
<path
fill="#B9B9B9"
opacity="1.000000"
stroke="none"
d=" M360.000000,157.000000 C445.978790,157.000000 531.457581,156.998657 616.936340,157.001236 C632.262817,157.001709 641.998840,166.797821 641.999146,182.213196 C642.000916,271.524384 641.898560,360.835785 642.108398,450.146484 C642.140198,463.677826 630.511597,474.228729 617.986023,474.208954 C427.200470,473.908447 236.414246,473.922333 45.628529,474.158508 C31.508949,474.175995 20.825279,463.518036 20.868862,449.241699 C21.132351,362.930573 20.977442,276.618225 21.055122,190.306381 C21.059866,185.035080 21.314177,179.648972 22.403088,174.518036 C24.557083,164.368423 34.607761,157.021545 45.577160,157.011627 C80.235199,156.980255 114.893280,157.000000 149.551346,157.000000 C219.534225,157.000000 289.517120,157.000000 360.000000,157.000000 M265.000000,302.500000 C265.000000,329.638916 264.986816,356.777832 265.030060,383.916656 C265.032898,385.700653 265.134369,387.610443 265.756378,389.246338 C268.897522,397.507599 276.467865,400.490845 284.746582,395.464508 C301.954895,385.016602 318.697327,373.801392 335.631592,362.902100 C353.537262,351.377533 371.500580,339.941193 389.328918,328.298248 C400.978180,320.690613 400.993195,311.320953 389.382721,303.731628 C365.885529,288.372528 342.291901,273.160889 318.730255,257.900482 C307.365387,250.539673 296.161346,242.908707 284.556580,235.946579 C273.636658,229.395309 265.002625,234.531113 265.000702,247.055817 C264.997925,265.203888 265.000000,283.351929 265.000000,302.500000 z"
id="path5" />
<path
fill="#FFFFFF"
opacity="1.000000"
stroke="none"
d=" M265.000000,302.000000 C265.000000,283.351929 264.997925,265.203888 265.000702,247.055817 C265.002625,234.531113 273.636658,229.395309 284.556580,235.946579 C296.161346,242.908707 307.365387,250.539673 318.730255,257.900482 C342.291901,273.160889 365.885529,288.372528 389.382721,303.731628 C400.993195,311.320953 400.978180,320.690613 389.328918,328.298248 C371.500580,339.941193 353.537262,351.377533 335.631592,362.902100 C318.697327,373.801392 301.954895,385.016602 284.746582,395.464508 C276.467865,400.490845 268.897522,397.507599 265.756378,389.246338 C265.134369,387.610443 265.032898,385.700653 265.030060,383.916656 C264.986816,356.777832 265.000000,329.638916 265.000000,302.000000 z"
id="path6" />
</svg>

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@@ -0,0 +1,90 @@
<?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 1039 614"
enable-background="new 0 0 1039 614"
xml:space="preserve"
sodipodi:docname="MediaBar_logo_SW_mono_SHORT.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="defs10" /><sodipodi:namedview
id="namedview10"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="0.98465195"
inkscape:cx="383.3842"
inkscape:cy="268.62284"
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=" M215.230072,518.448547 C216.097900,515.443542 216.766510,512.833374 217.492325,510.000000 C245.648331,510.000000 273.793915,510.000000 301.939484,510.000000 C302.939331,510.000000 303.955444,510.117462 304.936493,509.981628 C313.343964,508.817383 320.674316,511.954315 328.378204,514.797546 C337.342743,518.106018 346.869507,520.088257 356.294983,521.906006 C371.867737,524.909302 387.508484,527.647339 403.209564,529.868103 C414.376190,531.447510 425.675507,532.195068 436.940094,532.947632 C450.260864,533.837524 463.601135,534.604797 476.945160,534.939026 C499.188751,535.496155 521.441528,535.867615 543.691467,535.929138 C558.440735,535.969788 573.226501,535.846863 587.932678,534.857544 C603.060181,533.839905 618.131775,531.848083 633.189392,529.973938 C647.529541,528.189148 661.894775,526.424377 676.112915,523.888184 C692.549683,520.956238 709.140747,518.246887 724.096924,510.011292 C725.304810,509.346222 726.865112,509.043365 728.262390,509.041016 C759.918213,508.987732 791.574036,509.000031 823.689392,509.000031 C826.219116,520.269714 828.853699,531.504944 825.976807,543.085388 C823.978455,551.129578 817.664246,555.932556 811.155334,559.864441 C798.097412,567.752258 783.349731,571.421509 768.683411,574.911438 C753.177429,578.601196 737.558228,581.845886 721.920593,584.941956 C710.332214,587.236267 698.673035,589.250488 686.976013,590.896667 C675.032043,592.577637 663.003235,593.655762 651.011902,595.000488 C639.175720,596.327820 627.352295,597.784241 615.499207,598.937012 C609.108643,599.558533 602.671326,599.774353 596.248901,599.976440 C583.167419,600.388245 570.083069,600.730896 556.997620,600.985046 C536.915833,601.375183 516.833008,601.840393 496.749054,601.931274 C485.666565,601.981384 474.576111,601.445251 463.497986,600.969482 C450.989288,600.432373 438.468353,599.937683 425.993683,598.921692 C414.128784,597.955383 402.311890,596.381531 390.482666,594.999573 C376.571899,593.374573 362.627686,591.959412 348.777679,589.913574 C335.662842,587.976318 322.697510,585.027222 309.582977,583.087280 C290.888214,580.321899 272.677460,575.598938 254.744934,569.879639 C245.490875,566.928101 236.261154,563.377563 227.757507,558.744751 C219.453522,554.220642 213.865524,546.819397 214.043716,536.577576 C214.146606,530.662292 214.687256,524.754578 215.230072,518.448547 z"
id="path2" />
<path
fill="#C8C8C8"
opacity="1.000000"
stroke="none"
d=" M174.078720,187.882538 C174.385803,189.408966 174.960938,190.935257 174.961624,192.461823 C174.999268,276.011963 174.988754,359.562103 174.453644,443.563446 C129.277191,444.009735 84.630196,444.013519 39.983231,443.993744 C29.198257,443.988983 21.325663,436.491302 21.028820,425.828705 C20.864725,419.934387 20.999969,414.031769 20.999973,408.132874 C21.000015,346.326721 21.001759,284.520538 20.990532,222.714386 C20.990231,221.055740 20.676064,219.383453 20.805677,217.740997 C21.238888,212.251480 20.492048,206.188721 22.610405,201.416809 C26.479988,192.699936 34.791191,189.113480 44.038651,189.075058 C85.519699,188.902679 127.001884,189.014496 168.483551,188.952637 C170.349152,188.949860 172.213684,188.255020 174.078720,187.882538 z"
id="path3" />
<path
fill="#CACACA"
opacity="1.000000"
stroke="none"
d=" M866.159912,444.043640 C866.106628,442.882202 866.006592,441.720764 866.006592,440.559326 C866.004822,357.335419 866.010986,274.111511 866.546448,190.436707 C911.044739,189.990524 955.013000,189.989151 998.981323,190.020020 C1000.956421,190.021408 1003.010071,190.019989 1004.893005,190.522461 C1014.309570,193.035324 1019.999939,200.675659 1019.999939,210.526749 C1020.000000,281.309113 1019.990295,352.091492 1020.009766,422.873871 C1020.012939,434.589478 1011.696716,444.366974 999.061157,444.213806 C954.766541,443.676971 910.461243,444.029114 866.159912,444.043640 z"
id="path4" />
<path
fill="#FFFFFF"
opacity="1.000000"
stroke="none"
d=" M642.000000,492.000000 C504.668976,492.000000 367.837982,492.007538 231.006973,491.990753 C213.329834,491.988586 197.742874,479.343262 194.068604,462.633972 C193.339264,459.317200 193.044693,455.840637 193.042694,452.437439 C192.989120,360.939026 192.856583,269.440186 193.117493,177.942459 C193.171539,158.983154 205.450027,145.812973 222.583267,141.079895 C225.673691,140.226166 229.030045,140.042664 232.263763,140.041870 C424.427155,139.995071 616.590576,140.032379 808.753967,139.947617 C827.057373,139.939545 843.486572,152.051819 846.960083,170.650864 C847.555481,173.839096 847.955994,177.117783 847.957886,180.354980 C848.010376,271.520081 847.995483,362.685181 848.003906,453.850311 C848.005554,471.728851 836.792358,486.961578 818.693909,490.930542 C815.376343,491.658081 811.900452,491.952789 808.497070,491.956573 C753.164734,492.017883 697.832397,492.000000 642.000000,492.000000 M408.500000,474.000000 C541.155823,474.000000 673.812073,473.849609 806.466797,474.234650 C819.614380,474.272797 831.175842,463.575836 831.134583,449.658783 C830.870544,360.666779 830.931946,271.673523 831.064148,182.680923 C831.087341,167.063034 820.378662,156.888992 805.397217,156.900894 C615.746033,157.051605 426.094727,157.000000 236.443451,157.000046 C235.443527,157.000046 234.429825,156.892563 233.445816,157.017914 C222.831177,158.369949 214.189850,163.378632 211.540894,174.189514 C210.374725,178.948914 210.065567,184.018188 210.060806,188.947449 C209.976807,275.940308 209.998886,362.933258 210.001083,449.926208 C210.001450,464.527679 219.366562,473.994415 233.819275,473.998169 C259.048828,474.004730 284.278412,474.000000 309.507965,474.000000 C342.171967,474.000000 374.835999,474.000000 408.500000,474.000000 z"
id="path5" />
<path
fill="#FFFFFF"
opacity="1.000000"
stroke="none"
d=" M470.999268,56.008606 C478.080780,46.904430 484.917328,37.975853 492.243896,29.469269 C499.274078,21.306780 507.730499,14.547179 518.938110,14.236814 C526.245911,14.034445 534.043579,15.664103 539.490784,21.206964 C547.066956,28.916189 554.111450,37.174259 561.055176,45.472176 C569.831726,55.960323 578.543762,66.523552 586.798096,77.422142 C596.652222,90.432991 605.991638,103.833656 615.555847,117.064087 C617.796204,120.163223 615.770142,121.274780 613.182678,121.957214 C612.247803,122.203773 611.193848,121.999855 610.194275,121.999855 C550.384399,122.000015 490.574524,122.000038 430.764648,121.999641 C429.598450,121.999634 428.321289,122.302048 427.288483,121.929474 C424.932068,121.079414 423.416840,119.791931 425.460999,117.011757 C439.162445,98.377037 452.780548,79.681015 466.488373,61.051033 C467.757965,59.325569 469.464752,57.921833 470.999268,56.008606 z"
id="path6" />
<path
fill="#FFFFFF"
opacity="1.000000"
stroke="none"
d=" M866.085632,444.503815 C910.461243,444.029114 954.766541,443.676971 999.061157,444.213806 C1011.696716,444.366974 1020.012939,434.589478 1020.009766,422.873871 C1019.990295,352.091492 1020.000000,281.309113 1019.999939,210.526749 C1019.999939,200.675659 1014.309570,193.035324 1004.893005,190.522461 C1003.010071,190.019989 1000.956421,190.021408 998.981323,190.020020 C955.013000,189.989151 911.044739,189.990524 866.618164,189.970871 C866.159912,185.154236 866.159912,180.352509 866.159912,175.219986 C867.653748,175.144806 869.092346,175.009506 870.530884,175.009140 C914.169250,174.997925 957.808472,174.851959 1001.445618,175.084991 C1015.605042,175.160599 1025.345459,182.384720 1032.258301,194.884445 C1035.300171,200.384384 1034.944214,205.512314 1034.949707,210.926346 C1035.024414,285.044891 1034.976929,359.163574 1035.034058,433.282135 C1035.040161,441.160797 1030.435303,446.713684 1025.517456,451.668091 C1017.754089,459.489075 1007.615479,461.114532 996.880737,461.070099 C955.241760,460.897766 913.601685,461.000000 871.961975,461.000000 C870.155457,461.000000 868.348877,461.000000 866.011292,461.000000 C866.011292,455.499420 866.011292,450.231689 866.085632,444.503815 z"
id="path7" />
<path
fill="#FFFFFF"
opacity="1.000000"
stroke="none"
d=" M174.224472,187.493225 C172.213684,188.255020 170.349152,188.949860 168.483551,188.952637 C127.001884,189.014496 85.519699,188.902679 44.038651,189.075058 C34.791191,189.113480 26.479988,192.699936 22.610405,201.416809 C20.492048,206.188721 21.238888,212.251480 20.805677,217.740997 C20.676064,219.383453 20.990231,221.055740 20.990532,222.714386 C21.001759,284.520538 21.000015,346.326721 20.999973,408.132874 C20.999969,414.031769 20.864725,419.934387 21.028820,425.828705 C21.325663,436.491302 29.198257,443.988983 39.983231,443.993744 C84.630196,444.013519 129.277191,444.009735 174.382401,444.030182 C174.737961,448.729980 174.817245,453.430756 174.393692,458.085815 C174.298065,459.136627 172.588226,460.310577 171.366852,460.901947 C170.420822,461.359955 169.077637,460.999695 167.911011,460.999695 C125.078690,461.000061 82.245537,461.148987 39.414570,460.908203 C26.748209,460.837006 16.930914,455.100189 9.852262,444.182495 C6.592582,439.154968 5.933938,434.201477 5.940778,428.565857 C6.029986,355.067688 6.164409,281.568512 5.764170,208.072418 C5.720665,200.083664 9.208368,194.251083 13.163262,188.681961 C19.964035,179.105347 29.633146,174.772690 41.836056,174.866425 C85.991035,175.205673 130.150192,175.000000 175.168060,175.000000 C174.895874,179.129318 174.633041,183.116623 174.224472,187.493225 z"
id="path8" />
<path
fill="#B9B9B9"
opacity="1.000000"
stroke="none"
d=" M408.000000,474.000000 C374.835999,474.000000 342.171967,474.000000 309.507965,474.000000 C284.278412,474.000000 259.048828,474.004730 233.819275,473.998169 C219.366562,473.994415 210.001450,464.527679 210.001083,449.926208 C209.998886,362.933258 209.976807,275.940308 210.060806,188.947449 C210.065567,184.018188 210.374725,178.948914 211.540894,174.189514 C214.189850,163.378632 222.831177,158.369949 233.445816,157.017914 C234.429825,156.892563 235.443527,157.000046 236.443451,157.000046 C426.094727,157.000000 615.746033,157.051605 805.397217,156.900894 C820.378662,156.888992 831.087341,167.063034 831.064148,182.680923 C830.931946,271.673523 830.870544,360.666779 831.134583,449.658783 C831.175842,463.575836 819.614380,474.272797 806.466797,474.234650 C673.812073,473.849609 541.155823,474.000000 408.000000,474.000000 M586.229492,319.395325 C587.844971,313.210358 585.613464,308.445679 578.616882,303.871887 C551.096436,285.881165 523.586060,267.874084 495.963287,250.041458 C487.238708,244.409042 478.472534,238.692429 469.170746,234.150177 C461.849823,230.575211 454.054626,236.239990 454.040649,244.358078 C453.959473,291.498627 453.959900,338.639465 454.058899,385.779907 C454.069946,391.030212 456.924652,394.877625 461.877869,396.864655 C468.895386,399.679810 474.590881,395.717529 479.854248,392.373016 C498.671570,380.415802 517.141296,367.913239 535.831177,355.753143 C548.286072,347.649658 561.049011,340.010132 573.349304,331.683136 C578.020752,328.520630 581.782837,324.014771 586.229492,319.395325 z"
id="path9" />
<path
fill="#FFFFFF"
opacity="1.000000"
stroke="none"
d=" M586.094482,319.758270 C581.782837,324.014771 578.020752,328.520630 573.349304,331.683136 C561.049011,340.010132 548.286072,347.649658 535.831177,355.753143 C517.141296,367.913239 498.671570,380.415802 479.854248,392.373016 C474.590881,395.717529 468.895386,399.679810 461.877869,396.864655 C456.924652,394.877625 454.069946,391.030212 454.058899,385.779907 C453.959900,338.639465 453.959473,291.498627 454.040649,244.358078 C454.054626,236.239990 461.849823,230.575211 469.170746,234.150177 C478.472534,238.692429 487.238708,244.409042 495.963287,250.041458 C523.586060,267.874084 551.096436,285.881165 578.616882,303.871887 C585.613464,308.445679 587.844971,313.210358 586.094482,319.758270 z"
id="path10" />
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,6 +1,6 @@
/*
* Jellyfin Slideshow by M0RPH3US v3.0.9
* Modified by CodeDevMLH v1.1.0.0
* Jellyfin Slideshow by M0RPH3US v4.0.1
* Modified by CodeDevMLH
*
* New features:
* - optional Trailer background video support
@@ -14,6 +14,9 @@
* - option to disable loading screen
* - 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)
* - option to enable seasonal content (only show items that are relevant to the current season/holiday)
* - option to prefer local trailers (from the media item) over online sources
* - options to sort the content by various criteria (PremiereDate, ProductionYear, Random, Original order, etc.)
*/
@import url(https://fonts.googleapis.com/css2?family=Archivo+Narrow:ital,wght@0,400..700;1,400..700&display=swap);
@@ -172,6 +175,7 @@
overflow: hidden;
margin: 0 auto;
pointer-events: auto;
outline: none;
}
#slides-container[style*="display: none"],
@@ -350,13 +354,13 @@
width: 100%;
height: 100%;
mask-image: linear-gradient(to top,
#fff0 2%,
rgb(0 0 0 / 0.5) 6%,
rgba(255, 255, 255, 0) 2%,
rgba(0, 0, 0, 0.5) 6%,
#000000 8%);
-webkit-mask-image: linear-gradient(to top,
#fff0 2%,
rgb(0 0 0 / 0.5) 6%,
#000000 8%);
rgba(255, 255, 255, 0) 2%,
rgba(0, 0, 0, 0.5) 6%,
#000000 8%);
}
.backdrop-container.full-width-video {
@@ -380,13 +384,13 @@
border-radius: 5px;
z-index: 3;
mask-image: linear-gradient(to top,
#fff0 2%,
rgb(0 0 0 / 0.5) 6%,
#000000 8%);
rgba(255, 255, 255, 0) 2%,
rgba(0, 0, 0, 0.5) 6%,
#000000 8%);
-webkit-mask-image: linear-gradient(to top,
#fff0 2%,
rgb(0 0 0 / 0.5) 6%,
#000000 8%);
rgba(255, 255, 255, 0) 2%,
rgba(0, 0, 0, 0.5) 6%,
#000000 8%);
}
.backdrop-overlay {
@@ -399,13 +403,13 @@
border-radius: 5px;
z-index: 4;
mask-image: linear-gradient(to top,
#fff0 2%,
rgb(0 0 0 / 0.5) 4%,
#000000 6%);
rgba(255, 255, 255, 0) 2%,
rgba(0, 0, 0, 0.5) 4%,
#000000 6%);
-webkit-mask-image: linear-gradient(to top,
#fff0 2%,
rgb(0 0 0 / 0.5) 4%,
#000000 6%);
rgba(255, 255, 255, 0) 2%,
rgba(0, 0, 0, 0.5) 4%,
#000000 6%);
}
.gradient-overlay {
@@ -420,13 +424,13 @@
rgba(29, 29, 29, 0) 100%);
z-index: 4;
mask-image: linear-gradient(to top,
#fff0 2%,
rgb(0 0 0 / 0.5) 4%,
#000000 6%);
rgba(255, 255, 255, 0) 2%,
rgba(0, 0, 0, 0.5) 4%,
#000000 6%);
-webkit-mask-image: linear-gradient(to top,
#fff0 2%,
rgb(0 0 0 / 0.5) 4%,
#000000 6%);
rgba(255, 255, 255, 0) 2%,
rgba(0, 0, 0, 0.5) 4%,
#000000 6%);
}
.gradient-overlay.full-width-video {
@@ -521,6 +525,8 @@
font-family: "Archivo Narrow", sans-serif;
font-size: 18px;
white-space: nowrap;
background-color: rgb(255, 255, 255);
color: rgb(0, 0, 0);
cursor: pointer;
transition: all 0.3s ease;
font-weight: 700;
@@ -531,6 +537,7 @@
.detail-button {
font-size: 18px;
background-color: rgb(255, 255, 255);
color: rgb(0, 0, 0);
border-radius: 50%;
height: 50px;
@@ -543,6 +550,7 @@
.favorite-button {
font-size: 18px;
background-color: rgb(255, 255, 255);
color: red;
border-radius: 50%;
height: 50px;
@@ -658,7 +666,7 @@
display: flex;
align-items: center;
border-radius: 5px;
background: rgb(255 255 255 / 0.8);
background: rgba(255, 255, 255, 0.8);
color: #000;
border: none;
font-weight: 600;
@@ -708,13 +716,13 @@
object-position: center 20%;
z-index: 3;
mask-image: linear-gradient(to top,
#fff0 2%,
rgb(0 0 0 / 0.5) 6%,
#000000 8%);
rgba(255, 255, 255, 0) 2%,
rgba(0, 0, 0, 0.5) 6%,
#000000 8%);
-webkit-mask-image: linear-gradient(to top,
#fff0 2%,
rgb(0 0 0 / 0.5) 6%,
#000000 8%);
rgba(255, 255, 255, 0) 2%,
rgba(0, 0, 0, 0.5) 6%,
#000000 8%);
}
.gradient-overlay {
@@ -723,17 +731,17 @@
left: 0;
width: 100%;
height: 100%;
background: rgb(0 0 0 / 0.25);
background: rgba(0, 0, 0, 0.25);
z-index: 4;
pointer-events: none;
mask-image: linear-gradient(to top,
#fff0 2%,
rgb(0 0 0 / 0.5) 6%,
#000000 8%);
rgba(255, 255, 255, 0) 2%,
rgba(0, 0, 0, 0.5) 6%,
#000000 8%);
-webkit-mask-image: linear-gradient(to top,
#fff0 2%,
rgb(0 0 0 / 0.5) 6%,
#000000 8%);
rgba(255, 255, 255, 0) 2%,
rgba(0, 0, 0, 0.5) 6%,
#000000 8%);
}
.dots-container {
@@ -764,7 +772,22 @@
.button-container {
top: calc(50% + 25vh);
left: 50%;
transform: translateX(-50%) scale(0.95);
transform: translateX(-50%);
width: max-content;
max-width: 98vw;
flex-wrap: nowrap;
justify-content: center;
gap: 15px;
}
.button-container button {
margin: 0 !important;
min-width: 0 !important;
}
.button-container .detail-button,
.button-container .favorite-button {
flex-shrink: 0;
}
.logo {
@@ -821,10 +844,6 @@
.genre {
top: calc(50% + 16vh);
}
.button-container {
top: calc(50% + 27vh);
}
}
}
@@ -991,4 +1010,146 @@
.dots-container .slide-counter {
margin: 0;
}
}
.layout-tv .backdrop-container {
top: -5%;
}
@media screen and (min-width: 960px) and (-webkit-device-pixel-ratio: 1) {
.layout-tv .backdrop.animate {
animation: none !important;
}
.layout-tv .logo.animate {
animation: none !important;
}
.layout-tv .slide-counter,
.layout-tv .dots-container {
backdrop-filter: none;
-webkit-backdrop-filter: none;
}
}
/* Floating Custom Overlay Styling */
.custom-overlay-container {
position: absolute;
top: 8vh;
left: 4vw;
z-index: 15;
display: flex;
align-items: center;
justify-content: flex-start;
pointer-events: none; /* Let clicks pass through to the slider */
animation: fadeInOverlay 1.5s ease-in-out forwards;
}
.custom-overlay-text {
font-family: "Archivo Narrow", sans-serif;
color: #fff;
font-size: 2.5rem;
font-weight: 700;
text-shadow: 2px 2px 8px rgba(0, 0, 0, 0.8), -1px -1px 4px rgba(0, 0, 0, 0.5);
margin: 0;
letter-spacing: 1px;
}
.custom-overlay-image {
max-width: 300px;
max-height: 120px;
object-fit: contain;
filter: drop-shadow(2px 4px 6px rgba(0,0,0,0.5));
}
@keyframes fadeInOverlay {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Make it smaller on mobile portrait */
@media only screen and (max-width: 767px) and (orientation: portrait) {
.custom-overlay-container {
top: 5vh;
left: 50%;
transform: translateX(-50%);
width: 90%;
justify-content: center;
text-align: center;
}
.custom-overlay-text {
font-size: 1.8rem;
}
.custom-overlay-image {
max-width: 200px;
max-height: 80px;
}
@keyframes fadeInOverlay {
from {
opacity: 0;
transform: translate(-50%, -10px);
}
to {
opacity: 1;
transform: translate(-50%, 0);
}
}
}
/* Custom Overlay Styles */
.custom-overlay-style-Shadowed {
color: #fff;
text-shadow: 2px 2px 8px rgba(0, 0, 0, 0.9), -1px -1px 4px rgba(0, 0, 0, 0.8);
}
.custom-overlay-style-Frosted {
color: #fff;
background: rgba(0, 0, 0, 0.4);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
padding: 8px 24px;
border-radius: 50px;
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
text-shadow: none; /* override default */
}
.custom-overlay-style-Cinematic {
background: linear-gradient(to right, #bf953f, #fcf6ba, #b38728, #fbf5b7, #aa771c);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
text-shadow: none; /* override default */
filter: drop-shadow(0px 2px 8px rgba(255, 215, 0, 0.4)) drop-shadow(2px 2px 4px rgba(0,0,0,0.8));
animation: shineCinematic 4s linear infinite;
background-size: 200% auto;
}
@keyframes shineCinematic {
to {
background-position: 200% center;
}
}
.custom-overlay-style-Pulse {
color: #fff;
text-shadow: 2px 2px 8px rgba(0, 0, 0, 0.9), -1px -1px 4px rgba(0, 0, 0, 0.8);
animation: pulseOverlayText 3s ease-in-out infinite alternate;
}
@keyframes pulseOverlayText {
from {
transform: scale(1);
}
to {
transform: scale(1.05);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -20,11 +20,14 @@ This plugin is a fork and enhancement of the original [Media Bar by MakD](https:
- [Configuration](#configuration)
- [General Settings](#general-settings)
- [Custom Content](#custom-content)
- [Content Sorting](#content-sorting)
- [Content Limits](#content-limits)
- [Advanced Settings](#advanced-settings)
- [Build The Plugin By Yourself](#build-the-plugin-by-yourself)
- [Troubleshooting](#troubleshooting)
- [Effects Not Showing](#effects-not-showing)
- [Docker Permission Issues](#docker-permission-issues)
- [Credits](#credits)
- [Contributing](#contributing)
---
@@ -82,11 +85,27 @@ This plugin builds upon the original Media Bar with new capabilities and improve
* **Smarter Playback**:
* Option to wait for the trailer to end before advancing the slide.
* Mute/Unmute controls
* **Override Trailers**: Manually specify a custom trailer URL for any item via the Custom Media IDs list
* **Customization**:
* **Custom Media IDs**: Manually specify which items (Movies, Series, Collections/Boxsets) to display. Easily configurable via the plugin settings
* **Seasonal Content Mode**: Define date-based lists for holidays and seasons (e.g., Halloween, Christmas)
* Pagination dots turn into a counter (e.g., 1/20) if the limit is exceeded
<details>
<summary>Have a look:</summary>
<img width="167" height="142" alt="PagDots_Number" src="https://github.com/user-attachments/assets/6a0a5040-cf13-4d9c-ae96-f50ec249c3f1" />
</details>
* Option to disable the loading screen
* Client Settings: Optionally allow users to set selected media bar settings from their client.
<details>
<summary>Have a look:</summary>
<img width="513" height="575" alt="Client-Settings" src="https://github.com/user-attachments/assets/3e29a84f-f8ea-4b7b-b561-80493cb1535b" />
</details>
* **Local Trailers Preference**: Option to prefer local trailers (from the media item) over online sources.
* **Theme Video Support**: Option to prefer local theme videos (backdrops) over trailers.
* **Randomization**: Options to randomize theme videos and local trailers if multiple versions exist.
* **Include Watched Content**: Option to include watched items in the random slideshow.
* **Content Sorting Options**: Sort content by various criteria such as PremiereDate, ProductionYear, Random, or Original order.
* **Client-Side Settings**: Allow users to override settings locally on their device.
### Core Features
* **Immersive Slideshow**: Rotates through your media library
@@ -94,6 +113,7 @@ This plugin builds upon the original Media Bar with new capabilities and improve
* **Direct Play**: Click "Play" to start watching immediately
* **Details View**: Click "Info" to jump to the item's detail page
* **Add To Favorites**: Click the heart to add the item to your favorites
* **Customize**: Change the plugins behavior through the Jellyfin admin panel
## Installation
@@ -118,13 +138,14 @@ Because this plugin relies on injecting JavaScript and CSS into the web interfac
| Client Platform | Status | Notes |
| :--- | :---: | :--- |
| **Web Browsers** (Chrome, Firefox, Edge, etc.) | ✅ | Fully supported. |
| **Jellyfin Media Player** (Windows/Linux/macOS) | ✅ | Fully supported. |
| **Android App** | ✅ | Works (Web wrapper). |
| **iOS App** | ✅ | Works (Web wrapper). |
| **Android TV / Fire TV** | ❌ | **Not supported** (Native UI). |
| **Roku** | ❌ | **Not supported** (Native UI). |
| **Swiftfin** | ❌ | **Not supported** (Native UI). |
| **Web Browsers** (Firefox, Chrome etc.) | ✅ | Direct JS injection |
| **Jellyfin Media Player** (Windows/Linux/macOS) | ✅ | Uses jellyfin web |
| **Android App** | ✅ | Uses a web wrapper |
| **iOS App** | ✅ | Uses a web wrapper |
| **Android TV / Fire TV** | ❌ | **Not supported.** Uses a native Java/Kotlin UI. |
| **Roku** | ❌ | **Not supported.** Uses a native UI. |
| **Swiftfin** (iOS/tvOS) | ❌ | **Not supported.** Uses a native Swift UI. |
| **Kodi** (via Jellyfin Addon) | ❌ | **Not supported.** Uses Kodi's native skinning engine. |
## Configuration
@@ -139,30 +160,62 @@ Configure the plugin via **Dashboard** > **Plugins** > **Media Bar Enhanced**.
* **Wait For Trailer To End**: Prevents slide transition until the video finishes.
* **Enable Mobile Video**: specific setting to allow video playback on mobile devices (disabled by default to save data/battery).
* **Show Trailer Button**: Adds a button to open the trailer in a popup modal if video backdrops are disabled (e.g. on mobile if trailers are disabled there)
* **Prefer Local Trailers**: If enabled, local trailers will be preferred over remote (YouTube) trailers.
* **Prefer Local Backdrops / Theme Videos**: If enabled, local backdrop videos (Theme Videos) will be preferred over trailers.
### Custom Content
Define exactly what shows up in your bar.
* **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.
* **Manual Trailer Override**: Add `[YouTube_URL]` or `[Jellyfin_ID]` after an ID to force a specific trailer/video.
* Example ID: `a1b2c3d4e5... [https://www.youtube.com/watch?v=VIDEO_ID]`
* Example ID: `z1b2c3d4e5... [Jellyfin_ID]`
* **Example Mixed List**:
```
a1b2c3d4e5f6... <-- Plays local item video
6bdu812812hd... [https://youtu.be/...] <-- Item metadata + Custom YouTube Trailer
12h44h124sf7... [hdc78127z4ff...] <-- Item metadata + Custom Jellyfin Trailer/Video etc.
```
* Example Collection Name: `Halloween Collection [https://...] | My Description` (Note: Use `|` to separate description from name if using a name instead of an ID)
* **Apply Limits to Custom IDs**: If enabled, the "Content Limits" (see below) will also apply to your Custom Media IDs list. By default, custom lists show all listed items regardless of limits.
* **Enable Seasonal Content Mode**: Advanced date-based scheduling.
* Format: `DD.MM-DD.MM | Name | ID1, ID2, ID3`
* Example: `20.10-31.10 | Halloween | <ID_OF_HALLOWEEN_COLLECTION>`
* If the current date matches a range, those IDs are used. Otherwise, it defaults to standard behavior or the Custom Media IDs list.
* **GUI Configuration**: You can easily add "Seasons" via the **Add Season** button.
* **Active Period**: Select the Start and End Day/Month for each season.
* **Media IDs**: Enter the Comma-separated list of IDs (Movies, Series, Collections) for that season.
* **Priority**: If the current date matches a defined season, those IDs are used. If multiple seasons overlap, the first matching one is used. If no season matches, it falls back to the Default Custom Media IDs.
**How to get IDs:**
Check the URL of an item in the web interface:
`.../web/#/details?id=YOUR_ITEM_ID_HERE&...`
### Content Sorting
Customize the order of slides in the Media Bar.
* **Sort By**: Choose criteria like *Random*, *Premiere Date*, *Production Year*, *Critic Rating*, *Community Rating*, *Name*, or *Runtime*.
* **Sort Order**: Ascending or Descending.
* **Note**: Sorting applies to both server-fetched content AND Custom Media IDs. Select **Original** to preserve the exact order of your Custom Media IDs list.
### Content Limits
Fine-tune performance by limiting the number of items fetched from the server.
* **Total Max Items**: Maximum total items to fetch (combined).
* **Include Watched Content**: If enabled, the random slideshow will also include items that you have already watched.
* **Max Movies**: Maximum movies to include (for random selection).
* **Max Tv Shows**: Maximum TV shows to include (for random selection).
* **Preload Count**: Number of slides to preload for smooth transitions.
* *Intelligent Preloading*: The plugin uses a safe preloading strategy that respects this count but handles small lists gracefully to avoid playback issues.
* **Max Pagination Dots**: Maximum number of dots to show. If exceeded, it switches to a counter (e.g., 1/20).
### Advanced Settings
* **Slide Animations**: Enable/disable the "Zoom In" effect.
* **Use SponsorBlock**: Skips non-content segments in YouTube trailers (if the data exists).
* **Preferred YouTube Quality**: Select your preferred resolution (*Auto*, *Maximum*, *1080p*, *720p*).
* **Start Muted**: Videos start without sound (user can unmute).
* **Full Width Video**: Stretches video to cover the entire width (good for desktop, crop on mobile).
* **Enable Loading Screen**: Enable/disable the loading indicator while the bar initializes.
* **Always Show Arrows**: Keeps navigation arrows visible instead of hiding them on mouse leave.
* **Randomize Backdrop Video**: If enabled, a random video from the backdrops/theme videos will be selected instead of the first one.
* **Randomize Local Trailer**: If enabled, a random local trailer will be selected instead of the first one.
* **Enable Keyboard Controls**:
* `Left`/`Right`: Change slide
* `Space`: Pause/Play slideshow
@@ -233,6 +286,12 @@ volumes:
- /path/to/jellyfin/config/index.html:/jellyfin/jellyfin-web/index.html
```
## Credits
This project is based on the original [Jellyfin Media Bar by MakD](https://github.com/MakD/Jellyfin-Media-Bar) and incorporates concepts from [IAmParadox27's plugin fork](https://github.com/IAmParadox27/jellyfin-plugin-media-bar). Thanks for their work!
Also, special thanks to IAmParadox27 for the [File Transformation plugin](https://github.com/IAmParadox27/jellyfin-plugin-file-transformation) which this plugin can optionally use for improved Docker compatibility.
## Contributing
Feel free to contribute to this project by creating pull requests or reporting issues.

View File

@@ -43,7 +43,7 @@ Bevor du baust, musst du die Versionsnummer in den folgenden Dateien aktualisier
Führe den folgenden Befehl im Terminal (PowerShell) im Hauptverzeichnis aus. Wir nutzen hier `dotnet build` statt `publish`, um unnötige Dateien zu vermeiden.
```powershell
dotnet build Jellyfin.Plugin.MediaBar/Jellyfin.Plugin.MediaBar.csproj --configuration Release --output bin/Publish; Compress-Archive -Path bin/Publish/* -DestinationPath bin/Publish/Jellyfin.Plugin.MediaBar.zip -Force; $hash = (Get-FileHash -Algorithm MD5 bin/Publish/Jellyfin.Plugin.MediaBar.zip).Hash.ToLower(); $time = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"); Write-Output "`n----------------------------------------"; Write-Output "NEUE CHECKSUMME (MD5): $hash"; Write-Output "ZEITSTEMPEL: $time"; Write-Output "----------------------------------------`n"
dotnet build Jellyfin.Plugin.MediaBarEnhanced/Jellyfin.Plugin.MediaBarEnhanced.csproj --configuration Release --output bin/Publish; Compress-Archive -Path bin/Publish/* -DestinationPath bin/Publish/Jellyfin.Plugin.MediaBarEnhanced.zip -Force; $hash = (Get-FileHash -Algorithm MD5 bin/Publish/Jellyfin.Plugin.MediaBarEnhanced.zip).Hash.ToLower(); $time = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"); Write-Output "`n----------------------------------------"; Write-Output "NEUE CHECKSUMME (MD5): $hash"; Write-Output "ZEITSTEMPEL: $time"; Write-Output "----------------------------------------`n"
```
## 3. Manifest aktualisieren

View File

@@ -9,12 +9,92 @@
"imageUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/raw/branch/main/logo.png",
"versions": [
{
"version": "1.4.0.1",
"changelog": "- feat: Add client-side settings feature for selected media bar settings",
"version": "1.7.1.15",
"changelog": "feat: add custom text/image overlay option\n- feat: add option to disable pagination dots/counter\n- feat: add exclude seasonal content from random fetching option\n- Add hide arrows on mobile option \n- fix button issue on mobile when using ElegantFin Theme",
"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"
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.7.1.14/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "d4a115b5e3fd192572e21be8e95c55a7",
"timestamp": "2026-03-09T01:29:55Z"
},
{
"version": "1.7.0.14",
"changelog": "- Switched to YouTube no-cookie host and referrer policy for iframe security\n- fix playback issues on iOS/MacOS \n- Disable animations and backdrop filters for TV layout\n- removed list.txt functionality to clean up, use the web ui instead\n- Enhance logging with contextual messages, in order to be able to clearly assign logs to this plugin",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.7.0.14/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "07875c74aab766657be3b8033be6d53f",
"timestamp": "2026-03-06T03:13:48Z"
},
{
"version": "1.6.6.4",
"changelog": "- feat: add static backdrop also for video backdrops\n- fix: renaming issue of settings (avoiding conflict with other plugins)",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.6.6.4/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "2c55cf9687e44b04a0824997e2980dc9",
"timestamp": "2026-02-19T17:21:40Z"
},
{
"version": "1.6.5.2",
"changelog": "- refactored seasonal UI settings",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.6.5.2/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "552cb3376c77ede5a0664ced56bf7d1e",
"timestamp": "2026-02-16T23:57:57Z"
},
{
"version": "1.6.4.1",
"changelog": "- fix slide transition when using local/backdrop videos",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.6.4.1/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "a9c5a863427de84639eca082483936da",
"timestamp": "2026-02-15T22:56:17Z"
},
{
"version": "1.6.3.1",
"changelog": "- fix path issue on subpath installations",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.6.3.0/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "6a952445bfb80ba4603017358e48da91",
"timestamp": "2026-02-15T22:38:19Z"
},
{
"version": "1.6.2.3",
"changelog": "- feat: add options for local backdrops (theme videos) support and randomization features for local trailer/backdrops if more than one is available\n- feat: add option to include watched content in the random selection",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.6.2.3/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "c7ff2d783889c25b5a53783bfbe30b11",
"timestamp": "2026-02-15T00:38:07Z"
},
{
"version": "1.6.1.32",
"changelog": "- feat: add seasonal UI logic\n- add option to also set the limits for custom ids\n- fix tv mode scroll issue\n- smaller fixes and improvements",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.6.1.32/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "e196fd393ef0bcf51f8ce535103f1811",
"timestamp": "2026-02-14T16:34:32Z"
},
{
"version": "1.6.0.2",
"changelog": "- add local trailer support on trailer button\nfix: iOS/MacOS playback issue?",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.6.0.2/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "cdd0208f8cc4f4b04f50e7138e508370",
"timestamp": "2026-02-10T22:07:33Z"
},
{
"version": "1.5.1.3",
"changelog": "- fix: iOS/MacOS playback issue?",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.5.1.3/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "9d9dbed453673d4b78acf2adaaaee126",
"timestamp": "2026-02-10T20:12:59Z"
},
{
"version": "1.5.0.28",
"changelog": "- fix: Keyboard controls in TV mode\n- Add sorting options for content\n- Add local trailer support\n- fix performance issue\n- Update mediaBarEnhanced.js and mediaBarEnhanced.css with version 4.0.1 from upstream repo",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.5.0.28/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "0261ff27be18d48cefa5078706954240",
"timestamp": "2026-02-10T00:35:41Z"
},
{
"version": "1.3.0.3",

View File

@@ -0,0 +1,116 @@
(async () => {
// 1. Initialisierung
const apiClient = window.ApiClient;
if (!apiClient) {
console.error("❌ ApiClient nicht gefunden. Bitte in der Browser-Konsole einer Jellyfin-Seite ausführen.");
return;
}
// 2. Item ID abfragen oder festlegen
let itemId = prompt("Bitte die Item ID eingeben (von einem Film/Serie mit Theme Video/Backdrop Video):");
if (!itemId) {
console.warn("Keine Item ID eingegeben. Abbruch.");
return;
}
itemId = itemId.trim();
const userId = apiClient.getCurrentUserId();
console.log(`%c🔍 Untersuche Item: ${itemId}`, "color: #00a4dc; font-size: 1.2em; font-weight: bold;");
// 3. Helper Funktion für Fetch requests
const fetchJson = async (url) => {
try {
const res = await fetch(url, {
headers: {
'Authorization': `MediaBrowser Client="Jellyfin Web", Device="Browser", DeviceId="${apiClient.deviceId()}", Version="${apiClient.appVersion()}", Token="${apiClient.accessToken()}"`
}
});
if (res.ok) return await res.json();
console.warn(`⚠️ Request fehlgeschlagen: ${url} (${res.status})`);
return null;
} catch (e) {
console.error(`❌ Fehler bei Request: ${url}`, e);
return null;
}
};
// ---------------------------------------------------------
// TEST 1: Standard Item Details mit erweiterten Feldern
// ---------------------------------------------------------
console.group("1. Standard Item Details (mit Fields)");
const fields = "Overview,RemoteTrailers,MediaSources,LocalTrailerCount,ThemeVideoIds,ThemeSongIds";
const itemDetailsUrl = `${apiClient.serverAddress()}/Users/${userId}/Items/${itemId}?Fields=${fields}`;
const item = await fetchJson(itemDetailsUrl);
if (item) {
console.log("Name:", item.Name);
console.log("ThemeVideoIds:", item.ThemeVideoIds);
console.log("ThemeSongIds:", item.ThemeSongIds);
console.log("LocalTrailerCount:", item.LocalTrailerCount);
console.log("RemoteTrailers:", item.RemoteTrailers);
if (item.ThemeVideoIds && item.ThemeVideoIds.length > 0) {
console.log(`%c✅ ThemeVideoIds gefunden: ${item.ThemeVideoIds.length}`, "color: green; font-weight: bold;");
} else {
console.log(`%c❌ Keine ThemeVideoIds im Item-Objekt.`, "color: orange;");
}
}
console.groupEnd();
// ---------------------------------------------------------
// TEST 2: ThemeMedia Endpoint
// ---------------------------------------------------------
console.group("2. Endpoint: /Items/{Id}/ThemeMedia");
const themeMediaUrl = `${apiClient.serverAddress()}/Items/${itemId}/ThemeMedia?userId=${userId}`;
const themeMedia = await fetchJson(themeMediaUrl);
if (themeMedia) {
console.dir(themeMedia);
if (themeMedia.ThemeVideos && themeMedia.ThemeVideos.length > 0) {
console.log(`%c✅ ThemeVideos gefunden: ${themeMedia.ThemeVideos.length}`, "color: green; font-weight: bold;");
themeMedia.ThemeVideos.forEach(v => console.log(` - ID: ${v.Id}, Name: ${v.Name}, Path: ${v.Path}`));
} else {
console.log("❌ Keine ThemeVideos in ThemeMedia gefunden.");
}
}
console.groupEnd();
// ---------------------------------------------------------
// TEST 3: ThemeVideos Endpoint (Spezifisch)
// ---------------------------------------------------------
console.group("3. Endpoint: /Items/{Id}/ThemeVideos");
// Manchmal auch unter Users/{UserId}/Items/{Id}/ThemeVideos
const themeVideosUrl = `${apiClient.serverAddress()}/Items/${itemId}/ThemeVideos?userId=${userId}`;
const themeVideos = await fetchJson(themeVideosUrl);
if (themeVideos) {
// Kann Array oder Objekt mit Items sein
const videos = Array.isArray(themeVideos) ? themeVideos : (themeVideos.Items || []);
console.dir(videos);
if (videos.length > 0) {
console.log(`%c✅ ThemeVideos Endpoint lieferte Ergebnisse: ${videos.length}`, "color: green; font-weight: bold;");
} else {
console.log("❌ ThemeVideos Endpoint lieferte leeres Array.");
}
}
console.groupEnd();
// ---------------------------------------------------------
// TEST 4: LocalTrailers Endpoint
// ---------------------------------------------------------
console.group("4. Endpoint: /Items/{Id}/LocalTrailers");
const localTrailersUrl = `${apiClient.serverAddress()}/Users/${userId}/Items/${itemId}/LocalTrailers`;
const localTrailers = await fetchJson(localTrailersUrl);
if (localTrailers && localTrailers.length > 0) {
console.log(`%c LocalTrailers gefunden: ${localTrailers.length}`, "color: blue;");
console.dir(localTrailers);
} else {
console.log("❌ Keine LocalTrailers gefunden.");
}
console.groupEnd();
console.log("%cFertig.", "font-weight: bold;");
})();

View File

@@ -0,0 +1,32 @@
(async () => {
const apiClient = window.ApiClient;
if (!apiClient) { console.error("Logged in?"); return; }
try {
// Fetch 1 random item ID
const rnd = await apiClient.getItems(apiClient.getCurrentUserId(), { SortBy: "Random", Limit: 1, Recursive: true, IncludeItemTypes: "Movie,Series" });
if (rnd.Items.length > 0) {
const id = rnd.Items[0].Id;
console.log("Random Item ID:", id);
// Fetch Default Details
const defd = await apiClient.getItem(apiClient.getCurrentUserId(), id);
console.log("Default Fields:", defd);
// Fetch ALL Known Fields manually
const allFields = "Chapters,People,MediaStreams,UserData,RecursiveItemCount,DateCreated,MediaSources,ProductionYear,Studios,Genres,Tags,RemoteTrailers,ProviderIds,Overview,CommunityRating,CriticRating,OfficialRating,PremiereDate,RunTimeTicks";
const full = await res.json();
console.log("Full Details:", full);
// Helper to download JSON
const blob = new Blob([JSON.stringify(full, null, 2)], { type: "application/json" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = `jellyfin-item-${id}.json`;
a.click();
URL.revokeObjectURL(url);
console.log("Downloaded JSON file.");
} else { console.warn("No items."); }
} catch (e) { console.error(e); }
})();

View File

@@ -0,0 +1,32 @@
(async () => {
// 1. Get Auth Data from the active client
const apiClient = window.ApiClient;
if (!apiClient) {
console.error("ApiClient not found. Are you logged in?");
return;
}
try {
console.log("Fetching random item...");
// 2. Fetch 1 random item
// const result = await apiClient.getItems(apiClient.getCurrentUserId(), { SortBy: "Random", Limit: 1, Recursive: true, IncludeItemTypes: "Movie,Series" });
const result = await apiClient.getItems(apiClient.getCurrentUserId(), {
SortBy: "Random",
Limit: 1,
Recursive: true,
IncludeItemTypes: "Movie,Series", // Optional: filter types
Fields: "Overview,RemoteTrailers,Genres,CommunityRating,CriticRating,OfficialRating,PremiereDate,RunTimeTicks,ProductionYear,MediaSources" // Request ALL fields
});
if (result.Items.length > 0) {
const item = result.Items[0];
console.log("Random Item Found:", item.Name);
console.dir(item); // Prints the full interactive object
} else {
console.warn("No items found.");
}
} catch (error) {
console.error("Error fetching item:", error);
}
})();

View File

@@ -0,0 +1,28 @@
(async () => {
const apiClient = window.ApiClient;
if (!apiClient) {
console.error("ApiClient nicht gefunden.");
return;
}
// Die ID des Items, das du abrufen möchtest
const itemId = "DEINE_ITEM_ID_HIER";
const userId = apiClient.getCurrentUserId();
try {
console.log(`Rufe Details für Item ${itemId} ab...`);
// Nutze getItem() statt getItems()
// Parameter: userId, itemId
const item = await apiClient.getItem(userId, itemId);
if (item) {
console.log("Item Details gefunden:", item.Name);
console.dir(item); // Zeigt alle Metadaten (Genres, Pfade, ProviderIds, etc.)
} else {
console.warn("Item konnte nicht gefunden werden.");
}
} catch (error) {
console.error("Fehler beim Abrufen des Items:", error);
}
})();

View File

@@ -0,0 +1,37 @@
(async () => {
const apiClient = window.ApiClient;
if (!apiClient) {
console.error("ApiClient nicht gefunden.");
return;
}
const itemId = "DEINE_ITEM_ID_HIER";
const userId = apiClient.getCurrentUserId();
const fields = "Overview,RemoteTrailers,Genres,CommunityRating,CriticRating,OfficialRating,PremiereDate,ProductionYear,MediaSources,RunTimeTicks,LocalTrailerCount,ThemeVideoIds";
try {
console.log(`Rufe erweiterte Details für Item ${itemId} ab...`);
const url = apiClient.getUrl(`Users/${userId}/Items/${itemId}`, {
Fields: fields
});
const item = await apiClient.getJSON(url);
if (item) {
console.log(`%cErgebnis für: ${item.Name}`, "color: #00a4dc; font-weight: bold;");
console.log("Remote Trailer:", item.RemoteTrailers);
console.log("Local Trailer Count:", item.LocalTrailerCount);
console.log("Media Sources:", item.MediaSources);
console.log("ThemeVideos:", item.ThemeVideoIds);
console.dir(item);
} else {
console.warn("Item konnte nicht gefunden werden.");
}
} catch (error) {
console.error("Fehler beim Abrufen des Items:", error);
}
})();

View File

@@ -0,0 +1,73 @@
(async () => {
const apiClient = window.ApiClient;
if (!apiClient) {
console.error("ApiClient not found. Are you logged in?");
return;
}
const userId = apiClient.getCurrentUserId();
const serverAddress = apiClient.serverAddress();
const maxDaysRecent = 30; // 30 Tage Limit
const pastDate = new Date();
pastDate.setDate(pastDate.getDate() - maxDaysRecent);
const dateStr = pastDate.toISOString();
console.log(`\n%c=== TEST: DateCreated Direkt-Abfrage ===`, "color: #00a4dc; font-weight: bold; font-size: 14px;");
console.log(`Wir suchen Filme, die nach dem ${dateStr} hinzugefügt wurden.\n`);
// Wir probieren alle denkbaren Parameter-Schreibweisen aus,
// die Jellyfin historisch oder in Forks für "DateCreated" akzeptieren könnte.
const testCases = [
{ name: "MinDateCreated (PascalCase)", param: `MinDateCreated=${dateStr}` },
{ name: "minDateCreated (camelCase)", param: `minDateCreated=${dateStr}` },
{ name: "DateCreatedMin", param: `DateCreatedMin=${dateStr}` },
{ name: "dateCreatedMin", param: `dateCreatedMin=${dateStr}` },
{ name: "StartDate", param: `StartDate=${dateStr}` },
{ name: "startDate", param: `startDate=${dateStr}` }
];
try {
for (let i = 0; i < testCases.length; i++) {
const test = testCases[i];
const apiUrl = `${serverAddress}/Items?IncludeItemTypes=Movie,Series&Recursive=true&enableUserData=true&Limit=5&fields=Id,DateCreated&userId=${userId}&${test.param}`;
console.log(`%cTest ${i+1}: ${test.name}`, "color: yellow;");
console.log(`URL: ${apiUrl}`);
const response = await fetch(apiUrl, {
headers: {
Authorization: `MediaBrowser Client="${apiClient.appName()}", Device="${apiClient.deviceName()}", DeviceId="${apiClient.deviceId()}", Version="${apiClient.appVersion()}", Token="${apiClient.accessToken()}"`
}
});
if (!response.ok) {
console.error(`-> ❌ HTTP Fehler: ${response.status}`);
continue;
}
const data = await response.json();
const items = data.Items || [];
// Zur Auswertung: Wenn die Abfrage ignoriert wird, liefert er oft ALLE (hier max 5) zurück.
// Filtert er wirklich, sollten es WENIGER als 5, und zwar im besten Fall genau die RICHTIGEN sein.
console.log(`-> Ergebnis: ${items.length} Items zurückgeliefert.`);
if (items.length > 0) {
// Wir checken, ob die zurückgelieferten Items WIRKLICH neu sind
const oldItems = items.filter(item => new Date(item.DateCreated) < pastDate);
if (oldItems.length > 0) {
console.log(` ❌ Filter FEHLGESCHLAGEN: Es wurden ${oldItems.length} "alte" Filme zurückgegeben (z.B. ${oldItems[0].Name}). Er ignoriert also den Parameter.`);
} else {
console.log(` ✅ Filter KÖNNTE funktionieren: Alle zurückgegebenen Filme sind neuer als unser Datum! (Erster: ${items[0].Name})`);
}
} else {
console.log(` ❓ Keine Items gefunden (entweder strenger Filter oder gar keine neuen Filme vorhanden).`);
}
console.log("\n");
}
} catch (error) {
console.error("Fehler beim Abruf:", error);
}
})();

View File

@@ -0,0 +1,56 @@
(async () => {
const apiClient = window.ApiClient;
if (!apiClient) {
console.error("ApiClient not found. Are you logged in?");
return;
}
const userId = apiClient.getCurrentUserId();
const serverAddress = apiClient.serverAddress();
const maxDaysRecent = 30; // Test: Added in last 30 days
const pastDate = new Date();
pastDate.setDate(pastDate.getDate() - maxDaysRecent);
const dateStr = pastDate.toISOString();
console.log(`Searching for items added after: ${dateStr}`);
const testUrls = [
// Test 1: minDateCreated (CamelCase)
`${serverAddress}/Items?IncludeItemTypes=Movie,Series&Recursive=true&enableUserData=true&Limit=5&fields=Id,DateCreated&userId=${userId}&minDateCreated=${dateStr}`,
// Test 2: minDateLastSaved
`${serverAddress}/Items?IncludeItemTypes=Movie,Series&Recursive=true&enableUserData=true&Limit=5&fields=Id,DateCreated&userId=${userId}&minDateLastSaved=${dateStr}`,
];
try {
for (let i = 0; i < testUrls.length; i++) {
const apiUrl = testUrls[i];
console.log(`\n%cTest ${i+1}: Testing URL:\n${apiUrl}`, "color: yellow;");
const response = await fetch(apiUrl, {
headers: {
Authorization: `MediaBrowser Client="${apiClient.appName()}", Device="${apiClient.deviceName()}", DeviceId="${apiClient.deviceId()}", Version="${apiClient.appVersion()}", Token="${apiClient.accessToken()}"`
}
});
if (!response.ok) {
console.error(`Failed to fetch items: ${response.status} ${response.statusText}`);
continue;
}
const data = await response.json();
const items = data.Items || [];
console.log(`%cErgebnis: ${items.length} Items gefunden!`, "color: #00a4dc; font-weight: bold;");
if(items.length > 0) {
console.log("Gefundene Items:");
items.forEach(item => {
console.log(`- Name: ${item.Name}, DateCreated: ${item.DateCreated}, Art: ${item.Type}`);
});
}
}
} catch (error) {
console.error("Fehler beim Abrufen der URL:", error);
}
})();

View File

@@ -0,0 +1,72 @@
(async () => {
const apiClient = window.ApiClient;
if (!apiClient) {
console.error("ApiClient not found. Are you logged in?");
return;
}
const userId = apiClient.getCurrentUserId();
const serverAddress = apiClient.serverAddress();
const maxDaysRecent = 30; // Test: Added in last 30 days
// 1. Calculate the cutoff date
const pastDate = new Date();
pastDate.setDate(pastDate.getDate() - maxDaysRecent);
const dateStr = pastDate.toISOString();
console.log(`\n%c=== TEST: 2-Stufen "Zuletzt Hinzugefügt" Filter ===`, "color: #00a4dc; font-weight: bold; font-size: 14px;");
console.log(`Suche Items neuer als: ${dateStr} (${maxDaysRecent} Tage alt)\n`);
const apiUrl = `${serverAddress}/Items?IncludeItemTypes=Movie,Series&Recursive=true&enableUserData=true&Limit=50&fields=Id,DateCreated&userId=${userId}&minDateLastSaved=${dateStr}`;
try {
console.log(`%cSchritt 1: API Call mit minDateLastSaved...`, "color: yellow;");
console.log(`URL: ${apiUrl}`);
const response = await fetch(apiUrl, {
headers: {
Authorization: `MediaBrowser Client="${apiClient.appName()}", Device="${apiClient.deviceName()}", DeviceId="${apiClient.deviceId()}", Version="${apiClient.appVersion()}", Token="${apiClient.accessToken()}"`
}
});
if (!response.ok) {
throw new Error(`Failed to fetch items: ${response.status} ${response.statusText}`);
}
const data = await response.json();
let items = data.Items || [];
console.log(`-> API lieferte ${items.length} potenziell neue/geänderte Items zurück.\n`);
if (items.length > 0) {
console.log("Die API hielt diese Items für neu/aktuell:");
items.forEach(item => console.log(` - ${item.Name} (DateCreated: ${item.DateCreated})`));
}
console.log(`\n%cSchritt 2: Lokaler DateCreated Filter (Wie das Plugin ihn jetzt nutzt)...`, "color: yellow;");
// Exakt dieser Filter-Block ist jetzt auch so in mediaBarEnhanced.js
const finalItems = items.filter(item => {
if (!item.DateCreated) return true; // Fallback falls Jellyfin kein Datum schickt
const dCreated = new Date(item.DateCreated);
return dCreated >= pastDate;
});
console.log(`%c-> FINALES ERGEBNIS: ${finalItems.length} echte Neuzugänge bleiben übrig!`, "color: #00ff00; font-weight: bold; font-size: 14px;");
if(finalItems.length > 0) {
console.log("Diese Items schaffen es in die Slideshow:");
finalItems.forEach(item => {
console.log(` 🎬 Name: ${item.Name}, DateCreated: ${item.DateCreated}`);
});
}
// Teste den Fallback
if(finalItems.length === 0 && items.length > 0) {
console.log("\n%c💡 HINWEIS: Da nach Filterung 0 Items übrig bleiben, greift in der Slideshow jetzt automatisch unser Fallback und zeigt zufällige Filme aller Jahre!", "color: orange;");
}
} catch (error) {
console.error("Fehler beim Abruf:", error);
}
})();

View File

@@ -0,0 +1,62 @@
(async () => {
const apiClient = window.ApiClient;
if (!apiClient) {
console.error("ApiClient not found. Are you logged in?");
return;
}
const userId = apiClient.getCurrentUserId();
const serverAddress = apiClient.serverAddress();
// Example test configuration flags
const maxItems = 50;
const includeWatchedContent = false; // set to false to ONLY show unplayed (newly watched)
const maxParentalRating = 12; // Test age limit
const maxDaysRecent = 30; // Test recency limit
// Build the query parameters just like in mediaBarEnhanced.js
const sortParams = "sortBy=Random";
const playedFilter = includeWatchedContent ? '' : '&isPlayed=False';
let parentalFilter = '';
if (maxParentalRating) {
parentalFilter = `&MaxOfficialRating=${maxParentalRating}`;
}
let dateFilter = '';
if (maxDaysRecent) {
const pastDate = new Date();
pastDate.setDate(pastDate.getDate() - maxDaysRecent);
dateFilter = `&MinDateCreated=${pastDate.toISOString()}`;
}
const apiUrl = `${serverAddress}/Items?IncludeItemTypes=Movie,Series&Recursive=true&hasOverview=true&imageTypes=Logo,Backdrop&${sortParams}${playedFilter}${parentalFilter}${dateFilter}&enableUserData=true&Limit=${maxItems}&fields=Id&userId=${userId}`;
try {
console.log(`Testing generated URL with filters:\n%c${apiUrl}`, "color: yellow;");
// Execute the fetch
const response = await fetch(apiUrl, {
headers: {
Authorization: `MediaBrowser Client="${apiClient.appName()}", Device="${apiClient.deviceName()}", DeviceId="${apiClient.deviceId()}", Version="${apiClient.appVersion()}", Token="${apiClient.accessToken()}"`
}
});
if (!response.ok) {
throw new Error(`Failed to fetch items: ${response.status} ${response.statusText}`);
}
const data = await response.json();
const items = data.Items || [];
console.log(`%cErgebnis: ${items.length} Items gefunden!`, "color: #00a4dc; font-weight: bold;");
if(items.length > 0) {
console.log("Erstes Item als Beispiel:");
console.dir(items[0]);
}
} catch (error) {
console.error("Fehler beim Abrufen der URL:", error);
}
})();