diff --git a/Jellyfin.Plugin.MediaBarEnhanced/Configuration/configPage.html b/Jellyfin.Plugin.MediaBarEnhanced/Configuration/configPage.html index c2d5715..389b079 100644 --- a/Jellyfin.Plugin.MediaBarEnhanced/Configuration/configPage.html +++ b/Jellyfin.Plugin.MediaBarEnhanced/Configuration/configPage.html @@ -449,7 +449,7 @@ ApiClient.getPluginConfiguration(MediaBarEnhancedConfigurationPage.pluginId).then(function (config) { var keys = [ - 'MediaBarIsEnabled', 'ShuffleInterval', 'RetryInterval', 'MinSwipeDistance', + 'ShuffleInterval', 'RetryInterval', 'MinSwipeDistance', 'LoadingCheckInterval', 'MaxPlotLength', 'MaxMovies', 'MaxTvShows', 'MaxItems', 'PreloadCount', 'FadeTransitionDuration', 'MaxPaginationDots', 'SlideAnimationEnabled', 'EnableVideoBackdrop', 'UseSponsorBlock', @@ -462,6 +462,12 @@ 'IncludeWatchedContent' ]; + // 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) { @@ -539,8 +545,15 @@ 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 = [ - 'MediaBarIsEnabled', 'ShuffleInterval', 'RetryInterval', 'MinSwipeDistance', + 'ShuffleInterval', 'RetryInterval', 'MinSwipeDistance', 'LoadingCheckInterval', 'MaxPlotLength', 'MaxMovies', 'MaxTvShows', 'MaxItems', 'PreloadCount', 'FadeTransitionDuration', 'MaxPaginationDots', 'SlideAnimationEnabled', 'EnableVideoBackdrop', 'UseSponsorBlock', diff --git a/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js b/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js index 789fbe4..08d3e98 100644 --- a/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js +++ b/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js @@ -63,6 +63,7 @@ const CONFIG = { sortOrder: "Ascending", applyLimitsToCustomIds: false, seasonalSections: "[]", + isEnabled: true, }; // State management @@ -1638,6 +1639,7 @@ const SlideCreator = { "data-item-id": itemId, }); + let videoBackdrop; let backdrop; let isVideo = false; let trailerUrl = null; @@ -1721,7 +1723,7 @@ const SlideCreator = { // Create container for YouTube API const videoClass = CONFIG.fullWidthVideo ? "video-backdrop-full" : "video-backdrop-default"; - backdrop = SlideUtils.createElement("div", { + videoBackdrop = SlideUtils.createElement("div", { className: `backdrop video-backdrop ${videoClass}`, id: `youtube-player-${itemId}` }); @@ -1864,12 +1866,12 @@ const SlideCreator = { videoAttributes.muted = ""; - backdrop = SlideUtils.createElement("video", videoAttributes); - backdrop.volume = 0.4; + videoBackdrop = SlideUtils.createElement("video", videoAttributes); + videoBackdrop.volume = 0.4; - STATE.slideshow.videoPlayers[itemId] = backdrop; + STATE.slideshow.videoPlayers[itemId] = videoBackdrop; - backdrop.addEventListener('play', (event) => { + videoBackdrop.addEventListener('play', (event) => { const slide = document.querySelector(`.slide[data-item-id="${itemId}"]`); if (!slide || !slide.classList.contains('active')) { console.log(`Local video ${itemId} started playing but slide is not active, pausing.`); @@ -1882,14 +1884,14 @@ const SlideCreator = { } }); - backdrop.addEventListener('ended', (event) => { + videoBackdrop.addEventListener('ended', (event) => { const slide = event.target.closest('.slide'); if (slide && slide.classList.contains('active')) { SlideshowManager.nextSlide(); } }); - backdrop.addEventListener('error', (event) => { + videoBackdrop.addEventListener('error', (event) => { console.warn(`Local video error for item ${itemId}`); const slide = event.target.closest('.slide'); if (slide && slide.classList.contains('active')) { @@ -1899,13 +1901,18 @@ const SlideCreator = { } } - if (!isVideo) { - backdrop = SlideUtils.createElement("img", { - className: "backdrop high-quality", - src: this.buildImageUrl(item, "Backdrop", 0, serverAddress, 60), - alt: LocalizationUtils.getLocalizedString('Backdrop', 'Backdrop'), - loading: "eager", - }); + // Always create a static backdrop image (to show while video loads or if no video) + backdrop = SlideUtils.createElement("img", { + className: "backdrop high-quality", + src: this.buildImageUrl(item, "Backdrop", 0, serverAddress, 60), + alt: LocalizationUtils.getLocalizedString('Backdrop', 'Backdrop'), + loading: "eager", + }); + + // If video, static backdrop should be strictly a background (no animation) + if (isVideo) { + backdrop.style.animation = "none"; + backdrop.style.transition = "none"; } const backdropOverlay = SlideUtils.createElement("div", { @@ -1915,8 +1922,14 @@ const SlideCreator = { const backdropContainer = SlideUtils.createElement("div", { className: "backdrop-container" + (isVideo && CONFIG.fullWidthVideo ? " full-width-video" : ""), }); + backdropContainer.append(backdrop, backdropOverlay); + // If video exists, append on top of static backdrop + if (isVideo && videoBackdrop) { + backdropContainer.appendChild(videoBackdrop); + } + const logo = SlideUtils.createElement("img", { className: "logo high-quality", src: this.buildImageUrl(item, "Logo", undefined, serverAddress, 40),