error message

This commit is contained in:
Simon
2026-02-08 19:47:47 +00:00
parent 1becdce9ff
commit 10ebcc87c0
3 changed files with 82 additions and 0 deletions

View File

@@ -6,6 +6,7 @@ let hasNextPage = true;
let isLoading = false; let isLoading = false;
let hlsPlayer = null; let hlsPlayer = null;
let currentLoadController = null; let currentLoadController = null;
let errorToastTimer = null;
// 2. Observer Definition (Must be defined before initApp uses it) // 2. Observer Definition (Must be defined before initApp uses it)
const observer = new IntersectionObserver((entries) => { const observer = new IntersectionObserver((entries) => {
@@ -198,6 +199,14 @@ async function initApp() {
}; };
} }
const errorToastClose = document.getElementById('error-toast-close');
if (errorToastClose) {
errorToastClose.onclick = () => {
const toast = document.getElementById('error-toast');
if (toast) toast.classList.remove('show');
};
}
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
ensureViewportFilled(); ensureViewportFilled();
}); });
@@ -212,6 +221,20 @@ function applyTheme() {
if (select) select.value = theme; if (select) select.value = theme;
} }
function showError(message) {
const toast = document.getElementById('error-toast');
const text = document.getElementById('error-toast-text');
if (!toast || !text) return;
text.textContent = message;
toast.classList.add('show');
if (errorToastTimer) {
clearTimeout(errorToastTimer);
}
errorToastTimer = setTimeout(() => {
toast.classList.remove('show');
}, 4000);
}
async function openPlayer(url) { async function openPlayer(url) {
const modal = document.getElementById('video-modal'); const modal = document.getElementById('video-modal');
const video = document.getElementById('player'); const video = document.getElementById('player');
@@ -253,16 +276,28 @@ async function openPlayer(url) {
hlsPlayer.on(window.Hls.Events.MANIFEST_PARSED, function() { hlsPlayer.on(window.Hls.Events.MANIFEST_PARSED, function() {
video.play(); video.play();
}); });
hlsPlayer.on(window.Hls.Events.ERROR, function(event, data) {
if (data && data.fatal) {
showError('Unable to play this stream.');
closePlayer();
}
});
} else if (video.canPlayType('application/vnd.apple.mpegurl')) { } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = streamUrl; video.src = streamUrl;
} else { } else {
console.error("HLS not supported in this browser."); console.error("HLS not supported in this browser.");
showError('HLS is not supported in this browser.');
return; return;
} }
} else { } else {
video.src = streamUrl; video.src = streamUrl;
} }
video.onerror = () => {
showError('Video failed to load.');
closePlayer();
};
modal.style.display = 'flex'; modal.style.display = 'flex';
document.body.style.overflow = 'hidden'; document.body.style.overflow = 'hidden';
} }
@@ -274,6 +309,7 @@ function closePlayer() {
hlsPlayer.destroy(); hlsPlayer.destroy();
hlsPlayer = null; hlsPlayer = null;
} }
video.onerror = null;
video.pause(); video.pause();
video.src = ''; video.src = '';
modal.style.display = 'none'; modal.style.display = 'none';

View File

@@ -93,6 +93,11 @@
</div> </div>
</div> </div>
<div id="error-toast" class="error-toast" role="alert" aria-live="assertive">
<span id="error-toast-text"></span>
<button id="error-toast-close" type="button" aria-label="Close"></button>
</div>
<script src="static/app.js"></script> <script src="static/app.js"></script>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script> <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</body> </body>

View File

@@ -768,6 +768,47 @@ video {
object-fit: contain; object-fit: contain;
} }
.error-toast {
position: fixed;
right: 20px;
bottom: 20px;
max-width: min(360px, 90vw);
background: rgba(0, 0, 0, 0.85);
color: #ffffff;
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 10px;
padding: 12px 14px;
display: flex;
align-items: center;
gap: 12px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
z-index: 3000;
opacity: 0;
pointer-events: none;
transform: translateY(8px);
transition: opacity 0.2s ease, transform 0.2s ease;
}
.error-toast.show {
opacity: 1;
pointer-events: auto;
transform: translateY(0);
}
.error-toast button {
background: transparent;
border: none;
color: inherit;
cursor: pointer;
font-size: 16px;
}
body.theme-light .error-toast {
background: rgba(255, 255, 255, 0.95);
color: #000000;
border: 1px solid rgba(0, 0, 0, 0.12);
}
/* Scrollbar styling */ /* Scrollbar styling */
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 8px; width: 8px;