Commit Graph
321 Commits
Author SHA1 Message Date
zarzet 7691acecef perf(analysis): reuse sorted spectral percentile windows
Reuse sorted windows for related percentiles and reject unsuitable edges before computing expensive tail statistics. Preserve cutoff results with 31 regression fixtures and 400 exact old/new comparisons.
2026-09-20 17:21:11 +07:00
zarzet de238fd0cd perf(audio): share the Opus artwork metadata buffer
Write picture headers and payload into one backing allocation instead of copying a second complete block. Verify byte parity for JPEG, PNG and extensionless artwork, including a large fixture.
2026-09-20 17:21:01 +07:00
zarzet d91bfae155 perf(library): dispose unused playback row subscriptions
Auto-dispose media-item playback providers after their last listener leaves so scrolling does not retain every visited row subscription. Test disposal of 200 rows, active-row behavior and reattachment.
2026-09-20 17:21:01 +07:00
zarzet 5053ed93ee perf(mornye): reuse exact luminance contributions for contrast sampling
Use 6 KiB of lookup tables to avoid repeated Color allocations and exponentiation during frame sampling. Exhaustively verify exact Flutter luminance parity for every 8-bit RGB value.
2026-09-20 17:20:52 +07:00
zarzet 6038ce5777 perf(mornye): release outgoing artwork decoders when replaced
Retain the outgoing decoder only while its frame remains displayed, then release its provider subscription as soon as replacement artwork is ready. Verify decoder disposal while preserving cover transitions.
2026-09-20 17:20:52 +07:00
zarzet a7717ddfbf perf(player): scope position and contrast rebuilds to controls
Keep playback position updates inside the timeline subtree and notify only artwork foreground controls when contrast changes. Preserve layout and transport state; add regression coverage for stable artwork and transport widgets.
2026-09-20 17:20:52 +07:00
zarzet 0c930c691f fix(player): preserve offline motion artwork and smooth cover changes 2026-09-20 12:20:24 +07:00
zarzet dc25370350 feat(artists): add branded headers and incremental release loading 2026-09-20 11:46:16 +07:00
zarzet e61ff64adc feat(mornye): cache motion covers and refine player and search
Save album motion videos in app storage during downloads and prefer offline playback with an aspect-aware layout. Add cache management for saved videos.

Center active lyrics on opening, expand lyrics during manual scrolling, and adjust landscape header spacing. Group search rows and skeletons with dividers and remove redundant result icons.

Validation: Flutter analysis clean; 723 tests passed, 4 skipped; iOS simulator build installed.
2026-09-19 17:26:26 +07:00
zarzet 63e1a9b9c8 feat(ui): add Mornye glass theme and adaptive music player
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.
2026-09-19 12:10:10 +07:00
zarzet df87f1e950 perf(images): decode local covers to their fitted display size 2026-09-17 18:25:24 +07:00
zarzet 1ef81b4530 perf(library): batch album deletion and refresh once 2026-09-17 17:32:12 +07:00
zarzet 0dd1a9ac82 perf(audio): validate FLAC remuxes before encoder fallback 2026-09-17 02:59:29 +07:00
zarzet 39a3e680a4 perf(lyrics): stream MP3 audio when updating ID3 lyrics 2026-09-17 02:59:22 +07:00
zarzet cd4b8ead90 perf(analysis): serialize and cancel owned FFmpeg sessions 2026-09-17 02:59:22 +07:00
zarzet fd777c34d9 perf(player): commit seek gestures once after scrubbing 2026-09-17 02:59:21 +07:00
zarzet a064e96c37 perf(ui): pause motion headers when collapsed 2026-09-17 02:59:21 +07:00
zarzet 7064f1a53a perf(theme): bound cover palette decoding and coalesce requests 2026-09-17 02:59:14 +07:00
zarzet f0ed293d48 feat: add opt-in Discord Rich Presence on Android
Use the official Discord Social SDK through JNI to share built-in player activity, clear presence when playback stops, and guard against late callbacks after disabling. Package the SDK optionally through SPOTIFLAC_DISCORD_SDK_DIR with license notices.

Credit: @itsmegaaa for the Rich Presence initiative and contribution in #575 and #576.

Validation: 15 Dart tests, scoped Flutter analysis, and one Android 16 ARM64 SDK/JNI instrumentation test passed. Visible presence on a signed-in Discord profile remains unverified.
2026-09-17 02:12:24 +07:00
zarzet e063e6d5da feat(metadata): display saved ReplayGain values and refresh after analysis 2026-09-15 21:44:59 +07:00
zarzet 0ad17f0caa fix(library): reset checkpoints and artwork on forced full scans 2026-09-15 21:44:53 +07:00
zarzet 347208b3d9 fix(library): preserve cached covers across directory aliases 2026-09-15 21:44:36 +07:00
zarzet aa99726439 feat(backend): migrate production backend to Rust
Replace the Go backend with the Rust workspace and route Android/iOS through
UniFFI bindings. Include the migrated extension runtime, network, providers,
media metadata, downloads and library operations, with version 5.0.0+147.

Remove Go sources, adapters, native build selection and CI dependencies.
Build Rust unconditionally and lock the iOS Rust pod using a relative path.
Retain legacy source and migration evidence in a local ignored archive.

Validation: Android Kotlin compile and 53 native tests; Swift Rust-branch
equivalence and syntax; CocoaPods install; workflow, shell, Ruby, plist and
diff checks. Reuse the preceding 100 Rust tests, fmt/Clippy and five-ABI
build checkpoint; no new APK or iOS application build for this cleanup.

