Commit Graph
100 Commits
Author SHA1 Message Date
zarzet 1dc4e77f42 refactor(i18n): share supported language choices
Use one non-generated language catalog in setup and appearance settings. Filter supported locale codes once and retain the resulting immutable picker list.
2026-09-06 14:05:09 +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 4a4de098c8 ci(ios): reuse backend build script without duplicate framework setup
Build the XCFramework through scripts/build_ios.sh and use the framework configuration already committed in the Xcode project. Remove duplicate registration and its dedicated Ruby dependency setup.

Verified an unsigned release archive and one Gobackend reference, link entry, and embedded framework.
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
zarzet df8f4f5d7b fix(android): scope SAF read failures to each descriptor
Remove the activity-wide descriptor failure flag and centralize direct-read/fallback handling. A pipe, revoked URI, or malformed file no longer disables direct metadata reads for subsequent files.

Test fallback isolation, descriptor cleanup, and a successful direct read after a failure.
2026-09-06 14:04:04 +07:00
zarzet 4a7908cf4f perf(mp3): share bounded ID3 metadata and cover reads
Parse tags and artwork with one bounded frame walker and use a combined MP3 scan on cold cover caches. Skip artwork for tag-only reads and skip further pictures after finding a usable cover. Preserve earlier fields when trailing frames are malformed.

Cover ID3 versions, extended headers, unsynchronization, malformed data, and large artwork with byte-read assertions.
2026-09-06 14:04:04 +07:00
zarzet 39dc17f9de refactor(ffmpeg): remove unused live DASH subsystem
Remove the unreachable live streaming and DASH manifest call graph, its state, result model, enum, and exclusive imports. Remove the uncalled availability probe while retaining active file conversion and decryption paths.
2026-09-06 14:03:49 +07:00
zarzet 857d146c55 fix(ios): isolate download progress subscriptions
Give every subscription its own cursor, payload, and worker queue so an old blocked waiter cannot advance a replacement listener. Serialize lifecycle handling and guard cancellation.

Add a restart regression with an injected waiter; verified with Thread Sanitizer.
2026-09-06 14:03:49 +07:00
zarzet 49c3c66f15 fix(metadata): preserve Track fields during enrichment
Apply resolved metadata with copyWith and retain the existing field precedence. Keep UPC, preview URLs, and source-only fields when enrichment updates other tags.

Extract the pure merge helpers and add regression tests for field preservation.
2026-09-06 14:03:49 +07:00
zarzet 099e211f5a fix(conversion): reserve FLAC outputs without overwriting files
Reuse the conversion output lifecycle for M4A conversion and native FLAC suffix correction. Reserve destination names atomically, reject empty output, and clean partial files while preserving the input on failure.

