Commit graph

20 commits

Author SHA1 Message Date
Alex
3fc371b8c4 Extension OAuth + store: flatten action JSON, open auth URLs, spotiflac:// callback
Third-party extensions (e.g. Spotify PKCE addons) need three things the current app does not fully provide:

Extension button results – The Go runtime returned { success, result: { message, open_auth_url, … } } while Flutter read message / open_auth_url only on the outer map, so OAuth buttons appeared to do nothing. InvokeAction now merges the extension’s return object onto the top-level JSON (arrays/non-objects still use result).

Flutter – extension_detail_page: unwrap nested result for compatibility, merge setting_updates into saved extension settings (for copyable OAuth URLs), and launchUrl when open_auth_url is set.

Mobile OAuth return – spotiflac://callback?code=…&state=<extension_id> was not handled on Android (manifest + MainActivity) or iOS (AppDelegate open URL + cold-start launchOptions). This wires SetExtensionAuthCodeByID + invokeExtensionAction(..., "completeSpotifyLogin") so PKCE extensions can finish login after the browser redirect.

Extension store HTTP – Add Cache-Control: no-cache on registry and extension package downloads to reduce stale CDN/proxy responses.

Testing: Install a metadata extension that uses PKCE; tap Connect; confirm browser opens, return via spotiflac://callback, and tokens complete without pasting the code manually.

extension InvokeAction JSON was nested under result while the Flutter settings UI only read the top level, so OAuth-related buttons never showed messages or opened the browser. This PR flattens that payload, merges optional setting_updates, launches open_auth_url, adds spotiflac://callback handling on Android and iOS, and sends no-cache on store HTTP fetches. Needed for extensions like SpoitiLists (Spotify Web API + PKCE).
2026-04-12 02:40:31 -06:00
zarzet
03fd734048 perf: lazy extension VM init, incremental startup maintenance, and UI optimizations
- Defer extension VM initialization until first use with lockReadyVM() pattern to eliminate TOCTOU races and reduce startup overhead
- Add validateExtensionLoad() to catch JS errors at install time without keeping VM alive
- Teardown VM on extension disable to free resources; re-init lazily on re-enable
- Replace full orphan cleanup with incremental cursor-based pagination across launches
- Batch DB writes (upsertBatch, replaceAll) with transactions for atomicity
- Parse JSON natively on Kotlin side to avoid double-serialization over MethodChannel
- Add identity-based memoization caches for unified items and path match keys in queue tab
- Use ValueListenableBuilder for targeted embedded cover refreshes instead of full setState
- Extract shared widgets (_buildAlbumGridItemCore, _buildFilterButton, _navigateWithUnfocus)
- Use libraryCollectionsProvider selector and MediaQuery.paddingOf for fewer rebuilds
- Simplify supporter chip tiers and localize remaining hardcoded strings
2026-03-25 19:55:02 +07:00
zarzet
5948e4f125 chore: remove redundant inline comments 2026-03-14 15:07:15 +07:00
zarzet
7d5cb574c6 feat: move Amazon Music to extension, fix Deezer download timeout 2026-03-08 04:15:28 +07:00
zarzet
ab26d84632 chore: rebuild dev history without streaming-era commits 2026-02-27 13:48:44 +07:00
zarzet
30973a8e78 feat: lyrics provider extensions, configurable lyrics cascade, and iOS method channel parity
Add lyrics_provider as a new extension type alongside metadata_provider and
download_provider. Extensions implementing fetchLyrics() are called before
built-in providers, giving user-installed extensions highest priority.

Built-in lyrics cascade is now configurable from Download Settings:
  - Reorderable provider list (LRCLIB, Musixmatch, Netease, Apple Music, QQ Music)
  - Per-provider options: Netease translation/romanization, Apple/QQ multi-person
    word-by-word speaker tags, Musixmatch language code
  - Provider order and options synced to Go backend on app start and on change

Go backend changes:
  - New lyrics_provider manifest type with validation (extension_manifest.go)
  - ExtensionProviderWrapper.FetchLyrics() with Goja JS bridge (extension_providers.go)
  - Configurable SetLyricsProviderOrder/GetLyricsProviderOrder cascade (lyrics.go)
  - LyricsFetchOptions struct for per-provider settings (lyrics.go)
  - Extracted tryLRCLIB() helper, randomized LRCLIB User-Agent (lyrics.go)
  - Refactored msToLRCTimestamp to separate msToLRCTimestampInline (lyrics.go)
  - New provider source files: lyrics_apple.go, lyrics_musixmatch.go,
    lyrics_netease.go, lyrics_qqmusic.go
  - JSON export functions for lyrics settings (exports.go)
  - hasLyricsProvider field in extension manager JSON output

Platform channels:
  - Android (MainActivity.kt): setLyricsProviders, getLyricsProviders,
    getAvailableLyricsProviders, setLyricsFetchOptions, getLyricsFetchOptions
  - iOS (AppDelegate.swift): same 5 method channel handlers for iOS parity

