Refactor video thumbnail handling and improve overlay positioning for enhanced user experience
This commit is contained in:
parent
f226d1f402
commit
f22ff5c1a4
@ -52,7 +52,9 @@
|
|||||||
background-color: #444;
|
background-color: #444;
|
||||||
aspect-ratio: 16/9;
|
aspect-ratio: 16/9;
|
||||||
width: 20vw;
|
width: 20vw;
|
||||||
transition: width 0.3s ease, box-shadow 0.3s ease;
|
transition: width 0.3s ease, box-shadow 0.3s ease, left 0.3s ease;
|
||||||
|
transform: translate(-50%, 0);
|
||||||
|
position: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-thumbnail.focussed {
|
.video-thumbnail.focussed {
|
||||||
@ -104,6 +106,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: block;
|
display: block;
|
||||||
|
position: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
#video-overlay-container #back-button { /* Back button is now inside the container */
|
#video-overlay-container #back-button { /* Back button is now inside the container */
|
||||||
@ -299,7 +302,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let videoThumbnails = [];
|
let videoInfo = [];
|
||||||
let selectedThumbnailIndex = 0;
|
let selectedThumbnailIndex = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -314,12 +317,19 @@
|
|||||||
let index;
|
let index;
|
||||||
if (append) {
|
if (append) {
|
||||||
$("#video-container").append(thumbnail);
|
$("#video-container").append(thumbnail);
|
||||||
index = videoThumbnails.length;
|
index = videoInfo.length;
|
||||||
videoThumbnails.push(thumbnail)
|
videoInfo.push({
|
||||||
|
thumbnail,
|
||||||
|
data
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
$("#video-container").prepend(thumbnail);
|
$("#video-container").prepend(thumbnail);
|
||||||
index = 0;
|
index = 0;
|
||||||
videoThumbnails.unshift(thumbnail);
|
videoInfo.unshift({
|
||||||
|
thumbnail,
|
||||||
|
data
|
||||||
|
});
|
||||||
|
selectedThumbnailIndex++;
|
||||||
}
|
}
|
||||||
if (selected) {
|
if (selected) {
|
||||||
thumbnail.classList.add("focussed");
|
thumbnail.classList.add("focussed");
|
||||||
@ -332,14 +342,83 @@
|
|||||||
* @param index The index of the thumbnail to select.
|
* @param index The index of the thumbnail to select.
|
||||||
*/
|
*/
|
||||||
function selectThumbnail(index) {
|
function selectThumbnail(index) {
|
||||||
if (index < 0 || index >= videoThumbnails.length) return; // Out of bounds check
|
if (index < 0 || index >= videoInfo.length) return; // Out of bounds check
|
||||||
if (selectedThumbnailIndex !== -1 && videoThumbnails[selectedThumbnailIndex]) {
|
if (selectedThumbnailIndex !== -1 && videoInfo[selectedThumbnailIndex]) {
|
||||||
videoThumbnails[selectedThumbnailIndex].classList.remove("focussed");
|
videoInfo[selectedThumbnailIndex].thumbnail.classList.remove("focussed");
|
||||||
}
|
}
|
||||||
selectedThumbnailIndex = index;
|
selectedThumbnailIndex = index;
|
||||||
videoThumbnails[selectedThumbnailIndex].classList.add("focussed");
|
videoInfo[selectedThumbnailIndex].thumbnail.classList.add("focussed");
|
||||||
// $("#video-container")[0].style.position = "relative";
|
for (let i = 0; i < videoInfo.length; i++) {
|
||||||
// $("#video-container")[0].style.left = (-index * 5) + "vw";
|
if (i < selectedThumbnailIndex - 1) {
|
||||||
|
videoInfo[i].thumbnail.style.left = "-20%";
|
||||||
|
} else if (i === selectedThumbnailIndex - 1) {
|
||||||
|
videoInfo[i].thumbnail.style.left = "15%";
|
||||||
|
} else if (i === selectedThumbnailIndex) {
|
||||||
|
videoInfo[i].thumbnail.style.left = "50%";
|
||||||
|
} else if (i === selectedThumbnailIndex + 1) {
|
||||||
|
videoInfo[i].thumbnail.style.left = "85%";
|
||||||
|
} else {
|
||||||
|
videoInfo[i].thumbnail.style.left = "120%";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the currently selected video.
|
||||||
|
*/
|
||||||
|
function startVideo() {
|
||||||
|
showSpinner();
|
||||||
|
|
||||||
|
let currentVideo = videoInfo[selectedThumbnailIndex].data
|
||||||
|
|
||||||
|
// Clear previous handlers and set new ones for this specific load attempt
|
||||||
|
videoElement.oncanplaythrough = null;
|
||||||
|
videoElement.onerror = null;
|
||||||
|
|
||||||
|
videoElement.oncanplaythrough = function() {
|
||||||
|
hideSpinner();
|
||||||
|
videoElement.oncanplaythrough = null; // Clean up handler
|
||||||
|
videoElement.onerror = null; // Clean up handler
|
||||||
|
videoElement.play().catch(err => {
|
||||||
|
console.error("Error attempting to play video:", err);
|
||||||
|
exitVideoPlayback(); // Exit overlay on play error
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
videoElement.onerror = function() {
|
||||||
|
console.error("Error loading video.");
|
||||||
|
hideSpinner();
|
||||||
|
videoElement.oncanplaythrough = null; // Clean up handler
|
||||||
|
videoElement.onerror = null; // Clean up handler
|
||||||
|
exitVideoPlayback(); // Exit overlay on load error
|
||||||
|
};
|
||||||
|
|
||||||
|
videoElement.src = currentVideo.url;
|
||||||
|
videoElement.load();
|
||||||
|
|
||||||
|
// --- Setup Inactivity Controls (session-specific) ---
|
||||||
|
showControlsAndResetTimer(); // Initial call
|
||||||
|
|
||||||
|
updatePlayPauseButtonState(); // Initial state for the button
|
||||||
|
|
||||||
|
|
||||||
|
// Show overlay and request fullscreen
|
||||||
|
overlayContainer.css('display', 'flex');
|
||||||
|
const containerEl = overlayContainer[0];
|
||||||
|
if (containerEl.requestFullscreen) {
|
||||||
|
containerEl.requestFullscreen().catch(err => console.error("Error attempting to enable full-screen mode:", err));
|
||||||
|
} else if (containerEl.mozRequestFullScreen) {
|
||||||
|
containerEl.mozRequestFullScreen();
|
||||||
|
} else if (containerEl.webkitRequestFullscreen) {
|
||||||
|
containerEl.webkitRequestFullscreen();
|
||||||
|
} else if (containerEl.msRequestFullscreen) {
|
||||||
|
containerEl.msRequestFullscreen();
|
||||||
|
}
|
||||||
|
// FOCUS: Set focus in the video overlay
|
||||||
|
if (playPauseButton && playPauseButton.length) {
|
||||||
|
playPauseButton.focus();
|
||||||
|
}
|
||||||
|
updatePlayPauseButtonState()
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
@ -358,9 +437,9 @@
|
|||||||
$.getJSON("/api/homepage", function(data) {
|
$.getJSON("/api/homepage", function(data) {
|
||||||
createVideoThumbnailElement(data.currentVideo, true, true);
|
createVideoThumbnailElement(data.currentVideo, true, true);
|
||||||
for (let i = 0; i < 10; i++)
|
for (let i = 0; i < 10; i++)
|
||||||
{
|
|
||||||
createVideoThumbnailElement(data.nextVideo, false, true);
|
createVideoThumbnailElement(data.nextVideo, false, true);
|
||||||
}
|
for (let i = 0; i < 10; i++)
|
||||||
|
createVideoThumbnailElement(data.nextVideo, false, false);
|
||||||
// currentVideo = data.currentVideo;
|
// currentVideo = data.currentVideo;
|
||||||
// nextVideo = data.nextVideo;
|
// nextVideo = data.nextVideo;
|
||||||
// $("#current-thumb").attr("src", currentVideo.thumbnail);
|
// $("#current-thumb").attr("src", currentVideo.thumbnail);
|
||||||
@ -369,6 +448,7 @@
|
|||||||
|
|
||||||
hideSpinner();
|
hideSpinner();
|
||||||
showVideoContainer();
|
showVideoContainer();
|
||||||
|
selectThumbnail(selectedThumbnailIndex);
|
||||||
}).fail(function(jqXHR, textStatus, errorThrown) {
|
}).fail(function(jqXHR, textStatus, errorThrown) {
|
||||||
console.error("Failed to load homepage data:", textStatus, errorThrown);
|
console.error("Failed to load homepage data:", textStatus, errorThrown);
|
||||||
hideSpinner();
|
hideSpinner();
|
||||||
@ -384,60 +464,6 @@
|
|||||||
if (backButton) backButton.click(exitVideoPlayback);
|
if (backButton) backButton.click(exitVideoPlayback);
|
||||||
|
|
||||||
|
|
||||||
$("#play-button").click(function() {
|
|
||||||
if (currentVideo && currentVideo.url && videoElement && overlayContainer) {
|
|
||||||
showSpinner();
|
|
||||||
|
|
||||||
// Clear previous handlers and set new ones for this specific load attempt
|
|
||||||
videoElement.oncanplaythrough = null;
|
|
||||||
videoElement.onerror = null;
|
|
||||||
|
|
||||||
videoElement.oncanplaythrough = function() {
|
|
||||||
hideSpinner();
|
|
||||||
videoElement.oncanplaythrough = null; // Clean up handler
|
|
||||||
videoElement.onerror = null; // Clean up handler
|
|
||||||
videoElement.play().catch(err => {
|
|
||||||
console.error("Error attempting to play video:", err);
|
|
||||||
exitVideoPlayback(); // Exit overlay on play error
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
videoElement.onerror = function() {
|
|
||||||
console.error("Error loading video.");
|
|
||||||
hideSpinner();
|
|
||||||
videoElement.oncanplaythrough = null; // Clean up handler
|
|
||||||
videoElement.onerror = null; // Clean up handler
|
|
||||||
exitVideoPlayback(); // Exit overlay on load error
|
|
||||||
};
|
|
||||||
|
|
||||||
videoElement.src = currentVideo.url;
|
|
||||||
videoElement.load();
|
|
||||||
|
|
||||||
// --- Setup Inactivity Controls (session-specific) ---
|
|
||||||
showControlsAndResetTimer(); // Initial call
|
|
||||||
|
|
||||||
updatePlayPauseButtonState(); // Initial state for the button
|
|
||||||
|
|
||||||
|
|
||||||
// Show overlay and request fullscreen
|
|
||||||
overlayContainer.css('display', 'flex');
|
|
||||||
const containerEl = overlayContainer[0];
|
|
||||||
if (containerEl.requestFullscreen) {
|
|
||||||
containerEl.requestFullscreen().catch(err => console.error("Error attempting to enable full-screen mode:", err));
|
|
||||||
} else if (containerEl.mozRequestFullScreen) {
|
|
||||||
containerEl.mozRequestFullScreen();
|
|
||||||
} else if (containerEl.webkitRequestFullscreen) {
|
|
||||||
containerEl.webkitRequestFullscreen();
|
|
||||||
} else if (containerEl.msRequestFullscreen) {
|
|
||||||
containerEl.msRequestFullscreen();
|
|
||||||
}
|
|
||||||
// FOCUS: Set focus in the video overlay
|
|
||||||
if (playPauseButton && playPauseButton.length) {
|
|
||||||
playPauseButton.focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// --- Setup Custom Video Controls Events (session-specific for video element) ---
|
// --- Setup Custom Video Controls Events (session-specific for video element) ---
|
||||||
$(videoElement).on('play.currentVideo', updatePlayPauseButtonState);
|
$(videoElement).on('play.currentVideo', updatePlayPauseButtonState);
|
||||||
$(videoElement).on('pause.currentVideo', updatePlayPauseButtonState);
|
$(videoElement).on('pause.currentVideo', updatePlayPauseButtonState);
|
||||||
@ -519,16 +545,14 @@
|
|||||||
|
|
||||||
case 'ArrowRight':
|
case 'ArrowRight':
|
||||||
case 39: // ArrowRight
|
case 39: // ArrowRight
|
||||||
nextIndex = Math.min(selectedThumbnailIndex + 1, videoThumbnails.length - 1);
|
nextIndex = Math.min(selectedThumbnailIndex + 1, videoInfo.length - 1);
|
||||||
selectThumbnail(nextIndex);
|
selectThumbnail(nextIndex);
|
||||||
keyHandled = true;
|
keyHandled = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Enter':
|
case 'Enter':
|
||||||
case 13: // Enter
|
case 13: // Enter
|
||||||
if (currentIndex !== -1) {
|
startVideo();
|
||||||
activeFocusableSet[currentIndex].click();
|
|
||||||
}
|
|
||||||
keyHandled = true;
|
keyHandled = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user