Refactor visibility management in slideshow and video playback; optimize state updates and debounce observer for improved performance.

This commit is contained in:
CodeDevMLH
2026-02-12 02:28:32 +01:00
parent ccba1857e1
commit a90f805ea8
2 changed files with 59 additions and 35 deletions

View File

@@ -999,14 +999,3 @@
.layout-tv .backdrop-container{ .layout-tv .backdrop-container{
top: -5%; top: -5%;
} }
/* .layout-tv .video-backdrop {
mask-image: linear-gradient(to top,
#fff0 2%,
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%);
} */

View File

@@ -1432,16 +1432,19 @@ const VisibilityObserver = {
// If a full screen video player is active, hide slideshow and stop playback // If a full screen video player is active, hide slideshow and stop playback
if ((videoPlayer && !videoPlayer.classList.contains('hide')) || (trailerPlayer && !trailerPlayer.classList.contains('hide'))) { if ((videoPlayer && !videoPlayer.classList.contains('hide')) || (trailerPlayer && !trailerPlayer.classList.contains('hide'))) {
const container = document.getElementById("slides-container"); if (this._lastVisibleState !== 'player-active') {
if (container) { this._lastVisibleState = 'player-active';
container.style.display = "none"; const container = document.getElementById("slides-container");
container.style.visibility = "hidden"; if (container) {
container.style.pointerEvents = "none"; container.style.display = "none";
container.style.visibility = "hidden";
container.style.pointerEvents = "none";
}
if (STATE.slideshow.slideInterval) {
STATE.slideshow.slideInterval.stop();
}
SlideshowManager.stopAllPlayback();
} }
if (STATE.slideshow.slideInterval) {
STATE.slideshow.slideInterval.stop();
}
SlideshowManager.stopAllPlayback();
return; return;
} }
@@ -1456,20 +1459,27 @@ const VisibilityObserver = {
activeTab && activeTab &&
activeTab.getAttribute("data-index") === "0"; activeTab.getAttribute("data-index") === "0";
container.style.display = isVisible ? "block" : "none"; const newState = isVisible ? 'visible' : 'hidden';
container.style.visibility = isVisible ? "visible" : "hidden";
container.style.pointerEvents = isVisible ? "auto" : "none"; // Only update DOM and trigger actions when state actually changes
if (this._lastVisibleState !== newState) {
this._lastVisibleState = newState;
container.style.display = isVisible ? "block" : "none";
container.style.visibility = isVisible ? "visible" : "hidden";
container.style.pointerEvents = isVisible ? "auto" : "none";
if (isVisible) { if (isVisible) {
if (STATE.slideshow.slideInterval && !STATE.slideshow.isPaused) { if (STATE.slideshow.slideInterval && !STATE.slideshow.isPaused) {
STATE.slideshow.slideInterval.start(); STATE.slideshow.slideInterval.start();
SlideshowManager.resumeActivePlayback(); SlideshowManager.resumeActivePlayback();
}
} else {
if (STATE.slideshow.slideInterval) {
STATE.slideshow.slideInterval.stop();
}
SlideshowManager.stopAllPlayback();
} }
} else {
if (STATE.slideshow.slideInterval) {
STATE.slideshow.slideInterval.stop();
}
SlideshowManager.stopAllPlayback();
} }
}, },
@@ -1477,7 +1487,13 @@ const VisibilityObserver = {
* Initializes visibility observer * Initializes visibility observer
*/ */
init() { init() {
const observer = new MutationObserver(() => this.updateVisibility()); // MARK: Mark
// const observer = new MutationObserver(() => this.updateVisibility());
let debounceTimer = null;
const observer = new MutationObserver(() => {
if (debounceTimer) clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => this.updateVisibility(), 250);
});
observer.observe(document.body, { childList: true, subtree: true }); observer.observe(document.body, { childList: true, subtree: true });
document.body.addEventListener("click", () => this.updateVisibility()); document.body.addEventListener("click", () => this.updateVisibility());
@@ -1700,6 +1716,7 @@ const SlideCreator = {
const iframe = event.target.getIframe(); const iframe = event.target.getIframe();
if (iframe) { if (iframe) {
iframe.setAttribute('tabindex', '-1'); iframe.setAttribute('tabindex', '-1');
iframe.setAttribute('inert', '');
} }
// Store start/end time and videoId for later use // Store start/end time and videoId for later use
@@ -2772,8 +2789,26 @@ const SlideshowManager = {
const currentSlide = document.querySelector(`.slide[data-item-id="${currentItemId}"]`); const currentSlide = document.querySelector(`.slide[data-item-id="${currentItemId}"]`);
if (!currentSlide) return; if (!currentSlide) return;
// Use playCurrentVideo to properly restore video with correct mute state // YouTube player: just resume, don't reload
this.playCurrentVideo(currentSlide, currentItemId); const ytPlayer = STATE.slideshow.videoPlayers?.[currentItemId];
if (ytPlayer && typeof ytPlayer.playVideo === 'function') {
if (STATE.slideshow.isMuted) {
if (typeof ytPlayer.mute === 'function') ytPlayer.mute();
} else {
if (typeof ytPlayer.unMute === 'function') ytPlayer.unMute();
if (typeof ytPlayer.setVolume === 'function') ytPlayer.setVolume(40);
}
ytPlayer.playVideo();
return;
}
// HTML5 video: just resume, don't reset currentTime
const html5Video = currentSlide.querySelector('video.video-backdrop');
if (html5Video) {
html5Video.muted = STATE.slideshow.isMuted;
if (!STATE.slideshow.isMuted) html5Video.volume = 0.4;
html5Video.play().catch(e => console.warn("Error resuming HTML5 video:", e));
}
}, },
/** /**