Compare commits

..

5 Commits

Author SHA1 Message Date
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
4 changed files with 44 additions and 62 deletions

View File

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

View File

@@ -201,6 +201,9 @@
user-select: none; user-select: none;
margin: 0; margin: 0;
padding: 0; padding: 0;
-webkit-appearance: none;
appearance: none;
border: none;
} }
.arrow i { .arrow i {
@@ -238,6 +241,9 @@
opacity: 0.3; opacity: 0.3;
transition: opacity 0.3s ease; transition: opacity 0.3s ease;
text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.8); text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.8);
-webkit-appearance: none;
appearance: none;
border: none;
} }
.pause-button i { .pause-button i {
@@ -274,6 +280,9 @@
opacity: 0.3; opacity: 0.3;
transition: opacity 0.3s ease; transition: opacity 0.3s ease;
text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.8); text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.8);
-webkit-appearance: none;
appearance: none;
border: none;
} }
.mute-button i { .mute-button i {
@@ -353,14 +362,8 @@
right: 0%; right: 0%;
width: 100%; width: 100%;
height: 100%; height: 100%;
mask-image: linear-gradient(to top, mask-image: linear-gradient(to top, rgba(255,255,255,0) 2%, rgba(0,0,0,0.5) 6%, #000000 8%);
#fff0 2%, -webkit-mask-image: linear-gradient(to top, rgba(255,255,255,0) 2%, rgba(0,0,0,0.5) 6%, #000000 8%);
rgb(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%);
} }
.backdrop-container.full-width-video { .backdrop-container.full-width-video {
@@ -383,14 +386,8 @@
object-position: center 20%; object-position: center 20%;
border-radius: 5px; border-radius: 5px;
z-index: 3; z-index: 3;
mask-image: linear-gradient(to top, mask-image: linear-gradient(to top, rgba(255,255,255,0) 2%, rgba(0,0,0,0.5) 6%, #000000 8%);
#fff0 2%, -webkit-mask-image: linear-gradient(to top, rgba(255,255,255,0) 2%, rgba(0,0,0,0.5) 6%, #000000 8%);
rgb(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%);
} }
.backdrop-overlay { .backdrop-overlay {
@@ -402,14 +399,8 @@
background-color: rgba(0, 0, 0, 0.2); background-color: rgba(0, 0, 0, 0.2);
border-radius: 5px; border-radius: 5px;
z-index: 4; z-index: 4;
mask-image: linear-gradient(to top, mask-image: linear-gradient(to top, rgba(255,255,255,0) 2%, rgba(0,0,0,0.5) 4%, #000000 6%);
#fff0 2%, -webkit-mask-image: linear-gradient(to top, rgba(255,255,255,0) 2%, rgba(0,0,0,0.5) 4%, #000000 6%);
rgb(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%);
} }
.gradient-overlay { .gradient-overlay {
@@ -423,14 +414,8 @@
rgba(29, 29, 29, 0.35) 30%, rgba(29, 29, 29, 0.35) 30%,
rgba(29, 29, 29, 0) 100%); rgba(29, 29, 29, 0) 100%);
z-index: 4; z-index: 4;
mask-image: linear-gradient(to top, mask-image: linear-gradient(to top, rgba(255,255,255,0) 2%, rgba(0,0,0,0.5) 4%, #000000 6%);
#fff0 2%, -webkit-mask-image: linear-gradient(to top, rgba(255,255,255,0) 2%, rgba(0,0,0,0.5) 4%, #000000 6%);
rgb(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%);
} }
.gradient-overlay.full-width-video { .gradient-overlay.full-width-video {
@@ -531,6 +516,8 @@
gap: 6px; gap: 6px;
-webkit-tap-highlight-color: #fff0; -webkit-tap-highlight-color: #fff0;
border-radius: 8px; border-radius: 8px;
-webkit-appearance: none;
appearance: none;
} }
.detail-button { .detail-button {
@@ -543,6 +530,8 @@
cursor: pointer; cursor: pointer;
transition: color 0.2s; transition: color 0.2s;
-webkit-tap-highlight-color: #fff0; -webkit-tap-highlight-color: #fff0;
-webkit-appearance: none;
appearance: none;
} }
.favorite-button { .favorite-button {
@@ -555,6 +544,8 @@
cursor: pointer; cursor: pointer;
transition: color 0.2s; transition: color 0.2s;
-webkit-tap-highlight-color: #fff0; -webkit-tap-highlight-color: #fff0;
-webkit-appearance: none;
appearance: none;
} }
.favorite-button.favorited { .favorite-button.favorited {
@@ -662,7 +653,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
border-radius: 5px; border-radius: 5px;
background: rgb(255 255 255 / 0.8); background: rgba(255, 255, 255, 0.8);
color: #000; color: #000;
border: none; border: none;
font-weight: 600; font-weight: 600;
@@ -711,14 +702,8 @@
object-fit: cover; object-fit: cover;
object-position: center 20%; object-position: center 20%;
z-index: 3; z-index: 3;
mask-image: linear-gradient(to top, mask-image: linear-gradient(to top, rgba(255,255,255,0) 2%, rgba(0,0,0,0.5) 6%, #000000 8%);
#fff0 2%, -webkit-mask-image: linear-gradient(to top, rgba(255,255,255,0) 2%, rgba(0,0,0,0.5) 6%, #000000 8%);
rgb(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%);
} }
.gradient-overlay { .gradient-overlay {
@@ -727,17 +712,11 @@
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
background: rgb(0 0 0 / 0.25); background: rgba(0, 0, 0, 0.25);
z-index: 4; z-index: 4;
pointer-events: none; pointer-events: none;
mask-image: linear-gradient(to top, mask-image: linear-gradient(to top, rgba(255,255,255,0) 2%, rgba(0,0,0,0.5) 6%, #000000 8%);
#fff0 2%, -webkit-mask-image: linear-gradient(to top, rgba(255,255,255,0) 2%, rgba(0,0,0,0.5) 6%, #000000 8%);
rgb(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%);
} }
.dots-container { .dots-container {

View File

@@ -836,7 +836,7 @@ const LocalizationUtils = {
} }
} }
if (window.ApiClient && STATE.jellyfinData?.accessToken) { if (window.ApiClient && STATE.jellyfinData && STATE.jellyfinData.accessToken) {
try { try {
const userId = window.ApiClient.getCurrentUserId(); const userId = window.ApiClient.getCurrentUserId();
if (userId) { if (userId) {
@@ -846,7 +846,7 @@ const LocalizationUtils = {
}); });
if (userResponse.ok) { if (userResponse.ok) {
const userData = await userResponse.json(); const userData = await userResponse.json();
if (userData.Configuration?.AudioLanguagePreference) { if (userData.Configuration && userData.Configuration.AudioLanguagePreference) {
locale = userData.Configuration.AudioLanguagePreference.toLowerCase(); locale = userData.Configuration.AudioLanguagePreference.toLowerCase();
} }
} }
@@ -856,7 +856,7 @@ const LocalizationUtils = {
} }
} }
if (!locale && window.ApiClient && STATE.jellyfinData?.accessToken) { if (!locale && window.ApiClient && (STATE.jellyfinData && STATE.jellyfinData.accessToken)) {
try { try {
const configUrl = window.ApiClient.getUrl('System/Configuration'); const configUrl = window.ApiClient.getUrl('System/Configuration');
const configResponse = await fetch(configUrl, { const configResponse = await fetch(configUrl, {
@@ -1031,7 +1031,7 @@ const LocalizationUtils = {
*/ */
getLocalizedString(key, fallback, ...args) { getLocalizedString(key, fallback, ...args) {
const locale = this.cachedLocale || 'en-us'; const locale = this.cachedLocale || 'en-us';
let translated = this.translations[locale]?.[key] || fallback; let translated = (this.translations[locale] && this.translations[locale][key]) || fallback;
if (args.length > 0) { if (args.length > 0) {
for (let i = 0; i < args.length; i++) { for (let i = 0; i < args.length; i++) {
@@ -1776,9 +1776,12 @@ const SlideCreator = {
} }
const isLowPower = isLowPowerDevice(); const isLowPower = isLowPowerDevice();
const isIOSApp = /iPhone|iPad|iPod/i.test(navigator.userAgent);
const limitVideos = isLowPower || isIOSApp;
const itemIndex = STATE.slideshow.itemIds ? STATE.slideshow.itemIds.indexOf(itemId) : -1; const itemIndex = STATE.slideshow.itemIds ? STATE.slideshow.itemIds.indexOf(itemId) : -1;
const isActiveSlide = itemIndex !== -1 && itemIndex === STATE.slideshow.currentSlideIndex; const isActiveSlide = itemIndex !== -1 && itemIndex === STATE.slideshow.currentSlideIndex;
const shouldCreateVideo = !isLowPower || isActiveSlide; // Limit YouTube iframe bulk creation on low power devices OR iOS (which kills the WebProcess on OOM)
const shouldCreateVideo = !limitVideos || isActiveSlide;
if (isYoutube && videoId && shouldCreateVideo) { if (isYoutube && videoId && shouldCreateVideo) {
isVideo = true; isVideo = true;
@@ -2804,7 +2807,7 @@ const SlideshowManager = {
if (currentItemId) { if (currentItemId) {
const currentSlide = document.querySelector(`.slide[data-item-id="${currentItemId}"]`); const currentSlide = document.querySelector(`.slide[data-item-id="${currentItemId}"]`);
const video = currentSlide?.querySelector('video'); const video = currentSlide ? currentSlide.querySelector('video') : null;
if (video) { if (video) {
video.muted = STATE.slideshow.isMuted; video.muted = STATE.slideshow.isMuted;
@@ -2964,7 +2967,7 @@ const SlideshowManager = {
if (!currentSlide) return; if (!currentSlide) return;
// YouTube player: just resume, don't reload // YouTube player: just resume, don't reload
const ytPlayer = STATE.slideshow.videoPlayers?.[currentItemId]; const ytPlayer = (STATE.slideshow.videoPlayers && STATE.slideshow.videoPlayers[currentItemId]) ? STATE.slideshow.videoPlayers[currentItemId] : undefined;
if (ytPlayer && typeof ytPlayer.playVideo === 'function') { if (ytPlayer && typeof ytPlayer.playVideo === 'function') {
if (STATE.slideshow.isMuted) { if (STATE.slideshow.isMuted) {
if (typeof ytPlayer.mute === 'function') ytPlayer.mute(); if (typeof ytPlayer.mute === 'function') ytPlayer.mute();

View File

@@ -9,12 +9,12 @@
"imageUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/raw/branch/main/logo.png", "imageUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/raw/branch/main/logo.png",
"versions": [ "versions": [
{ {
"version": "1.7.1.8", "version": "1.7.1.10",
"changelog": "- 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", "changelog": "- 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", "targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.7.1.8/Jellyfin.Plugin.MediaBarEnhanced.zip", "sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.7.1.9/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "d10d107db41ecf9cb26d4b248426c4a1", "checksum": "af20c62dae53ee05dec1ac7ae6bb1149",
"timestamp": "2026-03-08T19:29:24Z" "timestamp": "2026-03-08T20:58:25Z"
}, },
{ {
"version": "1.7.0.14", "version": "1.7.0.14",