Commit Graph
2461 Commits
Author SHA1 Message Date
zarzet 99ccc8826f refactor(layering): move logic files out of screens
Search bucketing, refresh policy, folder data, history snapshot and the
selection and collapsing-header mixins hold no widgets, so they move to
controllers; the settings search catalog is pure presentation metadata and
moves to utils. Files with many importers keep a re-export in screens.
2026-10-19 00:37:42 +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 ab8a329d2d refactor(layering): move UI action helpers from services and utils to controllers
Batch actions, clickable metadata, playback, auth launcher, action forms and
the glass warmup drive UI flows, so they belong with the controllers. Files
with more than three importers (or an importer that must stay untouched) keep
a one-line re-export at the old path.
2026-10-19 00:37:42 +07:00
zarzet ff3f752014 refactor(metadata): share the sidecar publish path between save-cover and save-lyrics
_saveCoverArt and _saveLyrics repeated the same SAF/local publish
skeleton: render into a temp dir and publish it to the download tree
with createSafFileFromPath (or write next to the audio file), clean the
temp dir, then report the outcome. Move that skeleton into
_publishSidecarFile with parameters for the temp prefix, extension, mime
type, success message and whether a snackbar hides the current one.

Each caller keeps its own try/catch, base name, lyrics progress
snackbar and the render step. The cover render returns null after its
no-source snackbar so the helper stops at the same point as before
(without deleting the temp dir, as before). Await order, mounted checks,
messages and cleanup placement are unchanged.
2026-10-19 00:23:50 +07:00
zarzet adf2047df6 refactor(utils): share the FNV-1a 32-bit hash
Add fnv1a32 in hash_utils.dart for the scan output name (UTF-8 bytes) and
qualityVariantStagingLabel (UTF-16 code units). Unit tests pin outputs
computed from the original inline code.
2026-10-19 00:15:48 +07:00
zarzet 036589a4b1 refactor(notifications): reuse formatMegabytes
The progress notification formatted megabytes inline with the same
expression as formatMegabytes (one decimal, power-of-two scaling, so the
double result is identical). It now calls the helper. No output change.
2026-10-19 00:15:48 +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 92d655fd1c refactor(player): move restorePlaybackSession to playback_session_restore.dart
The function only needed the file-level logger, which the new file declares
with the same tag. It is re-exported from music_player_service.dart.
2026-10-18 23:53:44 +07:00
zarzet 548567eff3 refactor(player): move PlayableMedia to playable_media.dart
The class moves verbatim and is re-exported from music_player_service.dart.
The toJson/fromJson artwork round trips stay: toJson drops non-positive
numbers, blank formats and empty artwork, so a copyWith would not be an
exact replacement for them.
2026-10-18 23:53:44 +07:00
zarzet 992e21e297 refactor(player): port tests to musicPlayerRuntime and delete the test-only wrappers
The wrappers only forwarded to musicPlayerRuntime and were referenced by one
test file. The forwarding helpers now live in that test.
2026-10-18 23:53:38 +07:00
zarzet 95666c1043 refactor(settings): move log_screen widgets into a part
The page file mixed the log_screen State with standalone private
widgets and helpers. They move verbatim into log_screen_widgets.dart so the
page file holds only the page and its State. Private visibility is
unchanged because parts share the library. No behavior change.

