Commit Graph
306 Commits
Author SHA1 Message Date
zarzet fbf479c102 fix(download): stop crashing native finalization on Android regex
Android's regex engine rejects Pattern.UNICODE_CHARACTER_CLASS, so NativeFinalizationPolicy failed to initialize and every native download crashed while writing metadata. List Unicode spaces explicitly and cover the separator with a device test.
2026-10-02 01:24:26 +07:00
zarzet fe36f08918 feat(backend): hold library scans in place while paused
Path and SAF scans wait at their next file checkpoint while paused and keep their position in memory. Cancel, backend shutdown and released request leases still end a paused scan.
2026-10-01 21:00:42 +07:00
zarzet 72b689b1f8 build(android): sign release APKs with APK Signature Scheme v4
Release signing now also writes the V4 .apk.idsig beside each APK, verifies it in CI and publishes it for adb incremental installs. Normal installers keep using the V1-V3 signatures inside the APK.
2026-10-01 21:00:42 +07:00
zarzet d65f3a1cc2 perf(library): overlap SAF listings and metadata reads
SD cards, USB drives and network shares pay a provider round trip per query. Folder listings are now prefetched four at a time while the walk stays serial, so order, deduplication and error counts are unchanged. Full and incremental scans share a six-worker in-order read pool; incremental scans were fully serial.

Changed files reuse the listing's name and timestamp, CUE copies skip the name and MIME queries, and directories holding CUE sheets are not listed twice.
2026-10-01 19:06:25 +07:00
zarzet 6e6d9dd00e fix(background): keep library scans and update downloads running with the screen off
Android froze the process once the activity stopped, because only track downloads held a foreground service. A dataSync BackgroundWorkService with a partial wake lock now covers library scans and in-app APK downloads, and stops when the last task ends or the system timeout fires. Its notification shows the existing localized progress, so no duplicate appears. If Android refuses the service, work continues as before.

On iOS a scan holds its own background task; on expiry it cancels the scan cleanly instead of being suspended.
2026-10-01 18:46:21 +07:00
zarzet 41340a4a21 feat(metadata): write primary-artist tags in native writers
Native tag writers accept artist_tag_mode=primary and keep only the first credited artist in ARTIST and ALBUMARTIST for every format: FLAC download embedding, FLAC/Opus edits, and the ID3, MP4, APE and RIFF writers. The Android finalizer's FFmpeg fallback applies the same rule.

Rust and Kotlin share one separator set (comma, semicolon, ampersand, a spaced x, feat/ft/featuring/with) and test the same fixtures. The Go-parity split_vorbis pattern is unchanged. Refs #618.
2026-10-01 16:12:44 +07:00
zarzet 1e246138c8 perf(download): avoid repeated progress decoding and queue regrouping 2026-09-30 23:39:22 +07:00
zarzet 9051f37cf5 perf(library): reduce scan allocations and keep SAF workers busy 2026-09-30 23:39:22 +07:00
zarzet fe88048db2 refactor(backend): retire unused native bridge entry points 2026-09-30 21:47:15 +07:00
zarzet b8e3a4c166 refactor(download): simplify finalization and remove the retired worker 2026-09-30 21:44:31 +07:00
zarzet c5789df87d fix(storage): retain document access for library metadata and covers 2026-09-30 21:42:53 +07:00
zarzet cda9868a1f fix(startup): keep shared backend alive across activity recreation 2026-09-30 20:58:36 +07:00
zarzet fb08110797 fix(download): verify ReplayGain tags independently of metadata embedding 2026-09-30 20:58:18 +07:00
zarzet 88508c806a perf(library): reuse bounded artwork thumbnails during scans 2026-09-30 20:57:59 +07:00
zarzet 8aa8d598d8 feat(lyrics): keep the screen awake while viewing lyrics 2026-09-30 20:21:21 +07:00
zarzet e61e54f93f fix(download): align native metadata preparation and ReplayGain support 2026-09-28 12:21:15 +07:00
zarzet e3bec31b36 fix(library): preserve indexed tracks when a full scan is incomplete 2026-09-28 12:13:17 +07:00
zarzet 4c2c356763 fix(download): detect mislabeled MP4 before native metadata writes 2026-09-28 12:13:17 +07:00
zarzet e0f5a96564 fix(player): distinguish AAudio access and decoder failures 2026-09-27 15:26:11 +07:00
zarzet d92bcf7716 feat(player): add AAudio hi-res, WavPack DSD and DAC volume 2026-09-27 15:26:11 +07:00
zarzet 608675a255 feat(player): add direct USB audio and DSD transport 2026-09-27 15:26:10 +07:00
zarzet 4e464b5b6b feat(player): add verified USB bit-perfect PCM output 2026-09-27 12:22:42 +07:00
zarzet 95e0e3197d feat(lyrics): support multiple vocalists and aligned lyrics 2026-09-26 14:50:05 +07:00
zarzet 5259c86365 feat(player): add Mornye media notification controls
Sync notification favorites with Library, add Mornye transport icons and an output action on legacy Android, and expose the iOS favorite command. Preserve playback position when controls refresh.

Vendor audio_service 0.18.19 with a small Android patch for custom notification actions. Modern Android keeps its system output switcher and transport layout.
2026-09-26 03:07:38 +07:00
zarzet 728d179d69 refactor(discord): remove rich presence and bundled SDK
Remove the presence setting, platform bridge, SDK archive, and SDK preparation from local and CI builds. Reject leftover Discord native libraries in release APK audits.
2026-09-26 03:07:04 +07:00
zarzet 64f76293ec fix(android): bundle Discord SDK in local and CI releases 2026-09-26 02:02:49 +07:00
zarzet 2ab4aaa8dc fix(ui): allow landscape only in the full player
Keep application pages in portrait and let player sheets inherit rotation from the full player. Restore portrait on navigation, replacement, removal, and completed dismissal; discard stale minimization geometry when the screen rotates on close.

