Commit Graph
619 Commits
Author SHA1 Message Date
zarzet ff7afa5b3c refactor(library): split local_library_provider.dart into source, scan and cover parts
The provider file mixed source management, the scan pipeline and the
cover lookup providers. Move the private notifier methods into
extensions in two parts (_LocalLibrarySources, _LocalLibraryScan) and the
cover request types and providers into a third part. The moves are
verbatim except for one reference to the static heartbeat constant,
which an extension must qualify with the class name. Public notifier
methods, which test subclasses override, stay on the class in the
library file.
2026-10-19 01:18:02 +07:00
zarzet de142abae6 refactor(library): share the scan completion tail as _finishScan
The full-scan and incremental branches of _runScan ended with the same
sequence: source state update, last-scanned prefs, summary refresh, the
mounted check, the final state, log and completion notification. Move
that sequence into _finishScan. The only differences, the cover cache
prune after a full scan and the summary text, become parameters; the
summary stays a closure so it still reads the state after the final
update. Each call is the last statement of its branch, so the early
return on unmount keeps the same effect.
2026-10-19 01:18:02 +07:00
zarzet b0600c1ff7 refactor(library): remove the unreachable snapshot sub-branch of the incremental scan
The Dart incremental ingestion branch runs only when
PlatformBridge.supportsCoreBackend (Platform.isAndroid || Platform.isIOS)
is false. Its useSnapshotBridge flag required Platform.isAndroid, so it
could never be true there, and the native handlers for
scanSafTreeIncrementalFromSnapshot and
scanLibraryFolderIncrementalFromSnapshot are already gone.

Remove the flag, both PlatformBridge methods, and
LibraryDatabase.writeFileModTimesSnapshot(Map), whose only other user was
test/library_scan_snapshot_test.dart (deleted with it). The live native
snapshot path (writeNativeFileModTimesSnapshot) and the host-test branch
with _backfillLegacyFileModTimes are unchanged.
2026-10-19 01:18:02 +07:00
zarzet 857c2954d8 refactor(collections): move playlist cover file I/O into PlaylistCoverStore
LibraryCollectionsNotifier carried about 130 lines of File and Directory
work for playlist covers. PlaylistCoverStore now owns the playlist_covers
directory, the <playlistId>.jpg normalization with its temp file, the
backup restore copy or base64 write, and the delete helpers. The
directory is still resolved through getApplicationSupportDirectory on
each call, at the same points as before.

