Wire up playback reporting, fix duration flash, hide video from audio mini player
Playback reporting (position sync / resume-on-another-device): - player_configure_jellyfin now builds a PlaybackReporter sharing the player controller's Arc, so Start/Progress/Stopped actually reach Jellyfin on every auth path (login/restore/reauth); previously they never did. - The PlaybackReporterWrapper now shares the same Arc the controller and MPV progress loop report through, instead of a dead parallel Option. - Android position callbacks now emit throttled progress reports (30s/item), mirroring the MPV backend. Duration flash on pause: - resolveDuration() prefers the live store duration for the already-loaded track over the runTimeTicks estimate, so pausing no longer clobbers the slider's max to 0 when runTimeTicks is missing. Video leaking into audio mini player: - isVideoItem() also checks the backend PlayerMediaItem mediaType discriminator, so a video started via player_play_item (no Jellyfin `type`, mediaType "video") no longer surfaces in the audio mini player. Middle-truncation of long media names: - New truncateMiddle util applied to track/episode/card/mini-player titles so distinguishing tails (episode numbers, suffixes) stay visible. Adds regression tests for the duration and mini-player fixes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -76,6 +76,25 @@ describe("shouldShowAudioMiniPlayer", () => {
|
||||
expect(get(shouldShowAudioMiniPlayer)).toBe(false);
|
||||
});
|
||||
|
||||
it("hides a video queue item that has no Jellyfin `type` but mediaType 'video'", () => {
|
||||
// Regression: player_play_item (every Movie/Episode via VideoPlayer) pushes
|
||||
// a backend PlayerMediaItem onto the queue with item_type: None but
|
||||
// media_type: Video → serialized with no `type` and mediaType: "video".
|
||||
// Without the mediaType check this slipped past the Movie/Episode guard and
|
||||
// surfaced the last-played video in the audio mini player after leaving
|
||||
// /player.
|
||||
const videoQueueItem = { id: "v2", mediaType: "video" } as unknown as MediaItem;
|
||||
currentQueueItem.set(videoQueueItem);
|
||||
player.setIdle();
|
||||
expect(get(shouldShowAudioMiniPlayer)).toBe(false);
|
||||
});
|
||||
|
||||
it("hides for a live TV channel", () => {
|
||||
const channelItem = { id: "c1", type: "TvChannel" } as unknown as MediaItem;
|
||||
player.setPlaying(channelItem, 0, 0);
|
||||
expect(get(shouldShowAudioMiniPlayer)).toBe(false);
|
||||
});
|
||||
|
||||
it("shows in remote mode when the session has a now-playing item", () => {
|
||||
isRemoteMode.set(true);
|
||||
selectedSession.set({ nowPlayingItem: { id: "r1" } });
|
||||
|
||||
Reference in New Issue
Block a user