The first Settings page lists Playback, Downloads and storage,
Appearance, Metadata and About, each with a line saying where it stands,
and each opens its own page with a way back. On one long page, every
setting added pushed the rest further from reach.
Audio and subtitle language are chosen from a list of languages by name
instead of typed as "jpn or eng". The list stores the three-letter tag a
Matroska file carries, reads a stored tag in either ISO form, and still
takes any other tag typed in.
The single "proton-stream" bar over every page is gone. The library has a
large title that folds away as the grid scrolls, with search and refresh as
icons; search opens into a field in the bar that takes the keyboard at once,
and back closes and clears it. History, Shares, Downloads and Settings each
name themselves in a bar of their own, drawn in the page's background until
content scrolls under it. The title page now draws its backdrop under the
status bar, with the back button below it.
A search with no results says so instead of claiming the library is empty.
A title without artwork shows the accent as a gradient with its initials
instead of a black card with a play triangle, so a library of unmatched
titles is no longer a grid of identical cards. Art with the name already
over it, and episode stills, get the gradient without initials. While
artwork loads, and while the catalog first loads, the page shows pulsing
shapes where the posters will be rather than a spinner.
The screenshot tests turn artwork loading off, so whether a failed fetch
lands before the capture no longer decides what the image shows.
The desktop's rule: the title watched last, or with nothing part watched,
one of the titles the provider has a backdrop for, turning over once a
day. Large art fading to black behind the name, rating, genres and three
lines of synopsis, with Resume or Play and More info.
History sits second in the navigation, as on the desktop: every played
episode, newest first, under Today, Yesterday, a weekday or a date. The
still plays the episode, the text opens its title, and the cross takes
it off the page — forgetting its position and watched mark — with Undo.
The list is the desktop's Library::history rule over the records the
library already holds, so no bridge call is added; HistoryTest pins the
rule and the day headings.
- a long press on a title opens a sheet: Play or Resume, Open, Download
all, and Mark watched or unwatched for the whole title
- a long press on a Continue watching card offers Resume, Open, and
Remove from Continue watching, which forgets the position as the
desktop does
- marking a title and leaving Continue watching both say what they did
in a snackbar with Undo, which puts every changed watch state back
- the "next up" episode is one shared function, used by the title page
and the menu alike
Playback, Downloads and storage, Appearance, Metadata and About, each a
group of rows with one line of explanation, and the whole row as the
target. The paragraphs under the switches are gone; what they said is
either the row's supporting line or a code comment.
Storage shows the cache's use against its budget as a bar over the
budget chips. Clearing the cache and deleting offline episodes are rows
that say how much they free, and the delete still asks first. Licence
and notices are rows under About.
- each share is a row with its name and how it is unlocked; Refresh,
Re-enter link and Remove sit behind a menu instead of three differently
styled controls that squeezed the name into a column a word wide
- Remove asks first, saying that offline episodes and watch progress go
with it
- Add share is an extended floating button, where the share sheet and a
tapped link land too
- an empty page says what to do instead of showing a bare heading
- titles are 2:3 posters three across on a phone, named under the poster
instead of in a card body; cropped backdrops at full width fitted two
titles to a screen
- a title's caption says "Film" or "1 episode" rather than "1 episodes",
and wraps at large font scales instead of being cut to "2023 · 7"
- Continue watching cards carry the resume bar on the still and say how
much is left: "S03E11 · 12 min left"
- search is a filled pill with a clear button
- pull to refresh crawls the shares, as the bar's refresh icon does
- the backdrop runs edge to edge and fades into the page, with the back
button over it
- one full-width Play that names the episode it plays ("Resume S02E01")
- Start over, Download, Match and the provider link as one row of
labelled icons instead of four buttons in three styles over three lines
- the synopsis is clamped to three lines and opens on a tap; the watched
count joins the year, rating and genres
- seasons are chips showing one season at a time, opened on the season
Play lands in, instead of stacked accordions
- episode rows head with "1. Mother and Children", or "Episode 1", rather
than the filename; numbering, size and air date sit under it, and the
resume bar lies on the still's lower edge
- the per-title track form is gone: the player's track chooser already
stores each title's choice, and Settings holds the global default
The type ramp now draws in Inter Regular and SemiBold, the same two files
the desktop bundles, so the clients read as one app. Inter is declared
above the ramp: top-level properties initialise in file order, and the
ramp built first would have captured it as null and silently used the
system face. Its OFL text ships in the licences beside the notices.
Screenshots re-recorded.
Roborazzi draws Library (phone, tablet, font scale 1.5, empty), a title,
Shares, Settings and Downloads from fixed records under Robolectric, and
build-android.sh check compares them with the committed images in
app/src/test/screenshots. The redesign changes every screen; a layout
regression now fails the gate and shows up in review as a changed image.
A drive.proton.me/urls/ link opened from a browser, or text containing
one shared to the app, switches to Shares and opens the Add form with
the link filled in, fragment included. A playing episode moves to the
mini transport instead of covering the form. A recreated activity does
not offer the same link again.
The view filter is not autoVerify, since the domain is Proton's, so
Android only routes browser links here once "Open supported links" is
allowed in the app's settings; sharing works without that.
storedPalette() reads and resolves the theme file without building the
engine, so onCreate can set the window background and system-bar icon
polarity before anything draws. Previously the background was a hex literal
in themes.xml and the bar icons were pinned dark, which meant every cold
start flashed one flavour's colour and Latte drew white icons on a
near-white page.
Adds the Material scheme mapping, type ramp and shape tokens the palette
feeds, plus unit tests for both.