diff --git a/lib/services/navidrome_service.dart b/lib/services/navidrome_service.dart index 68c5def..83ac7f4 100644 --- a/lib/services/navidrome_service.dart +++ b/lib/services/navidrome_service.dart @@ -178,4 +178,92 @@ class NavidromeService { Uri? coverUrl(String coverId) { return _uri('getCoverArt.view', {'id': coverId}); } + + Future setFavorite(String songId) async { + try { + final r = await http.get(_uri('star.view', {'id': songId})).timeout(const Duration(seconds: 10)); + return r.statusCode == 200; + } catch (e) { + debugPrint('Navidrome setFavorite Fehler: $e'); + return false; + } + } + + Future removeFavorite(String songId) async { + try { + final r = await http.get(_uri('unstar.view', {'id': songId})).timeout(const Duration(seconds: 10)); + return r.statusCode == 200; + } catch (e) { + debugPrint('Navidrome removeFavorite Fehler: $e'); + return false; + } + } + + Future> getFavorites() async { + try { + final r = await http.get(_uri('getStarred.view')).timeout(const Duration(seconds: 15)); + if (r.statusCode != 200) return []; + final data = jsonDecode(r.body); + final songs = data['subsonic-response']?['starred']?['song'] as List? ?? []; + return songs.map((j) => SubsonicSong.fromJson(j)).toList(); + } catch (e) { + debugPrint('Navidrome getFavorites Fehler: $e'); + return []; + } + } + + Future> getArtists() async { + try { + final r = await http.get(_uri('getArtists.view')).timeout(const Duration(seconds: 15)); + if (r.statusCode != 200) return []; + final data = jsonDecode(r.body); + final indexData = data['subsonic-response']?['artists']?['index'] as List? ?? []; + final artists = []; + for (final idx in indexData) { + final artistList = idx['artist'] as List? ?? []; + for (final a in artistList) { + artists.add(SubsonicArtist.fromJson(a)); + } + } + return artists; + } catch (e) { + debugPrint('Navidrome getArtists Fehler: $e'); + return []; + } + } + + Future> getArtistSongs(String artistId) async { + try { + final r = await http.get(_uri('getArtist.view', {'id': artistId})).timeout(const Duration(seconds: 15)); + if (r.statusCode != 200) return []; + final data = jsonDecode(r.body); + final albums = data['subsonic-response']?['artist']?['album'] as List? ?? []; + final songs = []; + for (final album in albums) { + final albumSongs = album['song'] as List? ?? []; + for (final song in albumSongs) { + songs.add(SubsonicSong.fromJson(song)); + } + } + return songs; + } catch (e) { + debugPrint('Navidrome getArtistSongs Fehler: $e'); + return []; + } + } +} + +class SubsonicArtist { + final String id; + final String name; + + const SubsonicArtist({ + required this.id, + required this.name, + }); + + factory SubsonicArtist.fromJson(Map j) => SubsonicArtist( + id: j['id'] as String, + name: j['name'] as String? ?? 'Unbekannt', + ); }