From fa7cb6e9087e87c6358fe91d05e1beefefc371a0 Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Tue, 23 Jun 2026 21:10:50 +0200 Subject: [PATCH 001/118] fix: Autoplay now resets time to zero and ignores trigger if episode already started --- src/lib/components/player/VideoPlayer.svelte | 28 +++++++---- src/lib/services/nextEpisodeService.ts | 6 ++- src/routes/player/[id]/+page.svelte | 51 ++++++++++++++------ 3 files changed, 59 insertions(+), 26 deletions(-) diff --git a/src/lib/components/player/VideoPlayer.svelte b/src/lib/components/player/VideoPlayer.svelte index 905f3a581..761297068 100644 --- a/src/lib/components/player/VideoPlayer.svelte +++ b/src/lib/components/player/VideoPlayer.svelte @@ -1,6 +1,6 @@ + + diff --git a/src/lib/components/player/VideoPlayer.scrubRegression.test.ts b/src/lib/components/player/VideoPlayer.scrubRegression.test.ts index f2f53ac82..3535f0d51 100644 --- a/src/lib/components/player/VideoPlayer.scrubRegression.test.ts +++ b/src/lib/components/player/VideoPlayer.scrubRegression.test.ts @@ -23,6 +23,27 @@ import { describe, it, expect, vi, beforeEach } from "vitest"; // ---- Mocks (must precede component import) -------------------------------- const channelHandlers: Record void> = {}; +// These tests pin the **flag-off** interim behaviour: when `experimentalNativeVideo` +// is off, VideoPlayer overrides Android's native backend response to HTML5 +// rendering and stops the native backend. That flag now defaults to *on* +// (DR-160, so picture-in-picture has a real surface to shrink into), so the +// default no longer selects this path and the tests have to say which path they +// are guarding rather than inherit it. (DR-161) +vi.mock("$lib/stores/nativeVideo", async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + experimentalNativeVideo: { + subscribe: (run: (v: boolean) => void) => { + run(false); + return () => {}; + }, + set: () => {}, + current: () => false, + }, + }; +}); + vi.mock("@tauri-apps/api/event", () => ({ listen: vi.fn(async (channel: string, handler: any) => { channelHandlers[channel] = handler; diff --git a/src/lib/components/player/VideoPlayer.svelte b/src/lib/components/player/VideoPlayer.svelte index 66e75b2e1..728a3206a 100644 --- a/src/lib/components/player/VideoPlayer.svelte +++ b/src/lib/components/player/VideoPlayer.svelte @@ -38,7 +38,13 @@ enableNativeVideoCompositing, disableNativeVideoCompositing, } from "$lib/utils/videoSurface"; - import { isPipSupported, enterPip, setAutoEnterEnabled } from "$lib/utils/pictureInPicture"; + import { + isPipSupported, + enterPip, + setAutoEnterEnabled, + setHtml5VideoState, + } from "$lib/utils/pictureInPicture"; + import { enterImmersive, exitImmersive } from "$lib/utils/immersive"; import { createTapGestureState, registerTap, @@ -109,8 +115,39 @@ endedFired = true; onEnded?.(); } + + /** + * Keep native's picture-in-picture state in step with the `