vc=83 — fix: swapping videos from the minibar kept playing the old one
The inline player's auto-resolve→play LaunchedEffect read the shared activity-scoped VideoDetailViewModel's `resolved` stream without checking it belonged to the newly-opened video. Right after a swap (e.g. pick another video from the browse screen while one sits in the minibar), the VM still holds the previous video's resolved URLs for one composition frame until vm.load() nulls them — so setPlayingFrom fired with streamUrl=NEW but resolved=OLD: NowPlaying.claim won under the new url (title/details/minibar flipped to NEW) while the controller kept streaming OLD, and the correct re-fire with NEW's resolved was then swallowed by the 'already playing this url' short-circuit. Restore the loadedUrl fence (the same guard VideoDetailBody and every ViewModel already use) that the vc=75 expandable-player rearchitect dropped when the inline resolve→play wiring moved out of VideoDetailScreen.
This commit is contained in:
parent
2b3eb8bef4
commit
ea82ba765a
2 changed files with 34 additions and 2 deletions
|
|
@ -9,6 +9,21 @@ const val STRAW_SDK_TARGET = 35
|
|||
|
||||
// Sulkta fork — Straw
|
||||
//
|
||||
// vc=83 / 0.1.0-CQ — fix: swapping videos from the minibar kept playing
|
||||
// the old one:
|
||||
// * With a video minimized to the bottom minibar, picking a different
|
||||
// video updated the title, details and related list but the OLD video
|
||||
// kept playing. The inline player's resolve→play effect read the
|
||||
// shared (activity-scoped) view-model's `resolved` stream without
|
||||
// checking it actually belonged to the newly-opened video. For one
|
||||
// frame after the swap the view-model still holds the previous video's
|
||||
// resolved URLs, so playback was claimed under the NEW url while
|
||||
// streaming the OLD media — and the correct re-fire was then swallowed
|
||||
// by the "already playing this url" short-circuit, so the new video
|
||||
// never started. Restored the loadedUrl fence (the same guard
|
||||
// VideoDetailBody and every ViewModel already use) that the vc=75
|
||||
// expandable-player rearchitect had dropped from the inline wiring.
|
||||
//
|
||||
// vc=82 / 0.1.0-CP — subscription-feed enrichment goes lightweight:
|
||||
// * Filling in a feed row's view count + duration used to run the FULL
|
||||
// stream extraction per item (the same path opening a video does):
|
||||
|
|
@ -149,6 +164,6 @@ const val STRAW_SDK_TARGET = 35
|
|||
// vc=19 / 0.1.0-AE — rust pipeline cutover. Extraction via
|
||||
// strawcore-core (Sulkta-Coop/strawcore) via the UniFFI wrapper; no
|
||||
// NewPipeExtractor in the runtime path.
|
||||
const val STRAW_VERSION_CODE = 82
|
||||
const val STRAW_VERSION_NAME = "0.1.0-CP"
|
||||
const val STRAW_VERSION_CODE = 83
|
||||
const val STRAW_VERSION_NAME = "0.1.0-CQ"
|
||||
const val STRAW_APPLICATION_ID = "com.sulkta.straw"
|
||||
|
|
|
|||
|
|
@ -447,6 +447,23 @@ private fun InlinePlayerSurface(
|
|||
LaunchedEffect(controller, resolved, streamUrl, retryVersion, started) {
|
||||
if (!started) return@LaunchedEffect
|
||||
val c = controller ?: return@LaunchedEffect
|
||||
// Only start playback once the VM's resolved stream actually belongs
|
||||
// to THIS video. The VM is activity-scoped, so the instant the user
|
||||
// swaps to a new video (e.g. picks another from the browse screen
|
||||
// while the current one sits in the minibar) `state` still holds the
|
||||
// PREVIOUS video's resolved for one composition frame — until
|
||||
// vm.load(streamUrl) nulls it. Without this fence we'd call
|
||||
// setPlayingFrom(streamUrl=NEW, resolved=OLD): NowPlaying.claim wins
|
||||
// under the NEW url, so the title/details/minibar all flip to NEW,
|
||||
// but the controller keeps streaming OLD's media — and the later
|
||||
// re-fire with NEW's resolved short-circuits on the "already playing
|
||||
// this url" guard below, so NEW never actually starts. That's the
|
||||
// "swap from the minibar keeps playing the old video" bug.
|
||||
// VideoDetailUiState.loadedUrl exists for exactly this fence (it's
|
||||
// used by VideoDetailBody + every ViewModel); the vc=75 expandable-
|
||||
// player rearchitect dropped it when the inline-player resolve→play
|
||||
// wiring moved out of the old VideoDetailScreen into here.
|
||||
if (state.loadedUrl != streamUrl) return@LaunchedEffect
|
||||
val r = resolved ?: return@LaunchedEffect
|
||||
if (NowPlaying.current.value?.streamUrl == streamUrl) return@LaunchedEffect
|
||||
c.setPlayingFrom(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue