Refactor video thumbnail handling and improve overlay positioning for enhanced user experience
This commit is contained in:
		@@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user