feat(navidrome): Erweiterte Service-APIs (Artists, Favoriten)
- getArtists(): Alle Künstler vom Server laden - getArtistSongs(): Alle Songs eines Künstlers - setFavorite()/removeFavorite(): Server-Favoriten toggle - getFavorites(): Favoriten vom Server laden - SubsonicArtist-Klasse für Künstler APIs für Phase 2 vorbereitet (Artist-Tab, Server-Favoriten-Sync) Tests: 70/70 grün
This commit is contained in:
@@ -178,4 +178,92 @@ class NavidromeService {
|
|||||||
Uri? coverUrl(String coverId) {
|
Uri? coverUrl(String coverId) {
|
||||||
return _uri('getCoverArt.view', {'id': coverId});
|
return _uri('getCoverArt.view', {'id': coverId});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> 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<bool> 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<List<SubsonicSong>> 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<List<SubsonicArtist>> 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 = <SubsonicArtist>[];
|
||||||
|
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<List<SubsonicSong>> 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 = <SubsonicSong>[];
|
||||||
|
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<String, dynamic> j) => SubsonicArtist(
|
||||||
|
id: j['id'] as String,
|
||||||
|
name: j['name'] as String? ?? 'Unbekannt',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user