Commit Graph
117 Commits
Author SHA1 Message Date
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 21fd51d62c feat(autoplay): enable personalization by default and confirm learning resets 2026-10-17 16:18:26 +07:00
zarzet ac8523d789 feat(metadata): add per-field download tag separators 2026-10-12 12:11:06 +07:00
zarzet d2dcf28622 feat(autoplay): add opt-in on-device recommendation learning 2026-10-11 14:34:11 +07:00
zarzet 02901a0c91 feat(lyrics): use Apple Music as the default lyrics provider 2026-10-09 18:08:03 +07:00
zarzet 1abc45e2bf feat(playback): automate mute and headphone playback controls 2026-10-05 01:55:08 +07:00
zarzet 0ec8c96269 feat(automix): add configurable duration and transition effects 2026-10-04 03:55:24 +07:00
zarzet 983f1b26a5 feat(settings): default to built-in playback and word-synced lyrics 2026-10-03 13:40:39 +07:00
zarzet 84cac92983 feat(network): add SMB and WebDAV libraries with streaming and uploads 2026-10-03 04:27:47 +07:00
zarzet 0b2cf0e4e5 feat(discord): add opt-in mobile rich presence with track artwork 2026-10-03 02:14:11 +07:00
zarzet 1eea52c1c2 feat(playback): add local listening statistics and annual recap
Measure actual playback time and count plays after 30 seconds, with local SQLite aggregation for weekly, monthly and annual summaries. Add recording controls and safe clearing without affecting music or playlists.
2026-10-02 18:17:54 +07:00
zarzet 575f3fc1bd fix(ios): preserve Now Playing ownership with motion artwork
Restore the non-mixing music audio session after decorative video initialization and before playback resumes. Add an artwork switch that releases or pauses video decoders and uses still covers when disabled.
2026-10-02 18:13:02 +07:00
zarzet a549671c4e feat(metadata): add a primary artist tag mode
Artist Tag Mode gains "Primary artist only": downloads and re-enrichment write only the first credited artist to Artist and Album Artist, so players list one artist. The FFmpeg MP3, M4A and Vorbis embeds and the AC-4 path now honor the mode; MP3 and M4A previously ignored it.

Manual metadata edits, lyrics embedding and format conversion keep existing or typed credits joined instead of dropping names. The picker scrolls so three options fit on small and landscape screens. Closes #618.
2026-10-01 16:12:58 +07:00
zarzet 8aa8d598d8 feat(lyrics): keep the screen awake while viewing lyrics 2026-09-30 20:21:21 +07:00
zarzet d92bcf7716 feat(player): add AAudio hi-res, WavPack DSD and DAC volume 2026-09-27 15:26:11 +07:00
zarzet 608675a255 feat(player): add direct USB audio and DSD transport 2026-09-27 15:26:10 +07:00
zarzet 4e464b5b6b feat(player): add verified USB bit-perfect PCM output 2026-09-27 12:22:42 +07:00
zarzet 5f0463a7a4 feat(player): continue playback with Library autoplay 2026-09-27 11:53:40 +07:00
zarzet 728d179d69 refactor(discord): remove rich presence and bundled SDK
Remove the presence setting, platform bridge, SDK archive, and SDK preparation from local and CI builds. Reject leftover Discord native libraries in release APK audits.
2026-09-26 03:07:04 +07:00
zarzet 3ca881b169 feat(lyrics): animate pronunciation and translation visibility
Add a contextual language menu for available lyric supplements in portrait and landscape. Remember independent visibility choices across tracks and player sessions without changing embedded lyrics or download options.

Fade and collapse supplements over 320 ms while interpolating lyric row heights and keeping the active line aligned. Honor reduced motion and control auto-hide; cover menu availability, persistence, animation, and word timing in widget tests.
2026-09-25 10:29:22 +07:00
Bartolo 14ce4bc868 Add Hi-Res authenticity check
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.
2026-09-23 22:29:15 +02:00
zarzet 5b519070a3 feat(player): add beat-matched AutoMix and refine Mornye navigation
Add default-off local beat analysis, pitch-preserving tempo matching, crossfade fallback, and cancellation-safe two-deck playback. Expose AutoMix in settings and the Mornye queue.

