Merge branch 'upstream'

# Conflicts:
#	slideshowpure.js
This commit is contained in:
IAmParadox27
2026-05-25 20:43:48 +01:00
2 changed files with 29 additions and 91 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Jellyfin Slideshow by M0RPH3US v4.0.4
* 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);
+28 -90
View File
@@ -1,5 +1,5 @@
/*
* Jellyfin Slideshow by M0RPH3US v4.0.4
* 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,
@@ -188,12 +188,12 @@ const initLocalization = async () => {
*/
const initLoadingScreen = () => {
const currentPath = window.location.href.toLowerCase().replace(window.location.origin, "");
const currentPath = window.location.href.toLowerCase();
const isHomePage =
currentPath.includes("/web/#/home.html") ||
currentPath.includes("/web/#/home") ||
currentPath.includes("/web/index.html#/home.html") ||
currentPath === "/web/index.html#/home" ||
currentPath.endsWith("/web/index.html#/home") ||
currentPath.endsWith("/web/");
if (!isHomePage) return;
@@ -760,6 +760,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}`,
{
@@ -1056,60 +1062,31 @@ const VisibilityObserver = {
if (!container) return;
const isVisible =
(window.location.hash === "#/home.html" ||
window.location.hash === "#/home") &&
activeTab.getAttribute("data-index") === "0";
(window.location.hash === "#/home.html" ||
window.location.hash === "#/home") &&
(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;
},
@@ -1221,11 +1198,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}`,
@@ -1542,36 +1514,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);
@@ -1753,6 +1695,7 @@ const SlideshowManager = {
STATE.slideshow.currentSlideIndex = index;
this.updateDots();
this.preloadAdjacentSlides(index);
this.pruneSlideCache();
const itemData = STATE.slideshow.loadedItems[currentItemId];
const hasTrailerData =
@@ -1765,7 +1708,8 @@ const SlideshowManager = {
setTimeout(() => {
if (
STATE.slideshow.currentSlideIndex === index &&
!STATE.slideshow.isPaused
!STATE.slideshow.isPaused &&
VisibilityObserver.wasVisible
) {
const player = STATE.slideshow.players[currentItemId];
@@ -1856,15 +1800,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);
},
@@ -1883,7 +1821,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);
@@ -2105,7 +2043,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);
@@ -2357,7 +2295,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 (