Commit Graph
23 Commits
Author SHA1 Message Date
nvrl 255e463fc8 feat(app,android,ios): display type, artwork fade-in, shimmer, lifting tiles and paged shelves
A first pass at making the three clients look like a streaming app rather
than a file browser, with no new data behind it.

- Type: a Hero rung (34) set in Inter Display Bold, the optical size Inter
  draws for large text, for the banner's name and a title page's name where
  no logo stands in. Desktop `Role::Hero` and `theme::display`; Android and
  iOS `displayLarge`, at a tighter 1.1 leading. The font has its private use
  mappings stripped like the other two cuts.
- Artwork fades in over its skeleton on Android and iOS, as it already did
  on desktop cards; art already decoded draws at once. Desktop episode
  stills and logos fade in too.
- Skeletons shimmer: a soft diagonal highlight instead of a pulse.
- Desktop tiles lift towards the viewer under the pointer, capped so a
  lifted tile never reaches its neighbour, and keyboard focus gets a ring
  of its own.
- Desktop shelves share one `ui::shelf`: edges fade into the page and, under
  the pointer, round buttons page the row along.
- Genres are chips on Android and iOS; quality (4K, HDR, 10-bit, Dual audio)
  moves out of the facts line into small outlined marks on all three.
- Desktop title page and hero buttons use a tonal style beside the accent
  one, and the player's top bar a dark glass style, instead of egui's stock
  buttons. Episode numbers leave monospace for the type ramp.
- The phone players' top and bottom bars are gradients rather than flat
  bands, and a double-tap seek is felt as well as seen.
2026-10-30 20:36:09 +01:00
nvrl 4b9cbd26bc feat(android): notify when a show gains episodes
NewEpisodesWorker runs crawl_for_news every six hours on a network with
the battery not low, and posts one notification per show, grouped. A
setting under Playback turns it off and cancels the schedule.
2026-10-13 21:26:15 +02:00
nvrl 5b931111b3 feat(android,ios): play from Downloads, and say what a download waits for
- A finished download row on the phones plays when tapped and has an
  Open button for its title, as the desktop's does.
- iOS queued downloads say "Waiting for Wi-Fi" or "Waiting for a
  connection", as Android's already do.
- Android download workers post their notifications as one group, each
  named for its episode, under a "Downloading 12 episodes" summary.
  Before, a season made fourteen loose notifications that all said
  "Making episode available offline".
2026-10-13 15:48:59 +02:00
nvrl 6ddbcea429 feat(android,ios): offer posters and synopses on the library, as the desktop does
The offer appears when metadata is off and there is a library to put
posters on. It says what turning metadata on sends, links to Settings
and never turns anything on itself. "Not now" is stored on the device.
The existing library screenshots now run with metadata on, as their
shelf implies, and a new screenshot covers the offer.
2026-10-13 15:15:28 +02:00
nvrl 01c252b794 feat(android,ios): mark a whole season watched from the title page
Marking was one episode at a time on the title page, or the whole title
from the library's long-press menu, so joining a show at season three
meant ticking every earlier episode. The season row gains a mark button
beside its download one, with an Undo, through a new markEpisodes that
setTitleWatched now uses too. Episodes already in the asked-for state
are left alone, so Undo restores only what changed.

Season chips were keyed by label, and two seasons with one label is a
crash in a lazy list; they are keyed by position now.
2026-10-12 22:51:10 +02:00
nvrl 603cc0c1a9 feat(core,app,android,ios): add a first share without a detour or a name to invent
The empty library said to add a link "under Shares, then refresh" with
nothing to press on the phones, and on the desktop only switched page.
All three now open the add form from there, the desktop with the caret
in the link field; and adding already crawls, so there is nothing to
refresh.

A share's name was required before the viewer had seen anything to name.
It is optional now: without one, ShareStore::add_verified takes the
shared folder's own name from the link it has just opened. The link
comes first in each form. The desktop form submits on Enter, and the
Android link field has an eye to check what was pasted.
2026-10-12 22:37:17 +02:00
nvrl 5807493a4a feat(core,app,android,ios): look at shares again on their own, and say when they were last looked at
No client crawled a share unless someone pressed Refresh, so a new
episode stayed out of the library until then, and nothing said how stale
the library was.

Catalog schema v11 adds share_crawls: when each share's last crawl
finished and was attempted, how many files it stored and how many were
new, and why the last attempt failed. A failure keeps the last good
crawl's numbers.

