The AniList query now keeps the start date, season, banner, popularity,
status, next airing episode, tags, main studios, director and story
relations, as TitleDetails in one JSON column (schema v10). Matches
stored without them are fetched again by id, never searched, so
hand-picked matches stay; refreshing the same entry keeps its episodes
and fanart. Enrichment records the entries it walked. node_first_seen
remembers when each file appeared, across recrawls.
pstr_core::franchise groups titles that share a provider id. The grid
folds each franchise into its lead with a +N badge, and the title page
lists the whole franchise in release order. pstr_core::shelves picks
rows by airing status, director, studio and genre. A row needs three
franchises, so one franchise's titles never make a row on their own.
Desktop:
- Covers are the default grid (Settings > Appearance > Library tiles).
- The hero and title band use fanart or banner decoded at 1920 px.
- New sorts: recently added, newest, highest rated, most popular.
- Titles can show the share's, English or romaji name; search matches
all of them.
Android carries TitleDetails through a hand-picked match; its screens
are unchanged.
AniList's per-season lookup searched for "<title> 2nd Season" and the
scorer picked the base entry again, so Attack on Titan seasons 2-4 and
Jigokuraku season 2 were captioned with season one's names. Episode
names came from streamingEpisodes, which is partial and numbered however
a streaming site counted. Bleach S17 and Mushishi S02/S03 had none.
AniList now walks SEQUEL relations from the match and takes each
entry's episodes from ani.zip, which carries TVDB's season, number and
absolute number. An episode row keeps all three plus its place in the
AniList entry. EpisodeGuide::get matches whichever numbering a file
uses and never answers from another season.
Episodes and fanart are stored as one enrichment. The episode list is
replaced even when empty, and the enrichment is recorded as asked, so a
film is not re-asked every run. Storing a different match drops the old
entry's episode rows. AniList's 4.75:1 bannerImage is no longer stored
as the 16:9 backdrop; ani.zip's 1920x1080 fanart is used instead.
Schema v9 adds the columns and deletes the AniList episode rows and
banners. Matches are kept. Desktop, Android and the CLI now share
service::plan and MetadataService::work. The settings text names
ani.zip. Audit and roadmap in docs/METADATA.md; bug entry B61.
- Settings > Storage chooses the streaming cache's budget, 1 to 16 GiB,
and shows what it holds against it. The bridge gains
set_stream_cache_budget, which the next connection is built with and
an open one evicts down to at once. Android keeps the choice in its own
settings, like the desktop keeps it in desktop.json, and tells the
engine as it is created. Unset stays at the shared 4 GiB default.
- Settings > Playback can turn hardware decoding off for a device whose
decoder shows green or torn frames. pstr_mpv sets hwdec before each
loadfile, so it applies from the next episode.
A SwiftUI app that drives the same UniFFI engine as Android: Rust owns the
Proton sessions, SQLite and every decrypted byte, and Swift asks it questions
off the main thread. Playback goes through MPVKit's libmpv, with the pstr://
stream protocol ported from the Android JNI half, and secrets live in the
Keychain.
scripts/build-ios.sh builds the static library for aarch64-apple-ios, writes
the Swift bindings (module PstrBridge), generates the Xcode project with
XcodeGen and packages an unsigned .ipa for SideStore or AltStore, which
re-sign it with the viewer's own Apple ID. The generated project, Info.plist
and build output are ignored.
A track picked on one episode now carries over to the next by its title as
well as its language, so e.g. "Signs & Songs" vs "Full" subtitles in the same
language stick. Catalog migration V8 adds the title columns; the Android
bridge keeps a stored title only while its language is unchanged.
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.