Commit Graph
743 Commits
Author SHA1 Message Date
austinried e7ee6fa9a2 release: bump to 3.0.0 and refresh F-Droid metadata
Bump versionCode to 13 and versionName to 3.0.0. The Flutter app ended at
2.0.0-alpha.3+12 (versionCode 12), so 13 keeps the eventual com.subtracks
release an in-place upgrade.

Metadata was still inherited from the Flutter app:
- add the changelog for versionCode 13
- rewrite the descriptions for the native app
- replace the Flutter phone screenshots with native renders, and mute the
  screenshot fixture palette so the placeholder artwork reads as covers
2026-10-04 00:30:08 +00:00
austinried 836d0636d1 search: tighten the filter bar's vertical padding 2026-10-04 00:30:08 +00:00
austinried f6e087b6ab search: list playlists before artists, albums and songs
Order the result sections smallest-first and apply the review fixes: pad
the filter bar for the navigation bar, keep at least one filter enabled,
hide the clear button on an empty field, drop the unused autoFocus and
bar-modifier parameters, and test the filter mask and section order.
2026-10-04 00:30:08 +00:00
austinried 5d81c2dc41 library: match the list options search rounding to the search field 2026-10-04 00:30:07 +00:00
austinried f54ea54566 search: outline the shared search field to match the list options entry 2026-10-04 00:30:07 +00:00
austinried 3bef469acc search: add a type filter bar and share the search field
Add a filter chip bar above the keyboard to toggle songs, albums, artists
and playlists independently, all on by default and scrolling when it
overflows. Extract one compact 48dp search field and use it in both the
cross-library screen and the library tabs.
2026-10-04 00:30:07 +00:00
austinried 12ad62813e search: localize the cross-library search strings 2026-10-04 00:30:07 +00:00
austinried b25b9deacd search: address review findings
Prefix result keys per type so ids shared across songs, albums, artists
and playlists cannot collide and crash the list; add a loading state so
a query in flight no longer reads as no results; gate on code points to
match SQLite's length(); bind the three-character floor to one constant;
label the search field for TalkBack; and drop the vacuous trigram-plan
test. Cancel the ViewModel scope in its test teardown so it cannot leak
into later Robolectric tests.
2026-10-04 00:30:07 +00:00
austinried c1081b4ae7 search: require three characters and play songs in album context
Drop the library-wide instr fallback: below three characters the
cross-type search now returns nothing instead of scanning every table,
and the screen asks for more input. Lock in that a song result plays its
album context rather than a search queue.
2026-10-04 00:30:07 +00:00
austinried 5a3d5ded78 search: expose cross-library search from a home FAB
Add FTS5-backed search across songs, albums, artists and playlists,
reachable from a search FAB on the Home tab. Terms of three characters
or more run through the trigram indices; shorter terms fall back to the
instr scan, matching the per-tab filters. Results are grouped by type
and route into detail screens or song playback.
2026-10-04 00:30:07 +00:00
austinried 98a3d336a8 port the library tab labels from the old plural names
Albums/Artists/Playlists were new keys because the old Flutter strings
were plurals, so their translations went unused. Take the `other` form of
resourcesAlbumName/resourcesArtistName/resourcesPlaylistName into the three
plain-string resources for the 26-27 locales that translated them. Arabic
`resources_album_name` and Hungarian `resources_playlist_name` stay English
because their upstream `other` form is empty.
2026-10-04 00:30:07 +00:00
austinried 699a6e86f5 address review: localize connection errors, tighten i18n guard, drop dead resources
- AddSourceViewModel resolves SubsonicException.uiMessage too, so malformed/
  HTTP/truncated responses show localized text instead of the raw parser
  message; add a regression test.
- StringResourcesTest now requires an 'other' quantity in every plural and
  asserts exact placeholder (index and conversion) equality, both of which
  could previously pass while crashing getQuantityString at runtime.
- Map the pre-enum song_downloads.error sentences back to their DownloadError
  so existing failed rows keep their specific message.
- Localize the media-session star/unstar button label.
- Remove 12 unreferenced resources (queue name, filter year, sync_failed, and
  the unused codec_* strings; codec labels stay in AudioEncoding).
