diff --git a/README.md b/README.md
index f26a04c..dcde692 100644
--- a/README.md
+++ b/README.md
@@ -124,6 +124,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??
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) => {