Commit Graph
99 Commits
Author SHA1 Message Date
zarzet ca950dc35a refactor(android): remove backend switches that became constants
Rust is the only backend, so several single-backend switches had become
constants and their other branches could never run:

- CoreBackend.supportsOutputDescriptors was always false. The
  descriptor branch in SafDownloadHandler and its pfd/detachFd cleanup
  never ran, and the Rust planner rejects output_fd anyway.
- routesApplication was always true on Android and iOS. Drop the member,
  the "go" value of getBackendImplementations (the reply keys and the
  "rust" value Dart receives are unchanged), the iOS routing guard and
  the interface defaults that threw for unrouted methods.
- cleanupExtensions(), waitForDownloadProgressDelta and
  scanCueForLibrary had no production caller. Dart reaches cleanup
  through the cleanupExtensions channel method, and RustCoreBackend
  overrides openDownloadProgress, so the polling default goes too.

The UniFFI exports DownloadState.wait_progress_delta and
ExtensionManager.scan_cue_file_for_library were used only by those
Kotlin overrides. Bindings are generated at build time by
scripts/build_rust_backend.sh; no generated binding is tracked.
2026-10-18 23:01:04 +07:00
zarzet 2debaa5363 refactor(providers): remove the unused Deezer catalogue search
DeezerClient::search_all was reachable only through
Backend::search_deezer, which had no production caller: no UniFFI
export, platform channel or extension API wraps it, and no built-in
Deezer catalogue search is planned. Remove the chain together with the
items that existed only for it: the core search result types, the Deezer
search page types and their API error wrappers, the cached Search value,
and the latency test that exercised the search fan-out.

The Search cache bucket stays because the coalesced Deezer lookups use
it. The shared error context helper moves into the deezer module now
that search.rs is gone. searchDeezerByISRC is a separate, live method
and is untouched.
2026-10-18 22:22:57 +07:00
zarzet d60baee4a7 refactor(rust): restrict test-only functions
check_from_deezer and the lyrics cache_size accessor are only called by
unit tests in their own crate, so compile them only for tests and narrow
them to the crate.

call_download is only used by the extensions integration tests, which
can only reach public items; the download manager goes through
call_download_provider. Keep it public but hide it from the docs.

RequestLease::wait_cancelled stays public: the extensions crate's unit
tests call it across the crate boundary and a later coalescer change is
expected to use it.
2026-10-18 22:22:57 +07:00
zarzet ef5fa1cb46 perf(lyrics): compile credit regexes once
with_credits runs for every parse_lyrics data job and compiled up to
seven regexes per call. Hoist them into LazyLock statics next to the
other lyrics patterns, with the same pattern text, so each is compiled
once per process. Every other regex in the workspace is already static.

storage_failure also lowercased the error message once per probe on the
download failure path; lowercase it once and reuse it.
2026-10-18 22:22:57 +07:00
zarzet 5dbf9e6c29 refactor(network): drop the ignored insecure_tls parameter inside Rust
NetworkService::set_network_compatibility_options ignored the
insecure_tls flag by design because TLS verification is never disabled.
Remove the parameter from the network service and the extension
environment so the dead flag no longer travels through internal layers.

The UniFFI method keeps its signature: Kotlin and Swift still pass the
flag, and the mobile binding accepts and ignores it until the binding
and channel cleanup lands separately.
2026-10-18 22:22:57 +07:00
zarzet db85ef0547 docs(rust): mark the Unicode case table as frozen and generated
The table is pinned to Unicode 15.0.0 for matching parity and its generator
is no longer in the repository. Say so in the header and mark the file as
generated for linguist.
2026-10-18 22:02:52 +07:00
zarzet 43f7257d3d docs(rust): say that Go is the retired backend in crate docs
Rust is the only backend and routes the app on Android and iOS. Rewrite
the migration-era crate, script and comment wording that implied Go still
runs, and note in each crate doc that Go mentions describe the retired
backend whose observable behavior remains a compatibility contract.
2026-10-18 22:02:52 +07:00
zarzet 5254760bbd build(rust): drop unused direct dependencies and centralize pins
Remove tokio from spotiflac-extensions and thiserror and the direct hyper
entry from spotiflac-network (hyper stays resolved through hyper-util).
Move roxmltree, rusqlite and libc into workspace.dependencies. libc already
resolves to 0.2.190, so the workspace pin uses that exact version. No
resolved version or enabled feature changes.
2026-10-18 22:02:35 +07:00
zarzet d63d95db63 fix(lyrics): restore QQ Music search after the desktop CGI broke
The desktop search CGI now answers HTTP 500 for every query, so QQ Music
never reached its lyrics. Search through the suggestion box instead, rank
title and artist matches, and check the length of the best few through
the song detail CGI so a live or remixed cut is skipped. The lyrics CGI
is unchanged and still answers.
2026-10-18 20:50:36 +07:00
zarzet 56ad01ec2c feat(lyrics): add lrc.red and BetterLyrics, split SpotiFLAC-Mobile Lyrics
Add two keyless providers that serve Apple Music TTML: lrc.red, matched by
recording, and BetterLyrics, which answers songs it has already cached.
TTML is read into the first-party Apple line structure, so vocal sides,
backing groups, word timing, translations and romanization share one eLRC
formatter. The XML depth guard moves to core so both readers use it.

