All notable changes to Musly will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Smart Transcoding: New automatic quality mode that switches bitrate in real time based on active network
- Detects WiFi vs mobile data via
connectivity_plus - Configure separate bitrates for WiFi and mobile; the app picks the right one automatically
- Live connection badge (WiFi / Mobile pill) in Settings → Playback while smart mode is active
- Smart mode toggle persists across restarts
- Detects WiFi vs mobile data via
- Dynamic & Custom Accent Colors: The accent color now propagates everywhere in the app
- On Android 12+ the wallpaper-derived Material You palette is used automatically (via
dynamic_color) - On all other platforms any color picked in Settings → Display is applied to every widget
- Eliminated all hardcoded
AppTheme.appleMusicRedreferences in settings tabs, mini player, song tiles, cast button, and album artwork shadow
- On Android 12+ the wallpaper-derived Material You palette is used automatically (via
- iOS Control Center player: Fixed the player widget shown in the iOS Control Center and Lock Screen
- Disabled the podcast-style ±15 s skip buttons that were hiding the standard ⏮ ▶/⏸ ⏭ controls
- Added
MPNowPlayingInfoPropertyMediaType = .audioandMPNowPlayingInfoPropertyDefaultPlaybackRatefor correct system content categorization - Fixed an artwork caching race condition: concurrent 1-second position updates no longer restart artwork downloads already in progress
- Server connection retry:
AuthProvider._verifyConnection()now retries the ping up to 3 times (2 s backoff) before declaring the server unreachable — handles slow mobile network initialization on launch - Retry button on the server-unreachable screen: A "Retry" button lets users re-attempt the connection without restarting the app (
AuthProvider.retryConnection()) - Localization — Settings strings: All hardcoded strings in the five Settings tabs are now in
app_en.arb(~100 new keys covering Playback, Storage, About, Display, and Server sections)
- Loading screen: The app no longer flashes the login screen while checking the server on startup;
AuthState.authenticatingnow shows a centeredCircularProgressIndicatoron a black background - Home screen desktop layout: Improved density and alignment for macOS/Windows/Linux
- Wider horizontal padding (32 px), larger section headers and album cards (180 px)
- Song lists render as a compact table (
_DesktopSongRow) instead of fullSongTilecards - Recent albums (6) and playlists (3) shown instead of 4 and 2
- Error messages: Improved error string formatting in
AuthProvider._formatError()— stripsException:,Network error:, and verbose library boilerplate for cleaner display - Connection timeout: Server ping timeout increased from 6 s to 10 s
- Now Playing screen: Matrix transforms updated to Flutter 3.41-compatible
scaleByDouble/translateByDoublesignatures;.withOpacity()replaced with.withValues(alpha:)throughout
seekForward/seekBackwardevents from iOS Control Center: AddedonSeekForward/onSeekBackwardcallbacks toAndroidSystemServiceand registered handlers inPlayerProvider(clamping backward seeks toDuration.zero)- Settings tab indicator color hardcoded:
indicatorColorandlabelColorinsettings_screen.dartnow useTheme.of(context).colorScheme.primary DjMixerServiceremoved: Deleted unuseddj_mixer_service.dartthat was included by mistake;services.dartbarrel still intact
- Added
connectivity_plus: ^7.0.0— network type detection for Smart Transcoding - Added
dynamic_color: ^1.7.0— Material You wallpaper color extraction on Android 12+ - Added
path: ^1.9.0
- Spotify-style Desktop UX: Complete redesign of the PC layout
- New collapsible sidebar (
DesktopNavigationSidebar) with 260 px expanded / 72 px collapsed states - Sidebar sections: Home, Search, Your Library (scrollable playlist list with Liked Songs shortcut), Settings, Collapse/Expand toggle
- Settings navigation item restored directly in the sidebar
- All sidebar strings localised via ARB (
expand,createPlaylist)
- New collapsible sidebar (
- Artwork Style Editor: Full custom editor in Settings → Display → Artwork Style
- Shape: Rounded rectangle, Circle, or Square
- Corner Radius: slider (0–24 px), only visible when shape is Rounded
- Shadow intensity: None, Soft, Medium, Strong
- Shadow color: Black or Accent (Musly red)
- Live 108 px animated preview updates in real-time
- All options persisted to
SharedPreferencesand restored on next launch (awaited beforerunApp)
- No-artwork placeholder in mobile player: Songs without cover art now show a clean dark gradient tile with a music note icon and localised "No artwork" label instead of an infinite shimmer loader. Shimmer is still used while the image is actually fetching.
- Desktop player bar accent colors: All active-state indicators (shuffle, repeat, progress slider, volume slider, favorite heart, lyrics button) now use Musly red
- Update dialog colors: Header gradient and download button changed from purple/blue (
#6C5CE7 → #00B4D8) to Musly red/pink (appleMusicRed → appleMusicPink) - Desktop lyrics: Lyrics view now uses
rootNavigator: trueso it covers the full window (sidebar + content + player bar); close button pops from the root navigator correctly - React marketing website: Version number and release date in Hero and Download sections are now fetched live from the GitHub public API (
/repos/dddevid/Musly/releases/latest) with a 10-minute session cache — no auth token required
- Library list alignment: Album/artist tiles in the Library screen now use an explicit
InkWell → Padding → Rowlayout so artwork and text align with section headers on all platforms - Artwork settings not persisting:
PlayerUiSettingsService.initialize()is nowawait-ed beforerunApp, guaranteeing saved values are loaded into notifiers before any widget builds
- Jukebox Mode (#41): Server-side audio playback via the Subsonic jukebox API
- New
JukeboxServicewrapping all jukebox API calls (get,start,stop,skip,set,add,clear,shuffle,remove,setGain) - Dedicated
JukeboxScreenremote-control UI with now-playing artwork, playback controls, volume slider, and queue list - Toggle in Settings → Server to enable/disable jukebox mode
- "Play on Jukebox" and "Add to Jukebox Queue" options in the song long-press context menu (shown only when jukebox is enabled)
- Auto-refresh on screen open + 5-second polling to stay in sync with current server state
- Friendly error screen when the server returns 501 (jukebox not enabled), with setup instructions
- New
- Genre Support: Enhanced genre browsing
- Genres screen now shows song count per genre and a tooltip
- Genre screen rebuilt with two tabs: Songs and Albums
- #29 Offline Playlists: Playlists are now correctly restored from local cache when the server is unreachable
- #37 Music Folder Selection: Fixed the music folder selection dialog in Server settings
- #44 Album Art Aspect Ratio: Album artwork now preserves its original aspect ratio (
BoxFit.contain) instead of stretching
- Localizations: Removed duplicate keys from
app_en.arb; cleaned non-English ARB files of orphaned section markers and English fallback strings
- Internationalization (i18n): Full app translation support via Flutter's
flutter_localizations- 24 languages: Bengali, Danish, German, Greek, Spanish, Finnish, French, Irish, Hindi, Indonesian, Italian, Norwegian, Polish, Portuguese, Romanian, Russian, Albanian, Swedish, Telugu, Turkish, Ukrainian, Vietnamese, Chinese (Simplified), and English as base
- Crowdin integration for community-driven translations with GitHub Actions auto-sync
- Added
TRANSLATIONS.mdguide for contributors - Added
LocaleServicefor runtime language switching
- Google Cast / Chromecast Support: Stream music to Cast-compatible devices
- New
CastServicemanaging session lifecycle and media loading - New
CastButtonwidget displayed in the player and mini-player - Album art shown on the TV/receiver as a video-style visualization (1280×720)
- Integrated
flutter_chrome_castpackage (bundled underpackages/) - UPnP device discovery via new
UPnPServiceas a fallback discovery layer
- New
- mTLS Client Certificate Authentication: Secure mutual TLS for self-hosted servers
- Certificate file picker on the login screen (
.p12/.pfx) - Optional password field for password-protected certificates
ServerConfigmodel extended withclientCertPathandclientCertPasswordfieldsSubsonicServicenow configures the HTTP client with the chosen certificate
- Certificate file picker on the login screen (
- Discord Rich Presence: Show currently playing song in Discord status
- New
DiscordRpcServicewired into the player pipeline
- New
- Auto-Update Service: New
UpdateServicethat checks GitHub Releases for newer versions and prompts the user - Windows NSIS Installer: Packaged installer (
installer.nsi) with dynamic version injection via/Dflag from the CI pipeline - Linux Platform Support: Full Linux desktop build configuration added
- Star Rating Widget: Visual 1–5 star picker widget used in the song options menu
- React Marketing Website: Added under
react-website/, deployed to GitHub Pages via Actions workflow
- Google Cast Display: Receiver now shows album art like Spotify
- Switched from raw audio streaming to a video-style Cast session with artwork
- Uses
GenericMediaMetadatafor broader Cast receiver compatibility
- Support Dialog: Streamlined post-login dialog
- Removed 5-second wait timer; close button is immediately available
- Added "Don't show again" checkbox
- Removed BuyMeACoffee and donation links
- Build System: Upgraded to Gradle 8.0 for Java 21 compatibility
flutter_chrome_castuses Gradle 8.0.2 and Kotlin 1.9.0compileSdkbumped to 34, Java compatibility set toVERSION_11- Resolves "Unsupported class file major version 65" build error
- CI/CD Pipeline: Overhauled GitHub Actions release workflow
- Flutter dependency caching enabled to speed up builds
- Updated all action versions to current releases
- Removed hardcoded Flutter version pin for better forward compatibility
- Removed AAB (Android App Bundle) artifact from release builds
- Code Quality: Cleaned up Dart lint warnings across the codebase
- Removed unused imports, variables, and dead code
- Fixed impossible null checks
- Replaced deprecated API usages
- Android Boot Crash: Removed
AutoStartReceiverthat caused crashes on device startup- App no longer requests
RECEIVE_BOOT_COMPLETEDpermission
- App no longer requests
- Android 16 / Media3 Playback Bug: Implemented workaround for a Media3 regression introduced in Android 16 that prevented playback from starting correctly
- Low Power Device Crashes: Optimized image caching and rendering pipeline to avoid OOM crashes on constrained hardware
- Flutter 3.41.1 Compatibility: Hid
RepeatModere-export fromcupertino.dartto resolve a symbol conflict introduced in Flutter 3.41.1 - Cast Service Resource Leaks: Added proper
dispose()anddisconnect()methods;loadMedia()now returns a success/failure boolean - installer.nsi not tracked: Removed
installer.nsifrom.gitignoreso the Windows installer script is included in the repository
- Donation popup: Support dialog no longer shows BuyMeACoffee or cryptocurrency donation options
AutoStartReceiver: Android boot-start receiver removed entirelyDOCUMENTATION.md: Replaced by inline code documentation and README improvements
- Support Dialog After Login: Shows after each successful login
- Discord community invite link (optional)
- Donation options: Buy Me a Coffee, Bitcoin, Solana
- 5-second timer before close button enables
- Copy buttons for cryptocurrency addresses
- Discord Integration in Settings: Added Discord community link to Settings → About → LINKS
- Discord Community Section in README: Added dedicated section with Discord badge and invite link
- Landscape Lyrics Display: Significantly improved lyrics viewing in landscape mode
- Lyrics now occupy right 60% of screen while album art stays on left 40%
- Created
CompactLyricsViewwidget specifically optimized for landscape - Portrait mode keeps fullscreen lyrics overlay
- Fixed overflow issues in lyrics dialog
- Playlist Duration Calculation: Enhanced playlist screen with accurate total duration
- Total duration now calculated from actual song lengths
- Displays formatted duration (e.g., "12 songs • 1 hr 23 min")
- Homepage Loading Issue on Windows: Fixed infinite skeleton loading
- Added 5-second timeout to server initialization calls in
LibraryProvider - App now continues in local mode if server doesn't respond
- Improved error handling for missing server configuration
- Added 5-second timeout to server initialization calls in
- Windows SMTC Error Handling: Improved error messages for RustLib initialization
- App continues normally even if SMTC (Windows System Media Transport Controls) fails to initialize
- Added informative debug messages explaining SMTC will be disabled
-
#27 Star Rating System: Added 1-5 star rating support for songs
- Rate songs via the song options menu (three-dot menu)
- Rating dialog with visual star picker
- Shows current rating in menu title
- Uses Subsonic
setRatingAPI endpoint - Added
userRatingfield to Song model
-
Landscape Mode for Full Player: New horizontal layout when device is rotated
- Album artwork displayed on the left (40% width)
- Song info and controls on the right (60% width)
- Lyrics toggle replaces controls with synced lyrics on right side
- Automatic layout switch based on screen orientation
- Created
CompactLyricsViewwidget optimized for landscape mode
- Playlist & Album Screens: Enhanced with calculated total duration
- Playlist screen now shows total duration calculated from songs (e.g., "12 songs • 1 hr 23 min")
- More accurate duration display based on actual song lengths
- Performance Optimizations: Migrated synced lyrics view to
flutter_lyricpackage (v3.0.2)- Reduced blur effects from sigma 80 to 40 for better GPU performance
- Added
RepaintBoundaryaround animated backgrounds - Implemented position update throttling (100ms intervals)
- Reduced image cache sizes for lower memory usage
- Widget Optimization: Replaced
ConsumerandProvider.ofwithSelectorpatternSongTile: Now only rebuilds when current song changesDesktopPlayerBar: Optimized controls, progress bar, and volume slider- Reduced unnecessary widget rebuilds across the app
- Synced lyrics assertion error:
selectionAutoResumeDurationmust be less thanactiveAutoResumeDuration - Library "Local" filter removed: Cleaned up unused local music filter from library screen
- Storage permissions for Android 13+: Added
READ_MEDIA_AUDIOandREAD_MEDIA_IMAGESpermissions - Server not configured errors: LibraryProvider now gracefully handles local-only mode without server errors
- Premium Equalizer: 10-band EQ with presets (Rock, Pop, Jazz, Classical, Bass Boost, Treble Boost, Vocal, Electronic, Hip Hop) and custom preset saving
- Settings Categories: Reorganized settings into 5 tabs (Playback, Storage, Server, Display, About)
- Local File Support: Play music files stored on device with automatic library scanning
- Transcoding/Streaming Quality: Configure WiFi and Mobile bitrate settings with format selection (MP3, Opus, AAC)
- Offline Mode: Automatic fallback to downloaded music when server is unreachable
- Offline Playback Indicator: Orange banner shows when in offline mode
-
Synced Lyrics Display:
- Added blur effect for non-active lines (distance-based)
- Added glow shadow for active line
- Improved scale animations (1.15x-1.18x for active)
- Enhanced line spacing and visual hierarchy
- Applied to mobile, desktop, and fullscreen views
-
Shuffle Functionality: Now properly shuffles playlist regardless of current playback state
-
Artists Tab: Now correctly displays artists when "Artists" filter is selected
-
Homepage Empty State: Added fallback message and refresh button when no content
-
#26: Transcoding/streaming quality settings
- Added WiFi and Mobile bitrate configuration in Server settings
- Support for format selection (MP3, Opus, AAC)
- Bitrate options from 64kbps to 320kbps or original quality
-
#25: Library search now works on all items, not just playlists
- Implemented
LibrarySearchDelegatethat searches across playlists, albums, and artists
- Implemented
-
#24: Artists tab now displays content
- Fixed
_getFilteredItemsto properly filter and return artists list
- Fixed
-
#22: Homepage shows fallback when no content available
- Added empty state widget with refresh button when no albums/songs loaded
-
#20: Shuffle button now always shuffles instead of acting as play/pause
- Modified shuffle logic to always shuffle the playlist, even when already playing
-
#19: Download button in playlist now downloads all songs
- Implemented batch download functionality in playlist screen
-
#18: Play/Pause state now correctly shows only for the active playlist
- Fixed playlist header to compare current playing context
-
#17: Lyrics scroll now uses smooth animations without line-break changes
- Used fixed font size for all lines to prevent layout shifts
-
#16: Library search button now works
- Connected search icon to
LibrarySearchDelegate
- Connected search icon to
-
#15: Swipe down to minimize player implemented
- Added gesture detector for vertical swipe to dismiss full player
-
#14: Option to hide volume bar from player
- Added toggle in Display settings to show/hide volume slider
-
#13: Click on album/artist name navigates to respective screen
- Made album and artist names tappable in now playing screen
-
#12: Internet radio station support
- Added
RadioScreenwith server radio stations - Support for streaming internet radio URLs
- Added
-
#11: All Songs view with sort options and playback
- Added
AllSongsScreenwith play/shuffle buttons
- Added
-
#10: Auto-DJ feature for queue
- Implemented smart queue that adds similar songs when queue ends
-
#9: ReplayGain support
- Added ReplayGain toggle in Playback settings
-
#8: Progress bar freezes on rewind
- Fixed position stream subscription to properly update on seek
-
#7: Custom TLS/SSL certificates
- Added option to allow self-signed certificates in login
- Added custom certificate file picker in Advanced Options
-
#5: Lyrics text stability
- Fixed line break changes during playback by using consistent font sizing
-
#4: Music Folders support
- Added music folder selection in Server settings
-
#3: Error messages for incorrect URL
- Added proper error handling and snackbar messages for connection failures
-
#1: Miniplayer persists
- Implemented nested navigator architecture to maintain miniplayer state