Einseitige Playlist-Sicherung: melden, merken, bei leerer Tabelle holen

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012A2pmbnVNPiHdyf2GW8eLP
This commit is contained in:
Hermes (Server)
2026-08-27 13:43:20 +02:00
co-authored by Claude Sonnet 5
parent 0519c68b26
commit faabf28abc
4 changed files with 352 additions and 4 deletions
+91 -4
View File
@@ -22,6 +22,7 @@ class PlaylistService extends ChangeNotifier {
Future<String> createPlaylist(String name, {String? description}) async {
final id = await db.createPlaylist(name, description: description);
notifyListeners();
await _sichereNeuePlaylist(id, name);
return id;
}
@@ -30,24 +31,39 @@ class PlaylistService extends ChangeNotifier {
notifyListeners();
}
Future<void> addSongToPlaylist(String playlistId, String songId, int position) async {
Future<void> addSongToPlaylist(
String playlistId, String songId, int position) async {
await db.addSongToPlaylist(playlistId, songId, position);
notifyListeners();
final cloudId = await _cloudIdDerPlaylist(playlistId);
final songCloudId = (await db.songById(songId))?.cloudId;
if (cloudId == null || songCloudId == null) return;
await _still(() =>
_cloud!.fuegePlaylistSongsHinzu(cloudId, [songCloudId]));
}
Future<void> removeSongFromPlaylist(String playlistId, String songId) async {
Future<void> removeSongFromPlaylist(
String playlistId, String songId) async {
final songCloudId = (await db.songById(songId))?.cloudId;
await db.removeSongFromPlaylist(playlistId, songId);
notifyListeners();
final cloudId = await _cloudIdDerPlaylist(playlistId);
if (cloudId == null || songCloudId == null) return;
await _still(() => _cloud!.entfernePlaylistSong(cloudId, songCloudId));
}
Future<void> reorderSong(String playlistId, String songId, int newPosition) async {
Future<void> reorderSong(
String playlistId, String songId, int newPosition) async {
await db.reorderPlaylistSong(playlistId, songId, newPosition);
notifyListeners();
await _sichereReihenfolge(playlistId);
}
Future<void> reorderAll(String playlistId, List<String> orderedSongIds) async {
Future<void> reorderAll(
String playlistId, List<String> orderedSongIds) async {
await db.reorderAllPlaylistSongs(playlistId, orderedSongIds);
notifyListeners();
await _sichereReihenfolge(playlistId);
}
Future<void> toggleFavorite(String songId) async {
@@ -135,4 +151,75 @@ class PlaylistService extends ChangeNotifier {
return 0;
}
}
/// Führt [aktion] aus und verwirft jeden Fehler.
///
/// Die Sicherung ist einseitig und ohne Rollback: schlägt sie fehl, bleibt
/// der lokale Stand, wie er ist, und die nächste Änderung versucht es
/// erneut.
Future<void> _still(Future<void> Function() aktion) async {
try {
await aktion();
} catch (e) {
debugPrint('Playlist-Sicherung übersprungen: $e');
}
}
Future<String?> _cloudIdDerPlaylist(String playlistId) async {
if (_cloud == null || !_cloud.istAngemeldet) return null;
return (await db.playlistById(playlistId))?.cloudId;
}
Future<void> _sichereNeuePlaylist(String id, String name) async {
final cloud = _cloud;
if (cloud == null || !cloud.istAngemeldet) return;
await _still(() async {
final cloudId = await cloud.legePlaylistAn(name);
await db.setPlaylistCloudId(id, cloudId);
});
}
Future<void> _sichereReihenfolge(String playlistId) async {
final cloudId = await _cloudIdDerPlaylist(playlistId);
if (cloudId == null) return;
final songs = await db.watchPlaylistSongs(playlistId).first;
final ids = [
for (final s in songs)
if (s.cloudId != null) s.cloudId!,
];
if (ids.isEmpty) return;
await _still(() => _cloud!.setzePlaylistReihenfolge(cloudId, ids));
}
/// Holt die Playlisten des Servers **nur** auf ein Gerät ohne eigene:
/// Neuinstallation oder Wiederherstellung.
///
/// Es gibt bewusst keinen Rück-Merge — Umbenennungen und Änderungen eines
/// zweiten Geräts erscheinen hier nicht. Der beidseitige Abgleich ist eine
/// eigene, spätere Spec.
Future<int> stelleWiederHer() async {
final cloud = _cloud;
if (cloud == null || !cloud.istAngemeldet) return 0;
if (await db.countPlaylists() > 0) return 0;
var angelegt = 0;
try {
for (final vomServer in await cloud.playlisten()) {
final id = await db.createPlaylist(vomServer.name);
await db.setPlaylistCloudId(id, vomServer.id);
final songCloudIds = await cloud.playlistSongs(vomServer.id);
var position = 0;
for (final songCloudId in songCloudIds) {
final song = await db.songByCloudId(songCloudId);
if (song == null) continue;
await db.addSongToPlaylist(id, song.id, position++);
}
angelegt++;
}
} catch (e) {
debugPrint('Playlist-Wiederherstellung abgebrochen: $e');
}
notifyListeners();
return angelegt;
}
}