Commit Graph
13 Commits
Author SHA1 Message Date
austinried 7a890094fc logging: add file-based logging and a Send logs option
Capture logs to rotating app-private files with Subsonic credential and URL basic-auth redaction, mirror to Logcat, and capture uncaught crashes. Log slow SQL (>100ms), SQL errors, migrations and DB lifecycle via a decorating SQLiteDriver. Add a Send logs row in Settings that zips the logs and opens the share sheet through a FileProvider.
2026-10-09 07:58:54 +00:00
austinried 293561d81f settings: guard the About links and align the support label 2026-10-08 17:56:34 +00:00
austinried 8aee86fc60 settings: restore the version, homepage and support links in About 2026-10-08 17:19:18 +00:00
austinried 05de10c912 clear the build warnings and fail on new ones
A clean build now emits no warnings of its own, and Kotlin
`allWarningsAsErrors` plus lint `warningsAsErrors` stop new ones from
sneaking back in.

- Kotlin: give SearchFilter's @StringRes parameter an explicit @param:
  target; use safe calls for File.parentFile in StringResourcesTest.
- Packaging: keep debug symbols for the prebuilt .so files that have no
  symbol table, which is what the "unable to strip" warning was about.
- Lint: move `modifier` to the first optional parameter across the Compose
  screens, use mutableIntStateOf for int state, read Resources via
  LocalResources, use the KTX Bitmap.get/String.toUri, drop the unused
  ic_action_name and ic_stat_name bitmaps and the dead -v24 qualifier on
  the notification vector, fix the pt-BR "album" accents and the unused
  Vietnamese/Thai plural quantities, and suppress the intentional
  cleartext/user-certificate, backup, exported-service and
  plural-candidate findings. Disable the version-update nags, which the
  dependency-update process owns.

The AboutLibraries plugin still resolves the variant classpaths during
configuration, so AGP keeps warning about that one; upstream in
mikepenz/AboutLibraries#1369.
2026-10-08 10:27:09 +00:00
austinried fd2e1cfd86 artists: show a credited track artist's name and type on their page
A track artist without an artists row had no name on the artist page, so
the header and the placeholder letter were blank. Derive the name from the
songs that credit them, and label the page 'Album artist' when they lead an
album or 'Artist' when they are only credited on tracks. The hero art keeps
the letter placeholder when there is no artist image.
2026-10-04 01:49:55 +00:00
austinried 8e6c1593dc metadata: say Subsonic-compatible and use lowercase subtracks
Drop the "API" from the server compatibility wording, and lowercase the brand
in the title, description, old changelog and the app name to match the logo.
2026-10-04 00:30:08 +00:00
austinried 12ad62813e search: localize the cross-library search strings 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 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 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 ce035f457b post our own download progress notification
The platform posts one notification per download, so queueing an album buries
the UI in them and they can be swiped away. Hiding them (VISIBILITY_HIDDEN,
which needs DOWNLOAD_WITHOUT_NOTIFICATION) and posting one aggregated
notification instead gives a single ongoing entry with the overall progress and
a Cancel action that stops everything in flight.

It is refreshed from the download state the poller already maintains, so it
tracks the engine without extra queries, and it is tied to this process: if we
are killed the downloads continue with no notification, which is the trade for
not writing a service.
2026-10-04 00:30:03 +00:00
austinried 05ac1768d3 start kotlin/jetpack compose rewrite
replace the flutter project with a gradle/compose android app:
- nix flake dev shell (jdk21, android sdk 35, build-tools 37, gradle)
- material3 app with a placeholder screen
- roborazzi/robolectric screenshot tests with one golden
- carry over the existing launcher/notification assets
2026-10-04 00:29:51 +00:00