Commit Graph
3167 Commits
Author SHA1 Message Date
zarzet 631b9aa5e8 refactor(android): move finalizer post-processing into NativeFinalizerPostProcess.kt
Move the extension post-processing hook stage out of
NativeDownloadFinalizer into a sibling file as an extension function.
The body is verbatim. The shared materializeForFFmpeg and
replaceStatePath helpers stay on the object because every stage uses
them, and no object member needed wider visibility.
2026-10-19 00:14:47 +07:00
zarzet 0b4725c2c0 refactor(android): move finalizer metadata into NativeFinalizerMetadata.kt
Move the metadata embedding stage, ReplayGain tagging and verification,
the album key and duration helpers, and the final audio quality probe
out of NativeDownloadFinalizer into a sibling file of extension
functions. Bodies are verbatim. The moved code reads three JSON helpers
that stay on the object, so parseObject, optPositiveInt and
optPositiveBitrateKbps widen from private to internal.
2026-10-19 00:14:47 +07:00
zarzet ead04c00b4 refactor(android): move finalizer container into NativeFinalizerContainer.kt
Move the lossless container conversion and automatic conversion stages,
with their file-local helpers (output extension, M4A sniffing, unique
output path, preserved container rename), out of NativeDownloadFinalizer
into a sibling file of extension functions. Bodies are verbatim except
one moved comment line whose em dash is rewritten as a colon. No object
member needed wider visibility.
2026-10-19 00:14:47 +07:00
zarzet 92af56eea7 refactor(android): move finalizer decrypt into NativeFinalizerDecrypt.kt
NativeDownloadFinalizer.kt is a 1300-line god file. Move the decryption
stage (finalizeDecryption, ISO-BMFF extension normalization and key
candidate expansion) into a sibling file as NativeDownloadFinalizer
extension functions, matching NativeFinalizerMedia/FFmpeg/SafPublish.
Bodies are verbatim; file-local helpers stay private, and no object
member needed wider visibility.
2026-10-19 00:14:47 +07:00
zarzet 42c90dbf62 refactor(network): split client.rs into pool, stream, headers and tests, and factor execute_stream
client.rs held the connection pool, the streaming response type, header
helpers, tests and a 274-line execute_stream in one 1220-line file (audit
RS-15). Move the self-contained parts into client/ and break
execute_stream into phase helpers so the redirect loop reads top-down.

Pure moves (verbatim apart from pub(super) on items the parent uses):
- client/pool.rs: Connector and Pool.
- client/stream.rs: ResponseBody and HttpStream (re-exported from client,
  so crate::HttpStream is unchanged).
- client/headers.rs: update_explicit_cookies, forward_sensitive_headers
  and canonical_header. error_chain stays in client.rs; it is not a
  header helper.
- client/tests.rs: the existing unit tests.

execute_stream helpers (base line ranges refer to main:client.rs). Each
body is the statements it replaces; the loop, await points, error
mapping, redirect limit and header mutations stay in the same order:
- prepare_request: 720-769, request validation, method, body, headers,
  user agent, default JSON content type and explicit referer, returned
  as PreparedRequest. Only the mut markers moved to the call site.
- outgoing_headers: 773-802, per-attempt cookie header and gzip
  negotiation, returning (outgoing, gzip). header(&url) became
  header(url) because url is now a reference.
- send: 803-845, the request, its 45 s header timeout and the native
  HTTPS-to-HTTP fallback retry. The permit is passed by value and
  returned, so drop(permit) still runs before the retry acquires a new
  one. matches!(method, ..) became matches!(*method, ..).
- redirect_target: 862-869, Location resolution, credential rejection
  and redirect policy validation, returning the target.
- release_redirect_body: 906-928, the 20 ms drain of a small HTTP/1.1
  redirect body.
- response_reader: 932-959, discard eligibility and gzip decoder setup,
  returning (headers, small_http1, reader).
- canonical_headers: 960-970, canonical response header map.

The redirect request rewrite (871-905) stays inline: it updates the
loop-carried method, body and headers and reads six other values, so a
helper would need nine parameters or a state struct that rewrites every
statement in the loop.

hyper is not a direct dependency, so the response type is named through
the pooled client's tower Service implementation (HyperResponse).
No public path or signature changes.
2026-10-19 00:00:04 +07:00
zarzet 12d422afa3 refactor(extensions): split manager.rs into install, lifecycle, info and tests modules
manager.rs mixed package install/upgrade/remove, the runtime lifecycle,
listing/info helpers and tests in one 1245-line file (audit RS-14). Move
each group into a sibling module under manager/, next to the existing
downloads, metadata, postprocess and providers modules:

- manager/install.rs: install, install_or_upgrade, stage, candidate,
  install_package, remove, upgrade, upgrade_package, check_upgrade and the
  install-only helpers error_from_rollback and remove_directory.
- manager/lifecycle.rs: prepare_with_lease, validate, lifecycle,
  lifecycle_with_lease, teardown_runtime, teardown, failed, ready and
  ready_with_lease.
- manager/info.rs: load_all, load_directory, installed,
  installed_versions, provider_ids, summary, asset and information.