- Make buildTree's fallback arguments required; only tests used the defaults.
2026-10-04 00:30:07 +00:00
austinried 3162ac07d5 localize transient messages and the download notification
Route user-facing messages produced below the UI through a typed UiMessage
(string-resource id plus format args) instead of pre-built English strings:
showMessage, SyncStatus.Failed, playback errors and download toasts now
resolve in the current locale at the UI edge. Subsonic and page-cap
exceptions carry a UiMessage alongside their developer message, and the
download progress notification is formatted from resources.

Internal invariants and log tags stay plain strings.
2026-10-04 00:30:07 +00:00
austinried a1e45380cc leave the fixed ID3v1 genre names untranslated 2026-10-04 00:30:07 +00:00
austinried 24757bda3f localize user-facing text into string resources
Move every exposed UI string into res/values/strings.xml (+ plurals) and
read it via stringResource/pluralStringResource or getString, with 27
locale files carried over from the Flutter app's Weblate translations.
Only strings whose English is unchanged reuse an old translation; reworded
ones get fresh keys.

Persisted download failures become a DownloadError enum mapped to string
resources (stored by name, unknown legacy values degrade to Failed), the
per-app locale config is generated by AGP, and StringResourcesTest guards
locale keys and placeholders.
2026-10-04 00:30:07 +00:00
austinried 88cd3764bf align the swipe peek with the skip and harden its edges
Resolve previousItem/upcomingItem through the same offline download scan the transport uses, so the peeking art is the track the swipe will actually play. Clear a frozen strip when a fallback swipe fires, prefer the dragged direction over an opposite fling, and simplify the hand-back and ratio prefetch.
2026-10-04 00:30:07 +00:00
austinried 73add672e1 keep the previous artwork visible and stop the neighbour flashing mid-swipe
Swipe-back now goes to the previous track (previousTrack) instead of restarting, so the previous peek stays visible past the restart threshold. The frozen strip only hands back once the live neighbour props match it, so a stale neighbour can no longer flash while the slide settles.
2026-10-04 00:30:07 +00:00
austinried b4539b9ba5 peek the adjacent artwork while swiping the now playing screen
Resolve the previous/next queue items and render a three-slot cover strip that follows the drag, so the neighbouring cover slides in from the side on release. The strip is rotated optimistically at commit and hands back to live state once the controller reports the new track (or after a grace period), so a prop update mid-animation cannot desync it. Ratio prefetch and layered cover loading keep the incoming art from snapping as it loads.
2026-10-04 00:30:07 +00:00
austinried 317a8f4e09 swipe between tracks on the now playing screen
Left/right drags on the cover art skip to the next/previous track, mirroring the transport buttons; the cover follows the finger and settles back on release. Also drops the ripple on the title/artist block.
2026-10-04 00:30:07 +00:00
austinried 4ddbefe7cd downloads: address review on the cancel/progress rows
Name the cancel and delete buttons after the row so screen readers can
tell them apart, show an indeterminate bar when a running track has no
known total, and drop the no-op media refresh on cancel. Trim the dead
size alias and a redundant guard, and cover a queued row with no engine
id plus a failed track in the progress denominator.
2026-10-04 00:30:07 +00:00
austinried 196733f9a7 downloads: base album/artist progress on completed tracks
The aggregate summed bytes over only the currently active songs, so it
reset each time a track finished and the next one started. Count completed
tracks (plus the fraction of each running track) over the node's full track
count instead, so it climbs one track at a time.
2026-10-04 00:30:07 +00:00
austinried 5e074db834 downloads: show progress and cancel on album and artist rows too
A node with any active download now shows the aggregate progress bar and
cancels all its active downloads instead of offering delete; a node with
only finished downloads keeps the trash.
2026-10-04 00:30:07 +00:00
austinried 814331c402 downloads: show progress and a cancel button for in-progress downloads
In-progress rows on Manage downloads now render a determinate progress bar
and a cancel button; completed and failed rows keep the delete button.
Cancelling removes only the active rows, so any completed downloads stay
and can still be deleted.
2026-10-04 00:30:07 +00:00
austinried c3bfb612f8 address review: fix reveal anchoring and ID3v1 names
RevealNewFrontItem compared the post-anchor firstVisibleItemIndex against the
front threshold, so it only worked when the row was at index 0 and exactly one
item was prepended. Recover the pre-change position by subtracting the number
of items now before the old front, and cover the one-in and multi-prepend cases
with integration tests.

