From 18b5a6dca1213ba1ef0a45891efb996d01524138 Mon Sep 17 00:00:00 2001 From: M0RPH3US Date: Tue, 19 May 2026 20:38:34 +0530 Subject: [PATCH 1/4] Update slideshowpure.js Attempt to fix #105 --- slideshowpure.js | 96 +++++++----------------------------------------- 1 file changed, 14 insertions(+), 82 deletions(-) diff --git a/slideshowpure.js b/slideshowpure.js index 95a71b9..de2f36e 100644 --- a/slideshowpure.js +++ b/slideshowpure.js @@ -1,5 +1,5 @@ /* - * Jellyfin Slideshow by M0RPH3US v4.0.4 + * Jellyfin Slideshow by M0RPH3US v4.0.5 */ //Core Module Configuration @@ -1057,58 +1057,29 @@ const VisibilityObserver = { const isVisible = (window.location.hash === "#/home.html" || window.location.hash === "#/home") && - activeTab.getAttribute("data-index") === "0"; + (activeTab ? activeTab.getAttribute("data-index") === "0" : false); container.style.display = isVisible ? "block" : "none"; if (isVisible && !this.wasVisible) { - const currentItemId = - STATE.slideshow.itemIds[STATE.slideshow.currentSlideIndex]; - const currentSlide = document.querySelector( - `.slide[data-item-id="${currentItemId}"]`, - ); - const player = STATE.slideshow.players[currentItemId]; - - if (currentSlide && player) { - const trailerContainer = currentSlide.querySelector(".video-container"); - const backdrop = currentSlide.querySelector(".backdrop"); - const plotContainer = currentSlide.querySelector(".plot-container"); - if (trailerContainer) trailerContainer.classList.remove("active"); - if (backdrop) backdrop.classList.remove("with-video"); - if (plotContainer) plotContainer.classList.remove("with-video"); - - try { - if (typeof player.pauseVideo === "function") { - player.pauseVideo(); - } - if (typeof player.seekTo === "function") { - player.seekTo(0); - } - } catch (e) { - console.warn(`Failed to reset player for ${currentItemId}:`, e); - } - } - - if (STATE.slideshow.slideInterval && !STATE.slideshow.isPaused) { - STATE.slideshow.slideInterval.start(); - } + SlideshowManager.updateCurrentSlide(STATE.slideshow.currentSlideIndex); } else if (!isVisible && this.wasVisible) { - // Transitioning FROM visible TO hidden if (STATE.slideshow.slideInterval) { STATE.slideshow.slideInterval.stop(); } - Object.keys(STATE.slideshow.players).forEach((itemId) => { const player = STATE.slideshow.players[itemId]; - if (player && typeof player.pauseVideo === "function") { + if (player && typeof player.destroy === "function") { try { - player.pauseVideo(); - } catch (e) { - console.warn(`Failed to pause player for ${itemId}:`, e); - } + player.destroy(); + } catch (e) {} } }); + STATE.slideshow.players = {}; + container.querySelectorAll(".slide").forEach((slide) => slide.remove()); + STATE.slideshow.createdSlides = {}; } + this.wasVisible = isVisible; }, @@ -1220,11 +1191,6 @@ const SlideCreator = { } catch (e) {} if (videoId) { - // trailerContainer = SlideUtils.createElement("div", { - // className: "video-container", - // id: `trailer-${item.Id}`, - // style: { width: `calc(100vh * 1.777)` }, - // }); trailerContainer = SlideUtils.createElement("div", { className: "video-container", id: `trailer-${item.Id}`, @@ -1541,36 +1507,6 @@ const SlideCreator = { container.appendChild(slide); STATE.slideshow.createdSlides[itemId] = true; - // if (videoId) { - // loadYouTubeAPI().then((YT) => { - // if (!document.getElementById(`trailer-${itemId}`)) return; - - // STATE.slideshow.players[itemId] = new YT.Player( - // `yt-player-${itemId}`, - // { - // videoId: videoId, - // playerVars: { - // autoplay: 0, - // controls: 0, - // rel: 0, - // fs: 0, - // showinfo: 0, - // modestbranding: 1, - // }, - // events: { - // onStateChange: (e) => - // SlideshowManager.onPlayerStateChange( - // e, - // itemId, - // trailerContainer, - // ), - // onReady: (e) => e.target.mute(), - // }, - // }, - // ); - // }); - // } - if (videoId) { const startTime = await ApiUtils.getSkipSegments(videoId); @@ -1752,6 +1688,7 @@ const SlideshowManager = { STATE.slideshow.currentSlideIndex = index; this.updateDots(); this.preloadAdjacentSlides(index); + this.pruneSlideCache(); const itemData = STATE.slideshow.loadedItems[currentItemId]; const hasTrailerData = @@ -1764,7 +1701,8 @@ const SlideshowManager = { setTimeout(() => { if ( STATE.slideshow.currentSlideIndex === index && - !STATE.slideshow.isPaused + !STATE.slideshow.isPaused && + VisibilityObserver.wasVisible ) { const player = STATE.slideshow.players[currentItemId]; @@ -1855,15 +1793,9 @@ const SlideshowManager = { }, nextSlide() { - // if (STATE.slideshow.isVideoPlaying) { - // return; - // } - const currentIndex = STATE.slideshow.currentSlideIndex; const totalItems = STATE.slideshow.totalItems; - const nextIndex = (currentIndex + 1) % totalItems; - this.updateCurrentSlide(nextIndex); }, @@ -2356,7 +2288,7 @@ const initPageVisibilityHandler = () => { } } else { console.log("Tab active - resuming slideshow"); - if (!STATE.slideshow.isPaused) { + if (!STATE.slideshow.isPaused && VisibilityObserver.wasVisible) { const currentItemId = STATE.slideshow.itemIds[STATE.slideshow.currentSlideIndex]; if ( From 787fd379ef28ac9a3c9e9f8578bb44e906e73dae Mon Sep 17 00:00:00 2001 From: M0RPH3US Date: Tue, 19 May 2026 20:39:04 +0530 Subject: [PATCH 2/4] Update slideshowpure.css --- slideshowpure.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slideshowpure.css b/slideshowpure.css index d4a037c..f65f121 100644 --- a/slideshowpure.css +++ b/slideshowpure.css @@ -1,5 +1,5 @@ /* - * Jellyfin Slideshow by M0RPH3US v4.0.4 + * Jellyfin Slideshow by M0RPH3US v4.0.5 */ @import url(https://fonts.googleapis.com/css2?family=Archivo+Narrow:ital,wght@0,400..700;1,400..700&display=swap); From ad2a5473e86ddb171acde094ce312241d86d05e3 Mon Sep 17 00:00:00 2001 From: M0RPH3US Date: Tue, 19 May 2026 21:28:53 +0530 Subject: [PATCH 3/4] Update slideshowpure.js --- slideshowpure.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/slideshowpure.js b/slideshowpure.js index de2f36e..8873a10 100644 --- a/slideshowpure.js +++ b/slideshowpure.js @@ -1,5 +1,5 @@ /* - * Jellyfin Slideshow by M0RPH3US v4.0.5 + * Jellyfin Slideshow by M0RPH3US v4.0.6 */ //Core Module Configuration @@ -17,8 +17,8 @@ const CONFIG = { maxPlotLength: 360, maxMovies: 15, maxTvShows: 15, - maxItems: 500, - preloadCount: 3, + maxItems: 50, + preloadCount: 1, fadeTransitionDuration: 500, slideAnimationEnabled: true, enableTrailers: true, @@ -759,6 +759,12 @@ const ApiUtils = { return STATE.slideshow.loadedItems[itemId]; } + const MAX_CACHED_ITEMS = 20; + const cacheKeys = Object.keys(STATE.slideshow.loadedItems); + if (cacheKeys.length >= MAX_CACHED_ITEMS) { + delete STATE.slideshow.loadedItems[cacheKeys[0]]; + } + const response = await fetch( `${STATE.jellyfinData.serverAddress}/Items/${itemId}`, { @@ -1814,7 +1820,7 @@ const SlideshowManager = { */ pruneSlideCache() { const currentIndex = STATE.slideshow.currentSlideIndex; - const keepRange = 5; + const keepRange = 2; Object.keys(STATE.slideshow.createdSlides).forEach((itemId) => { const index = STATE.slideshow.itemIds.indexOf(itemId); @@ -2036,7 +2042,7 @@ const SlideshowManager = { await this.updateCurrentSlide(0); STATE.slideshow.slideInterval = new SlideTimer(() => { - if (!STATE.slideshow.isPaused) { + if (!STATE.slideshow.isPaused && VisibilityObserver.wasVisible) { this.nextSlide(); } }, CONFIG.shuffleInterval); From 23a98399b8d8d7855c51f0dafbc47716906bff14 Mon Sep 17 00:00:00 2001 From: M0RPH3US Date: Tue, 19 May 2026 21:29:13 +0530 Subject: [PATCH 4/4] Update slideshowpure.css --- slideshowpure.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slideshowpure.css b/slideshowpure.css index f65f121..04ff110 100644 --- a/slideshowpure.css +++ b/slideshowpure.css @@ -1,5 +1,5 @@ /* - * Jellyfin Slideshow by M0RPH3US v4.0.5 + * Jellyfin Slideshow by M0RPH3US v4.0.6 */ @import url(https://fonts.googleapis.com/css2?family=Archivo+Narrow:ital,wght@0,400..700;1,400..700&display=swap);