Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions lib/screens/now_playing_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -1904,14 +1905,15 @@ class _SongInfoState extends State<_SongInfo> {
) async {
if (widget.song == null) return;

final subsonicService = Provider.of<SubsonicService>(
// Use LibraryProvider so the playlist list gets refreshed after creation
final libraryProvider = Provider.of<LibraryProvider>(
context,
listen: false,
);

try {
await subsonicService.createPlaylist(
name: playlistName,
await libraryProvider.createPlaylist(
playlistName,
songIds: [widget.song!.id],
);

Expand Down
34 changes: 26 additions & 8 deletions lib/services/subsonic_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -452,13 +452,32 @@ class SubsonicService {
required String name,
List<String>? songIds,
}) async {
final params = <String, String>{'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<void> updatePlaylist({
Expand Down Expand Up @@ -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');
}
Expand Down