Album and artist context menus gain an Info dialog covering the plural
album artists, sort names and the play and download details the screens
do not show. Multiple artist links collapse into one ellipsised entry
that opens the artist chooser instead of listing each artist.
Sort lists can now prefer regular names over sort names, or only use
sort names for names without Latin letters. The new plain-name indexes
keep those orders out of a temp B-tree.
Also carry plural artists through the Media3 queue so Now Playing and
the mini player keep them, drop the album artist tap ripple, and show
the aggregate download progress in the tab bar where offline mode used
to sit.
Only reserve the action-button width for the lines they actually overlap, so the collapsed bio's More stays on the third full-width line without moving the actions or spacing.
Turn the 3-cover layout upside down so the stem runs from the centre to the top edge and the two arms open toward the bottom, leaving one boundary straight up from the centre.
Nudge the star and overflow row 8dp right, and restore the vertical offset, so the action row and shuffle button share a centre line. Keep the extra collapsed-bio spacing and the gap before the Albums header.
Move the breathing room into the bio text instead of offsetting the star and overflow actions, which broke their centre alignment with the shuffle button.
The three-line collapsed bio let its More control sit under the star and overflow buttons, and the collapsed state had no bottom gap before the Albums header. Move the actions up, reserve their width on all three collapsed lines, and add the same bottom gap the expanded state uses.
Move change detection into a desired CTE with UPDATE ... FROM so mass updates do not turn the trailing WHERE into a quadratic correlated scan, and so no-op passes write zero rows. Fold the trigger optimization into the 35->36 migration and re-check/rewrite it from onOpen, so a future migration cannot silently restore the full UPDATE triggers. Re-resolve artist detail art when the active source becomes ready, and cover artist search renames in a Room-level test.
The materialized art update rewrote every artist row on every library-changing sync. That fired the FTS5 content-sync triggers for each artist, which was the real cost: the same SQL is ~10ms with the triggers removed and ~4.7s for 100 changed artists with them in place. Only update rows whose cover lists actually changed, and replace the generated artist search triggers with UPDATE OF name, sortName so art-only writes never touch the FTS index. Existing databases get this through migration 36->37; fresh databases get it from the onCreate callback.
Cap the resolver at four covers, re-rank after deduplication so duplicate covers do not consume the grid budget, carry a thumbnail per fallback step, and advance to the grid when both the full image and its thumbnail fail. Negative-cache failed provider-image fetches per artist URL, clear materialized downloaded covers when all downloads are removed, and drop redundant plumbing.
Store the OpenSubsonic artistImageUrl and two materialized cover-id lists on each artist row, backfill them in the 35->36 migration, and refresh downloaded covers only for affected artists when downloads change. Icons and the artist hero now resolve provider art, server artist art, then the same materialized grid synchronously, with a definitive-failure fallback so a dead provider URL does not strand the letter placeholder.
Download artwork also caches the provider image for the track and album artists, falls back to the artist cover when that fetch fails, and keeps both keys across sweeps. Query timing for the materialization pass is down from roughly 3.4s to 1.9s on the 20k-song benchmark.
Load up to four thumbnail covers per visible artist row on demand and render the same 1-4 layout inside the circular artist icon. Lists stay on the expensive per-row query for now.
When an artist has no portrait, build a 1-4 cover hero from album credits on demand. Uses full-res for one cover and thumbnails for 2-4; three covers use a Y split.
Exercise context and block drags against the queue authority: all context positions across the up-next block, a far move that crosses the window, a context move while an up-next track plays, and moving the playing up-next track.
A context drag that crosses the up-next block moves the block's anchor in the repository but the old player.move used the combined drop position, leaving the two in different orders. Rebuild the window for context moves that happen while a block exists, in both the in-window and window-offset paths.
Also drop the redundant rebuildWindow snapshot parameter, the unused media-item context read-back, and add coverage for shuffled album context, ranged album moves and ranged up-next moves.
Use album gain for items whose queue entry references an album and track gain for playlists, singles and other mixed contexts, including shuffled album queues. Carry the resolved context on each media item so the audio thread does not need to inspect the queue.
Keep a track moved within an album as an album range so it stays in album context; moves out of playlists, artists, genres and other mixed contexts remain pinned song entries.
Use symmetric page margins for the artist bio, let lines below the action buttons use the full width, and stop the expanding bio from shifting the hero gradient.
Keep source line breaks, treat the triple-space paragraph separator some servers return as a blank line, justify wrapped bio lines, and append a bold Less control to the expanded bio.
Retry a failed download bio fetch instead of blacklisting the artist for
the rest of the process, and give a failed or offline refresh its own
message so it is not mistaken for a server with no biography.
Wait for the stored row before choosing the bio text, so a cached bio no
longer flashes the loading state on entry, and bound the page refresh so
a stalled response cannot leave the loading state up indefinitely.
Render an oversized first token instead of a blank collapsed line, and
check whether the whole remainder fits in one measurement.
Load the biography when the artist page is entered. A stored biography is
rendered immediately while it refreshes in the background; otherwise the
page starts with the loading message and falls back to the empty state.
Collapse a biography to two lines and append a bold More only when the
text does not fit. Tapping that line expands the biography, after which
the first lines keep clear of the star and overflow buttons and the rest
use the full width.
Artist biographies come from getArtistInfo2, which the library sync does
not call. Store them in their own table so a page open can use the last
value immediately and downloads can keep it for offline use, without
pulling a large text column into every artist list query.
A missing row means the artist has never been fetched; a row with a null
biography means the server had none. That lets the page show the loading
state only until the first fetch completes.
The fallback art reads albums and credits, but a successful sync invalidates through the sources row, so observing those tables only adds refreshes for play, star, and sync writes that do not change artist art.
Avoid re-requesting search focus when the screen is restored, keep the cheaper album-credit-first art lookup, and test restoration plus association-table invalidation.
Keep the search field from stealing focus again when a result is dismissed, observe album and credit tables in artist paging, and simplify the cover fallback to one ranked union. Cover the association-table and invalidation paths in tests.
Fall back to the first album credit cover (then the first track credit) for artist art, keep list searches when opening a result, resume search at the end of the query, and navigate immediately from the artist chooser.
Use 'album' and 'track' instead of a 1/0 flag so the credit kind is readable
without a comment. This column is a constant in the SQL, not a stored value,
and only the per-artist credit query compares it, so the text costs nothing
meaningful.
Default the second row to a greyed "No artist bio available" placeholder.
Keep the collapsed two-line layout with a bold More and the expanded flow
that wraps around the action buttons for the next PR, which will supply the
server biography.
Keep the type and count on the first row with space reserved for the hanging
shuffle, and put the star and more buttons on the blank second row so they sit
at their old height.
Keep the type and count on the same row as the star and more buttons, and move
that row down to where it sat before the split. Give the Albums and Appears on
headers the album and microphone icons alongside the disc-title styling.
Move the star and more buttons from the meta line onto the first section
header so they sit below the hanging shuffle button again, and remove the
per-section counts now that the meta line carries the total.
Distinguish the album-credit rule (any downloaded song on the album) from the
track-credit rule (the credited track itself must be downloaded) in the
repository test, so a swap of those clauses fails.