Validated with 12 Flutter tests and targeted analysis. iOS simulator build confirms portrait startup from a landscape device. Platform orientation restrictions still apply on large Android displays and multitasking iPads.
2026-09-25 18:05:40 +07:00
zarzet 3e32a4342b build(android): enable all release APK signing schemes 2026-09-25 16:44:55 +07:00
zarzet abb8dc4a42 feat(concerts): show artwork-themed event details in app 2026-09-25 12:00:28 +07:00
zarzet 1d6ff18d06 feat(player): add native audio output controls 2026-09-25 11:27:49 +07:00
zarzet 040c328479 feat(widgets): add native Android and iOS home screen players
Publish artwork, metadata, and transport state through a shared Dart bridge. Add configurable Android RemoteViews and iOS WidgetKit players with controls and links into the full player.

Serialize widget commands and session restoration, and share one headless-capable iOS Flutter engine with the foreground scene. Include native integration tests, Dart bridge tests, and widget setup documentation.
2026-09-25 01:22:58 +07:00
Bartolo 14ce4bc868 Add Hi-Res authenticity check
Introduce a per-file Hi-Res authenticity checker and optional auto re-download for flagged fake Hi-Res downloads. Adds Rust checker modules (fft, evidence, FLAC/WAV decoding, tests) and a mobile API (check_hires_authenticity). Wire platform bindings for Android/iOS and PlatformBridge. Add Dart HiResCheckService, UI HiResCheckCard, settings toggle (redownloadFakeHiRes) and integration in the download pipeline to quarantine and replace suspicious files with LOSSLESS when safe. Adds claxon FLAC dependency.
2026-09-23 22:29:15 +02:00
zarzet 1e3414b3d0 fix(ci): audit stripped iOS archives and configure FFmpeg tests 2026-09-23 22:59:44 +07:00
zarzet ba44bafa92 fix: sync lyric romanization and clear stale selection menus
Preserve romanization and translation metadata through Rust exports and cache, match rounded line times, and retain word endings. Highlight romanization with the main lyric clock in Material and Mornye.

Clear selection overlay ownership safely when collection screens are disposed. Add parser, rendering, cache and overlay lifecycle regression coverage.
2026-09-23 12:42:08 +07:00
zarzet 1ebdac8645 style: remove trailing whitespace 2026-09-18 00:31:27 +07:00
zarzet 054041e40d perf(extensions): collect unreachable JavaScript cycles after idle bursts 2026-09-17 18:27:46 +07:00
zarzet a9a395b9f8 perf(metadata): preserve typed values across the Rust extension bridge 2026-09-17 18:07:56 +07:00
zarzet 2c4e391643 perf(extensions): validate JSON without allocating argument trees 2026-09-17 18:07:22 +07:00
zarzet 91ef538c87 perf(cue): parse SAF previews without copying audio 2026-09-17 17:38:49 +07:00
zarzet 1387a28d66 perf(android): batch SAF library recovery metadata queries 2026-09-17 17:38:15 +07:00
zarzet c868aac2cc perf(android): batch SAF lookups during download publication 2026-09-17 03:30:30 +07:00
zarzet 3eb44dc892 perf(downloads): log finalization stage durations 2026-09-17 02:59:29 +07:00
zarzet 0dd1a9ac82 perf(audio): validate FLAC remuxes before encoder fallback 2026-09-17 02:59:29 +07:00
zarzet 1a4b90db43 fix(android): validate native metadata editor results 2026-09-17 02:59:28 +07:00
zarzet 6cd2c82790 chore(android): update native dependencies and build tooling 2026-09-17 02:59:14 +07:00
zarzet f0ed293d48 feat: add opt-in Discord Rich Presence on Android
Use the official Discord Social SDK through JNI to share built-in player activity, clear presence when playback stops, and guard against late callbacks after disabling. Package the SDK optionally through SPOTIFLAC_DISCORD_SDK_DIR with license notices.

Credit: @itsmegaaa for the Rich Presence initiative and contribution in #575 and #576.

Validation: 15 Dart tests, scoped Flutter analysis, and one Android 16 ARM64 SDK/JNI instrumentation test passed. Visible presence on a signed-in Discord profile remains unverified.
2026-09-17 02:12:24 +07:00
zarzet aa99726439 feat(backend): migrate production backend to Rust
Replace the Go backend with the Rust workspace and route Android/iOS through
UniFFI bindings. Include the migrated extension runtime, network, providers,
media metadata, downloads and library operations, with version 5.0.0+147.

Remove Go sources, adapters, native build selection and CI dependencies.
Build Rust unconditionally and lock the iOS Rust pod using a relative path.
Retain legacy source and migration evidence in a local ignored archive.

Validation: Android Kotlin compile and 53 native tests; Swift Rust-branch
equivalence and syntax; CocoaPods install; workflow, shell, Ruby, plist and
diff checks. Reuse the preceding 100 Rust tests, fmt/Clippy and five-ABI
build checkpoint; no new APK or iOS application build for this cleanup.

Known follow-up: URL/URLSearchParams globals are missing from the Rust JS
runtime. A controlled extension replay confirms a URL-resolution regression;
this commit does not fix that runtime gap.
2026-09-14 22:58:27 +07:00
zarzet c27dc7c1b6 fix(replaygain): report decoder failures and reject incomplete scans 2026-09-07 16:36:50 +07:00
zarzet e3f7817b29 fix(memory): release retired runtimes and idle download heap 2026-09-07 16:28:47 +07:00
zarzet c48406f5d0 fix(download): resolve missing album folders before publishing 2026-09-07 16:13:41 +07:00