Recent Access History:
- Quick access to recently visited artists, albums, playlists, and tracks
- Tap search bar to show recent access list
- Stays visible after keyboard dismiss, exit with back button
- Persists across app restarts (SharedPreferences)
- X button to remove items, Clear All button for all
Artist Screen Redesign:
- Full-width header image with gradient overlay
- Monthly listeners display with compact notation
- Popular section with top 5 tracks and download status
- Extension artists skip Spotify/Deezer fetch (no rate limit errors)
Go Backend:
- GetArtistWithExtensionJSON now returns top_tracks, header_image, listeners
Bug Fixes:
- Search bar unfocus when tapping outside
- Keyboard not appearing on Settings navigation return
- Recent access artist navigation uses correct screen for extensions
- Extension artist screen correctly parses and forwards top tracks
Localization:
- Added recentPlaylistInfo, errorGeneric strings
- Multi-language support via Crowdin
Extensions:
- YT Music: v1.5.0 (top_tracks in getArtist)
- Spotify Web: v1.6.0
- Add locale field to AppSettings model with 'system' default
- Add Language section in Appearance settings page
- Support System Default, English, and Indonesian options
- App language changes take effect immediately
- Add localization strings for language selector
Fixes:
- Fix Separate Singles not working (#54) - albumType not extracted from Deezer API
- Fix extension artist/album metadata missing provider IDs and cover URLs
- Fix YTMusic extension not extracting album name and duration from search
- Fix extension collection screens setState after dispose
- Fix search source chips referencing removed badge props
Changes:
- Deezer convertTrack now includes album_type from record_type
- Track creation preserves albumType and source throughout download flow
- Go exports include provider_id in album/artist responses
- Version bump to 3.1.0+59
- Add PopScope with canPop:true to all settings pages for predictive back gesture support
- Change settings navigation to use PageRouteBuilder instead of MaterialPageRoute
- Add album folder structure setting (artist_album vs album_only)
- Fix extension search result parsing to handle both array and object formats
- Update CHANGELOG
Fixes back gesture freeze issue on OnePlus and other Android 13+ devices with gesture navigation
- Add utils.hmacSHA1(key, message) for cryptographic operations in extensions
- Add artist type handling in track_provider for extension URL results
- Fix extension store not refreshing after uninstall
- Update CHANGELOG with new features and Spotify Web extension docs
- 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
- Fixed download showing 'Song not found' when actually permission error
- Added permission error type detection in Go backend
- Android 13+ now requests both MANAGE_EXTERNAL_STORAGE and READ_MEDIA_AUDIO
- MANAGE_EXTERNAL_STORAGE opens Settings (system-level)
- READ_MEDIA_AUDIO shows dialog (app-level, resets on clear data)
- Proper permission check before showing 'granted' status
- Add albumType field to Track model with isSingle getter
- Add separateSingles setting in AppSettings
- Modify _buildOutputDir() to organize into Albums/ and Singles/ folders
- Add UI toggle in download settings page
- Parse album_type/record_type from Spotify and Deezer APIs
When enabled, singles are saved to a separate 'Singles' folder
- Add duplicate detection in addToHistory() by spotifyId, deezerId, or ISRC
- Replace existing entry and move to top when re-downloading same track
- Add _deduplicateHistory() to clean up existing duplicates on app load
- Auto-save after removing duplicates from storage
Fixes duplicate history entries when downloading same track multiple times
- Add multi-select mode with long-press to select tracks
- Add bottom action bar for selection (Material 3 style)
- Add filter tabs: All/Albums/Singles
- Add album grouping view when Albums filter selected
- Add DownloadedAlbumScreen for viewing tracks in an album
- Reactive UI updates when tracks deleted
- Auto-pop when album has <2 tracks
- Update issue templates with (Stable Version) text
- Bump version to 2.2.8
- Reset metadata source to Deezer when search provider extension is disabled
- Reset default service to Tidal when download provider extension is disabled
- Check extension enabled state in Options page (Primary Provider)
- Check extension enabled state in Download Settings (Service selector)
- Show extension download providers in service selector when enabled
- Remove hardcoded Spotify client ID/secret from Go backend
- Spotify now requires user to provide their own credentials
- Deezer remains free (no credentials required)
- Update UI to show 'Free' badge for Deezer, 'API Key' for Spotify
- Show warning card when Spotify selected without credentials
- Add hasSpotifyCredentials check to platform bridge
- 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
- 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
- Fix Flutter logs not appearing in release mode by bypassing Logger package
- Add detailed logging for Deezer search API calls
- Replace music_note icon with app logo on home screen
- Remove shadow/border from logo in About and Home screens
- Align icon size (40x40) with avatar in About page for consistent layout
- Fix progress bar jumping from 1% to 100% (threshold-based updates)
- Fix incomplete downloads with temp file + size validation
- Applies to Tidal, Qobuz, and Amazon services
- Add Deezer API client (no auth required, rate limit per user IP)
- Add search source selector in Settings (Deezer/Spotify)
- Default to Deezer for better reliability
- Auto-fallback to Deezer when Spotify API is rate limited (429)
- Support fallback for tracks and albums via SongLink API
- Update README with metadata source documentation
- Version 2.1.5-preview (build 42)
- Add actual quality display (bit depth/sample rate) in history and metadata
- Add quality disclaimer in quality picker
- Fix fallback service display showing wrong service
- Fix Open in Spotify not opening app correctly
- Remove romaji conversion feature
- Amazon now reads quality from FLAC file
- Quality picker now shows track name, artist, and cover
- Tap to expand long track titles (icon only shows when truncated)
- Ripple effect follows rounded corners including drag handle
- Update dialog redesigned with Material Expressive 3 style
- Fixed update notification stuck at 100% after download complete
- Ask before download now enabled by default
- Finalizing notification for multi-progress polling
- Add HTTPS-only validation for APK downloads and update checks
- Use .select() for Riverpod providers to prevent unnecessary rebuilds
- Add keys to all list builders for efficient updates
- Implement request cancellation for outdated API requests
- Debounce all network requests (URLs and searches)
- Limit file existence cache to 500 entries
- Add ref.onDispose for timer cleanup
- Add error handling for share intent stream
- Redesign About page with Material Expressive 3 style
- Rename Search tab to Home
- Remove Features section from README
- Add foreground service for background downloads with wake lock
- Persist download queue to SharedPreferences for app restart recovery
- Fix share intent causing app restart (singleTask + onNewIntent)
- Fix back button clearing state during loading
- Upgrade Kotlin to 2.3.0 for share_plus 12.0.1 compatibility
- Add WAKE_LOCK permission for foreground service
- Download queue now persisted to SharedPreferences
- Auto-restore pending downloads on app restart
- Interrupted downloads reset to queued and auto-resumed
- singleTask launch mode to prevent app restart on share intent
- onNewIntent handler for proper intent handling
- Reverted share_plus to 10.1.4 (12.0.1 has Kotlin build issues)