Add regressions for existing outputs, concurrent conversions, staging, and cleanup.
2026-09-06 14:03:49 +07:00
zarzet 62ef538690 perf(library): page missing-file cleanup with safe SAF batch checks 2026-09-06 02:34:49 +07:00
zarzet 90d3a5e3de perf(extensions): clone only the requested storage value 2026-09-06 02:34:49 +07:00
zarzet ffe088f831 perf(artwork): batch and throttle cached preview validation 2026-09-06 02:34:49 +07:00
zarzet ab21de45c1 perf(library): reuse collection lookups across selection rebuilds 2026-09-06 02:34:49 +07:00
zarzet 7b87a8ee15 perf(search): decode large extension results off the UI isolate 2026-09-06 02:34:49 +07:00
zarzet 856139f908 fix(search): let latest live queries supersede cancelled requests 2026-09-06 02:34:49 +07:00
zarzet d95d070565 perf(library): stream normalized scan timestamp snapshots 2026-09-06 02:34:49 +07:00
zarzet 3368cf8c5d perf(cache): enforce cover byte budget during foreground use 2026-09-06 02:33:43 +07:00
zarzet dae509078e perf(queue): apply sparse progress updates with chunked snapshots 2026-09-06 02:33:42 +07:00
zarzet 1d0bb56f9b perf(images): size decoded covers from layout constraints 2026-09-06 02:33:42 +07:00
zarzet fdb4a0eaa5 fix(auth): preserve shared signed-session challenge identity 2026-09-06 02:33:42 +07:00
zarzet 2ef2beb621 fix(ui): resolve collapsed header title overlap 2026-09-04 23:58:14 +07:00
zarzet 958b79ebca fix(ui): improve adaptive phone and tablet layouts 2026-09-04 23:44:43 +07:00
zarzet 514081fc6a fix(cover): preserve provider high-resolution artwork 2026-09-04 19:48:15 +07:00
zarzet 448a3426a0 fix(extensions): shorten verification timeout 2026-09-04 17:01:06 +07:00
zarzet 15ffb3abf5 feat(metadata): add safe batch editing and matching 2026-09-04 16:55:44 +07:00
zarzet cbeada208b feat(library): add bulk duplicate cleanup 2026-09-04 12:39:03 +07:00
zarzet 55da453913 fix(audio): preserve Opus codec in M4A scans 2026-09-04 12:39:03 +07:00
zarzet 83beccbb63 build(ios): require iOS 16 and restore local builds 2026-09-04 12:39:03 +07:00
zarzet 7be959e7e9 fix(extensions): preserve verification callback retries 2026-09-04 12:39:03 +07:00
zarzet 4aba2926f8 fix(conversion): preserve Unicode SAF document names 2026-09-04 12:39:03 +07:00
zarzet e1e3ffe0b0 fix(ios): handle non-optional callback binding 2026-09-01 15:11:53 +07:00
zarzet a78fc3f677 Merge remote-tracking branch 'origin/main' 2026-09-01 14:59:52 +07:00
zarzet 4ba3ab2fc7 perf(library): optimize CIFS scan recovery 2026-09-01 12:00:37 +07:00
zarzet 0d148113f0 perf(library): resume and parallelize SAF indexing 2026-09-01 02:14:15 +07:00
zarzet 5eb7f9a872 fix(build): hide unexported lyrics search results from gomobile 2026-08-31 16:45:32 +07:00
zarzet 01fc7ee6c2 feat(lyrics): use direct Kugou, QQ Music, and Genius sources 2026-08-31 13:39:18 +07:00
zarzet a1ee346f2f chore(logging): sanitize diagnostics and reduce noise 2026-08-31 01:49:49 +07:00
zarzet 8f17cd1682 fix(backup): use compact sflb file extension 2026-08-30 23:34:57 +07:00
zarzet 897fb7d523 feat(backup): stream versioned ZIP archives 2026-08-30 23:19:09 +07:00
zarzet 2c9881944d feat(updater): resume and verify APK downloads 2026-08-30 23:19:00 +07:00
zarzet b18def64d3 perf(lyrics): coalesce and persist provider results 2026-08-30 23:18:51 +07:00
zarzet bd07d5c233 perf(import): batch playlist metadata enrichment 2026-08-30 23:18:38 +07:00
zarzet aecba736e1 perf(metadata): coalesce MusicBrainz ISRC lookups 2026-08-30 23:18:33 +07:00
zarzet 6f95bf6085 perf(store): coalesce and condition registry requests 2026-08-30 23:18:21 +07:00
zarzet 0edd0f8f04 perf(extensions): refresh provider health off the download path 2026-08-30 23:18:12 +07:00
zarzet 91b2de8175 perf(playback): stream SAF tracks through descriptor leases 2026-08-30 23:18:03 +07:00
zarzet c056bd60a6 build(deps): add archive and crypto dependencies 2026-08-30 23:17:41 +07:00
zarzet 2e0a5f7b9c fix(downloads): hide unknown byte totals in notifications 2026-08-30 18:58:19 +07:00
zarzet 892d152e5c fix(resolver): retire unavailable resolver endpoints 2026-08-30 18:51:20 +07:00
zarzet d2325dbcbf chore(deps): update Flutter and Go packages 2026-08-30 18:25:59 +07:00
zarzet 29a86b0dc3 feat(player): add sleep timer 2026-08-30 17:23:16 +07:00
zarzet a926a2825b fix(player): handle headset media controls 2026-08-30 17:04:41 +07:00
zarzet d0a9868c2d feat(resolver): add cross-platform fallback chain 2026-08-30 16:55:16 +07:00
zarzet e9bb3ae303 feat(l10n): merge Crowdin translation updates (#531)
Merge Crowdin changes per key so translations from PR #531 are retained without dropping localization keys added on main. Normalize locale filenames for Flutter, keep incomplete languages behind the 70% production threshold, and retain them in Crowdin for continued translation.
2026-08-30 12:59:48 +07:00
zarzet 0290ab7151 fix(ci): standardize Android ARM release build 2026-08-30 12:06:04 +07:00
zarzet c281fe121d perf(android): tighten R8 keep rules 2026-08-30 11:57:59 +07:00
zarzet e931d5e2b0 refactor(core): reduce generated and duplicate code 2026-08-30 11:57:47 +07:00
zarzet 7141ca980f fix(library): sync track playback controls 2026-08-30 00:43:13 +07:00
zarzet d5465e9768 fix(download): throttle progress diagnostics 2026-08-30 00:17:27 +07:00
zarzet b4c4214336 chore(release): bump version to 4.9.5 2026-08-30 00:04:57 +07:00
zarzet f1fb01604d perf(download): reduce progress wakeups and harden retries 2026-08-29 23:47:58 +07:00
zarzet fd74240c24 perf(extensions): coalesce signed session lifecycle 2026-08-29 23:47:34 +07:00
zarzet bb1be4fdb4 perf(extensions): streamline prepared download work 2026-08-29 23:47:21 +07:00
zarzet f21f47b2bd perf(network): improve connection fallback and reuse 2026-08-29 23:47:04 +07:00
zarzet 0394a1bfcc build(go): update toolchain to 1.26.6 2026-08-29 18:57:31 +07:00
zarzet 760d796673 fix(ci): harden release workflow inputs and actions 2026-08-29 18:57:22 +07:00
zarzet 97fdc85513 fix(security): redact secrets from exported logs 2026-08-29 18:57:06 +07:00
zarzet 7556d93e80 fix(security): bound cover download memory usage 2026-08-29 18:56:56 +07:00
zarzet 740ce173b2 fix(security): prevent extension network sandbox bypasses 2026-08-29 18:56:46 +07:00
zarzet 8988f99f79 fix(security): sandbox extension FFmpeg execution 2026-08-29 18:53:52 +07:00
zarzet 63d29d2ed4 fix(security): validate extension callback state 2026-08-29 18:53:33 +07:00
zarzet 29db940d63 fix(security): encrypt extension storage at rest 2026-08-29 18:52:16 +07:00
zarzet cab1af1828 fix(download): restore reliable provider fallback retries 2026-08-29 03:19:38 +07:00
zarzet 5dac33dfa4 fix(download): preserve finalization metadata and library labels 2026-08-29 00:31:25 +07:00
zarzet c3b2214e2a perf: optimize library scans and extension runtime 2026-08-28 21:00:11 +07:00
zarzet 686cc25395 fix(library): prevent pinch gesture blocking scroll 2026-08-28 19:57:40 +07:00
zarzet 357190757c fix(database): cache unavailable FTS5 capability 2026-08-28 18:47:54 +07:00
zarzet 887a8ede12 feat(metadata): limit embedded cover resolution 2026-08-28 13:21:05 +07:00
zarzet 45d9bbd7b2 perf: harden download and persistence lifecycle 2026-08-28 12:51:03 +07:00
zarzet 51f61c9c95 fix(audio-analysis): avoid spectrogram splice noise 2026-08-28 01:48:52 +07:00
zarzet 433f8ed685 perf: reduce queue and extension runtime overhead 2026-08-28 01:47:51 +07:00
zarzet a744514e10 fix(library): recover transient file availability 2026-08-28 01:04:04 +07:00
zarzet 847fc725b6 fix(analysis): reject false spectral rolloff cutoffs 2026-08-28 00:33:55 +07:00
zarzet 862037a9d5 fix(metadata): preserve selected release artwork and title 2026-08-27 22:22:23 +07:00
zarzet 933a3c49e2 fix(library): persist artwork previews and stabilize completion 2026-08-27 21:42:38 +07:00
zarzet fca8e46412 fix(library): show play action for completed batch items 2026-08-27 17:04:58 +07:00
zarzet 2b117415ae feat: add file format library quality label 2026-08-27 16:50:46 +07:00
zarzet 4609e59806 fix(library): show play actions during batch downloads 2026-08-27 13:56:48 +07:00
zarzet 47deb9f34e fix(extensions): resume metadata after verification 2026-08-27 13:08:44 +07:00
zarzet 9bbfee25d0 fix(playlists): remove play action from online playlists 2026-08-27 12:15:24 +07:00
zarzet 4fa0ab860b chore(deps): upgrade Flutter Go and Android dependencies 2026-08-27 10:42:14 +07:00
zarzet 1a7c20111a feat(library): add lyrics filtering and metadata actions 2026-08-27 01:44:06 +07:00
zarzet 04c42bd511 perf(downloads): bound native queue state 2026-08-27 00:17:25 +07:00
zarzet 5e8608cef9 fix(extensions): accept artist tracks alias 2026-08-26 23:08:53 +07:00