Working on better video flow
This commit is contained in:
parent
1cfb023ff6
commit
f226d1f402
@ -38,7 +38,7 @@
|
|||||||
100% { transform: rotate(360deg); }
|
100% { transform: rotate(360deg); }
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-container {
|
#video-container {
|
||||||
display: none;
|
display: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -51,20 +51,15 @@
|
|||||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);
|
||||||
background-color: #444;
|
background-color: #444;
|
||||||
aspect-ratio: 16/9;
|
aspect-ratio: 16/9;
|
||||||
object-fit: cover;
|
width: 20vw;
|
||||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
transition: width 0.3s ease, box-shadow 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-thumbnail:focus {
|
.video-thumbnail.focussed {
|
||||||
outline: 3px solid #557; /* Existing focus outline */
|
outline: 3px solid #557; /* Existing focus outline */
|
||||||
box-shadow: 0 0 400px -10px #446; /* Existing focus shadow */
|
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;
|
width: 50vw;
|
||||||
z-index: 2;
|
z-index: 3; /* Ensure focused thumbnail is on top */
|
||||||
}
|
}
|
||||||
|
|
||||||
.side-video {
|
.side-video {
|
||||||
@ -186,7 +181,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showVideoContainer() {
|
function showVideoContainer() {
|
||||||
$(".video-container").css("display", "flex");
|
$("#video-container").css("display", "flex");
|
||||||
}
|
}
|
||||||
|
|
||||||
let currentVideo = null;
|
let currentVideo = null;
|
||||||
@ -235,7 +230,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// FOCUS: Return focus to the main view's play button
|
// 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();
|
$('#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 = $(`<img src="${data.thumbnail}" class="video-thumbnail" alt="Video Thumbnail" tabindex="0">`)[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() {
|
$(document).ready(function() {
|
||||||
// Initialize global selectors for static elements
|
// Initialize global selectors for static elements
|
||||||
overlayContainer = $("#video-overlay-container");
|
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");
|
$(".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) {
|
$.getJSON("/api/homepage", function(data) {
|
||||||
currentVideo = data.currentVideo;
|
createVideoThumbnailElement(data.currentVideo, true, true);
|
||||||
nextVideo = data.nextVideo;
|
for (let i = 0; i < 10; i++)
|
||||||
$("#current-thumb").attr("src", currentVideo.thumbnail);
|
{
|
||||||
$("#next-thumb").attr("src", nextVideo.thumbnail);
|
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
|
// Consider populating prev-thumb and next-thumb here if data provides them
|
||||||
|
|
||||||
hideSpinner();
|
hideSpinner();
|
||||||
showVideoContainer();
|
showVideoContainer();
|
||||||
|
|
||||||
// FOCUS: Set initial focus on the main screen
|
|
||||||
if ($(".video-container").is(":visible")) {
|
|
||||||
$('#current-thumb').focus();
|
|
||||||
}
|
|
||||||
}).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();
|
||||||
@ -397,12 +435,6 @@
|
|||||||
if (playPauseButton && playPauseButton.length) {
|
if (playPauseButton && playPauseButton.length) {
|
||||||
playPauseButton.focus();
|
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);
|
overlayContainer.on('mousemove.inactivityControls', showControlsAndResetTimer);
|
||||||
|
|
||||||
// --- TV Remote/Keyboard Navigation ---
|
// --- 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'));
|
const getOverlayViewFocusableElements = () => [backButton, playPauseButton, seekBar].filter(el => el && el.length > 0 && el.is(':visible'));
|
||||||
|
|
||||||
$(document).on('keydown', function(e) {
|
$(document).on('keydown', function(e) {
|
||||||
@ -429,19 +460,15 @@
|
|||||||
|
|
||||||
if (isOverlayVisible) {
|
if (isOverlayVisible) {
|
||||||
activeFocusableSet = getOverlayViewFocusableElements();
|
activeFocusableSet = getOverlayViewFocusableElements();
|
||||||
} else {
|
|
||||||
activeFocusableSet = mainViewFocusable;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!activeFocusableSet || activeFocusableSet.length === 0) return;
|
const focusedElement = $(document.activeElement);
|
||||||
|
let currentIndex = -1;
|
||||||
|
|
||||||
const focusedElement = $(document.activeElement);
|
for (let i = 0; i < activeFocusableSet.length; i++) {
|
||||||
let currentIndex = -1;
|
if (focusedElement.is(activeFocusableSet[i])) {
|
||||||
|
currentIndex = i;
|
||||||
for (let i = 0; i < activeFocusableSet.length; i++) {
|
break;
|
||||||
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 keyHandled = false;
|
||||||
|
let nextIndex;
|
||||||
switch (e.key || e.keyCode) {
|
switch (e.key || e.keyCode) {
|
||||||
case 'ArrowLeft':
|
case 'ArrowLeft':
|
||||||
case 37: // ArrowLeft
|
case 37: // ArrowLeft
|
||||||
if (currentIndex !== -1) {
|
nextIndex = Math.max(selectedThumbnailIndex - 1, 0);
|
||||||
let nextIndex = (currentIndex - 1 + activeFocusableSet.length) % activeFocusableSet.length;
|
selectThumbnail(nextIndex);
|
||||||
activeFocusableSet[nextIndex].focus();
|
|
||||||
} else if (activeFocusableSet.length > 0) { // If nothing specific focused, focus last
|
|
||||||
$("#current-thumb").focus();
|
|
||||||
}
|
|
||||||
keyHandled = true;
|
keyHandled = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'ArrowRight':
|
case 'ArrowRight':
|
||||||
case 39: // ArrowRight
|
case 39: // ArrowRight
|
||||||
if (currentIndex !== -1) {
|
nextIndex = Math.min(selectedThumbnailIndex + 1, videoThumbnails.length - 1);
|
||||||
let nextIndex = (currentIndex + 1) % activeFocusableSet.length;
|
selectThumbnail(nextIndex);
|
||||||
activeFocusableSet[nextIndex].focus();
|
|
||||||
} else if (activeFocusableSet.length > 0) { // If nothing specific focused, focus first
|
|
||||||
$("#current-thumb").focus();
|
|
||||||
}
|
|
||||||
keyHandled = true;
|
keyHandled = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -535,11 +549,11 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="loader" id="loader"></div>
|
<div class="loader" id="loader"></div>
|
||||||
<div class="video-container">
|
<div id="video-container">
|
||||||
<img id="prev-thumb" class="video-thumbnail side-video" alt="Previous Video" tabindex="0">
|
<!-- <img id="prev-thumb" class="video-thumbnail side-video" alt="Previous Video" tabindex="0">-->
|
||||||
<img id="current-thumb" class="video-thumbnail current-video" alt="Current Video" tabindex="0">
|
<!-- <img id="current-thumb" class="video-thumbnail current-video" alt="Current Video" tabindex="0">-->
|
||||||
<img id="next-thumb" class="video-thumbnail side-video" alt="Next Video" tabindex="0">
|
<!-- <img id="next-thumb" class="video-thumbnail side-video" alt="Next Video" tabindex="0">-->
|
||||||
<div class="play-button" id="play-button" tabindex="0" role="button" aria-label="Play video"></div>
|
<!-- <div class="play-button" id="play-button" tabindex="0" role="button" aria-label="Play video"></div>-->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- STATIC VIDEO OVERLAY STRUCTURE -->
|
<!-- STATIC VIDEO OVERLAY STRUCTURE -->
|
||||||
|
Loading…
x
Reference in New Issue
Block a user