SpotiFLAC-Mobile Lyrics becomes its own provider instead of a fallback
inside Apple Music. New defaults are Apple Music, lrc.red, SpotiFLAC-Mobile
Lyrics, LyricsPlus and LRCLIB. Migration 13 moves untouched defaults to the
new list and keeps the former fallback right after Apple Music in custom
orders. Replace the dead LyricsPlus Workers mirror.
2026-10-18 19:24:31 +07:00
zarzet 3dc2d69051 fix(audio): preserve FLAC precision in Android bit-perfect playback 2026-10-15 00:28:17 +07:00
zarzet e049604b24 feat(lyrics): add SpotiFLAC fallback for Apple Music outages 2026-10-14 20:20:44 +07:00
zarzet 186c66aeb8 fix(lyrics): refresh LRC sidecars in their actual SAF folder
Resolve opaque SAF document ancestry before writing adjacent lyrics. Propagate failed requested LRC writes and cover native word-synced refresh in regression tests.
2026-10-13 19:38:00 +07:00
zarzet ac8523d789 feat(metadata): add per-field download tag separators 2026-10-12 12:11:06 +07:00
zarzet 879e86b20e test(rust): remove TCP timing dependence from chunked fixture 2026-10-11 16:14:01 +07:00
zarzet 08032f1877 chore(rust): update toolchain and dependencies with preserved vendor sources 2026-10-11 14:33:45 +07:00
zarzet e9b7e84113 fix(webdav): retain tracks across equivalent parent URI encodings
Match decoded path components once in Dart and Rust while rejecting encoded separators and paths outside the selected folder. Add folder scan diagnostics, shared parser fixtures, a synthetic 1806-track traversal and native Android regression coverage.
2026-10-10 23:22:21 +07:00
zarzet 02901a0c91 feat(lyrics): use Apple Music as the default lyrics provider 2026-10-09 18:08:03 +07:00
zarzet 1b9c35f322 fix(downloads): preserve browser verification and queues across restarts 2026-10-09 18:07:49 +07:00
zarzet c7b1d0b0ec fix(metadata): preserve original artwork resolution for SAF files 2026-10-09 10:34:49 +07:00
zarzet 461d5325d8 fix(extensions): retain packages with unreadable settings
Keep installed extensions visible with an error and disable execution when their encrypted settings cannot be read. Preserve settings and credentials so restoring the correct key remains possible.

