Working on better video flow
This commit is contained in:
		@@ -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 = $(`<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() {
 | 
			
		||||
			// 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 @@
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
	<div class="loader" id="loader"></div>
 | 
			
		||||
	<div class="video-container">
 | 
			
		||||
		<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="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 id="video-container">
 | 
			
		||||
<!--		<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="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>
 | 
			
		||||
 | 
			
		||||
	<!-- STATIC VIDEO OVERLAY STRUCTURE -->
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user