diff --git a/lib/screens/now_playing_screen.dart b/lib/screens/now_playing_screen.dart index 88c155c..f339e22 100644 --- a/lib/screens/now_playing_screen.dart +++ b/lib/screens/now_playing_screen.dart @@ -11,6 +11,7 @@ import '../l10n/app_localizations.dart'; import '../models/song.dart'; import '../models/radio_station.dart'; import '../providers/player_provider.dart'; +import '../providers/library_provider.dart'; import '../services/subsonic_service.dart'; import '../services/player_ui_settings_service.dart'; import '../widgets/star_rating_widget.dart'; @@ -1904,14 +1905,15 @@ class _SongInfoState extends State<_SongInfo> { ) async { if (widget.song == null) return; - final subsonicService = Provider.of( + // Use LibraryProvider so the playlist list gets refreshed after creation + final libraryProvider = Provider.of( context, listen: false, ); try { - await subsonicService.createPlaylist( - name: playlistName, + await libraryProvider.createPlaylist( + playlistName, songIds: [widget.song!.id], ); diff --git a/lib/services/subsonic_service.dart b/lib/services/subsonic_service.dart index 0d120c2..be0cb05 100644 --- a/lib/services/subsonic_service.dart +++ b/lib/services/subsonic_service.dart @@ -452,13 +452,32 @@ class SubsonicService { required String name, List? songIds, }) async { - final params = {'name': name}; + // songId must be appended directly, using it as a map key would produce + // songId[i]=x which Navidrome doesn't recognize + String url = _buildUrl('createPlaylist', {'name': name}); if (songIds != null && songIds.isNotEmpty) { - for (int i = 0; i < songIds.length; i++) { - params['songId[$i]'] = songIds[i]; + for (final songId in songIds) { + url += '&songId=${Uri.encodeComponent(songId)}'; } } - await _request('createPlaylist', params); + + try { + final response = await _dio.get(url); + final data = response.data; + + final decoded = data is String ? json.decode(data) : data; + final subsonicResponse = decoded['subsonic-response']; + if (subsonicResponse == null) { + throw Exception('Invalid response format'); + } + + if (subsonicResponse['status'] != 'ok') { + final error = subsonicResponse['error']; + throw Exception(error?['message'] ?? 'Unknown error'); + } + } on DioException catch (e) { + throw Exception('Network error: ${e.message}'); + } } Future updatePlaylist({ @@ -486,15 +505,14 @@ class SubsonicService { } } - debugPrint('updatePlaylist URL: $url'); + debugPrint('updatePlaylist URL: ${_sanitizeUrl(url)}'); try { final response = await _dio.get(url); final data = response.data; - final subsonicResponse = data is String - ? json.decode(data) - : data['subsonic-response']; + final decoded = data is String ? json.decode(data) : data; + final subsonicResponse = decoded['subsonic-response']; if (subsonicResponse == null) { throw Exception('Invalid response format'); }