Add upstream trailer layout feature and update version to 1.5.0.11
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s

This commit is contained in:
CodeDevMLH
2026-02-09 15:55:14 +01:00
parent df1cee0eeb
commit 535c0e17bf
6 changed files with 122 additions and 22 deletions

View File

@@ -52,6 +52,7 @@ const CONFIG = {
customMediaIds: "",
enableLoadingScreen: true,
enableClientSideSettings: false,
enableUpstreamTrailerLayout: false,
sortBy: "Random",
sortOrder: "Ascending",
};
@@ -1537,6 +1538,7 @@ const SlideCreator = {
let backdrop;
let isVideo = false;
let hasUpstreamVideo = false;
let trailerUrl = null;
// 1. Check for Remote/Local Trailers
@@ -1584,13 +1586,31 @@ const SlideCreator = {
if (isYoutube && videoId) {
isVideo = true;
// Create container for YouTube API
const videoClass = CONFIG.fullWidthVideo ? "video-backdrop-full" : "video-backdrop-default";
backdrop = SlideUtils.createElement("div", {
className: `backdrop video-backdrop ${videoClass}`,
id: `youtube-player-${itemId}`
});
if (CONFIG.enableUpstreamTrailerLayout) {
// UPSTREAM LAYOUT: Wrapper Container
const videoContainer = SlideUtils.createElement("div", {
className: "video-container",
id: `video-container-${itemId}`
});
const playerDiv = SlideUtils.createElement("div", {
id: `youtube-player-${itemId}`
});
videoContainer.appendChild(playerDiv);
slide.appendChild(videoContainer); // Append container first
isVideo = false;
hasUpstreamVideo = true;
} else {
// ENHANCED LAYOUT: Direct Backdrop Replacement
backdrop = SlideUtils.createElement("div", {
className: `backdrop video-backdrop ${videoClass}`,
id: `youtube-player-${itemId}`
});
}
// Initialize YouTube Player
SlideUtils.loadYouTubeIframeAPI().then(() => {
@@ -1676,6 +1696,15 @@ const SlideCreator = {
}
},
'onStateChange': (event) => {
const slide = document.querySelector(`.slide[data-item-id="${itemId}"]`);
const videoContainer = slide ? slide.querySelector('.video-container') : null;
if (event.data === YT.PlayerState.PLAYING) {
if (videoContainer) videoContainer.classList.add('active');
} else {
if (videoContainer) videoContainer.classList.remove('active');
}
if (event.data === YT.PlayerState.ENDED) {
if (CONFIG.waitForTrailerToEnd) {
SlideshowManager.nextSlide();
@@ -1737,12 +1766,30 @@ const SlideCreator = {
SlideshowManager.nextSlide();
}
});
if (CONFIG.enableUpstreamTrailerLayout) {
// Wrap in container
const videoContainer = SlideUtils.createElement("div", {
className: "video-container",
id: `video-container-${itemId}`
});
backdrop.style.position = "";
videoContainer.appendChild(backdrop);
slide.appendChild(videoContainer);
isVideo = false;
hasUpstreamVideo = true;
backdrop.addEventListener('play', () => videoContainer.classList.add('active'));
backdrop.addEventListener('pause', () => videoContainer.classList.remove('active'));
backdrop.addEventListener('ended', () => videoContainer.classList.remove('active'));
}
}
}
if (!isVideo) {
backdrop = SlideUtils.createElement("img", {
className: "backdrop high-quality",
className: hasUpstreamVideo ? "backdrop high-quality with-video" : "backdrop high-quality",
src: this.buildImageUrl(item, "Backdrop", 0, serverAddress, 60),
alt: LocalizationUtils.getLocalizedString('Backdrop', 'Backdrop'),
loading: "eager",
@@ -2655,18 +2702,6 @@ const SlideshowManager = {
return;
}
// Only trap keys if focus is on body (neutral) or inside our container.
// To allow standard TV navigation to work for other elements (e.g. library cards).
const activeEl = document.activeElement;
const isBody = activeEl === document.body || !activeEl;
const isInContainer = container.contains(activeEl) || activeEl === container;
if (!isBody && !isInContainer) {
return;
}
const focusElement = document.activeElement;
switch (e.key) {
case "ArrowRight":
SlideshowManager.nextSlide();