mirror of
https://github.com/IAmParadox27/jellyfin-plugin-media-bar.git
synced 2026-11-08 16:27:14 +01:00
new file: graveyard/slideshowpure.css new file: graveyard/slideshowpure.js modified: slideshowpure.css modified: slideshowpure.js
599 lines
21 KiB
JavaScript
599 lines
21 KiB
JavaScript
const getJellyfinCredentials = () => {
|
|
const jellyfinCreds = localStorage.getItem("jellyfin_credentials");
|
|
const deviceID = localStorage.getItem("_deviceId2");
|
|
if (!jellyfinCreds) {
|
|
console.error("No Jellyfin credentials found in localStorage");
|
|
return;
|
|
}
|
|
try {
|
|
const serverCredentials = JSON.parse(jellyfinCreds);
|
|
const firstServer = serverCredentials?.Servers?.[0];
|
|
if (!firstServer || !firstServer.AccessToken || !firstServer.UserId) {
|
|
console.error("Invalid Jellyfin credentials structure");
|
|
return;
|
|
}
|
|
return {
|
|
token: firstServer.AccessToken,
|
|
userId: firstServer.UserId,
|
|
deviceID
|
|
};
|
|
} catch (e) {
|
|
console.error("Could not parse Jellyfin credentials", e);
|
|
}
|
|
};
|
|
const credentials = getJellyfinCredentials();
|
|
if (credentials) {
|
|
console.log("Token:", credentials.token, "UserId:", credentials.userId, "DeviceID:", credentials.deviceID);
|
|
}
|
|
|
|
const initLoadingScreen = () => {
|
|
const currentPath = window.location.href.toLowerCase();
|
|
if (
|
|
currentPath.includes("/web/#/home.html") ||
|
|
currentPath.includes("/web/index.html#/home.html") ||
|
|
currentPath.endsWith("/web/")
|
|
) {
|
|
const loadingHTML = `
|
|
<div class="bar-loading" id="page-loader">
|
|
<h1>
|
|
<img src="https://i.imgur.com/DAYQRfa.png"
|
|
alt="Server Logo"
|
|
style="width: 250px; height: auto;">
|
|
</h1>
|
|
<div class="docspinner-loader">
|
|
<div class="loader-spinner-layer"></div>
|
|
</div>
|
|
</div>`;
|
|
document.body.insertAdjacentHTML("beforeend", loadingHTML);
|
|
|
|
const interval = setInterval(() => {
|
|
if (
|
|
document.querySelector(".manualLoginForm") ||
|
|
(
|
|
document.querySelector(".homeSectionsContainer") &&
|
|
document.querySelector(".slide.active")
|
|
)
|
|
) {
|
|
$(".bar-loading").fadeOut(700, () => $(".bar-loading").remove());
|
|
clearInterval(interval);
|
|
}
|
|
}, 100);
|
|
}
|
|
};
|
|
initLoadingScreen();
|
|
|
|
const observer = new MutationObserver((mutations) => {
|
|
for (let mutation of mutations) {
|
|
if (window.location.hash.includes("#/home.html")) {
|
|
let container = document.getElementById("slides-container");
|
|
|
|
if (!container) {
|
|
container = document.createElement("div");
|
|
container.id = "slides-container";
|
|
document.body.appendChild(container);
|
|
slidesInit();
|
|
}
|
|
container.style.display = "block";
|
|
} else {
|
|
const container = document.getElementById("slides-container");
|
|
if (container) container.style.display = "none";
|
|
}
|
|
}
|
|
});
|
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
|
|
|
|
const slidesInit = () => {
|
|
if (window.hasInitializedSlideshow) {
|
|
console.log("Slideshow already initialized. Skipping re-init.");
|
|
return;
|
|
}
|
|
window.hasInitializedSlideshow = !0;
|
|
const shuffleInterval = 8000;
|
|
let isTransitioning = !1;
|
|
const listFileName = `${window.location.origin}/web/avatars/list.txt`;
|
|
const { token, userId } = getJellyfinCredentials();
|
|
const shuffleArray = (array) => array.sort(() => Math.random() - 0.5);
|
|
const truncateText = (element, maxLength) => {
|
|
let text = element.innerText;
|
|
if (text.length > maxLength)
|
|
element.innerText = text.substring(0, maxLength) + "...";
|
|
};
|
|
const createSlideElement = (item, title) => {
|
|
const itemId = item.Id;
|
|
const plot = item.Overview || "No overview available";
|
|
const rating = item.CommunityRating;
|
|
const criticRating = item.CriticRating;
|
|
const runtime = item.RunTimeTicks;
|
|
const genresArray = item.Genres;
|
|
const age = item.OfficialRating;
|
|
const date = item.PremiereDate;
|
|
const season = item.ChildCount;
|
|
function createSeparator() {
|
|
const separatorHtml =
|
|
'<i class="material-icons radio_button_off separator-icon"></i>';
|
|
const tempDiv = document.createElement("div");
|
|
tempDiv.innerHTML = separatorHtml;
|
|
return tempDiv.firstChild;
|
|
}
|
|
const slide = document.createElement("a");
|
|
slide.className = "slide";
|
|
slide.target = "_top";
|
|
slide.rel = "noreferrer";
|
|
slide.tabIndex = 0;
|
|
slide.style.display = "none";
|
|
const backdrop = document.createElement("img");
|
|
backdrop.className = "backdrop";
|
|
backdrop.src = `${window.location.origin}/Items/${itemId}/Images/Backdrop/0`;
|
|
backdrop.alt = "Backdrop";
|
|
backdrop.loading = "eager";
|
|
const backdropOverlay = document.createElement("div");
|
|
backdropOverlay.className = "backdrop-overlay";
|
|
const backdropContainer = document.createElement("div");
|
|
backdropContainer.className = "backdrop-container";
|
|
backdropContainer.appendChild(backdrop);
|
|
backdropContainer.appendChild(backdropOverlay);
|
|
const logo = document.createElement("img");
|
|
logo.className = "logo";
|
|
logo.src = `${window.location.origin}/Items/${itemId}/Images/Logo`;
|
|
logo.alt = "Logo";
|
|
logo.loading = "eager";
|
|
const logoContainer = document.createElement("div");
|
|
logoContainer.className = "logo-container";
|
|
logoContainer.appendChild(logo);
|
|
const featuredContent = document.createElement("div");
|
|
featuredContent.className = "featured-content";
|
|
featuredContent.textContent = title;
|
|
const plotElement = document.createElement("div");
|
|
plotElement.className = "plot";
|
|
plotElement.textContent = plot;
|
|
truncateText(plotElement, 360);
|
|
const plotContainer = document.createElement("div");
|
|
plotContainer.className = "plot-container";
|
|
plotContainer.appendChild(plotElement);
|
|
const gradientOverlay = document.createElement("div");
|
|
gradientOverlay.className = "gradient-overlay";
|
|
const runTimeElement = document.createElement("div");
|
|
runTimeElement.className = "runTime";
|
|
if (season === undefined) {
|
|
const milliseconds = runtime / 10000;
|
|
const currentTime = new Date();
|
|
const endTime = new Date(currentTime.getTime() + milliseconds);
|
|
const options = { hour: "2-digit", minute: "2-digit", hour12: !0 };
|
|
const formattedEndTime = endTime.toLocaleTimeString([], options);
|
|
runTimeElement.textContent = `Ends at ${formattedEndTime}`;
|
|
} else {
|
|
runTimeElement.textContent = `${season} Season${season > 1 ? "s" : ""}`;
|
|
}
|
|
const ratingTest = document.createElement("div");
|
|
ratingTest.className = "rating-value";
|
|
const imdbLogo = document.createElement("img");
|
|
imdbLogo.className = "imdb-logo";
|
|
imdbLogo.src =
|
|
"https://upload.wikimedia.org/wikipedia/commons/6/69/IMDB_Logo_2016.svg";
|
|
imdbLogo.alt = "IMDb Logo";
|
|
imdbLogo.style.width = "30px";
|
|
imdbLogo.style.height = "30px";
|
|
ratingTest.appendChild(imdbLogo);
|
|
if (typeof rating === "number") {
|
|
const formattedRating = rating.toFixed(1);
|
|
ratingTest.innerHTML += `${formattedRating}`;
|
|
} else {
|
|
ratingTest.innerHTML += `<span style="color: #fff9;">N/A</span>`;
|
|
}
|
|
ratingTest.appendChild(createSeparator());
|
|
const tomatoRatingDiv = document.createElement("div");
|
|
tomatoRatingDiv.className = "tomato-rating";
|
|
const tomatoLogo = document.createElement("img");
|
|
tomatoLogo.className = "tomato-logo";
|
|
tomatoLogo.src =
|
|
"https://upload.wikimedia.org/wikipedia/commons/thumb/d/da/Rotten_Tomatoes_positive_audience.svg/1920px-Rotten_Tomatoes_positive_audience.svg.png";
|
|
const criticLogo = document.createElement("img");
|
|
criticLogo.className = "critic-logo";
|
|
let valueElement;
|
|
if (typeof criticRating === "number") {
|
|
valueElement = document.createTextNode(`${criticRating}% `);
|
|
} else {
|
|
const naSpan = document.createElement("span");
|
|
naSpan.textContent = "N/A ";
|
|
naSpan.style.color = "#fff9";
|
|
valueElement = naSpan;
|
|
}
|
|
if (criticRating === undefined || criticRating <= 59) {
|
|
criticLogo.src =
|
|
"https://upload.wikimedia.org/wikipedia/commons/thumb/5/52/Rotten_Tomatoes_rotten.svg/1024px-Rotten_Tomatoes_rotten.svg.png";
|
|
criticLogo.alt = "Rotten Tomato";
|
|
} else {
|
|
criticLogo.src = "https://i.imgur.com/iMfwDk7.png";
|
|
criticLogo.alt = "Fresh Tomato";
|
|
}
|
|
tomatoLogo.style.width = "15px";
|
|
tomatoLogo.style.height = "17px";
|
|
criticLogo.style.width = "15px";
|
|
criticLogo.style.height = "15px";
|
|
tomatoRatingDiv.appendChild(tomatoLogo);
|
|
tomatoRatingDiv.appendChild(valueElement);
|
|
tomatoRatingDiv.appendChild(criticLogo);
|
|
tomatoRatingDiv.appendChild(createSeparator());
|
|
const ageRatingDiv = document.createElement("div");
|
|
ageRatingDiv.className = "age-rating";
|
|
if (item.OfficialRating) {
|
|
ageRatingDiv.innerHTML = `${item.OfficialRating}`;
|
|
} else {
|
|
ageRatingDiv.innerHTML = `N/A`;
|
|
}
|
|
const premiereDate = document.createElement("div");
|
|
premiereDate.className = "date";
|
|
const year = date ? new Date(date).getFullYear() : NaN;
|
|
if (isNaN(year)) {
|
|
const naSpan = document.createElement("span");
|
|
naSpan.textContent = "N/A";
|
|
naSpan.style.color = "#fff9";
|
|
premiereDate.innerHTML = "";
|
|
premiereDate.appendChild(naSpan);
|
|
} else {
|
|
premiereDate.textContent = year;
|
|
}
|
|
ratingTest.appendChild(tomatoRatingDiv);
|
|
ratingTest.appendChild(premiereDate);
|
|
ratingTest.appendChild(createSeparator());
|
|
ratingTest.appendChild(ageRatingDiv);
|
|
ratingTest.appendChild(createSeparator());
|
|
ratingTest.appendChild(runTimeElement);
|
|
function parseGenres(genresArray) {
|
|
if (genresArray && genresArray.length > 0) {
|
|
return genresArray.slice(0, 3).join(" 🔹 ");
|
|
} else {
|
|
return "No Genre Available";
|
|
}
|
|
}
|
|
const genreElement = document.createElement("div");
|
|
genreElement.className = "genre";
|
|
genreElement.innerHTML = parseGenres(genresArray);
|
|
const infoContainer = document.createElement("div");
|
|
infoContainer.className = "info-container";
|
|
infoContainer.appendChild(ratingTest);
|
|
const buttonContainer = document.createElement("div");
|
|
buttonContainer.className = "button-container";
|
|
const playButton = document.createElement("button");
|
|
playButton.className = "play-button";
|
|
playButton.innerHTML = `
|
|
<span class="play-icon"><i class="material-icons">play_circle_fill</i></span>
|
|
<span class="play-text">Play</span>
|
|
`;
|
|
playButton.onclick = async () => {
|
|
const apiClient = window.ApiClient;
|
|
const userId = apiClient.getCurrentUserId();
|
|
const mediabrowser = apiClient.appName();
|
|
const appVersion = apiClient.appVersion();
|
|
const deviceName = apiClient.deviceName();
|
|
const deviceId = apiClient.deviceId();
|
|
const accessToken = apiClient.accessToken();
|
|
const baseUrl = apiClient.serverAddress();
|
|
if (!userId || !mediabrowser || !deviceName || !deviceId || !appVersion || !accessToken || !baseUrl) {
|
|
console.error("Details not found.");
|
|
return;
|
|
}
|
|
let sessionId = null;
|
|
try {
|
|
const response = await fetch(`${baseUrl}/Sessions?deviceId=${encodeURIComponent(deviceId)}`, {
|
|
headers: {
|
|
'X-Emby-Authorization': `MediaBrowser Client="${mediabrowser}", Device="${deviceName}", DeviceId="${deviceId}", Version="${appVersion}", Token="${accessToken}"`
|
|
}
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to fetch session data: ${response.statusText}`);
|
|
}
|
|
const sessions = await response.json();
|
|
if (sessions.length === 0) {
|
|
console.warn("No sessions found for deviceId:", deviceId);
|
|
return;
|
|
}
|
|
const session = sessions[0];
|
|
sessionId = session.Id;
|
|
console.log("Found sessionId:", sessionId);
|
|
} catch (error) {
|
|
console.error("Error fetching session data:", error);
|
|
return;
|
|
}
|
|
if (!sessionId) {
|
|
console.error("Session ID not found.");
|
|
return;
|
|
}
|
|
const playUrl = `${baseUrl}/Sessions/${sessionId}/Playing?playCommand=PlayNow&itemIds=${itemId}`;
|
|
try {
|
|
const playResponse = await fetch(playUrl, {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-Emby-Authorization': `MediaBrowser Client="${mediabrowser}", Device="${deviceName}", DeviceId="${deviceId}", Version="${appVersion}", Token="${accessToken}"`
|
|
}
|
|
});
|
|
if (!playResponse.ok) {
|
|
throw new Error(`Failed to send play command: ${playResponse.statusText}`);
|
|
}
|
|
console.log("Play command sent successfully to session:", sessionId);
|
|
} catch (error) {
|
|
console.error("Error sending play command:", error);
|
|
}
|
|
};
|
|
const detailButton = document.createElement("button");
|
|
detailButton.className = "detail-button";
|
|
detailButton.innerHTML = `
|
|
<span class="detail-icon"><i class="material-icons info_outline"></i></span>
|
|
<span class="detail-text">Info</span>
|
|
`;
|
|
detailButton.onclick = () => {
|
|
Emby.Page.show(`/details?id=${itemId}`);
|
|
}
|
|
buttonContainer.appendChild(detailButton);
|
|
buttonContainer.appendChild(playButton);
|
|
slide.append(
|
|
logoContainer,
|
|
backdropContainer,
|
|
gradientOverlay,
|
|
featuredContent,
|
|
plotContainer,
|
|
infoContainer,
|
|
genreElement,
|
|
buttonContainer
|
|
);
|
|
return slide;
|
|
};
|
|
const createSlideForItem = async (item, title) => {
|
|
const container = document.getElementById("slides-container");
|
|
const itemId = item.Id;
|
|
const slideElement = createSlideElement(item, title);
|
|
container.appendChild(slideElement);
|
|
if (container.children.length === 1) {
|
|
showSlide(0);
|
|
}
|
|
};
|
|
const fetchItemDetails = async (itemId) => {
|
|
const response = await fetch(`${window.location.origin}/Items/${itemId}`, {
|
|
headers: {
|
|
Authorization: `MediaBrowser Client="Jellyfin Web", Device="YourDeviceName", DeviceId="YourDeviceId", Version="YourClientVersion", Token="${token}"`,
|
|
},
|
|
});
|
|
const item = await response.json();
|
|
return item;
|
|
};
|
|
const fetchItemIdsFromList = async () => {
|
|
try {
|
|
const response = await fetch(listFileName);
|
|
if (!response.ok) {
|
|
throw new Error("Failed to fetch list.txt");
|
|
}
|
|
const text = await response.text();
|
|
return text
|
|
.split("\n")
|
|
.map((id) => id.trim())
|
|
.filter((id) => id)
|
|
.slice(1);
|
|
} catch (error) {
|
|
console.error("Error fetching list.txt:", error);
|
|
return [];
|
|
}
|
|
};
|
|
const fetchItemsFromServer = async () => {
|
|
try {
|
|
const response = await fetch(
|
|
`${window.location.origin}/Items?IncludeItemTypes=Movie,Series&Recursive=true&hasOverview=true&imageTypes=Logo,Backdrop&SortBy=random&isPlayed=False&Limit=100`,
|
|
{
|
|
headers: {
|
|
Authorization: `MediaBrowser Client="Jellyfin Web", Device="YourDeviceName", DeviceId="YourDeviceId", Version="YourClientVersion", Token="${token}"`,
|
|
},
|
|
}
|
|
);
|
|
const data = await response.json();
|
|
const items = data.Items;
|
|
const movies = items.filter((item) => item.Type === "Movie");
|
|
const tvShows = items.filter((item) => item.Type === "Series");
|
|
const shuffledMovies = shuffleArray(movies);
|
|
const shuffledTvShows = shuffleArray(tvShows);
|
|
const selectedMovies = shuffledMovies.slice(0, 15);
|
|
const selectedTvShows = shuffledTvShows.slice(0, 15);
|
|
const allItems = [];
|
|
const maxLength = Math.max(selectedMovies.length, selectedTvShows.length);
|
|
for (let i = 0; i < maxLength; i++) {
|
|
if (i < selectedMovies.length) allItems.push(selectedMovies[i]);
|
|
if (i < selectedTvShows.length) allItems.push(selectedTvShows[i]);
|
|
}
|
|
return allItems;
|
|
} catch (error) {
|
|
console.error("Error fetching items:", error);
|
|
return [];
|
|
}
|
|
};
|
|
const createSlidesForItems = async (items) => {
|
|
await Promise.all(
|
|
items.map((item) =>
|
|
createSlideForItem(item, item.Type === "Movie" ? "Movie" : "TV Show")
|
|
)
|
|
);
|
|
};
|
|
const createPaginationDots = () => {
|
|
const dotsContainer = document.createElement("div");
|
|
dotsContainer.className = "dots-container";
|
|
for (let i = 0; i < 5; i++) {
|
|
const dot = document.createElement("span");
|
|
dot.className = "dot";
|
|
dotsContainer.appendChild(dot);
|
|
}
|
|
const container = document.getElementById("slides-container");
|
|
container.appendChild(dotsContainer);
|
|
};
|
|
const showSlide = (index) => {
|
|
const slides = document.querySelectorAll(".slide");
|
|
const dots = document.querySelectorAll(".dot");
|
|
slides.forEach((slide, i) => {
|
|
if (i === index) {
|
|
slide.style.removeProperty("display");
|
|
slide.style.display = "block";
|
|
slide.offsetHeight;
|
|
slide.style.opacity = "1";
|
|
slide.classList.add("active");
|
|
} else {
|
|
slide.style.opacity = "0";
|
|
slide.classList.remove("active");
|
|
setTimeout(() => {
|
|
slide.style.display = "none";
|
|
}, 500);
|
|
}
|
|
document.getElementById("slides-container").offsetHeight;
|
|
});
|
|
dots.forEach((dot, i) => {
|
|
dot.classList.toggle("active", i === index % 5);
|
|
});
|
|
};
|
|
const initializeSlideshow = () => {
|
|
var slideInterval = null;
|
|
class SlideTimer {
|
|
constructor(fnctn, time) {
|
|
var timerObject = setInterval(fnctn, time);
|
|
this.stop = function () { if (timerObject) { clearInterval(timerObject); timerObject = null; } return this; };
|
|
this.start = function () { if (!timerObject) { this.stop(); timerObject = setInterval(fnctn, time); } return this; };
|
|
this.restart = function () { return this.stop().start(); };
|
|
}
|
|
}
|
|
const slides = document.querySelectorAll(".slide");
|
|
createPaginationDots();
|
|
const container = document.getElementById("slides-container");
|
|
let currentSlideIndex = 0;
|
|
let focusedSlide = null;
|
|
let containerFocused = !1;
|
|
const updateCurrentSlide = (index) => {
|
|
if (isTransitioning) return;
|
|
isTransitioning = !0;
|
|
currentSlideIndex = (index + slides.length) % slides.length;
|
|
showSlide(currentSlideIndex);
|
|
slideInterval.restart();
|
|
setTimeout(() => {
|
|
isTransitioning = !1;
|
|
}, 500);
|
|
};
|
|
const openActiveSlide = () => {
|
|
if (focusedSlide) {
|
|
window.location.href = focusedSlide.href;
|
|
}
|
|
};
|
|
if (slides.length > 0) {
|
|
showSlide(currentSlideIndex);
|
|
container.style.display = "block";
|
|
slideInterval =
|
|
new SlideTimer(function () {
|
|
updateCurrentSlide(currentSlideIndex + 1);
|
|
}, shuffleInterval);
|
|
}
|
|
slides.forEach((slide) => {
|
|
slide.addEventListener(
|
|
"focus",
|
|
() => {
|
|
focusedSlide = slide;
|
|
container.classList.remove("disable-interaction");
|
|
},
|
|
!0
|
|
);
|
|
slide.addEventListener(
|
|
"blur",
|
|
() => {
|
|
if (focusedSlide === slide) {
|
|
focusedSlide = null;
|
|
}
|
|
},
|
|
!0
|
|
);
|
|
});
|
|
document.addEventListener("keydown", (event) => {
|
|
if (containerFocused) {
|
|
switch (event.keyCode) {
|
|
case 37:
|
|
updateCurrentSlide(currentSlideIndex - 1);
|
|
break;
|
|
case 39:
|
|
updateCurrentSlide(currentSlideIndex + 1);
|
|
break;
|
|
case 13:
|
|
case 32:
|
|
openActiveSlide();
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
const leftArrow = document.createElement("div");
|
|
const rightArrow = document.createElement("div");
|
|
leftArrow.classList.add("arrow", "left-arrow");
|
|
rightArrow.classList.add("arrow", "right-arrow");
|
|
leftArrow.innerHTML = '<i class="material-icons arrow_back_ios_new"></i>';
|
|
rightArrow.innerHTML = '<i class="material-icons arrow_forward_ios"></i>';
|
|
container.appendChild(leftArrow);
|
|
container.appendChild(rightArrow);
|
|
let touchStartX = 0;
|
|
let touchEndX = 0;
|
|
const minSwipeDistance = 50;
|
|
let isTouchOnButton = false;
|
|
|
|
container.addEventListener(
|
|
"touchstart",
|
|
(event) => {
|
|
touchStartX = event.touches[0].clientX;
|
|
isTouchOnButton =
|
|
event.target.closest(".play-button, .detail-button") !== null;
|
|
},
|
|
{ passive: false }
|
|
);
|
|
container.addEventListener(
|
|
"touchmove",
|
|
(event) => {
|
|
touchEndX = event.touches[0].clientX;
|
|
},
|
|
{ passive: false }
|
|
);
|
|
|
|
container.addEventListener(
|
|
"touchend",
|
|
(event) => {
|
|
if (isTouchOnButton) return;
|
|
|
|
const swipeDistance = touchEndX - touchStartX;
|
|
if (Math.abs(swipeDistance) > minSwipeDistance) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
if (swipeDistance < 0) {
|
|
updateCurrentSlide(currentSlideIndex + 1);
|
|
} else {
|
|
updateCurrentSlide(currentSlideIndex - 1);
|
|
}
|
|
}
|
|
},
|
|
{ passive: false }
|
|
);
|
|
leftArrow.addEventListener("click", () =>
|
|
updateCurrentSlide(currentSlideIndex - 1)
|
|
);
|
|
rightArrow.addEventListener("click", () =>
|
|
updateCurrentSlide(currentSlideIndex + 1)
|
|
);
|
|
container.addEventListener("focus", () => {
|
|
containerFocused = !0;
|
|
});
|
|
container.addEventListener("blur", () => {
|
|
containerFocused = !1;
|
|
});
|
|
};
|
|
const initializeSlides = async () => {
|
|
const itemIds = await fetchItemIdsFromList();
|
|
let items;
|
|
if (itemIds.length > 0) {
|
|
const itemPromises = itemIds.map((id) => fetchItemDetails(id));
|
|
items = await Promise.all(itemPromises);
|
|
} else {
|
|
const allItems = await fetchItemsFromServer();
|
|
const itemPromises = allItems.map((item) => fetchItemDetails(item.Id));
|
|
items = await Promise.all(itemPromises);
|
|
}
|
|
items = shuffleArray(items);
|
|
await createSlidesForItems(items);
|
|
initializeSlideshow();
|
|
};
|
|
initializeSlides();
|
|
}; |