Refactor loader functionality to improve user experience during video loading

This commit is contained in:
Sebastiaan de Schaetzen 2025-06-17 11:47:50 +02:00
parent d2cea3d690
commit cc00e58561

View File

@ -16,6 +16,11 @@
}
.loader {
position: fixed; /* Changed for global overlay */
left: 50%;
top: 50%;
transform: translate(-50%, -50%); /* Center on screen */
z-index: 10001; /* Above video overlay */
border: 1.5vw solid #333;
border-top: 1.5vw solid #3498db;
border-bottom: 1.5vw solid #3498db;
@ -164,11 +169,18 @@
}
</style>
<script>
function hideLoader() {
function hideSpinner() { // Was hideLoader, now only hides spinner
$(".loader").hide();
$(".video-container").css("display", "flex");
}
function showSpinner() { // Was showLoader
$(".loader").show();
}
function showVideoContainer() {
$(".video-container").css("display", "flex");
}
let currentVideo = null;
let videoElement = null;
let overlayContainer = null;
@ -293,18 +305,30 @@
playPauseButton = customControls.find("#custom-play-pause-button");
seekBar = customControls.find("#custom-seek-bar");
// Spinner is visible by default (CSS). Video container is hidden (CSS).
// Pre-set all thumbnails to a placeholder state
$(".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) {
currentVideo = data.currentVideo;
$("#current-thumb").attr("src", currentVideo.thumbnail);
hideLoader();
// 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") && $('#play-button').length) {
$('#play-button').focus();
}
})
}).fail(function(jqXHR, textStatus, errorThrown) {
console.error("Failed to load homepage data:", textStatus, errorThrown);
hideSpinner();
// Display a user-friendly error message
if (!$('#init-error-msg').length) { // Prevent multiple error messages
$('body').append('<div id="init-error-msg" style="color:white; text-align:center; padding:20px; position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); background-color:rgba(0,0,0,0.8); border-radius:8px; z-index: 10002;">Failed to load content. Please try again later.</div>');
}
});
// Attach event listeners that can be set up once for static controls
if (playPauseButton) playPauseButton.click(handlePlayPauseClick);
@ -314,7 +338,30 @@
$("#play-button").click(function() {
if (currentVideo && currentVideo.url && videoElement && overlayContainer) {
// Set video source and load
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();
@ -341,7 +388,11 @@
playPauseButton.focus();
}
videoElement.play().catch(err => console.error("Error attempting to play video:", err));
// 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));
// }
}
});