0.3.02
This commit is contained in:
@@ -1776,7 +1776,7 @@ preserve:
|
||||
the search row instead of on "Off", which is the state the viewer is already in. Where
|
||||
no provider can be asked it says that instead, once, rather than leaving somebody
|
||||
looking for an option that is not there. `SubtitleMenuScreenshotTest` covers both.
|
||||
- **Client-side it is a second screen, not a third section.** The drop-up is 344dp by about
|
||||
- **Client-side it is a second screen, not a third section.** The drop-up is 440dp by about
|
||||
a third of a 720p screen; stacking a track list, the size chips and search results
|
||||
squeezed the tracks to one visible row. `SubtitleDownloadState.expanded` swaps
|
||||
`player_subtitle_main_section` out, and Back steps out of the download half before it
|
||||
@@ -1791,12 +1791,13 @@ preserve:
|
||||
|
||||
**Changing it mid-film is a drop-up**, `player_subtitle_overlay.xml`, anchored over the
|
||||
subtitle button it opens from rather than the full-height panel it used to be. It sits on
|
||||
somebody's film, so there is no scrim and the panel is near-black: the option under focus is
|
||||
the only fill on it (accent green), the choice in force is a quiet grey plate with a green
|
||||
label, and every other row has no background at all. The margins are measured off the
|
||||
somebody's film, so there is no scrim and the panel is near-black. It uses the shared
|
||||
`TvSettingsComponents` rows: focus is a raised control with a white ring, the choice in force
|
||||
keeps an accent wash and a CURRENT badge after focus moves, and every colour comes from the
|
||||
active Memby palette. Every other row has no background. The margins are measured off the
|
||||
transport row — 44dp end, 112dp bottom to clear its 72dp strip and the controls' 28dp
|
||||
padding — and the top margin is what caps the track list before its `ScrollView` (which
|
||||
takes the overflow via `layout_weight`) starts scrolling instead of growing up the screen.
|
||||
padding — and the top margin is what caps the track list before its `ScrollView` starts
|
||||
scrolling instead of growing up the screen.
|
||||
`bindSubtitleMenu` in `ui/player/SubtitleMenu.kt` fills it from plain
|
||||
`SubtitleMenuEntry` lists so `SubtitleMenuScreenshotTest` can render the real menu with no
|
||||
player, server or decoder → `build/screenshots/subtitles-menu/`; deciding *what* the entries
|
||||
@@ -2104,42 +2105,33 @@ 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.
|
||||
**It now gates the launcher**, which is the whole point of it: it was decoration, uncovered
|
||||
whenever the app happened to be ready, and on a warm start that was a fraction of a second —
|
||||
so the one thing Memby owns was in practice never seen. The clip plays once from the
|
||||
beginning, its last frame is held for `LAUNCH_INTRO_HOLD_MS` (2s), and only then is the home
|
||||
screen composed. Things to preserve: **it gates but it can never trap** — no player, a
|
||||
decoder error, or no rendered frame within three seconds all report finished immediately,
|
||||
and `LAUNCH_INTRO_MAX_MS` (9s, the clip's four plus the hold plus room for a weak box) is
|
||||
`AppRoot`'s outer bound on top of that, because a viewer must never be held on a black
|
||||
screen by a branding clip; **`LaunchIntro.played` is process-scoped, not saved**, so an
|
||||
activity Android recreates behind somebody is not a second launch and a profile switch does
|
||||
not replay it; the pulsing mark and the welcome line fade *out* under the clip and back in
|
||||
if the app is still opening when it ends, since the waiting screen and a four-second sting
|
||||
said two things at once; and it no longer loops — looping existed so a slow cold start never
|
||||
froze on the last frame, which the hold and the fade-out do instead, and a clip that never
|
||||
ends cannot gate anything. It is still muted, because it now runs on every single app open,
|
||||
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.
|
||||
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. 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.
|
||||
**Cold start is a local poster snapshot, never a live grid.**
|
||||
`data/StartupPosterSnapshotCache.kt` takes a balanced sample of films and series from the
|
||||
active viewer's Continue Watching, favourites, server-composed recommendation rows and
|
||||
latest films *after* Home's refresh has settled. On `Dispatchers.IO` it asks Coil for bounded
|
||||
220×330 poster requests, composes them into one 1280×720 angled wall and atomically writes a
|
||||
small JPEG under `filesDir/startup_posters/`, keyed by server, Emby user and Memby viewer.
|
||||
The next cold start performs only a file existence check and one asynchronous local decode;
|
||||
no URL is ever handed to `StartupPosterBackdrop`, and no list of poster bitmaps exists in
|
||||
composition. Snapshots refresh at most daily and the directory retains eight profiles.
|
||||
|
||||
**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.
|
||||
The bundled `drawable-nodpi/startup_poster_fallback.png` is a rights-safe wall of fictional
|
||||
artwork. `Theme.Memby.Launcher` draws it as MainActivity's window background before Compose
|
||||
exists, while `MembyLoadingScreen` uses the same resource as Coil's placeholder and gently
|
||||
crossfades a personalised file over it. One ten-second value supplies a tiny pan and scale
|
||||
inside `graphicsLayer`, then holds its final frame; frame-rate reads invalidate the layer
|
||||
rather than recomposing the wall. It has no focus targets and no launch hold: `AppRoot`
|
||||
calls it from one opening call site and uncovers the next screen the instant update, session
|
||||
and onboarding state allow it. The local video pre-roll remains playback-only; startup
|
||||
never borrows its
|
||||
decoder and never holds the launcher for branding.
|
||||
|
||||
**Welcome copy lives in `ui/WelcomeQuotes.kt`.** Twenty-five lines per tone, because five
|
||||
per tone meant a household saw the same sentence roughly every fifth time it appeared.
|
||||
`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.
|
||||
gained a duplicate on a copy-paste, looks identical to one that did not. The greeting is
|
||||
assembled separately so the authenticated name is trimmed once; the player also draws from
|
||||
the same tone-specific pool while it prepares a programme.
|
||||
|
||||
**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
|
||||
|
||||
Reference in New Issue
Block a user