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.
Every played episode, newest first, under Today, Yesterday, a weekday or a
date. A row shows the still (which plays it), the title (which opens it),
the episode, and where it stopped or that it was finished. Removing a row
resets that file to never played, with an Undo. History sits second in the
top bar, so Ctrl+1 to Ctrl+5 now run Library, History, Shares, Downloads,
Settings.
- the streaming cache's budget (1-16 GiB) is chosen in Settings, shows
what it holds, and can be emptied; a lower budget evicts at once
- hardware decoding can be turned off for a driver that shows green
frames, from the next file
- both live in desktop.json rather than the playback prefs shared with
Android, whose bridge record would reset them on every save. A file
that will not parse is never overwritten
The up-next card shows the next episode's still with the seconds left
running round it, and the still itself plays it. The window opens at
the size and maximized state it closed at; position is left to the
window manager.
- ImageCache drops the picture asked for longest ago past 256 MiB and
uploads at most six textures a frame
- posters and thumbnails larger than a card are stored scaled down, so
a cached grid no longer decodes and resizes full backdrops every launch
- a saved watch state patches the library in place instead of rebuilding
it from the catalog; the offline index reuses the library just built
- download byte progress sends one row, not a sorted copy of every row
- the CJK fallback font is found and read off the UI thread
- the watch-state upsert uses a cached statement
A block the player waits for no longer waits on its disk-cache write and
two fsyncs; the put runs in a spawned task and only the block itself is
synced before the rename. Opening a stream can fetch the first and last
block together, where MKV cues and the MP4 moov live. Downloads open a
copying stream that reads the disk cache but never fills it.
crawl_reporting reports the running file count after each listing.
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.