The notifier keeps setPlaylistCover, removePlaylistCover,
exportPlaylistCoverFiles and restoreFromBackup with unchanged signatures,
mutation ordering and error handling: a failed restore of one cover still
drops that cover path, removePlaylistCover still propagates delete
errors, and replacing a cover still deletes the old file quietly.
2026-10-19 01:01:25 +07:00
zarzet 8af7efb6ce refactor(providers): move UI-declared providers to lib/providers
The listening summary and system volume providers lived in UI files.
They move verbatim to lib/providers with the same names; the old files
re-export them so tests and other importers are unchanged.
2026-10-19 00:56:52 +07:00
zarzet ba376d69fc refactor(repo): prepare install paths in the repo notifier
The store list and the detail screen both built the temp and extension
directories before calling the notifier. The notifier now offers
installExtensionToDefaultPaths and updateExtensionToDefaultPaths; the
existing methods keep their signatures.
2026-10-19 00:48:31 +07:00
zarzet ce21896ff5 refactor(layering): move model files to models and fix inverted imports
library_database_models and ffmpeg_models are plain data types, so they live in
models (re-exports stay at the old paths). deleted_library_files uses providers
and download_progress uses provider state, so both move to providers, and
ffmpeg_reenrich is a service. models no longer import from services for these.
2026-10-19 00:37:42 +07:00
zarzet d6fd05c3a7 refactor(io): use isContentUri instead of inline content:// checks
The same startsWith check was inlined in 21 places across services and
providers. They now call the existing helper, which has identical
semantics (no trim, no case folding). No behavior change.
2026-10-19 00:15:48 +07:00
zarzet 0797085385 refactor(io): use deleteFileQuietly for exists-then-delete
Add deleteFileQuietly to file_access.dart (exists check, delete, swallow
errors) and use it for the try/exists/delete/catch (_) {} copies.
2026-10-19 00:15:48 +07:00
zarzet c2b7a0b782 refactor(downloads): move pure queue policy helpers into download_queue_policy.dart
The queue provider library mixed pure, notifier-free helpers (processing
gate, storage-write recovery, native worker status/progress mapping,
batch album-artist normalization) with the notifier. They now live in a
standalone file that the library imports and re-exports, so existing
importers are unchanged.
2026-10-18 23:28:33 +07:00
zarzet 8fd574f010 refactor(rewind): split the listening rewind screen and move its providers
The two Rewind providers move to lib/providers and are re-exported from the
screen so existing imports keep working. Story, slides and widgets become
part files of the screen library. No behavior change.
2026-10-18 22:40:10 +07:00
zarzet 6879df4917 refactor(services): clarify misleading names and drop a no-op rethrow
Remove the try/catch that only rethrew in the library scan helper, rename
the history loader that schedules a microtask, and fix two comments.
2026-10-18 22:12:29 +07:00
zarzet 019257541b refactor(logging): rename Go-era log names to native
The log buffer polls the native backend, so isFromGo, the Go log polling
methods and their private state now use native names. Comments that still
described the backend as Go are reworded. No string literals changed.
2026-10-18 22:12:29 +07:00
zarzet 4887172926 refactor(services): mark test-only members and privatize file-local ones
Annotate members that only tests call with @visibleForTesting and make
helpers used only inside their own file private.
2026-10-18 22:12:29 +07:00
zarzet ec1b84e6de refactor(services): remove members with no caller
Delete Dart members that have no reference in lib, test or integration_test:
unused player configuration helpers and event streams, two PlatformBridge
wrappers, database and export helpers, the unused global logger and the
now pointless 'hide log' imports.
2026-10-18 22:12:29 +07:00
zarzet 68c739dfa1 fix(equalizer): keep headroom and limiter choices when applying a preset
Applying a preset replaced every setting, so built-in presets silently
turned automatic headroom, the limiter and the compressor back on and
reset balance. Presets now carry only the curve, preamp, bass and treble.
The active preset is matched on the same fields, so it no longer shows as
Custom once headroom is off.
2026-10-18 20:58: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 759079517c fix(library): restore bit depth as the default quality badge 2026-10-18 03:11:54 +07:00
zarzet 1a6dc7366e feat(home): expose extension country settings and isolate regional caches 2026-10-18 03:11:33 +07:00
zarzet bfd180909c refactor(explore): centralize persistent cache storage 2026-10-18 00:47:21 +07:00
zarzet 1b66bc469d perf(history): suppress unchanged membership notifications 2026-10-18 00:47:21 +07:00
zarzet 579ffae9c3 refactor(downloads): centralize failed session accounting 2026-10-18 00:47:21 +07:00
zarzet 1456d36a98 refactor(downloads): update queue items and indexes together 2026-10-18 00:47:21 +07:00
zarzet bbeca05a7a perf(releases): narrow weekly release provider dependencies 2026-10-18 00:46:52 +07:00
zarzet 05a5613332 feat(player): add configurable full-screen cover art
Offer default and full-screen artwork in Material and Mornye, retaining landscape layouts and full-screen Mornye motion artwork. Keep the Material header readable over bright covers and normalize invalid saved styles without resetting other settings.

Validation: 144 related Flutter tests, flutter analyze, generated settings, formatter and diff checks.
2026-10-17 22:27:06 +07:00
zarzet 11c6cf9915 feat(player): synchronize music haptics with local playback 2026-10-17 16:18:37 +07:00
zarzet ecf594aac2 feat(equalizer): add multiband EQ and per-player native audio processing 2026-10-17 16:18:30 +07:00
zarzet 09e07671c7 fix(downloads): recover native queues when their service dies
Check service liveness while monitoring newly started native runs, matching the recovery protection already present during adoption. After three consecutive dead-service probes, reconcile completed results, requeue in-flight items and release the run instead of polling a stale running snapshot indefinitely.

