From 716ddaa5d852e42cd965df991073c51aee52d6fd Mon Sep 17 00:00:00 2001 From: M0RPH3US Date: Tue, 11 Feb 2025 23:46:59 +0530 Subject: [PATCH 1/2] Changed playback code --- slideshowpure.css | 233 +++++++++++++++------------------------------- slideshowpure.js | 81 ++++++++++------ 2 files changed, 123 insertions(+), 191 deletions(-) diff --git a/slideshowpure.css b/slideshowpure.css index 4afc598..e7dbf5f 100644 --- a/slideshowpure.css +++ b/slideshowpure.css @@ -54,11 +54,11 @@ } .left-arrow { - left: 10px; + left: 20px; } .right-arrow { - right: 10px; + right: 20px; } .dots-container { @@ -104,12 +104,11 @@ #slides-container { position: relative; - width: 100vw; - height: 750px; + width: 92vw; + height: 650px; overflow: hidden; margin: 0 auto; - border-radius: 7px; - top: -5em; + border-radius: 15px; } .slide { @@ -223,7 +222,7 @@ position: absolute; bottom: 0; color: #fff; - width: 50%; + width: 90%; height: 60%; font-size: 15px; padding: 10px 0 25px 15px; @@ -342,93 +341,54 @@ font-size: 10px; color: aquamarine; } - .play-button { + .button-container { position: absolute; + top: calc(50% + 190px); /* Same as the previous button positions */ + left: 7.5em; display: flex; - align-items: center; - justify-content: center; - padding: 10px 20px; - color: #fff; - background-color: rgba(255, 255, 255, 0); - border: none; - border-radius: 50px; - 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; - width: 30px; - height: 30px; - background-color: rgba( - 12, - 110, - 162, - 0.7 - ); - border: 3px solid rgba(12, 110, 162, 1); - border-radius: 50%; - } - - .play-text { - font-family: "Titillium Web", sans-serif; - margin-left: 10px; - font-size: 14px; - color: #fff; + gap: 2em; /* Space between buttons */ + z-index: 5; /* Ensures it's above other elements */ } + .play-button, .detail-button { - position: absolute; - display: flex; + display: inline-flex; /* Ensures icon and text are on the same line */ align-items: center; justify-content: center; - padding: 10px 20px; - color: #fff; - background-color: rgba(255, 255, 255, 0); - border: none; - border-radius: 50px; + padding: 8px 16px; /* Slightly reduced padding for thinner buttons */ + border: solid 2px; + border-radius: 25px; /* Sleeker look */ + font-size: 14px; + white-space: nowrap; /* Prevents text wrapping */ cursor: pointer; - font-size: 14px; - font-weight: 300; - transition: background-color 0.3s; - z-index: 4; - top: calc(50% + 190px); - left: 15.8em; + transition: all 0.3s ease; + font-weight: bold; + gap: 6px; /* Adds space between icon and text */ + -webkit-tap-highlight-color: transparent; } + .play-button { + background-color: #ffffff; + color: #000; + } + + .detail-button { + background-color: rgba(255, 255, 255, 0); + color: #fff; + } + + .play-button:hover, + .detail-button:hover { + opacity: 0.8; + } + + .play-icon, .detail-icon { + font-size: 18px; /* Ensures icons are aligned with text */ display: flex; align-items: center; - justify-content: center; - font-size: 20px; - width: 30px; - height: 30px; - background-color: rgba( - 12, - 110, - 162, - 0.7 - ); - border: 3px solid rgba(12, 110, 162, 1); - border-radius: 50%; - } - - .detail-text { - font-family: "Titillium Web", sans-serif; - margin-left: 10px; - font-size: 14px; - color: #fff; } } - @media only screen and (max-width: 767px) { .backdrop, .slide { @@ -676,99 +636,52 @@ display: none; } - .play-button { + .button-container { position: absolute; - display: flex; - align-items: center; - justify-content: flex-start; - padding: 10px 20px; - color: #fff; - background-color: rgba(255, 255, 255, 0); - border: none; - border-radius: 50px; - cursor: pointer; - font-size: 14px; - font-weight: 300; - transition: background-color 0.3s; - z-index: 4; bottom: 20px; left: 50%; - transform: translateX(-110%) scale(1.2); - outline: none; - -webkit-tap-highlight-color: transparent; - } - - .play-icon { + transform: translateX(-50%); display: flex; - align-items: center; - justify-content: center; - font-size: 20px; - width: 20px; - height: 20px; - background-color: rgba( - 12, - 110, - 162, - 0.7 - ); - border: 1.5px solid rgba(12, 110, 162, 1); - border-radius: 50%; - outline: none; - -webkit-tap-highlight-color: transparent; + gap: 15px; /* Adjust spacing between buttons */ + z-index: 4; } - .play-text { - display: block; - font-family: "Titillium Web", sans-serif; - margin-left: 5px; - font-size: 14px; - color: #fff; - } + .play-button, .detail-button { - position: absolute; - display: flex; - align-items: center; - justify-content: flex-start; - padding: 10px 20px; - color: #fff; - background-color: rgba(255, 255, 255, 0); - border: none; - border-radius: 50px; - cursor: pointer; - font-size: 14px; - font-weight: 300; - transition: background-color 0.3s; - z-index: 4; - bottom: 20px; - left: 50%; - transform: translateX(10%) scale(1.2); - outline: none; - -webkit-tap-highlight-color: transparent; - } - - .detail-icon { - display: flex; + display: inline-flex; /* Ensures icon and text are on the same line */ align-items: center; justify-content: center; - font-size: 20px; - width: 20px; - height: 20px; - background-color: rgba( - 12, - 110, - 162, - 0.7 - ); - border: 1.5px solid rgba(12, 110, 162, 1); - border-radius: 50%; - outline: none; + padding: 8px 16px; /* Slightly reduced padding for thinner buttons */ + border: none; + border-radius: 20px; /* Sleeker look */ + font-size: 14px; + white-space: nowrap; /* Prevents text wrapping */ + cursor: pointer; + transition: all 0.3s ease; + font-weight: bold; + gap: 6px; /* Adds space between icon and text */ -webkit-tap-highlight-color: transparent; } - .detail-text { - display: block; - font-family: "Titillium Web", sans-serif; - margin-left: 5px; + .play-button { + background-color: #ffffff; + color: #000; + } + + .detail-button { + background-color: rgba(255, 255, 255, 0.2); color: #fff; } + + .play-button:hover, + .detail-button:hover { + opacity: 0.8; + } + + .play-icon, + .detail-icon { + font-size: 18px; /* Ensures icons are aligned with text */ + display: flex; + align-items: center; + } } diff --git a/slideshowpure.js b/slideshowpure.js index 8f98520..073e050 100644 --- a/slideshowpure.js +++ b/slideshowpure.js @@ -5,8 +5,8 @@ const slidesInit = () => { const jsonCredentials = sessionStorage.getItem("json-credentials"); let userId = null; let token = null; - const deviceId = localStorage.getItem("_deviceId2"); - console.log(deviceId); + //const deviceId = localStorage.getItem("_deviceId2"); + //console.log(deviceId); if (jsonCredentials) { const credentials = JSON.parse(jsonCredentials); userId = credentials.Servers[0].UserId; @@ -165,59 +165,78 @@ const slidesInit = () => { const infoContainer = document.createElement("div"); infoContainer.className = "info-container"; infoContainer.appendChild(ratingTest); + // Create a container for the buttons + const buttonContainer = document.createElement("div"); + buttonContainer.className = "button-container"; // Add a class for styling + + // Create the Play button const playButton = document.createElement("button"); playButton.className = "play-button"; playButton.innerHTML = ` - - Play Now - `; + + Play +`; playButton.onclick = async () => { + if (!window.PlaybackManager) { + console.error("PlaybackManager is not available."); + return; + } + if (!window.ApiClient) { console.error("Jellyfin API client is not available."); return; } + const apiClient = window.ApiClient; const userId = apiClient.getCurrentUserId(); + if (!userId) { console.error("User not found."); return; } + try { - const sessions = await apiClient.getJSON( - apiClient.serverAddress() + "/Sessions" - ); - if (!sessions.length) { - console.error("No active Jellyfin sessions found."); + // Fetch the media item details + const item = await apiClient.getItem(userId, itemId); + if (!item) { + console.error("Media item not found."); return; } - const sessionId = sessions[0].Id; - const playbackUrl = `${apiClient.serverAddress()}/Sessions/${sessionId}/Playing?StartPositionTicks=0&PlayCommand=PlayNow&StartIndex=0&ItemIds=${itemId}&api_key=${token}`; - const response = await fetch(playbackUrl, { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `MediaBrowser Client="Jellyfin Web", Device="YourDevice", DeviceId="YourDeviceId", Version="YourVersion", Token="${token}"`, - }, - }); - if (response.status === 204) { - console.log("Playback started successfully."); - } else { - const errorData = await response.json(); - console.error("Failed to start playback:", errorData); - } + + // Initiate playback using PlaybackManager + window.PlaybackManager.play({ + items: [item], + startPositionTicks: 0, // Start from beginning + isMuted: false, + isPaused: false, + }) + .then(() => { + console.log("Playback started successfully."); + }) + .catch((error) => { + console.error("Failed to start playback:", error); + }); } catch (error) { - console.error("Error fetching sessions:", error); + console.error("Error starting playback:", error); } }; + + // Create the Details button const detailButton = document.createElement("button"); detailButton.className = "detail-button"; detailButton.innerHTML = ` - - More Details - `; + + Info +`; detailButton.onclick = () => { window.top.location.href = `/#!/details?id=${itemId}`; }; + + // Append buttons to the button container + buttonContainer.appendChild(playButton); + buttonContainer.appendChild(detailButton); + + // Append all elements to the slide slide.append( logoContainer, backdropContainer, @@ -226,9 +245,9 @@ const slidesInit = () => { plotContainer, infoContainer, genreElement, - playButton, - detailButton + buttonContainer ); + return slide; }; const createSlideForItem = async (item, title) => { From ccf3f943b31f187f85965aadf461ee55f45a4f33 Mon Sep 17 00:00:00 2001 From: M0RPH3US Date: Tue, 11 Feb 2025 23:52:43 +0530 Subject: [PATCH 2/2] Update README.md Added playbackManager instructions --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index e6c2f4f..d8ef209 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,16 @@ Here I present my version of the same with some code improvements, loading optim +
+ +main.jellyfin.bundle.js + +1. Similarly, search for `main.jellyfin.bundle.js` in the `jellyfin-web` directory. Open it with any code editor with administrator privileges. +2. Search for `this.playbackManager = e;` +3. Right after the `;`, paste the code block `window.PlaybackManager = this.playbackManager;console.log("PlaybackManager is now globally available:", window.PlaybackManager);` + +
+ And that is it. Hard refresh your web page (CTRL+Shift+R) twice, and Profit! # Want a Custom List to be showcased instead of random items??