Split software arch desc for easier manintenance. Many fixes related to next video playing and remote playback
🏗️ Build and Test JellyTau / Run Tests (push) Failing after 12s
🏗️ Build and Test JellyTau / Build Android APK (push) Has been skipped
Traceability Validation / Check Requirement Traces (push) Failing after 1s

This commit is contained in:
2026-03-01 19:47:46 +01:00
parent 3a9c126dfe
commit 09780103a7
45 changed files with 5663 additions and 3332 deletions
+39 -16
View File
@@ -4,27 +4,27 @@
* Handles user interactions with the next episode popup.
* Backend manages countdown logic and autoplay decisions.
*
* Navigation uses goto() directly to load the next episode.
* The player page's $effect detects the URL param change and
* calls loadAndPlay for the new episode.
*
* TRACES: UR-023 | DR-047, DR-048
*/
import { cancelAutoplayCountdown, playNextEpisode } from "$lib/api/autoplay";
import { goto } from "$app/navigation";
import { cancelAutoplayCountdown } from "$lib/api/autoplay";
import { nextEpisode } from "$lib/stores/nextEpisode";
import type { MediaItem } from "$lib/api/types";
/** Guard against double-navigation */
let isNavigating = false;
/**
* Cleanup next episode state (called on unmount/destroy)
*/
export function cleanup() {
nextEpisode.reset();
}
/**
* Handle episode ended event
* Backend now handles autoplay decisions via on_playback_ended()
* This function is kept for backwards compatibility but does nothing
*/
export async function handleEpisodeEnded(media: any) {
// Backend now handles this - no action needed
// The backend will emit ShowNextEpisodePopup event
isNavigating = false;
}
/**
@@ -36,13 +36,36 @@ export async function cancelAutoPlay() {
nextEpisode.hidePopup();
}
/**
* Navigate to the next episode via goto().
* Uses replaceState to prevent history buildup when auto-advancing.
*/
function navigateToEpisode(episode: MediaItem) {
if (isNavigating) {
console.warn("[NextEpisode] Already navigating, skipping duplicate navigation to", episode.id);
return;
}
isNavigating = true;
console.log("[NextEpisode] Navigating to next episode:", episode.id, episode.name);
nextEpisode.hidePopup();
goto(`/player/${episode.id}`, { replaceState: true }).finally(() => {
isNavigating = false;
});
}
/**
* Manually play the next episode
* Called when user clicks "Play Now" button on next episode popup
*
* @param nextEpisodeItem - The next episode to play
*/
export async function watchNextManually(nextEpisodeItem: any) {
await playNextEpisode(nextEpisodeItem);
nextEpisode.hidePopup();
export async function watchNextManually(nextEpisodeItem: MediaItem) {
await cancelAutoplayCountdown();
navigateToEpisode(nextEpisodeItem);
}
/**
* Auto-play the next episode when countdown reaches 0
* Called by playerEvents when countdown_tick event has remaining_seconds: 0
*/
export function autoPlayNext(nextEpisodeItem: MediaItem) {
navigateToEpisode(nextEpisodeItem);
}