_domainPattern moves with its only user, _LogSummaryCard.
2026-10-18 23:49:17 +07:00
zarzet 0d2fef4c33 refactor(settings): move extensions_page widgets into a part
The page file mixed the extensions_page State with standalone private
widgets and helpers. They move verbatim into extensions_page_widgets.dart so the
page file holds only the page and its State. Private visibility is
unchanged because parts share the library. No behavior change.
2026-10-18 23:49:17 +07:00
zarzet 6e43c03691 refactor(settings): move appearance_settings_page widgets into a part
The page file mixed the appearance_settings_page State with standalone private
widgets and helpers. They move verbatim into appearance_settings_page_widgets.dart so the
page file holds only the page and its State. Private visibility is
unchanged because parts share the library. No behavior change.
2026-10-18 23:49:17 +07:00
zarzet a3961eeff5 refactor(settings): move files_settings_page widgets into a part
The page file mixed the files_settings_page State with standalone private
widgets and helpers. They move verbatim into files_settings_page_widgets.dart so the
page file holds only the page and its State. Private visibility is
unchanged because parts share the library. No behavior change.
2026-10-18 23:49:16 +07:00
zarzet 486fd3b6e7 refactor(settings): move download_settings_page widgets into a part
The page file mixed the download_settings_page State with standalone private
widgets and helpers. They move verbatim into download_settings_page_widgets.dart so the
page file holds only the page and its State. Private visibility is
unchanged because parts share the library. No behavior change.
2026-10-18 23:49:16 +07:00
zarzet f3e44f3ee6 refactor(settings): move library_settings_page widgets into a part
The page file mixed the library_settings_page State with standalone private
widgets and helpers. They move verbatim into library_settings_page_widgets.dart so the
page file holds only the page and its State. Private visibility is
unchanged because parts share the library. No behavior change.
2026-10-18 23:49:16 +07:00
zarzet d0cdaafcfa refactor(settings): move extension_detail_page widgets into a part
The page file mixed the extension_detail_page State with standalone private
widgets and helpers. They move verbatim into extension_detail_page_widgets.dart so the
page file holds only the page and its State. Private visibility is
unchanged because parts share the library. No behavior change.
2026-10-18 23:49:16 +07:00
zarzet eeb010cd52 refactor(library): extract the ingestion store from library_database.dart
LibraryIngestionStore holds scan and incremental ingestion writes with
bodies unchanged. LibraryDatabase keeps thin delegating methods with the
same public signatures and passes in its connection and the lazy History
attachment. SQL text is unchanged.
2026-10-18 23:28:33 +07:00
zarzet fbed496014 refactor(history): move the history schema and row mapper into their own files
Mirror the library_schema and library_row_mapper split: HistorySchema owns
create, upgrade, index creation and backfills, HistoryRowMapper owns the
JSON/row mapping and the derived normalized and queue-sort columns. SQL text
is unchanged. Tests that read the history CREATE TABLE and index text now
read history_schema.dart.
2026-10-18 23:28:33 +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 b64b08c4d0 refactor(shell): move nav icons to a widget file and startup prompts into a part
BouncingIcon, SlidingIcon and SpinIcon are standalone widgets, so they now
live in lib/widgets/nav_destination_icons.dart. The SAF repair, upgrade intro,
update, announcement and SAF migration prompts move into a part as an
extension on the shell State; the call sites in initState are unchanged.
2026-10-18 22:42:38 +07:00
zarzet 12ff09907e refactor(setup): move the setup step builders into a part
The setup screen State mixed permission and folder logic with the step
builders. Move the builders and the step widgets into a part as an extension
on the State; the two setState calls in moved code go through a _setState
forwarder.
2026-10-18 22:42:37 +07:00
zarzet e9834f060c refactor(equalizer): split the equalizer screen into widgets and curve parts
The screen file mixed state, a dozen private widgets and the curve painter.
Move the widgets and the painter with its helpers into part files; code is
unchanged.
2026-10-18 22:42:37 +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 77c8639df2 refactor(lyrics): split player_lyrics.dart into line-style and word-sweep parts
The word-sweep painter and the line style helpers are self-contained, so
they move into part files of the same library. No behavior change.
2026-10-18 22:40:10 +07:00
zarzet 237690cd89 refactor(metadata): move editor form primitives into a widgets file
Options group, quick-select button, switch field, selection field and
section card become public StatelessWidgets in metadata_editor_fields.dart
with unchanged build bodies; State fields they read (color scheme, fetching
flag) are now constructor parameters.
2026-10-18 22:39:31 +07:00
zarzet 714bec6aaf refactor(metadata): split the edit sheet into cover and auto-fill parts
Cover editor members and auto-fill members move to extensions in part
files; bodies are unchanged except setState goes through a _setState
forwarder, as in the other State part files.
2026-10-18 22:39:31 +07:00
zarzet 77377f6b67 refactor(metadata): one option picker for provider and cover size
The provider and cover-size pickers shared the sheet shell and row layout.
Both now go through _showEditorOptionPicker<T>; per-picker differences
(label ellipsis, which context supplies the check icon theme) stay as
parameters.
2026-10-18 22:39:31 +07:00
zarzet 1c7146f906 refactor(home): split the home tab build into sliver-group builders
The 440 line build method now computes shared state once and composes one
private builder per sliver group (header, intro, search bar, filters, recent
access, home sections, explore, explore skeleton, search results). Conditions,
order, keys and provider watches are unchanged.
2026-10-18 22:32:15 +07:00
zarzet bdb2e636e9 refactor(home): move extension collection screens into their own library
ExtensionAlbumScreen, ExtensionPlaylistScreen and ExtensionArtistScreen and
their exclusive helpers lived in home_tab_widgets.dart, a part of the home tab
library. They now live in extension_collection_screens.dart, re-exported from
home_tab.dart so existing importers keep working. artist_screen.dart and
clickable_metadata.dart import the new library directly instead of home_tab.
2026-10-18 22:32:15 +07:00
zarzet 4009855ba5 refactor(library): build the filter sheet from the sort-mode table
The filter sheet moves into its own part. The sort chips now iterate
_librarySortModes with _sortLabel (same modes, labels and order), and the
source, quality and metadata groups use value/label tables since their chips
differ only in value and label.
2026-10-18 22:26:54 +07:00
zarzet 96568f720a refactor(library): move queue download labels, dialogs and sliver grid out of queue_tab.dart
Pure moves: download label helpers and the download dialogs become parts of
the queue_tab library, and the animated sliver grid becomes a public widget
in lib/widgets since it uses no private state.
2026-10-18 22:26:54 +07:00
zarzet 23c6621552 refactor(bridge): move platform_bridge helpers into part files
Top-level helpers and secondary classes (codec isolates, cache entries,
event and SAF models, the native worker job state and the NDJSON scan
file) move verbatim into part files grouped by concern. The
PlatformBridge class body is unchanged apart from three region comments
over groups that were already contiguous.