- manager/tests.rs: the existing unit tests.

Method bodies are moved verbatim (whitespace-normalized token streams
match the base), so the engine, status and download pool lock order is
unchanged. Methods called from other manager submodules become
pub(super) because method privacy follows the module of the impl block.
No public path changes.
2026-10-19 00:00:04 +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 380b5cb872 refactor(extensions): split backend/downloads.rs helpers into submodules and move its sibling tests
Move the prepared-download cache, metadata mapping, path building,
result matching and response envelopes into backend/downloads/ siblings.
The three #[path] test files become plain test modules next to them, so
test names are unchanged. download_attempt and the orchestration stay in
downloads.rs.
2026-10-18 23:40:19 +07:00
zarzet 1b2efc76cc refactor(extensions): split runtime.rs into control, vm and tests modules
Move Control and ControlWait, the worker loop and QuickJS VM, and the
unit tests into runtime/ siblings. ExtensionRuntime and the crate::runtime
paths used by the host modules are unchanged.
2026-10-18 23:36:13 +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 a6dda02396 refactor(lyrics): split native_lyrics into text, lrc, ttml, credits and tests modules
native_lyrics.rs kept only the shared types, has_usable_timing and the
execute entry point. Lexing and timing helpers move to text, the LRC
parser to lrc, the TTML parser and XML normalization to ttml, credit
extraction (with its regex statics) to credits, and the tests to
tests.rs. Function bodies are unchanged; only visibility on moved items
and use lines differ. The fixture include_str path gains one parent
segment for the new file depth.
2026-10-18 23:28:19 +07:00
zarzet 3f904004ff refactor(rust): move inline tests and the test-only hires decoder into submodules
Inline test modules of tags/write.rs, lyrics/payloads.rs and
extensions/src/files.rs become sibling tests.rs files, and the
cfg(test) reference decoder of media/hires moves into hires/reference.rs.
The artist-mode helpers of tags/write.rs move to write/artists.rs.
No behavior or public API change; the supplement_tests module of
payloads.rs is now named tests.
2026-10-18 23:28:19 +07:00
zarzet 92adce43ef refactor(native): share errorJson and retire Go-era names in native comments
MainActivitySafIo and SafDownloadHandler each defined an identical
errorJson. Keep one internal top-level function in MainActivitySafIo
and drop the private copy. errorJson, isMediaStoreUri, extFromFileName
and extFromMimeType never used their MainActivity receiver, so they
become plain top-level functions; call sites are unchanged.

Rust is the only backend. Rename the iOS invokeGoMethod, which
dispatches the OS-owned channel methods, to invokeOsMethod, and reword
the comments that still described Go calls, the Go progress stream, the
Go metadata reader or a "native migration boundary" so they describe
the current backend. Channel method names and reply keys are unchanged.
2026-10-18 23:01:04 +07:00
zarzet fcec0942b9 refactor(android): drop SDK checks below minSdk 24
Flutter 3.47.7 sets flutter.minSdkVersion to 24, which
android/app/build.gradle.kts uses as minSdk. The N (24) checks around
StorageManager.storageVolumes and the LOLLIPOP (21) check around
finishAndRemoveTask were therefore always true, and their else branches
could never run. Keep the true-branch bodies. Checks for API levels
above 24 are unchanged.
2026-10-18 23:01:04 +07:00
zarzet 8aca5e4ef2 refactor(android): drop unreachable dispatch cases and dead channel handlers
RustCoreBackend.invokeApplication handled readFileMetadata,
editFileMetadata and cancelNativeDataJob, but MainActivity intercepts
all three first: the metadata methods are in nativeBackendMethods and
dispatchBackendApplication answers cancelNativeDataJob before it calls
invokeApplication. No Kotlin code calls invokeApplication with those
names.

Dart never sends these channel methods, so their handlers go on every
platform:

- shareMultipleContentUris (Android) and getAvailableLyricsProviders
  (Android and iOS) have no Dart caller.
- scanLibraryFolderIncrementalFromSnapshot and
  scanSafTreeIncrementalFromSnapshot are called only from the Dart host
  branch of the library scan, which runs only when
  supportsCoreBackend is false, that is never on Android or iOS. The
  unreachable Dart wrappers are removed separately.

The allowlist and the when cases in MainActivity stay in sync (70
names). The UniFFI exports get_available_lyrics_providers_json and
scan_library_folder_incremental_from_snapshot were used only by the
removed handlers; the backend methods behind them stay.
2026-10-18 23:01:04 +07:00
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 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 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 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 e41e6ec432 test: share one FixedSettingsNotifier across tests
Replace 16 private SettingsNotifier fakes that only returned a fixed AppSettings with test/support/fixed_settings.dart. Mornye owner WIP tests and bespoke fakes are untouched.
2026-10-18 22:08:02 +07:00
zarzet 77c149eb20 test: skip the automix renderer test when ffmpeg is missing
Mirror the other ffmpeg-backed tests: skip instead of failing with a ProcessException on hosts without ffmpeg.
2026-10-18 22:08:02 +07:00