From 568d0a028cf8dffd666aa2442066b652ef683e43 Mon Sep 17 00:00:00 2001 From: M0RPH3US Date: Sat, 7 Feb 2026 18:01:34 +0530 Subject: [PATCH] Implement page visibility handling for slideshow Added page visibility handling to pause and resume slideshow and videos based on tab visibility. --- slideshowpure.js | 76 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/slideshowpure.js b/slideshowpure.js index 259ac26..6aebe3d 100644 --- a/slideshowpure.js +++ b/slideshowpure.js @@ -1,5 +1,5 @@ /* - * Jellyfin Slideshow by M0RPH3US v4.0.0 + * Jellyfin Slideshow by M0RPH3US v4.0.1 */ //Core Module Configuration @@ -51,6 +51,7 @@ const STATE = { players: {}, ytPromise: null, isMuted: true, + isVideoPlaying: false, }, }; @@ -1595,6 +1596,7 @@ const SlideshowManager = { STATE.slideshow.players[prevItemId].seekTo(0); } } + STATE.slideshow.isVideoPlaying = false; const prevSlide = document.querySelector( `.slide[data-item-id="${prevItemId}"]`, @@ -1737,6 +1739,10 @@ const SlideshowManager = { }, nextSlide() { + if (STATE.slideshow.isVideoPlaying) { + return; + } + const currentIndex = STATE.slideshow.currentSlideIndex; const totalItems = STATE.slideshow.totalItems; @@ -1930,17 +1936,24 @@ const SlideshowManager = { const plotContainer = slide.querySelector(".plot-container"); if (event.data === YT.PlayerState.PLAYING) { + STATE.slideshow.isVideoPlaying = true; if (container) container.classList.add("active"); if (backdrop) backdrop.classList.add("with-video"); if (plotContainer) plotContainer.classList.add("with-video"); if (STATE.slideshow.slideInterval) STATE.slideshow.slideInterval.stop(); } else if (event.data === YT.PlayerState.ENDED) { + STATE.slideshow.isVideoPlaying = false; if (container) container.classList.remove("active"); if (backdrop) backdrop.classList.remove("with-video"); if (plotContainer) plotContainer.classList.remove("with-video"); if (STATE.slideshow.slideInterval) STATE.slideshow.slideInterval.restart(); this.nextSlide(); + } else if ( + event.data === YT.PlayerState.PAUSED || + event.data === YT.PlayerState.CUED + ) { + STATE.slideshow.isVideoPlaying = false; } }, @@ -2188,6 +2201,8 @@ const slidesInit = async () => { initArrowNavigation(); + initPageVisibilityHandler(); + VisibilityObserver.init(); console.log("✅ Enhanced Jellyfin Slideshow initialized successfully"); @@ -2197,6 +2212,65 @@ const slidesInit = async () => { } }; +/** + * Initialize page visibility handling to pause when tab is inactive + */ +const initPageVisibilityHandler = () => { + let wasVideoPlayingBeforeHide = false; + + document.addEventListener("visibilitychange", () => { + if (document.hidden) { + console.log("Tab inactive - pausing slideshow and videos"); + wasVideoPlayingBeforeHide = STATE.slideshow.isVideoPlaying; + if (STATE.slideshow.slideInterval) { + STATE.slideshow.slideInterval.stop(); + } + const currentItemId = + STATE.slideshow.itemIds[STATE.slideshow.currentSlideIndex]; + if (currentItemId && STATE.slideshow.players[currentItemId]) { + const player = STATE.slideshow.players[currentItemId]; + if (typeof player.pauseVideo === "function") { + try { + player.pauseVideo(); + STATE.slideshow.isVideoPlaying = false; + } catch (e) { + console.warn("Error pausing video on tab hide:", e); + } + } + } + } else { + console.log("Tab active - resuming slideshow"); + if (!STATE.slideshow.isPaused) { + const currentItemId = + STATE.slideshow.itemIds[STATE.slideshow.currentSlideIndex]; + if ( + wasVideoPlayingBeforeHide && + currentItemId && + STATE.slideshow.players[currentItemId] + ) { + const player = STATE.slideshow.players[currentItemId]; + if (typeof player.playVideo === "function") { + try { + player.playVideo(); + STATE.slideshow.isVideoPlaying = true; + } catch (e) { + console.warn("Error resuming video on tab show:", e); + if (STATE.slideshow.slideInterval) { + STATE.slideshow.slideInterval.start(); + } + } + } + } else { + if (STATE.slideshow.slideInterval) { + STATE.slideshow.slideInterval.start(); + } + } + wasVideoPlayingBeforeHide = false; + } + } + }); +}; + window.slideshowPure = { CONFIG, STATE,