Initial Release

This commit is contained in:
M0RPH3US
2025-02-05 18:37:39 +05:30
committed by GitHub
parent f28903c0ee
commit 68844307bd
2 changed files with 1112 additions and 0 deletions
+685
View File
@@ -0,0 +1,685 @@
@import url("https://fonts.googleapis.com/css2?family=Titillium+Web:ital,wght@0,200;0,300;0,400;0,600;0,700;0,900;1,200;1,300;1,400;1,600;1,700&display=swap");
@media only screen and (min-width: 767px) {
div[data-role="page"].page {
overflow-y: scroll; /* Keeps vertical scrolling active */
scrollbar-width: none; /* For Firefox */
-ms-overflow-style: none; /* For Internet Explorer & Edge */
}
div[data-role="page"].page::-webkit-scrollbar {
display: none; /* Hides scrollbar in Webkit browsers */
}
.backdrop,
.slide {
position: absolute;
}
.featured-content,
.plot-container {
font-family: "Titillium Web", sans-serif;
left: 0;
}
.plot,
body {
overflow: hidden;
}
.arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
font-size: 24px;
cursor: pointer;
color: white;
z-index: 3;
display: flex;
justify-content: center;
align-items: center;
}
.arrow::before {
content: ""; /* Creates an empty element */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 40px; /* Size of the circle */
height: 40px; /* Size of the circle */
background-color: rgba(12, 110, 162, 0.7); /* Translucent background */
border-radius: 50%; /* Makes it a circle */
z-index: -1; /* Places the circle behind the arrow */
}
.left-arrow {
left: 10px; /* Position to the left */
}
.right-arrow {
right: 10px; /* Position to the right */
}
.dots-container {
position: absolute;
bottom: 5%;
left: 0;
right: 0;
z-index: 2;
display: flex;
justify-content: center; /* Centers the dots horizontally */
align-items: center;
width: 100vw; /* Full screen width */
height: 22px;
background-color: #ffffff00;
gap: 2vw; /* Evenly space the rectangles with a gap of 2vw */
}
.dot {
width: 15vw; /* Each rectangle takes 18% of the viewport width */
height: 4px; /* Thin rectangle height */
background-color: #cecece;
border-radius: 2px; /* Slightly rounded corners */
cursor: pointer;
transition: background-color 0.3s;
}
.dot.active {
background-color: rgba(12, 110, 162, 0.7) !important;
}
body {
margin: 0;
padding: 0;
}
.fade-in {
opacity: 1 !important;
}
.fade-out {
opacity: 0 !important;
}
#slides-container {
position: relative;
width: 100vw;
height: 750px;
overflow: hidden;
margin: 0 auto;
border-radius: 7px;
top: -5em;
}
.slide {
transition: opacity 0.5s ease-in-out; /* Smooth fade transition */
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: block;
}
.slide.active {
opacity: 1;
display: block;
}
.slide:focus {
outline: #fff solid 2px;
}
.backdrop-container {
position: relative;
top: -40%;
right: -35%;
width: 70%;
height: 100%;
}
.backdrop {
right: 0;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center 20%;
border-radius: 5px;
z-index: 1;
mask-image: linear-gradient(
to top,
rgba(0, 0, 0, 0) 10%,
rgba(0, 0, 0, 0.5) 15%,
rgba(0, 0, 0, 1) 30%
);
-webkit-mask-image: linear-gradient(
to top,
rgba(0, 0, 0, 0) 10%,
rgba(0, 0, 0, 0.5) 15%,
rgba(0, 0, 0, 1) 30%
);
}
.backdrop-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6); /* Adjust the alpha for dimness */
border-radius: 5px;
z-index: 2;
mask-image: linear-gradient(
to top,
rgba(0, 0, 0, 0) 10%,
rgba(0, 0, 0, 0.5) 15%,
rgba(0, 0, 0, 1) 30%
);
-webkit-mask-image: linear-gradient(
to top,
rgba(0, 0, 0, 0) 10%,
rgba(0, 0, 0, 0.5) 15%,
rgba(0, 0, 0, 1) 30%
);
}
.logo-container {
width: 45%;
height: 40%;
position: relative;
display: flex;
justify-content: left;
align-items: left;
}
.logo {
position: relative;
max-height: 100%;
max-width: 100%;
width: auto;
z-index: 3;
top: 5em;
left: 8em;
}
.featured-content {
position: absolute;
top: 0;
width: 100%;
height: 50px;
background-color: transparent;
color: #d3d3d3;
font-size: 22px;
display: none;
align-items: center;
justify-content: flex-start;
z-index: 2;
}
.plot-container {
position: absolute;
bottom: 0;
color: #fff;
width: 50%;
height: 60%;
font-size: 15px;
padding: 10px 0 25px 15px;
border-radius: 5px;
z-index: 3;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
text-align: justify;
}
.plot {
display: -webkit-box;
line-clamp: 4;
-webkit-line-clamp: 4;
-webkit-box-orient: vertical;
left: 7.9em;
position: absolute;
top: 190px;
}
.gradient-overlay {
position: absolute;
top: 0;
left: 0;
width: 70%;
height: 100%;
background: linear-gradient(to right, #000 49%, rgba(0, 0, 0, 0) 70%);
z-index: 2;
mask-image: linear-gradient(
to top,
rgba(0, 0, 0, 0) 8%,
rgba(0, 0, 0, 0.5) 10%,
rgba(0, 0, 0, 1) 12%
);
-webkit-mask-image: linear-gradient(
to top,
rgba(0, 0, 0, 0) 8%,
rgba(0, 0, 0, 0.5) 10%,
rgba(0, 0, 0, 1) 12%
);
}
.genre {
position: absolute;
top: calc(50% + 75px);
left: 8.4em;
text-align: center;
color: #fff;
font-family: "Titillium Web", sans-serif;
font-size: 14px;
z-index: 4;
}
.info-container {
position: absolute;
top: calc(50% + 0px);
display: flex;
align-items: center;
justify-content: center;
left: 2em !important;
color: #fff;
z-index: 4;
}
.rating-value {
font-family: "Titillium Web", sans-serif;
display: flex;
align-items: center;
margin: 0 6em;
z-index: 5;
position: relative;
top: 1.5em;
}
.runTime {
font-family: "Titillium Web", sans-serif;
font-weight: 500;
display: flex;
align-items: center;
margin: 0 8px;
margin-right: -3px;
}
.rating-value img {
margin-right: 6px;
}
.tomato-rating {
display: flex;
align-items: center;
margin-left: 0;
}
.tomato-rating img {
margin-left: 5px;
}
.age-rating {
display: flex;
align-items: center;
margin-left: 5px;
margin-right: 5px;
border-radius: 5px;
background: rgb(255 255 255 / 0.8);
color: #000;
border: none;
font-weight: 600;
white-space: nowrap;
padding: 0 0.6em;
}
.date {
font-family: "Titillium Web", sans-serif;
font-weight: 500;
display: flex;
align-items: center;
margin-right: 5px;
margin-left: 2px;
}
.separator-icon {
margin-left: 5px;
margin-right: 5px;
font-size: 10px;
color: aquamarine;
}
.play-button {
position: absolute;
display: flex;
align-items: center; /* Center vertically */
justify-content: center; /* Keep content aligned horizontally */
padding: 10px 20px;
color: #fff;
background-color: rgba(255, 255, 255, 0);
border: none;
border-radius: 50px; /* Round the edges */
cursor: pointer;
font-size: 14px;
font-weight: 300;
transition: background-color 0.3s;
z-index: 4;
top: calc(50% + 190px);
left: 6.8em;
}
.play-icon {
display: flex;
align-items: center;
justify-content: center;
font-size: 20px; /* Adjust the size of the play icon */
width: 30px; /* Ensure the icon area is circular */
height: 30px;
background-color: rgba(
12,
110,
162,
0.7
); /* Same as the button's background */
border: 3px solid rgba(12, 110, 162, 1);
border-radius: 50%; /* Make the icon a perfect circle */
}
.play-text {
font-family: "Titillium Web", sans-serif;
margin-left: 10px; /* Space between icon and text */
font-size: 14px;
color: #fff;
}
}
@media only screen and (max-width: 767px) {
.backdrop,
.slide {
position: absolute;
}
.arrow {
position: absolute;
/*top: 50%;
transform: translateY(-50%);*/
bottom: 25px;
font-size: 24px;
cursor: pointer;
color: rgba(255, 255, 255, 0.6);
z-index: 4;
-webkit-tap-highlight-color: transparent; /* Disable blue tap highlight */
}
.left-arrow {
left: 10px; /* Position to the left */
}
.right-arrow {
right: 10px; /* Position to the right */
}
.featured-content,
.plot-container {
font-family: "Titillium Web", sans-serif;
left: 0;
}
.plot,
body {
overflow: hidden;
}
body {
margin: 0;
padding: 0;
}
.fade-in {
opacity: 1 !important;
}
.fade-out {
opacity: 0 !important;
}
.dots-container {
position: absolute;
bottom: 11%;
left: 50%;
transform: translateX(-50%) scale(0.6);
z-index: 2;
display: flex;
gap: 5px;
background-color: #ffffff00;
border-radius: 50px;
justify-content: center;
align-items: center;
width: 140px;
height: 22px;
transition: opacity 0.5s ease-in-out;
}
.dot {
display: inline-block;
width: 9px;
height: 9px;
margin: 0 5px;
background-color: #cecece;
border-radius: 50%;
transition: background-color 0.3s;
}
.dot.active {
width: 32px;
height: 12px;
background-color: rgba(12, 110, 162, 0.7);
border-radius: 10px; /* Rounded rectangle shape */
}
#slides-container {
position: relative;
width: 92vw;
height: 650px;
overflow: hidden;
margin: 0 auto;
border-radius: 10px;
}
.slide {
transition: opacity 0.5s ease-in-out; /* Smooth fade transition */
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: block;
}
.slide.active {
opacity: 1;
display: block;
}
.slide:focus {
outline: #fff solid 2px;
}
.logo {
position: absolute;
bottom: 28%;
left: 50%;
transform: translateX(-50%);
max-height: 60%;
max-width: 80%;
width: auto;
z-index: 3;
}
.backdrop {
position: absolute;
top: 45px;
left: 0;
width: 100%;
height: calc(100% - 50px);
object-fit: cover;
object-position: center 20%;
z-index: 1;
border-radius: 13px;
mask-image: linear-gradient(
to top,
rgba(0, 0, 0, 0) 10%,
rgba(0, 0, 0, 0.5) 15%,
rgba(0, 0, 0, 1) 30%
);
-webkit-mask-image: linear-gradient(
to top,
rgba(0, 0, 0, 0) 10%,
rgba(0, 0, 0, 0.5) 15%,
rgba(0, 0, 0, 1) 30%
);
}
.gradient-overlay {
position: absolute;
top: 45px;
left: 0;
width: 100%;
height: calc(100% - 50px);
background: rgba(0, 0, 0, 0.55); /* Semi-transparent overlay color */
z-index: 2;
border-radius: 13px;
pointer-events: none;
mask-image: linear-gradient(
to top,
rgba(0, 0, 0, 0) 10%,
rgba(0, 0, 0, 0.5) 15%,
rgba(0, 0, 0, 1) 30%
);
-webkit-mask-image: linear-gradient(
to top,
rgba(0, 0, 0, 0) 10%,
rgba(0, 0, 0, 0.5) 15%,
rgba(0, 0, 0, 1) 30%
);
}
.genre {
position: absolute;
bottom: 16%;
left: 50%;
transform: translateX(-50%);
text-align: center;
color: #fff;
width: 90%;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-family: "Titillium Web", sans-serif;
font-size: 1.1em;
font-weight: 500;
z-index: 4;
box-sizing: border-box;
}
.info-container {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
bottom: 20%;
left: 50%;
transform: translateX(-50%);
font-size: 1.1em;
color: #fff;
z-index: 5;
width: 100%;
}
.rating-value {
font-family: "Titillium Web", sans-serif;
font-weight: 500;
display: flex;
align-items: center;
}
.date {
font-family: "Titillium Web", sans-serif;
font-weight: 500;
display: flex;
align-items: center;
margin-left: 2px;
}
.tomato-rating {
display: flex;
align-items: center;
}
.tomato-logo {
margin-right: 3px;
}
.critic-logo {
margin-left: 3px;
}
.imdb-logo {
margin-right: 3px;
}
.age-rating {
display: flex;
align-items: center;
border-radius: 5px;
background: rgb(255 255 255 / 0.8);
color: #000;
border: none;
font-weight: 600;
white-space: nowrap;
padding: 0 0.4em;
}
.separator-icon {
margin-left: 5px;
margin-right: 5px;
font-size: 1px;
color: aquamarine;
}
.featured-content,
.plot {
display: none;
}
.play-button {
position: absolute;
display: flex;
align-items: center; /* Center vertically */
justify-content: flex-start; /* Keep content aligned horizontally */
padding: 10px 20px;
color: #fff;
background-color: rgba(255, 255, 255, 0);
border: none;
border-radius: 50px; /* Round the edges */
cursor: pointer;
font-size: 14px;
font-weight: 300;
transition: background-color 0.3s;
z-index: 4;
bottom: 20px;
/*right: 0%;*/
left: 50%;
transform: translateX(-50%) scale(1.2);
outline: none; /* Remove the default blue focus outline */
-webkit-tap-highlight-color: transparent; /* Disable blue tap highlight */
}
.play-icon {
display: flex;
align-items: center;
justify-content: center;
font-size: 20px; /* Adjust the size of the play icon */
width: 20px; /* Ensure the icon area is circular */
height: 20px;
background-color: rgba(
12,
110,
162,
0.7
); /* Same as the button's background */
border: 1.5px solid rgba(12, 110, 162, 1);
border-radius: 50%; /* Make the icon a perfect circle */
outline: none; /* Remove the default blue focus outline */
-webkit-tap-highlight-color: transparent; /* Disable blue tap highlight */
}
.play-text {
display: block;
font-family: "Titillium Web", sans-serif;
margin-left: 5px; /* Space between icon and text */
font-size: 14px;
color: #fff;
}
}
+427
View File
@@ -0,0 +1,427 @@
const slidesInit = () => {
const shuffleInterval = 8000;
let isTransitioning = false;
const listFileName = `${window.location.origin}/web/avatars/list.txt`;
const jsonCredentials = sessionStorage.getItem("json-credentials");
const apiKey = sessionStorage.getItem("api-key");
const serverId = '4810878e0ca94ff0b08cd0df6e483c4f';
let userId = null;
let token = null;
const deviceId = localStorage.getItem("_deviceId2");
console.log(deviceId);
if (jsonCredentials) {
const credentials = JSON.parse(jsonCredentials);
userId = credentials.Servers[0].UserId;
token = credentials.Servers[0].AccessToken;
}
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 tomato = item.CriticRating;
const runtime = item.RunTimeTicks;
const genre = item.Genres;
const youtube = item.RemoteTrailers;
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";
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";
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 {
console.error("Rating is undefined or not a number:", rating);
ratingTest.innerHTML += `N/A ⭐`;
}
ratingTest.appendChild(createSeparator());
const tomatoRatingDiv = document.createElement("div");
tomatoRatingDiv.className = "tomato-rating";
const criticRating = item.CriticRating;
const tomatoLogo = document.createElement("img");
tomatoLogo.className = "tomato-logo";
const criticLogo = document.createElement("img");
criticLogo.className = "critic-logo";
tomatoLogo.src =
"https://upload.wikimedia.org/wikipedia/commons/thumb/d/da/Rotten_Tomatoes_positive_audience.svg/1920px-Rotten_Tomatoes_positive_audience.svg.png";
let valueElement;
if (typeof criticRating === "number") {
valueElement = document.createTextNode(`${criticRating}% `);
} else {
valueElement = document.createTextNode(`N/A `);
}
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 calender = "📅";
const premiereDate = document.createElement("div");
premiereDate.className = "date";
const year = date ? new Date(date).getFullYear() : "N/A";
premiereDate.textContent = isNaN(year) ? "N/A" : year;
ratingTest.appendChild(tomatoRatingDiv);
ratingTest.appendChild(document.createTextNode(calender));
ratingTest.appendChild(premiereDate);
ratingTest.appendChild(createSeparator());
ratingTest.appendChild(ageRatingDiv);
ratingTest.appendChild(createSeparator());
ratingTest.appendChild(runTimeElement);
const genresArray = item.Genres;
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 playButton = document.createElement("button");
playButton.className = "play-button";
playButton.innerHTML = `
<span class="play-icon"><i class="material-icons info_outline"></i></span>
<span class="play-text">Details</span>
`;
playButton.onclick = () => {
window.top.location.href = `/#!/details?id=${itemId}`;
//window.location.href = `/Videos/${itemId}/stream.mp4?Static=true&mediaSourceId=${itemId}&deviceId=${deviceId}&api_key=${apiKey}`;
//window.top.location.href = streamUrl;
};
slide.append(
logoContainer,
backdropContainer,
gradientOverlay,
featuredContent,
plotContainer,
infoContainer,
genreElement,
playButton
);
return slide;
};
const createSlideForItem = async (item, title) => {
const container = document.getElementById("slides-container");
const itemId = item.Id;
const backdropUrl = `${window.location.origin}/Items/${itemId}/Images/Backdrop/0`;
const logoUrl = `${window.location.origin}/Items/${itemId}/Images/Logo`;
const [backdropExists, logoExists] = await Promise.all([
fetch(backdropUrl, { method: "HEAD" }).then((res) => res.ok),
fetch(logoUrl, { method: "HEAD" }).then((res) => res.ok),
]);
if (backdropExists && logoExists) {
const slideElement = createSlideElement(item, title);
container.appendChild(slideElement);
console.log(`Added slide for item ${itemId}`);
if (container.children.length === 1) {
showSlide(0);
}
} else {
console.warn(`Skipping item ${itemId}: Missing backdrop or logo.`);
}
};
const fetchItemDetails = async (itemId) => {
const response = await fetch(
`${window.location.origin}/Users/${userId}/Items/${itemId}`,
{
headers: {
Authorization: `MediaBrowser Client="Jellyfin Web", Device="YourDeviceName", DeviceId="YourDeviceId", Version="YourClientVersion", Token="${token}"`,
},
}
);
const item = await response.json();
console.log("Item Title:", item.Name);
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);
} catch (error) {
console.error("Error fetching list.txt:", error);
return [];
}
};
const fetchItemsFromServer = async () => {
try {
const response = await fetch(
`${window.location.origin}/Users/${userId}/Items?IncludeItemTypes=Movie,Series&Recursive=true&hasOverview=true&imageTypes=Logo,Backdrop&isPlayed=False&Limit=150`,
{
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.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);
}
});
dots.forEach((dot, i) => {
dot.classList.toggle("active", i === index % 5);
});
};
const initializeSlideshow = () => {
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; // Skip if already transitioning
isTransitioning = true; // Set transitioning to true at the start
currentSlideIndex = (index + slides.length) % slides.length;
showSlide(currentSlideIndex);
// Re-enable arrows after a short delay to prevent rapid clicking
setTimeout(() => {
isTransitioning = false; // Reset after transition completes
}, 500); // Adjust the delay as needed (500ms is a reasonable starting point)
};
const openActiveSlide = () => {
if (focusedSlide) {
window.location.href = focusedSlide.href;
}
};
if (slides.length > 0) {
showSlide(currentSlideIndex);
container.style.display = "block";
setTimeout(() => {
setInterval(() => {
updateCurrentSlide(currentSlideIndex + 1);
}, shuffleInterval);
}, 8000);
}
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);
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();
};
document.addEventListener("DOMContentLoaded", () => {
document.body.addEventListener("click", (event) => {
const homeButton = event.target.matches(
".headerHomeButton, .css-17c09up, .mainDrawer-scrollContainer > a:nth-child(2)"
);
if (homeButton) {
event.preventDefault();
window.location.href = "/web/index.html#/home.html";
setTimeout(handleHomeNavigation, 300); // Delay for UI update
}
});
});