diff --git a/static/index.html b/static/index.html
index 96dc821..4ba1b43 100644
--- a/static/index.html
+++ b/static/index.html
@@ -38,7 +38,7 @@
100% { transform: rotate(360deg); }
}
- .video-container {
+ #video-container {
display: none;
width: 100%;
justify-content: center;
@@ -51,20 +51,15 @@
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);
background-color: #444;
aspect-ratio: 16/9;
- object-fit: cover;
- transition: transform 0.3s ease, box-shadow 0.3s ease;
+ width: 20vw;
+ transition: width 0.3s ease, box-shadow 0.3s ease;
}
- .video-thumbnail:focus {
+ .video-thumbnail.focussed {
outline: 3px solid #557; /* Existing focus outline */
box-shadow: 0 0 400px -10px #446; /* Existing focus shadow */
- transform: scale(1.05);
- z-index: 3; /* Ensure focused thumbnail is on top */
- }
-
- .current-video {
width: 50vw;
- z-index: 2;
+ z-index: 3; /* Ensure focused thumbnail is on top */
}
.side-video {
@@ -186,7 +181,7 @@
}
function showVideoContainer() {
- $(".video-container").css("display", "flex");
+ $("#video-container").css("display", "flex");
}
let currentVideo = null;
@@ -235,7 +230,7 @@
}
}
// FOCUS: Return focus to the main view's play button
- if ($(".video-container").is(":visible") && $('#play-button').length) {
+ if ($("#video-container").is(":visible") && $('#play-button').length) {
$('#play-button').focus();
}
}
@@ -304,6 +299,49 @@
}
}
+ let videoThumbnails = [];
+ let selectedThumbnailIndex = 0;
+
+ /**
+ * Creates a new video thumbnail element.
+ *
+ * @param data The video data returned by the server.
+ * @param selected Set to true if this is the currently selected video thumbnail.
+ * @param append Set to true if this thumbnail should be appended to the video container, false if it should be prepended.
+ */
+ function createVideoThumbnailElement(data, selected, append) {
+ let thumbnail = $(``)[0];
+ let index;
+ if (append) {
+ $("#video-container").append(thumbnail);
+ index = videoThumbnails.length;
+ videoThumbnails.push(thumbnail)
+ } else {
+ $("#video-container").prepend(thumbnail);
+ index = 0;
+ videoThumbnails.unshift(thumbnail);
+ }
+ if (selected) {
+ thumbnail.classList.add("focussed");
+ selectedThumbnailIndex = index;
+ }
+ }
+
+ /**
+ * Selects a video thumbnail by its index into the videoThumbnails array.
+ * @param index The index of the thumbnail to select.
+ */
+ function selectThumbnail(index) {
+ if (index < 0 || index >= videoThumbnails.length) return; // Out of bounds check
+ if (selectedThumbnailIndex !== -1 && videoThumbnails[selectedThumbnailIndex]) {
+ videoThumbnails[selectedThumbnailIndex].classList.remove("focussed");
+ }
+ selectedThumbnailIndex = index;
+ videoThumbnails[selectedThumbnailIndex].classList.add("focussed");
+ // $("#video-container")[0].style.position = "relative";
+ // $("#video-container")[0].style.left = (-index * 5) + "vw";
+ }
+
$(document).ready(function() {
// Initialize global selectors for static elements
overlayContainer = $("#video-overlay-container");
@@ -318,19 +356,19 @@
$(".video-thumbnail").attr("src", "data:image/svg+xml,%3Csvg xmlns=\\\'http://www.w3.org/2000/svg\\\' width=\\\'100%25\\\' height=\\\'100%25\\\' viewBox=\\\'0 0 16 9\\\'%3E%3C/svg%3E");
$.getJSON("/api/homepage", function(data) {
- currentVideo = data.currentVideo;
- nextVideo = data.nextVideo;
- $("#current-thumb").attr("src", currentVideo.thumbnail);
- $("#next-thumb").attr("src", nextVideo.thumbnail);
+ createVideoThumbnailElement(data.currentVideo, true, true);
+ for (let i = 0; i < 10; i++)
+ {
+ createVideoThumbnailElement(data.nextVideo, false, true);
+ }
+ // currentVideo = data.currentVideo;
+ // nextVideo = data.nextVideo;
+ // $("#current-thumb").attr("src", currentVideo.thumbnail);
+ // $("#next-thumb").attr("src", nextVideo.thumbnail);
// Consider populating prev-thumb and next-thumb here if data provides them
hideSpinner();
showVideoContainer();
-
- // FOCUS: Set initial focus on the main screen
- if ($(".video-container").is(":visible")) {
- $('#current-thumb').focus();
- }
}).fail(function(jqXHR, textStatus, errorThrown) {
console.error("Failed to load homepage data:", textStatus, errorThrown);
hideSpinner();
@@ -397,12 +435,6 @@
if (playPauseButton && playPauseButton.length) {
playPauseButton.focus();
}
-
- // The oncanplaythrough is now set before load()
- // videoElement.oncanplaythrough = function() {
- // hideSpinner(); // Changed from hideLoader()
- // videoElement.play().catch(err => console.error("Error attempting to play video:", err));
- // }
}
});
@@ -420,7 +452,6 @@
overlayContainer.on('mousemove.inactivityControls', showControlsAndResetTimer);
// --- TV Remote/Keyboard Navigation ---
- const mainViewFocusable = [$('#prev-thumb'), $('#current-thumb'), $('#next-thumb')].filter(el => el && el.length > 0);
const getOverlayViewFocusableElements = () => [backButton, playPauseButton, seekBar].filter(el => el && el.length > 0 && el.is(':visible'));
$(document).on('keydown', function(e) {
@@ -429,19 +460,15 @@
if (isOverlayVisible) {
activeFocusableSet = getOverlayViewFocusableElements();
- } else {
- activeFocusableSet = mainViewFocusable;
- }
- if (!activeFocusableSet || activeFocusableSet.length === 0) return;
+ const focusedElement = $(document.activeElement);
+ let currentIndex = -1;
- const focusedElement = $(document.activeElement);
- let currentIndex = -1;
-
- for (let i = 0; i < activeFocusableSet.length; i++) {
- if (focusedElement.is(activeFocusableSet[i])) {
- currentIndex = i;
- break;
+ for (let i = 0; i < activeFocusableSet.length; i++) {
+ if (focusedElement.is(activeFocusableSet[i])) {
+ currentIndex = i;
+ break;
+ }
}
}
@@ -480,33 +507,20 @@
}
}
- // If focus is not on a managed element, and not body/html, usually let it be.
- // However, for certain keys like Enter, we might want a default action.
- if (currentIndex === -1 && !focusedElement.is('body') && !focusedElement.is('html')) {
- return;
- }
-
let keyHandled = false;
+ let nextIndex;
switch (e.key || e.keyCode) {
case 'ArrowLeft':
case 37: // ArrowLeft
- if (currentIndex !== -1) {
- let nextIndex = (currentIndex - 1 + activeFocusableSet.length) % activeFocusableSet.length;
- activeFocusableSet[nextIndex].focus();
- } else if (activeFocusableSet.length > 0) { // If nothing specific focused, focus last
- $("#current-thumb").focus();
- }
+ nextIndex = Math.max(selectedThumbnailIndex - 1, 0);
+ selectThumbnail(nextIndex);
keyHandled = true;
break;
case 'ArrowRight':
case 39: // ArrowRight
- if (currentIndex !== -1) {
- let nextIndex = (currentIndex + 1) % activeFocusableSet.length;
- activeFocusableSet[nextIndex].focus();
- } else if (activeFocusableSet.length > 0) { // If nothing specific focused, focus first
- $("#current-thumb").focus();
- }
+ nextIndex = Math.min(selectedThumbnailIndex + 1, videoThumbnails.length - 1);
+ selectThumbnail(nextIndex);
keyHandled = true;
break;
@@ -535,11 +549,11 @@