Separate Search from Home, remove the Mornye greeting, and keep Home/Search icons moving continuously between full and compact navigation. Restore expansion on upward Library scrolling.

Validate beat analysis, transport handoff and cancellation, settings persistence, and navigation behavior. Flutter analysis and the signed iOS simulator build pass.
2026-09-20 20:36:26 +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 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 81ce677149 fix(download): remove legacy HIGH quality conversion 2026-09-07 01:20:28 +07:00
zarzet 887a8ede12 feat(metadata): limit embedded cover resolution 2026-08-28 13:21:05 +07:00
zarzet 2b117415ae feat: add file format library quality label 2026-08-27 16:50:46 +07:00
zarzet c6437d8428 feat(library): add bit depth quality label mode 2026-08-23 11:42:47 +07:00
zarzet ea63291db8 refactor(metadata): move cover resolution to extensions 2026-08-19 13:12:29 +07:00
zarzet f7439c6793 feat(library): add combined quality label #511 2026-08-11 16:56:12 +07:00
zarzet 5237aed25e feat(download): add automatic lossy conversion 2026-08-11 15:19:45 +07:00
zarzet 454ef53977 feat(library): add quality label display modes 2026-07-27 17:25:39 +07:00
zarzet ef3e019a3a feat(library): playlists filter view and configurable default view
Add a fourth Playlists chip/page to the Library filter pager, rendered
as an album-style grid of playlist cells (search filters by name, page
provider short-circuits since playlists come from libraryCollections).
Add a defaultLibraryView setting (last used / all / albums / singles /
playlists) in Library settings, applied on startup and whenever the
shell switches back to the Library tab.
2026-07-27 02:12:35 +07:00
zarzet ac56e76b62 feat(appearance): manual toggle to force backdrop blur on lower device tiers 2026-07-27 01:39:16 +07:00
zarzet 4713be02de chore(settings): graduate native download worker 2026-07-24 12:23:36 +07:00
zarzet 0961c09a6d feat(download): preserve quality variants 2026-07-16 08:45:01 +07:00
zarzet 9ac10dd6bb feat(player): ReplayGain/R128 volume normalization for the built-in player
Reads REPLAYGAIN_TRACK_GAIN (album gain fallback) from FLAC/MP3/M4A tags
and converts Opus R128_TRACK_GAIN/R128_ALBUM_GAIN (Q7.8, -23 LUFS) to the
same ReplayGain dB representation on the Go side, then attenuates the
internal player's volume per track. Off by default; toggle lives under
Library > Playback. Opus header output gain is left to the decoder, which
already applies it.

Closes #465
2026-07-14 15:18:42 +07:00
zarzet b3cad6e526 feat(settings): toggle to disable Hero animations
A single HeroMode above the router disables shared-element flights
app-wide (mini player expand, track metadata cover) for users who
prefer no motion or want to save the overlay rendering cost. On by
default; persisted in AppSettings.
2026-07-14 09:10:16 +07:00
zarzet 1998a9300e feat(downloads): support up to 3 concurrent downloads
The Dart queue loop was already built around an activeDownloads map and
per-item progress tracking but was gated to one download at a time. Add
a concurrentDownloads setting (1-3, default 1) exposed in Download
Settings > Performance, and let the scheduler keep up to that many
items in flight. The experimental Android native worker is still
strictly sequential, so it is skipped in favor of the Dart queue while
concurrency is enabled.
2026-07-10 10:17:59 +07:00
zarzet 3278e32711 fix(extensions): default verification browser to in-app first
Prefer the in-app browser for signed-session verification challenges,
normalize invalid saved modes to the new default, and keep the help
dialog modal until the user explicitly dismisses it.
2026-07-02 01:24:21 +07:00
zarzet 08c738dc69 feat(settings): add extension verification browser mode preference
Let users choose whether signed-session verification opens in the
external browser or in-app browser first, with automatic fallback to
the other mode when launch fails.
2026-07-02 01:24:19 +07:00
zarzet 3a2481e8b2 feat: add new playback experience and media integration 2026-06-28 22:22:33 +07:00
zarzet 50509d0a16 chore: clean up redundant comments across Go backend and Flutter sources 2026-06-26 22:57:03 +07:00
zarzet f0acda0f01 feat(network): add opt-in allow local/private network setting
Add a setting that relaxes the SSRF guard so extensions and built-in network code can reach private/local/loopback targets, for users routing traffic through a local proxy or custom DNS. Disabled by default. Wired end-to-end: Go backend (SetAllowPrivateNetwork toggles isPrivateIP guard), Android/iOS platform bridge, Dart settings model/provider, and a toggle in Download settings.
2026-06-26 20:29:15 +07:00
zarzet 7d300a39c9 refactor: generalize Tidal-specific naming to legacy/DASH terminology
- Rename downloadProviderMatchesBuiltIn -> downloadProviderReplacesLegacyProvider