Cover stale snapshots, transient probe failures, paused workers, run isolation, startup timeout and sequential verification reconciliation. Related queue and verification validation: 155 tests passed; scoped analyzer and formatter clean.

Refs #675
2026-10-17 11:45:53 +07:00
zarzet 83a55fb80b feat(library): add sectioned browsing and adaptive fast scrolling 2026-10-14 23:04:46 +07:00
zarzet e3b69a25ef fix(download): probe M4A streams before preserving requested FLAC
Provider and decryption extensions describe the downloaded container, not
its audio codec. A decrypted M4A/MP4 can still carry FLAC, so a requested
FLAC output now reaches the codec probe instead of being preserved early.
Lossy streams keep their native container and still receive metadata.
2026-10-13 18:27:16 +07:00
zarzet ac8523d789 feat(metadata): add per-field download tag separators 2026-10-12 12:11:06 +07:00
zarzet 3ff143f4be fix(library): retire deleted downloads and stale completion cards 2026-10-11 15:38:20 +07:00
zarzet d2dcf28622 feat(autoplay): add opt-in on-device recommendation learning 2026-10-11 14:34:11 +07:00
zarzet 58fb7750e5 fix(mornye): honor forced glass with increased system contrast
Apply the explicit blur override consistently to glass surfaces, tab lenses, menus and the clarity slider while preserving text contrast and reduced motion. Update localized guidance and accessibility regression coverage.
2026-10-10 23:21:41 +07:00
zarzet d273be026d feat(lyrics): customize text size and animate active lines 2026-10-10 17:04:09 +07:00
zarzet b30dd9fed0 feat(appearance): support imported TTF and OTF fonts 2026-10-10 16:59:06 +07:00
zarzet edf575e8fc fix(playlists): preserve repeated tracks during imports 2026-10-10 02:16:22 +07:00
zarzet 00cff9b3c3 fix(ios): restore lock screen controls across app transitions 2026-10-09 18:08:12 +07:00
zarzet 02901a0c91 feat(lyrics): use Apple Music as the default lyrics provider 2026-10-09 18:08:03 +07:00
zarzet 1cae561e6c feat(appearance): make Mornye glass outlines optional 2026-10-09 18:07:55 +07:00
zarzet 1b9c35f322 fix(downloads): preserve browser verification and queues across restarts 2026-10-09 18:07:49 +07:00
zarzet 37258a6160 fix(setup): recover folder permissions after Android restarts 2026-10-09 18:07:38 +07:00
zarzet 8251c16ca0 fix(repo): retry initialization before adding a registry
Coalesce repository startup and retry a failed owner initialization before changing the registry URL. Keep the original startup error and avoid rollback calls when initialization never succeeded.

Validation: 56 targeted Flutter tests passed (2 optional skips), analyzer clean; two Android profile integration cases verified unreadable extensions remain visible, the repository initializes, and encrypted settings reopen with their original key.
2026-10-08 20:30:24 +07:00
zarzet 9177a683a2 fix(storage): preserve extension encryption keys on read failures
Disable automatic deletion across clients sharing Android secure storage and enable protected migration. Reject replacement keys when encrypted settings exist or the saved key is malformed. Surface preparation failures through extension state and preserve retry behavior.

Validation: targeted Flutter tests, analyzer and Android secure-storage compatibility test passed. The original device key-loss trigger is not established.
2026-10-08 20:30:24 +07:00
zarzet e4b6156249 perf(downloads): index queued positions for scheduling 2026-10-08 17:51:56 +07:00
zarzet 1df593eb4f perf(downloads): index progress notification candidates 2026-10-08 17:05:13 +07:00
zarzet a167021766 perf(downloads): retain queue indexes between item removals 2026-10-08 16:15:15 +07:00
zarzet 4ab9e53e43 fix(downloads): finalize album ReplayGain after history is saved 2026-10-08 15:49:48 +07:00
zarzet 8192441f60 perf(downloads): check album ReplayGain readiness in one pass 2026-10-08 15:22:45 +07:00
zarzet f75593c15a perf(downloads): batch queue failures when folder access is lost 2026-10-08 12:03:29 +07:00