Adopt the canonical TagLib/mutagen names for two extended indices: 133 is
Worldbeat (was Negerpunk) and 148 is Abstract (was Christmas). Drop the unused
default on SongInfoDialog's genres argument.
2026-10-04 00:30:07 +00:00
austinried e8ac683b42 normalize every song genre into song_genres
Split genre tags on Navidrome's separators (semicolon, slash, comma) and
resolve ID3v1 numeric indices to their names, so a song's genres are one
deduped list. songs.genre is now derived data with no reader: drop the
column and its index, and read the song info dialog's genres from
song_genres.
2026-10-04 00:30:07 +00:00
austinried 31ed5064a5 home: reveal new front items and brick-pack genre chips
Scroll a recently played row back to the front when a new first item
appears while it is already at/near the start; the lazy layout otherwise
anchors the old first item and hides the new one. Balance the three
genre rows by estimated width and tighten their gap.
2026-10-04 00:30:07 +00:00
austinried ea74fce758 library: route the rediscover list through the download-free query too
Also assert the default pager still observes album writes and cover the
quoted-search path.
2026-10-04 00:30:07 +00:00
austinried c2acbd0eae downloads: skip redundant progress writes 2026-10-04 00:30:07 +00:00
austinried 487296e75e library: stop download writes from invalidating the browse lists
The album/artist/playlist paging SQL named song_downloads, so Room
invalidated the pages on every download progress tick, janking the list
and resetting scroll when a download started. Route the default (filter
off) path through a raw query that only observes its own table; the
downloaded/offline path keeps the download-aware queries.
2026-10-04 00:30:07 +00:00
austinried adc206337b settings: add icons to Manage downloads and Licenses 2026-10-04 00:30:07 +00:00
austinried 0cd6f30c88 address review: keep the notification tap when the activity is recreated 2026-10-04 00:30:07 +00:00
austinried b3cad97869 address review: signal now playing with an event flow, not an int 2026-10-04 00:30:07 +00:00
austinried fd3b1ce298 address review: keep notification taps working after recreation 2026-10-04 00:30:07 +00:00
austinried 46ab8f66c4 open now playing when the media notification is tapped 2026-10-04 00:30:07 +00:00
austinried 6eb23445f1 limit the home downloaded-songs preview in SQL 2026-10-04 00:30:07 +00:00
austinried 5dce881704 use the auto-mirrored TrendingUp icon 2026-10-04 00:30:06 +00:00
austinried 3e260aa170 address review: dedupe and trim genres, add a starred queue reference, fix the offline source switch 2026-10-04 00:30:06 +00:00
austinried 4779bfc88b keep playback running when offline mode is toggled, and swap the recently-added header icon 2026-10-04 00:30:06 +00:00
austinried bf180ef711 home: put a relevant icon on each section header 2026-10-04 00:30:06 +00:00
austinried 2061ebafca keep playback running when rebuilding the offline window, and order downloads newest-first 2026-10-04 00:30:06 +00:00
austinried 8848e951e4 play genres and downloads as lazy queue references instead of expanding every song 2026-10-04 00:30:06 +00:00
austinried adbd3b8d8e normalize every song's genres into song_genres and simplify the genre queries 2026-10-04 00:30:06 +00:00
austinried 3df16826e6 home: paginate the offline lists and add More to each downloaded section 2026-10-04 00:30:06 +00:00
austinried c44987ff31 home: swap to downloaded sections in offline mode 2026-10-04 00:30:06 +00:00
austinried 43c90c3453 home: tighten the genre chip rows 2026-10-04 00:30:06 +00:00
austinried d9aa18c37a home: play the whole genre list from a genre song row 2026-10-04 00:30:06 +00:00
austinried f62e8363de home: drop On repeat, restore starred, give artist lists the detail column 2026-10-04 00:30:06 +00:00
austinried e36a0e3de5 home: add an On repeat song row and move recently starred below genres 2026-10-04 00:30:06 +00:00
austinried b0a31d0291 home: show album more screens as lists with a section-relevant detail column 2026-10-04 00:30:06 +00:00
austinried 53aa0f71b3 home: add a little content gap and more space between sections 2026-10-04 00:30:06 +00:00