Fix: Review-Findings korrigiert (Tag-Leiste, Profil, Singleton u.a.)
CRIT: - Tag-Leiste: Toggle-Kopf 'Tags & Filter' eingebaut (war unerreichbar) + TagStats - Profil: Cloud-Count vor Dialog aufloesen (kein 'Instance of Future' mehr) HIGH: - CloudEinstellungen: toten Sync-Timer entfernt (echter Timer im ViewModel) - StatistikCard + RecentWidget jetzt eingebaut (gesamtMB/gesamtMin endlich genutzt) - CloudService als Singleton (konsistenter Token-Zustand in allen Services) MED/LOW: - Playlist-Erkennung nur noch via list= Parameter - Player: fehlende Quelle wird geloggt statt still - song_tile: null-ID-Guard vor Tag-Dialog - Scanner-Log mit Exception-Objekt - FavoritenService: anzahlFavoriten() fuer StatistikCard
This commit is contained in:
@@ -96,6 +96,18 @@ class DbHelper {
|
||||
);
|
||||
}
|
||||
|
||||
/// Löscht fehlerhafte Einträge ohne Dateipfad
|
||||
Future<void> alteDummiesLoeschen() async {
|
||||
final d = await db;
|
||||
await d.delete('songs', where: "datei_pfad = '' OR datei_pfad IS NULL");
|
||||
}
|
||||
|
||||
/// Einzelnen Song löschen
|
||||
Future<void> loeschSong(int id) async {
|
||||
final d = await db;
|
||||
await d.delete('songs', where: 'id = ?', whereArgs: [id]);
|
||||
}
|
||||
|
||||
// ─── Songs ──────────────────────────────────────
|
||||
|
||||
Future<int> songEinfuegen(Song song) async {
|
||||
@@ -193,6 +205,34 @@ class DbHelper {
|
||||
return rows.map((r) => Tag.fromMap(r)).toList();
|
||||
}
|
||||
|
||||
Future<void> songTagEntfernen(int songId, int tagId) async {
|
||||
final d = await db;
|
||||
await d.delete('song_tags',
|
||||
where: 'song_id = ? AND tag_id = ?',
|
||||
whereArgs: [songId, tagId]);
|
||||
}
|
||||
|
||||
Future<List<int>> songIdsFuerTag(String tagName) async {
|
||||
final d = await db;
|
||||
final rows = await d.rawQuery('''
|
||||
SELECT st.song_id FROM song_tags st
|
||||
JOIN tags t ON t.id = st.tag_id
|
||||
WHERE t.name = ?
|
||||
''', [tagName]);
|
||||
return rows.map((r) => r['song_id'] as int).toList();
|
||||
}
|
||||
|
||||
Future<Map<String, int>> tagCountsBerechnen() async {
|
||||
final d = await db;
|
||||
final rows = await d.rawQuery('''
|
||||
SELECT t.name, COUNT(st.song_id) as cnt
|
||||
FROM tags t
|
||||
LEFT JOIN song_tags st ON t.id = st.tag_id
|
||||
GROUP BY t.name
|
||||
''');
|
||||
return {for (final r in rows) r['name'] as String: r['cnt'] as int};
|
||||
}
|
||||
|
||||
// ─── Playlists ───────────────────────────────────
|
||||
|
||||
Future<int> playlistErstellen(String name) async {
|
||||
@@ -224,6 +264,21 @@ class DbHelper {
|
||||
whereArgs: [playlistId, songId]);
|
||||
}
|
||||
|
||||
/// Aktualisiert die Position aller Songs in einer Playlist (nach Drag & Drop)
|
||||
Future<void> playlistReihenfolgeAktualisieren(int playlistId, List<int> songIds) async {
|
||||
final d = await db;
|
||||
await d.transaction((txn) async {
|
||||
for (int i = 0; i < songIds.length; i++) {
|
||||
await txn.update(
|
||||
'playlist_songs',
|
||||
{'position': i},
|
||||
where: 'playlist_id = ? AND song_id = ?',
|
||||
whereArgs: [playlistId, songIds[i]],
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> metadatenAktualisieren(int songId, {String? titel, String? kuenstler, String? album}) async {
|
||||
final d = await db;
|
||||
final update = <String, dynamic>{};
|
||||
|
||||
Reference in New Issue
Block a user