0.2.41 - Preroll fixes, theme fixes

This commit is contained in:
ponzischeme89
2026-08-10 09:39:09 +12:00
parent e1bb687df4
commit 32c0054c44
17 changed files with 648 additions and 167 deletions
+42
View File
@@ -1192,6 +1192,31 @@ failure fallback; and the preroll player is stopped and parked at hand-off so it
hardware decoder while HEVC content plays. Returning to Home prepares the same instance again
in the next idle window rather than constructing one per title.
**The same clip plays behind the cold-start screen** (`ui/LaunchPreroll.kt`). It is the one
screen every launch shows and the clip was the one thing Memby owns that nobody ever saw
there. It borrows the *same* cached instance — no second decoder, no second copy of the
file — and hands it back on dispose, so the next playback still opens on a prepared player.
Things to preserve: it is **decoration and never a gate**, so every failure is silent and
leaves the pulsing-logo screen exactly as it was, and the logo only fades out on
`onRenderedFirstFrame` rather than on having asked the player to start; it is acquired
**after** `withFrameNanos`, because a cold start has nothing cached and constructing an
ExoPlayer inside the first composition of the screen that must appear immediately is the
cost the idle-handler prepare exists to avoid; it is muted and looped, where the pre-roll
before a programme is audible and must *end* — `PrerollPreloader.acquire`/`recycle`
normalise volume and repeat mode so a borrower cannot leave the next one wedged. And
`AppRoot` calls `MembyLoadingScreen` from **one** call site: the three states meaning "still
opening" were three, and Compose identifies a composable by where it is called from, so
moving between them disposed the screen and rebuilt it — which now means returning and
re-borrowing the player twice during the busiest stretch of a launch.
**What it says while it is opening is `ui/WelcomeQuotes.kt`.** Twenty-five lines per tone
plus eight headlines, because this is the most-read copy in the app and five per tone meant
a household saw the same sentence roughly every fifth time they switched the set on.
`WelcomeQuotesTest` counts the distinct lines a pool yields: a pool that shrank back, or
gained a duplicate on a copy-paste, looks identical to one that did not. The headline is
kept apart from the quotes and is not keyed on the tone — it names what the app is *doing*,
and rerolling it when the settings flow arrives would change the line mid-launch.
**Next up / auto-advance.** 30 s before an episode ends, `PlayerActivity` slides up
`player_next_up_banner.xml` and rolls into the next episode when it reaches zero (Settings
→ Playback turns it off; `Settings.autoPlayNextEpisode`). Which episode that is comes from
@@ -1563,6 +1588,23 @@ and two secondary greys, which is visible the moment a detail page opens from a
colour or radius belongs in the token file, or is a considered exception — not a fifth
value.
**The eight slots a theme sends are not the vocabulary the screens paint with**, which is
why picking a colour scheme used to change almost nothing outside the detail pages. The
launcher, the cold-start screen, Settings, Search, the update and maintenance screens and
the two overlays were drawn with a hundred-odd literal hexes — a lighter green for a label,
a near-black ink for text on a green fill, three neutral steps for controls — none of which
the palette could reach. Those shades are now *derived* in `DesignTokens.kt`
(`MembyAccentBright`, `MembyAccentInk`, `MembyAccentMuted`, `MembyControlSurface`,
`MembyControlSurfaceRaised`, `MembyOutline`, `MembyDisabledText`, `MembySplashTint`).
Derived rather than added to the wire on purpose: a theme sends the *decisions* and the app
works out the shades around them, so a scheme invented on the gateway tomorrow arrives
complete rather than half-applied — the same reason the palette carries no radii. What
stays a literal is anything carrying meaning of its own: the red/amber/blue status colours,
the genre tiles, and the ratings providers' own brand colours. And a screen-local alias must
be `get()`, never `val` — `SettingsSheet`'s `Canvas`/`Panel`/`TextPrimary` were values, so
the settings page, which is where the theme is *chosen*, was the one screen that could never
repaint.
**Those colours are the server's answer, not constants.** Every token in `DesignTokens.kt`
is now a `get()` over one process-wide `mutableStateOf(MembyPalette)`, and `applyMembyPalette`
is what repaints the app. Two things follow and both are easy to undo: an alias must be a