Validation: 80 extension Rust tests passed (2 ignored), Clippy and formatting; Android profile integration verified repository initialization and preservation of encrypted settings.
2026-10-08 20:29:57 +07:00
zarzet 4b07607884 test(progress): keep batch tests after production helpers 2026-10-08 17:53:55 +07:00
zarzet 2ded1cff68 perf(downloads): batch queue cancellation and progress cleanup 2026-10-08 08:47:47 +07:00
zarzet c67d2a2dd2 perf(downloads): batch cancellation resets for retry 2026-10-08 06:55:26 +07:00
zarzet 460f8ebc2d perf(collections): stage large playlist additions off the UI thread 2026-10-08 03:19:45 +07:00
zarzet aa54c57590 test(network): read complete fixture requests on BSD 2026-10-08 03:14:29 +07:00
zarzet 6325c4769c fix(downloads): preserve actual provider audio format 2026-10-08 01:50:36 +07:00
zarzet dc1e7c1273 fix(lyrics): treat placeholder zero timestamps as unsynced 2026-10-08 00:49:42 +07:00
zarzet 8ca9205cc4 fix(library): stage native scans before owner SQLite publication 2026-10-07 04:19:14 +07:00
zarzet 4d0fe68f17 perf(collections): hydrate native snapshots on bounded workers 2026-10-07 04:19:14 +07:00
zarzet 8b2ba446e3 perf(cache): batch cover maintenance on Rust workers 2026-10-07 03:06:00 +07:00
zarzet a2fd9c542c perf(collections): restore backups on Rust SQLite workers 2026-10-07 03:03:44 +07:00
zarzet f16c9c725a perf(backup): stream ZIP archives on Rust workers 2026-10-07 02:33:27 +07:00
zarzet ad674a55ad perf(backup): stream history backup codecs and restore transactions natively
Export, import, and split legacy history backups in Rust while preserving schema 15, all history columns, path keys, and atomic restore behavior. Keep provider refresh and pending history edits intact.
2026-10-06 23:29:59 +07:00
zarzet d1de833184 perf(library): index scans and snapshots with native SQLite workers
Move full and incremental ingestion, source snapshots, path keys, and download exclusion to native transactions. Preserve schema 17, FTS, WAL coordination, cancellation, and Android SAF timestamp backfill.
2026-10-06 23:29:33 +07:00
zarzet 56f91f4e6c perf(playlists): import CSV and export M3U through native workers
Move playlist parsing and serialization off the UI isolate, preserving field mapping, identifiers, durations, and export entries. Extend the shared parser contract tests with playlist fixtures.
2026-10-06 23:28:40 +07:00
zarzet 514e229fc8 perf(metadata): parse lyrics and encode ID3 artwork in native workers
Port LRC, enhanced LRC, and TTML parsing plus ID3v2.3 lyrics writing and picture encoding. Keep legacy contracts and deep XML fallback; guard asynchronous player updates against stale track results.
2026-10-06 23:28:20 +07:00
zarzet fb21c5c390 perf(audio): analyze AutoMix grids and spectral cutoffs natively
Move PCM beat analysis and spectrum cutoff estimation to cancellable Rust workers with the existing algorithms and isolated Dart fallbacks. Keep visual rendering and playback behavior unchanged.
2026-10-06 23:28:01 +07:00
zarzet d693e1a479 perf(theme): extract cover palettes with native quantization
Port the pinned Material quantizer and Dart RNG compatibility to Rust while keeping Material Score and final color schemes in Dart. Include exact palette fixtures, licenses, and Kotlin worker ABI coverage.
2026-10-06 23:27:38 +07:00
zarzet 927fd033cd perf(nas): process listings, artwork caches, and upload recovery natively
Move WebDAV/HTML parsing, content-addressed artwork caching, cover promotion, and streamed upload verification to native workers. Preserve proxy authentication, cancellation, cache limits, and deep XML fallback behavior.
2026-10-06 23:27:07 +07:00
zarzet 867371cb67 feat(native): add cancellable data workers and streamed file hashing
Introduce Android, iOS, and Dart worker dispatch with queued cancellation, binary inputs, and background JSON codecs. Move APK verification to streamed native SHA256 while retaining the isolated fallback.
2026-10-06 23:25:39 +07:00
zarzet 314dceb1d1 refactor(network): place range reader implementations before tests 2026-10-04 01:41:59 +07:00
zarzet 39d856c44f chore(network): keep JSON dependency scoped to tests 2026-10-04 01:41:58 +07:00
zarzet 7f7e9c0e39 perf(logging): batch UI updates and gate native log copies 2026-10-04 01:41:38 +07:00
zarzet c69f2cef9f perf(library): scan SAF CUE audio through live descriptors 2026-10-04 01:41:35 +07:00
zarzet 5019851903 perf(hires): analyze every channel in one audio decode pass 2026-10-04 01:41:00 +07:00
zarzet 3b553b38a3 perf(cover): avoid copying originals rejected by cache budget 2026-10-04 01:41:00 +07:00
zarzet 4e20102bdd perf(usb): reuse PCM buffers and respect native ring capacity 2026-10-04 01:40:59 +07:00
zarzet 644d035661 perf(isrc): bound retained indexes and stream FLAC comments 2026-10-04 01:40:58 +07:00
zarzet 3bc12d4483 perf(extensions): pass metadata values without internal JSON round trips 2026-10-04 01:40:57 +07:00