Album details: disc grouping, track numbers, year, client-side sort
Album drill-in now uses its own renderer instead of the generic list.
Improvements:
- Album title includes the production year in parentheses when
Jellyfin has one (e.g. "17 (2017)").
- Every track row shows its track number, padded to the widest number
in the album so "1." and "12." line up. The subtitle / duration
columns follow the same layout math as the standard list, so they
stay column-aligned with sibling views.
- Multi-disc albums render a "▤ Disc N" header before each disc's
tracks — non-selectable, so Up/Down navigation walks track-index
space and the cursor never lands on a header. Single-disc albums
render as a flat list (no header noise).
- After fetching the tracks, sort_album_tracks() re-orders by
(disc, track number, name) as a safety net. Jellyfin already applies
ParentIndexNumber,IndexNumber,SortName server-side, but a single
mis-tagged track was enough to leak into the disc grouping downstream.
Under the hood the app still tracks a TRACK-index cursor; the album
renderer builds visual rows + a track_to_visual map and drives a local
ListState so the highlight lands on the right visible line even when
disc headers push the visual index above the track index.
Four unit tests cover sort_album_tracks: disc-then-track ordering,
tracks with missing metadata sink to the tail, ties break on name,
and already-sorted input is preserved.