Known follow-up: URL/URLSearchParams globals are missing from the Rust JS
runtime. A controlled extension replay confirms a URL-resolution regression;
this commit does not fix that runtime gap.
2026-09-14 22:58:27 +07:00
zarzet 1da0da18a6 feat(backup): allow selecting categories and settings-only backups 2026-09-08 19:51:25 +07:00
zarzet 259fb5b6c0 fix(backup): allow selecting SFLB archives for restore 2026-09-07 19:38:14 +07:00
zarzet cadd60ce8d fix(metadata): preserve track tags across collection screens 2026-09-07 18:01:37 +07:00
zarzet c27dc7c1b6 fix(replaygain): report decoder failures and reject incomplete scans 2026-09-07 16:36:50 +07:00
zarzet c48406f5d0 fix(download): resolve missing album folders before publishing 2026-09-07 16:13:41 +07:00
zarzet 81ce677149 fix(download): remove legacy HIGH quality conversion 2026-09-07 01:20:28 +07:00
zarzet 660ed9fb60 fix(download): publish converted SAF files with the final extension 2026-09-07 01:06:35 +07:00
zarzet 650af6e59d fix(download): size quality picker to its content 2026-09-07 00:50:05 +07:00
zarzet 40546f48e6 fix(download): allow dragging the quality picker to dismiss 2026-09-07 00:47:15 +07:00
zarzet 7556d64596 fix(library): retain Opus badges when bitrate is missing 2026-09-06 23:59:23 +07:00
zarzet ed51b5d6ea revert: remove download size estimates 2026-09-06 22:17:23 +07:00
zarzet 174852b056 fix(download): estimate sizes from track quality metadata 2026-09-06 22:11:37 +07:00
zarzet ba00807786 fix(download): compare size estimates at each quality tier 2026-09-06 21:55:38 +07:00
zarzet c6195bcd10 feat(download): estimate file sizes in quality picker 2026-09-06 21:40:25 +07:00
zarzet bfffb8da11 fix(replaygain): write and verify native Opus gain tags
Preserve audio and artwork while replacing conflicting Opus gain tags with R128 comments. Verify manual, download, and album writes, handle SAF failures, and refresh playback normalization after saving.
2026-09-06 21:03:57 +07:00
zarzet 7920554f5c fix(metadata): preserve Opus tags during batch re-enrichment 2026-09-06 17:29:54 +07:00
zarzet 70a2a92558 fix: resolve backend and test analyzer diagnostics 2026-09-06 16:14:57 +07:00
zarzet 1b0c28b91a fix(download): route verification notifications to pending challenges 2026-09-06 16:03:46 +07:00
zarzet 0e71003e12 test: decouple app fixtures from extension identities 2026-09-06 16:03:11 +07:00
zarzet 34dd2f0ae9 style(dart): apply pinned formatter to existing files
Normalize three existing formatting differences with the pinned Dart formatter. No behavior changes.
2026-09-06 14:05:10 +07:00
zarzet 1d96521c0f fix(lyrics): align usability checks with shared fixtures
Trim after removing inline timestamps before matching speaker prefixes in Dart. Run one 21-case usability corpus through Dart, Go, and Kotlin tests.

Document the shared fixture and trigger Dart and Go CI when its resources change.
2026-09-06 14:05:09 +07:00
zarzet a89f786960 perf(ui): retain platform link lookup across rebuilds
Keep the platform lookup Future in widget state and replace it only when track identifiers change. Theme rebuilds retain loaded content without another native call.

Add widget regressions for theme and identifier changes.
2026-09-06 14:04:05 +07:00
zarzet 67440925eb perf(ui): retain track history lookup snapshots
Share the retained history lookup snapshot across albums, playlists, artists, home search results, and library folders. Reuse derived lookups until the track list is replaced.

Test reuse with 4,000 items and invalidation after replacement, sorting, and filtering.
2026-09-06 14:04:05 +07:00
zarzet 09c31d9dba refactor(batch): share local track actions and phase settings
Use shared coordinators for queueing FLAC replacements and batch metadata enrichment from album and queue screens. Keep selection lifecycle handling in each screen and synchronize a settings snapshot once per phase.

Cover cancellation, partial failure, screen disposal, and settings changes between preview and apply.
2026-09-06 14:04:05 +07:00
zarzet 7c12f548d7 fix(library): bound playlist picker SQL parameters
Deduplicate requested track keys and aggregate match counts in batches of 500 parameters. Use scalar preview lookups instead of expanding another playlist ID list.

Cover large selections, duplicate keys, empty selections, and cover selection in regression tests.
2026-09-06 14:04:05 +07:00
zarzet 3d35058b02 fix(playback): retain ReplayGain for SAF descriptor leases
Carry the original display name through playback leases to format-aware metadata reads. Cache successful normalization results by source identity, bound the cache, and retry transient read failures.

Add regressions for descriptor hints, album gain fallback, and failed-read retries.
2026-09-06 14:04:04 +07:00
zarzet b32bdbc291 perf(metadata): read complete SAF tags through descriptors
Add complete metadata reads with a display-name hint in Go and both native bridges. Read seekable SAF descriptors directly and use temporary copies only when direct reading fails.

Add format parity tests for MP3, FLAC, M4A, and WAV plus a Dart bridge hint regression.
2026-09-06 14:04:04 +07:00