feat(library): genre sliders, artist links, and navigation utils
- music landing: diverse per-genre album sliders (online counts / offline wide-probe fallback) and home-screen library shortcuts - add ArtistLinks component and shared navigation/genreDiversity utils - player/playback-mode refinements across Rust and frontend
This commit is contained in:
@@ -43,6 +43,18 @@
|
||||
let videoElement: HTMLVideoElement | null = $state(null);
|
||||
let isPlaying = $state(false);
|
||||
let currentTime = $state(0);
|
||||
// Guards against onEnded() firing more than once per loaded stream. For
|
||||
// transcoded HLS, both the native `ended` event and the "fatal network error
|
||||
// near end of stream" recovery path can fire for the same playback, which
|
||||
// would otherwise call playerOnPlaybackEnded twice (e.g. decrementing the
|
||||
// sleep-timer episode counter twice). Reset when the stream URL changes.
|
||||
let endedFired = $state(false);
|
||||
|
||||
function notifyEnded() {
|
||||
if (endedFired) return;
|
||||
endedFired = true;
|
||||
onEnded?.();
|
||||
}
|
||||
let isFullscreen = $state(false);
|
||||
let showControls = $state(true);
|
||||
let showSleepTimerModal = $state(false);
|
||||
@@ -188,6 +200,7 @@
|
||||
seekOffset = 0;
|
||||
isMediaReady = false; // Reset to loading state when stream URL changes
|
||||
hasPerformedInitialSeek = false; // Reset so new video can seek to initial position
|
||||
endedFired = false; // New stream loaded - allow onEnded to fire again
|
||||
}
|
||||
});
|
||||
|
||||
@@ -285,9 +298,7 @@
|
||||
if (isNearEnd) {
|
||||
// Near end of stream - treat as natural end, don't restart
|
||||
console.log('[VideoPlayer] Fatal network error near end of stream - treating as ended');
|
||||
if (onEnded) {
|
||||
onEnded();
|
||||
}
|
||||
notifyEnded();
|
||||
} else if (hlsFatalRecoveryAttempts <= 3) {
|
||||
console.error('[VideoPlayer] Fatal network error, trying to recover (attempt', hlsFatalRecoveryAttempts, ')');
|
||||
hls!.startLoad();
|
||||
@@ -762,9 +773,7 @@
|
||||
onReportStop(currentTime, reportMediaId);
|
||||
}
|
||||
// Notify parent that video has ended (for next episode popup)
|
||||
if (onEnded) {
|
||||
onEnded();
|
||||
}
|
||||
notifyEnded();
|
||||
}
|
||||
|
||||
async function togglePlayPause() {
|
||||
|
||||
Reference in New Issue
Block a user