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.
Add category browsing, a two-column Recently Added grid, and a dedicated download queue. Keep compact navigation icons and their animations aligned with the active tab.
Keep profile avatars circular and report lyric enrichment outcomes accurately, preserving existing lyrics and supporting instrumental markers.
Read embedded lyrics through the playback metadata fallback when the lyrics reader misses them. Restore edge icon highlighting during navbar drags, tune selection contrast, and blend the profile name field into its card.
Add a selectable Mornye theme with shared glass controls, dialogs, sheets, notifications, and collection headers while retaining Material components.
Update player artwork, lyrics transitions and highlighting, synchronized rolling time labels, volume controls, and compact navigation. Unify metadata, Library, search, and extension surfaces; preserve restored artwork and report extension load failures.
Validation: full Flutter analyzer clean; 713 tests passed and 4 skipped; pinned Dart formatting and diff checks passed; signed ARM64 and ARM32 release APKs built and verified.
Track options gain an Open on... entry listing every streaming platform
song.link resolves for the track, served by a new generic
GetTrackPlatformLinks with its own memory cache beside the availability
cache (same request budget). The sheet is data-driven from the platform
map so the app core stays service-agnostic. Completes the bridge
wrappers already landed in 901fa34d; also carries the en strings for
the duplicate review sheet landing next.
- SettingsGroup centers itself at 720dp via its incoming constraint
(not screen width, so groups inside clamped sheets are never
over-inset; unbounded-width contexts guarded); priority scaffold,
bespoke hero cards, and donate page get the same inset - all 18+
settings pages clamp from shared widgets
- queue list-mode, local/downloaded album track lists, favorite
artists, home recent-access, and extension detail sections adopt
wideListInset like the screens fixed earlier
- track metadata content clamped at 720dp, which also tames the
width-derived spectrogram height
- announcement dialog capped at 480dp wide; setup wizard and
tutorial content at 560dp with a 400dp action button
The full-bleed cover made the Hero flight from square list thumbnails
morph into a fullscreen rect and back. The header now blurs the cover
as a backdrop and shows a centered rounded square (album header layout),
so the flight stays square end to end.
- album/playlist/library-folder/track-metadata adopt
CollapsingHeaderScrollMixin; artist/library-folder adopt
SelectionModeMixin
- HeaderCircleButton and HeaderMetaRow replace per-screen copies
in album and playlist headers; dead _tallHeader flag removed
- SelectionBottomBar gains optional subtitle labels and backs the
playlist selection bar in queue tab
- single-track convert sheet now reuses BatchConvertSheet
(confirmLabelBuilder + sourceIsLossless params) instead of a
full inline copy
- provider priority page migrated to PrioritySettingsScaffold;
shared showDiscardChangesDialog and ReorderablePriorityItem
replace per-page copies
- home tab search rows unified into one _SearchResultRowItem;
_parseTrack copies rebuilt on Track.fromBackendMap with only
the load-bearing local overrides kept; loading/error scaffold
extracted
- PlayerArtwork widget shared by now-playing and mini player
- LocalOrNetworkCoverImage dispatches file vs network cover in
one place (playlist picker, queue nav, library folder)
The local/downloaded album screens had drifted copies of the album
header, selection bottom bar, disc chip, batch convert/ReplayGain trio,
and assorted small helpers. All now delegate to the shared widgets, with
the online album screen's design as the reference, and both album screens
run batch actions through the queue_tab engine via UnifiedLibraryItem
(strict-superset implementation covering both DB writebacks and SAF
paths). Also folds the remaining per-screen helper copies (cover URL,
error card, byte/clock formatting, readPositiveInt) into their shared
homes.
Intentional deltas: selection-bar strings follow queue_tab's l10n keys,
both providers reload after a conversion, and audio-analysis durations
round instead of floor.
Service ids ('deezer', 'tidal', 'qobuz', 'spotify', 'amazon', 'local')
were compared as raw string literals in every dispatch chain. Introduce
MusicServices constants and use them at the comparison/switch sites so
a typo becomes a compile error instead of a silently dead branch.
track_metadata_screen.dart was 5,470 lines, most of it one State class
mixing five surfaces. Move four cohesive method clusters into private
extensions on _TrackMetadataScreenState in new part files: header/info
cards, lyrics + save/re-enrich flows, audio conversion + CUE split, and
file actions. Same library, so private state access is unchanged;
setState goes through a _setState forwarder as in queue_tab. The screen
file is now 1,575 lines.
Use DraggableScrollableSheet for single and batch convert flows and open
convert sheets with isScrollControlled so long option lists remain usable
on smaller screens.
Let users choose FFmpeg dithering when reducing bit depth and SoXr or
SWR resampling when changing sample rate across single-track and batch
lossless conversion flows.
Capture lossless conversion labels before await boundaries in queue,
downloaded album, and track metadata flows to avoid BuildContext usage
across async gaps.
Expose an awaitable lyrics settings sync on SettingsNotifier and call it
before metadata re-enrich, lyrics autofill, and queue/local embed flows so
the backend uses the latest provider order and fetch options.
Pass localized lossless conversion labels through shared helpers and
replace hardcoded capped-lossless confirmation text in single-track and
batch convert flows across metadata, queue, and album screens.
- LosslessConversionQuality model with bit depth/sample rate caps,
applied only when they reduce source quality
- FFmpegService probes sample rate and appends codec-specific args
(-ar, -sample_fmt, -bits_per_raw_sample) for FLAC/ALAC/WAV/AIFF
- Batch + single-track convert sheets expose quality cap options
- Persist real converted bit depth/sample rate to history/library DB
- track_metadata: recognize and convert to WAV/AIFF targets
- convertedAudioQualityLabel reflects actual output quality
- PlaybackController with queue methods for albums/library/playlists
- Library tab play builds merged queue (downloaded + local together)
- Preview vs main player exclusivity
- Preview stops on bottom-nav tab switch
- Duration 0:00 fix, deleted track cleanup, Up Next sheet
- Animation utilities improvements
FFmpeg's MP4 muxer drops ISRC and label, so write them as iTunes freeform atoms natively after every M4A embed pass. The metadata screen now reads all edited fields from the file on load (file is the source of truth), fixing edited values reverting to stale cached values after reopening.