platform_bridge.dart was one 2900-line file mixing eight concerns; the
static class cannot be split without changing its type, so this moves
what can move mechanically and leaves the class intact for call sites
and the channel mocks in tests.
2026-10-18 22:24: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 9063104799 chore: retire Go-era config and rename SMB fixture servers
Drop the gomod renovate rule, the stray em dash in crowdin.yml and the migration wording in check_rust_backend.sh. Rename the SMB fixture servers so test_*.py discovery no longer implies unit tests, and describe supported_locales.dart as hand-maintained since its generator never existed.
2026-10-18 22:01:32 +07:00
zarzet acbc614f42 perf(library): build DateFormat and RegExp once instead of per row
The month-year DateFormat was rebuilt for every loaded row and every
fast-scroller drag label; it is now cached per locale tag. Constant-pattern
RegExp objects built per call (or per word) are now static or top-level.
2026-10-18 21:56:46 +07:00
zarzet 0810ee7847 refactor(library): drop unread QueueTab page parameters and fast-scroller callbacks
Nothing read parentPageController, parentPageIndex or nextPageIndex, and the
Library tab root watched showExtensionStore only to compute them, so toggling
that setting rebuilt the tab for nothing. No caller passed the fast scroller
onDragStart/onDragEnd callbacks.
2026-10-18 21:54:05 +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 dbee3d56cb feat(player): search lyrics online for files without them
The empty lyrics page offers Search online, which asks the enabled lyrics
providers in their configured order. The result is shown in the player
only and never written to the file; a late result is dropped after the
track changes, and a miss says so.
2026-10-18 19:24:39 +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 67a346c15b feat(home): greet in the header and gather listening shortcuts
Without a feed, the Material Home now greets in its header with a
prompt picked once per launch, keeps import and paste out of the
resting search field, and fills the page with Continue listening,
player shortcuts, Recently added tracks from the whole Library and the
most played tracks of the last four weeks.
2026-10-18 18:08:13 +07:00
zarzet 2ede99bef8 fix(player): restore the lighter full-screen cover scrim
Shade the app bar lightly and ease it out so white icons stay legible
without darkening the top of the cover.
2026-10-18 12:41:28 +07:00
zarzet 7c0b275f9f feat(onboarding): introduce the 5.2 release tour 2026-10-18 04:09:16 +07:00
zarzet 66d480dbdc fix(storage): retain legacy Android cipher migration support 2026-10-18 04:09:16 +07:00
zarzet 080df889d0 fix(library): recover missing local album artwork from audio 2026-10-18 04:09:15 +07:00
zarzet 02e67cf3d3 feat(library): add adaptive icons to collection tabs 2026-10-18 03:11:54 +07:00