Every client now crawls, quietly, any share not looked at for six hours:
the desktop at launch and every half hour while open, the phones at
launch and on their existing catch-up timer. A quiet crawl says only
news ("anime: 3 new files") and leaves failures on the share's row
rather than in a toast.

Share rows on all three show "120 files - crawled 2 h ago", or the last
failure until a crawl succeeds.
2026-10-12 22:22:25 +02:00
nvrl 67cf3044f1 fix(android): keep the accent button's width and corners
Moving the gradient onto a row inside the button lost both: the button's
own row hands its children no minimum size, so a fillMaxWidth button
painted the ramp only behind its label, and with square corners.

The gradient goes back on the button, and the 48dp touch-target padding
is taken by a box around it instead, with the button inside told not to
add its own. The primary button now matches the other buttons' 40dp
container at every width. The screenshots are re-recorded for it.
2026-10-04 17:14:11 +02:00
nvrl 3638e0e5df feat(core,app,android): sort, fold and shelve the Android library
Bring the phase 2 library to Android. Search, sorting and franchise folding
move from the desktop app into pstr_core::browse, so both clients find,
fold and order the same titles the same way.

The bridge gains AndroidEngine::arrangement, which returns the grid's tiles
and up to three shelves as keys into the library's titles. Each TitleRecord
now carries its display name, wide art, format, season, studios, directors,
tags, airing state and franchise. The library bar has a sort menu with the
franchise toggle, folded tiles show a +N badge, and shelves sit above the
grid. The title page shows the same facts, tags and franchise row as the
desktop. Settings -> Appearance gains Title names.

The default title name is now English, which is what Android always showed.
A folded franchise now sorts by its lead's displayed name rather than by its
alphabetically first member.
2026-10-04 02:04:15 +02:00
nvrl bedbe0ef52 fix(android): pin the version in the settings screenshot
The Settings index shows the installed version, read from the package,
so the committed image held 0.5.1 and the 1.0.0 bump failed the
screenshot check. SettingsScreen takes the version as a parameter that
defaults to the package's, and the test passes a fixed one.
2026-10-03 14:24:32 +02:00
nvrl 9cba54df14 feat(android): light-palette and tablet screenshots, and a title page that fits a tablet
The screenshot tests now also capture the library and a title in
Catppuccin Latte, and a title and the history page on a tablet. The
tablet capture showed the title page opening on nothing but its
backdrop: a 16:9 picture the width of a landscape tablet is taller than
the window. The backdrop is now no taller than about half the window,
and the rest of the page keeps a phone's reading width, centred.
2026-10-03 13:27:19 +02:00
nvrl 6c2ec83cb1 feat(android): a downloads page of rows under each show
Saved episodes are list rows with their still, the episode's name rather
than its file, and its size, under a heading per show; the page opens
with how much is on the device. Downloads still arriving come first, with
pause or resume and cancel as icons beside the progress. Deleting a saved
episode now asks first, since getting it back is a download.
2026-10-03 13:13:41 +02:00
nvrl 677ab2d928 feat(android): settings as a page per area, and a language picker
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.
2026-10-03 13:07:11 +02:00
nvrl fb32d6c850 feat(android): per-page app bars, edge to edge, and search behind an icon
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.
2026-10-03 12:56:03 +02:00
nvrl 110f97caf9 feat(android): generated placeholder art and a skeleton library
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.
2026-10-03 12:45:34 +02:00
nvrl 153859a735 feat(android): a featured title at the top of the library
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.
2026-10-03 05:25:33 +02:00
nvrl 1c61aadb22 feat(android): a history page
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.
2026-10-03 05:23:26 +02:00
nvrl 65ecc099b6 feat(android): settings as grouped rows
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.
2026-10-03 05:10:12 +02:00
nvrl 65a6ae9373 feat(android): shares as list rows with a menu, and Add as a button at the thumb
- 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
2026-10-03 05:03:22 +02:00
nvrl 2fbbd0e090 feat(android): a poster library with pull to refresh
- 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
2026-10-03 04:58:35 +02:00
nvrl eee45bc8f8 feat(android): a title page built around one Play button
- 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
2026-10-03 04:53:59 +02:00
nvrl 1c8df80c27 feat(android): Inter, the desktop's typeface
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.
2026-10-03 04:48:21 +02:00
nvrl c63f08ac91 test(android): screenshot tests for every screen
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.
2026-10-03 04:34:46 +02:00