- Rename Tidal DASH ffmpeg helpers and lossy format pickers to generic names

- Add utils.decryptCTRSegments crypto API + raw/bytes file read path in extension runtime

- Update l10n strings/descriptions to drop hardcoded service names

- Bump version to 4.5.7+134
2026-06-11 01:08:20 +07:00
zarzet d736e5aafe refactor(download): remove concurrent download option
The download API only permits one request at a time, so parallel
downloads are removed to avoid wasted/blocked API calls. Downloads
now always run sequentially (one track at a time).

- Drop concurrentDownloads from AppSettings + JSON serialization
- Remove setConcurrentDownloads and the settings UI (1-5 chips + warning)
- Strip optionsConcurrent* l10n keys from all ARBs and regenerate
- Rework queue worker into _processQueueSequential (single active download)
- Update marketing copy and adjust tests
2026-06-06 21:58:45 +07:00
zarzetandAmonoman ffdaf14ba5 feat: rebuild cross-extension sharing and queue controls
Co-authored-by: Amonoman <musaauron87@gmail.com>
2026-06-02 00:58:41 +07:00
zarzet 2a2d817314 feat: add AAC lossy target and toggle for Apple Music eLRC word sync
The HIGH-quality lossy format picker can now produce an AAC/M4A 320 kbps output alongside MP3 and Opus. FFmpegService.convertM4aToLossy/convertAudioFormat, the Dart queue pipeline, the Kotlin finalizer, and the library database format helper all route .m4a through a unified aac codec path and tag the resulting file with the M4A metadata writer. The Lossy Format setting gains a new option, and the track metadata convert dialog lists AAC next to the other targets.

Apple Music lyrics gain a 'eLRC word sync' switch (default off). When disabled the pax-to-LRC formatter strips inline word timestamps, producing line-synced LRC that is safer for players that choke on eLRC; enabling it restores the previous word-by-word behaviour. The change propagates through SetLyricsFetchOptions and invalidates the global lyrics cache on toggle.

Broad l10n migration: roughly 400 previously hardcoded English strings across queue, settings, track metadata, repo, audio analysis, setup and extension screens now live in the ARB catalog, with matching plural/placeholder forms. No behaviour change beyond localisation. Existing and new unit tests (lyrics eLRC toggle and Dart settings round-trip) pass.
2026-05-12 02:23:04 +07:00
zarzet 6b342aeac6 feat: add experimental Android native download worker
Introduce a service-owned download worker that offloads the full
download-and-finalize pipeline to DownloadService on Android, keeping
downloads alive independently of the Flutter UI process.

Key changes:
- Extract SAF download logic from MainActivity into SafDownloadHandler
- Add NativeDownloadFinalizer for Kotlin-side decryption, format
  conversion, metadata embedding, ReplayGain, post-processing, and
  history persistence
- Extend DownloadService with native queue management (start, pause,
  resume, cancel) using coroutine-based worker with AtomicFile snapshots
- Add Dart-side orchestration: snapshot polling, run-id correlation,
  adoption on app restart, and fallback to Dart queue
- Forward embedReplayGain, tidalHighFormat, and postProcessingEnabled
  through Go backend DownloadRequest struct
- Add nativeDownloadWorkerEnabled setting with UI toggle
- Make DownloadQueueLookup collections unmodifiable
2026-05-05 02:41:00 +07:00