Expandable player morph: one container, video page ⇄ minibar (vc=75)

Replace the separate Screen.VideoDetail page + MinibarOverlay with one
ExpandablePlayer container that morphs continuously between the full
video page and the bottom minibar, in both directions. The old flow just
made the minibar appear/vanish; this is a true shared-element transition.

- One fraction (0=minibar, 1=full page) drives a graphicsLayer
  scale+translate on a single mounted TextureView PlayerView. The
  transform runs in the render phase (reads the Animatable inside the
  layer block) so the morph is smooth without recomposing the detail
  body, and the same video surface stays live across the whole range.
- 100dp collapsed player is 16:9, same as expanded, so the morph is a
  pure uniform scale (no aspect distortion).
- Opening a video sets OpenVideo + expands instead of pushing a screen;
  the browse screen stays underneath so collapsing returns you there.
- New OpenVideo singleton (open video) distinct from NowPlaying (playing
  video); the two are kept in sync while collapsed so autoplay-next
  doesn't leave the open page stale.
- VideoDetailBody extracted from VideoDetailScreen; the inline player
  surface + resolve/play wiring became InlinePlayerSurface inside
  ExpandablePlayer. VideoDetailScreen + MinibarOverlay deleted.
- Back: fullscreen pops, then expanded collapses, then browse stack.
- Unchanged: shared controller, NowPlaying, setPlayingFrom, SponsorBlock,
  autoplay-next, PiP, background audio, and true-fullscreen Player (⛶).
This commit is contained in:
Sulkta 2026-06-20 12:17:41 -07:00
parent 024906d66c
commit c6e7f46633
8 changed files with 1294 additions and 1211 deletions

View file

@ -9,6 +9,23 @@ const val STRAW_SDK_TARGET = 35
// Sulkta fork — Straw
//
// vc=75 / 0.1.0-CI — expandable player (full rearchitect):
// * The video page and the bottom minibar are now ONE container that
// morphs continuously between them, both directions. Replaces the
// old separate Screen.VideoDetail page + MinibarOverlay (which just
// appeared/vanished). One fraction (0=minibar, 1=full page) drives a
// graphicsLayer scale+translate on a single mounted TextureView, so
// the morph runs in the render phase (smooth) and the same video
// surface stays live across the whole range — a true shared-element
// transition. Swipe the player down → it shrinks into the toolbar;
// swipe/tap the toolbar up → it grows back into the page.
// * Opening a video is no longer a nav push — it sets OpenVideo +
// expands. The browse screen underneath stays put, so collapsing
// drops you right back where you were.
// * Playback plumbing unchanged: shared controller, NowPlaying,
// setPlayingFrom, SponsorBlock, autoplay-next, PiP, background audio,
// and the true-fullscreen Player (⛶) all still key off NowPlaying.
//
// vc=73 / 0.1.0-CG — VideoDetail cleanup:
// * Inline player → TextureView surface so the swipe-down-to-minimize
// drag is smooth (a SurfaceView won't follow the Compose graphicsLayer
@ -57,6 +74,6 @@ const val STRAW_SDK_TARGET = 35
// vc=19 / 0.1.0-AE — rust pipeline cutover. Extraction via
// strawcore-core (Sulkta-OSS/strawcore) via the UniFFI wrapper; no
// NewPipeExtractor in the runtime path.
const val STRAW_VERSION_CODE = 74
const val STRAW_VERSION_NAME = "0.1.0-CH"
const val STRAW_VERSION_CODE = 75
const val STRAW_VERSION_NAME = "0.1.0-CI"
const val STRAW_APPLICATION_ID = "com.sulkta.straw"