fix(player): return from background audio onto the episode it advanced to

An episode that ends while backgrounded in audio-only mode advances in the
backend, but player_exit_background_audio returned only a position, so the
video page reloaded the episode it was mounted with -- the previous one, at
the new episode's timestamp.

The command now returns BackgroundAudioResume { itemId, positionSeconds }.
planHandoffReturn yields "other-item" when the id differs from the mounted
one, and the player page navigates to that episode with resumeAt=<seconds>,
marking the outgoing episode watched and suppressing its stale stop report.

TRACES: UR-040, UR-023 | DR-296 | UT-265, UT-266
This commit is contained in:
2026-09-24 03:45:59 +02:00
parent f6efa7208a
commit 1fb5f070c8
9 changed files with 240 additions and 24 deletions
+23 -2
View File
@@ -66,9 +66,14 @@ async playerEnterBackgroundAudio(item: PlayItemRequest, positionSeconds: number)
return await TAURI_INVOKE("player_enter_background_audio", { item, positionSeconds });
},
/**
* TRACES: UR-040 | DR-052 | UT-061, IT-013
* Returns the item the native player is on and its absolute position. The
* item matters: an episode that ended while backgrounded has already advanced
* in the backend, so reloading the video the webview was mounted with would
* bring back the previous episode. (DR-296)
*
* TRACES: UR-040, UR-023 | DR-052, DR-296 | UT-061, IT-013
*/
async playerExitBackgroundAudio() : Promise<number> {
async playerExitBackgroundAudio() : Promise<BackgroundAudioResume> {
return await TAURI_INVOKE("player_exit_background_audio");
},
/**
@@ -2190,6 +2195,22 @@ export type BackgroundAction =
* Stop making sound. The user did not ask for background playback.
*/
"pause"
/**
* Where playback stands when a background-audio handoff returns to the
* foreground. See [`PlayerController::background_audio_resume`].
*
* TRACES: UR-040, UR-023 | DR-296
*/
export type BackgroundAudioResume = {
/**
* Item the native audio player is on — `None` if the queue emptied (e.g.
* the sleep timer stopped playback while backgrounded).
*/
itemId: string | null;
/**
* Absolute position in that item, in seconds.
*/
positionSeconds: number }
/**
* Smart caching configuration
*/