Flutter side:
  - Extension model: hasLyricsProvider field + Lyrics Provider capability badge
  - Settings model: lyricsProviders, lyricsIncludeTranslationNetease,
    lyricsIncludeRomanizationNetease, lyricsMultiPersonWordByWord,
    musixmatchLanguage fields with generated serialization
  - Settings provider: setters + _syncLyricsSettingsToBackend()
  - Download settings UI: provider picker, toggle switches, language picker
  - Platform bridge: lyrics provider/options methods

Docs: lyrics provider extension documentation in site/docs.html
CHANGELOG: updated with lyrics provider and search feature entries
2026-02-14 01:42:18 +07:00
zarzet
7c08321ce3 refactor: continue code cleanup 2026-02-04 10:42:51 +07:00
zarzet
b9c3f2f0dd fix: remove duplicate plugin registration warning
Remove manual GeneratedPluginRegistrant.registerWith() call since
super.configureFlutterEngine() already handles this automatically.
2026-02-01 20:18:51 +07:00
zarzet
81b0eede8c v3.3.5: Same as 3.3.1 but fixes crash issues caused by FFmpeg
Changes:
- Fix FFmpeg crash issues during M4A to MP3/Opus conversion
- Add format picker (MP3/Opus) when selecting Tidal Lossy 320kbps
- Fix Deezer album blank screen when opened from home
- LRC file generation now follows lyrics mode setting
- Version bump to 3.3.5 (build 70)
2026-02-01 20:12:00 +07:00
zarzet
79180dd918 feat: add Home Feed with pull-to-refresh and gobackend.getLocalTime() API
- Add Home Feed/Explore feature with extension capabilities system
- Add pull-to-refresh on home feed (replaces refresh button)
- Add gobackend.getLocalTime() API for accurate device timezone detection
- Add YT Music Quick Picks UI with swipeable vertical format
- Fix greeting time showing wrong time due to Goja getTimezoneOffset() returning 0
- Update spotify-web and ytmusic extensions to use getLocalTime()
- Add Turkish language support
- Update CHANGELOG for v3.2.0
2026-01-21 08:30:44 +07:00
zarzet
03027813c1
chore: cleanup unused code and dead imports 2026-01-20 02:10:10 +07:00
zarzet
0119db094d
feat: add extended metadata (genre, label, copyright) support
- Add genre, label, copyright fields to ExtTrackMetadata and DownloadResponse
- Add utils.randomUserAgent() for extensions to get random User-Agent strings
- Fix VM race condition panic by adding mutex locks to all provider methods
- Fix Tidal release date fallback when req.ReleaseDate is empty
- Display genre, label, copyright in track metadata screen
- Store extended metadata in download history for persistence
- Add trackGenre, trackLabel, trackCopyright localization strings
2026-01-19 21:13:40 +07:00
zarzet
595bfb2711
feat: add button setting type for extension actions
- Add SettingTypeButton for action buttons in extension settings
- Add Action field to ExtensionSetting for JS function name
- Update extension detail page UI to render button settings
- Add InvokeAction method to execute button actions
2026-01-19 02:14:52 +07:00
zarzet
8d92d22fda
refactor: more code cleanup 2026-01-17 10:04:21 +07:00
zarzet
b99764b1ad
refactor: cleanup unused code and imports 2026-01-17 09:50:00 +07:00
zarzet
18bc079632 Merge dev into main: v3.0.0 stable release 2026-01-14 18:08:30 +07:00
zarzet
13b917d1a0 fix: preserve directory structure when extracting extension packages 2026-01-13 17:50:12 +07:00
zarzet
8daff4d0a4
feat: improve Extension Store with custom icons and various fixes
- Support custom extension icons from registry (iconUrl field)
- Support both camelCase and snake_case in registry JSON
- Fix download file extension (.spotiflac-ext)
- New extensions start disabled by default
- Preserve enabled state on extension upgrade
- Add toggle to show/hide Store tab in Settings > Options
- Reorder tabs: Home, History, Store, Settings
2026-01-13 01:01:43 +07:00
zarzet
93b4047143
fix: persist extension enabled state and clear search provider when disabled
- Save enabled state to settings store when extension is enabled/disabled
- Restore enabled state from settings store when extension is loaded
- Clear searchProvider setting when the extension is disabled
- Update search hint to check if extension is still enabled
2026-01-12 01:56:16 +07:00
zarzet
57cb575483
feat: add extension system with skipBuiltInFallback support
- Add extension manager, manifest, runtime, providers, settings
- Add extension provider and UI pages (extensions, detail, priority)
- Add download service picker widget
- Add metadata provider priority page
- Add source field to Track model for extension tracking
- Add skipBuiltInFallback manifest option to skip built-in providers
- Update download queue to use source extension first
- Add extension upgrade support without data loss
2026-01-12 00:17:52 +07:00