v2.42 — Issue #7: ID3-Reader erweitern + Metadaten-Dialog verschönern

## ID3-Reader (lib/services/id3_reader.dart)
- ID3v1: Jahr (Bytes 93-97) + Genre-Index (Byte 127, vollständige Genre-Liste 0-147)
- ID3v2: Text-Frames TIT2 (Titel), TPE1 (Künstler), TALB (Album), TYER (Jahr), TCON (Genre), TRCK (Track)
- ID3v2-Frames haben Vorrang vor ID3v1 (Füll-Logik)
- UTF-16/UTF-8 Encoding-Unterstützung für Text-Frames
- Genre-Bereinigung: Klammer-Präfixe entfernt, Track-Nummer extrahiert

## Song-Model (lib/models/song.dart)
- Neue Felder: jahr, genre, track (nullable, optional)
- Neue getter: dateiFormat (MP3/M4A/FLAC/WAV/OGG aus Dateiendung)
- DB-Migration v5→v6: jahr, genre, track Spalten

## Metadaten-Dialog (lib/widgets/metadaten_dialog.dart)
- Cover-Bild (128×128) mit rotem Glow-Rahmen oben falls vorhanden
- Editable Felder mit Icons: Titel, Künstler, Album, Jahr, Genre
- Read-Only-Info-Card: Dauer, Dateigröße, Format
- Cards mit roten Akzenten + Melo-Design (schwarz/rot/dunkelgrau)
- ID3-Fallback: Jahr/Genre aus Datei nachladen wenn nicht in DB
- Speichern persistiert auch Jahr und Genre in die DB

## Musik-Scanner (lib/services/musik_scanner.dart)
- jahr, genre, track aus ID3-Tags an Song-Model durchgereicht
- _nichtLeer-Helfer für null-sichere String-Extraktion
This commit is contained in:
Dustin
2026-08-02 16:10:58 +02:00
parent ae11a85872
commit a483436490
5 changed files with 410 additions and 54 deletions
+13 -3
View File
@@ -20,7 +20,7 @@ class DbHelper {
final pfad = await getDatabasesPath();
return openDatabase(
p.join(pfad, 'melo.db'),
version: 5,
version: 6,
onCreate: (db, version) async {
await db.execute('''
CREATE TABLE songs (
@@ -38,7 +38,10 @@ class DbHelper {
download_quelle TEXT DEFAULT 'local',
stream_url TEXT,
yt_url TEXT,
zuletzt_position INTEGER
zuletzt_position INTEGER,
jahr TEXT,
genre TEXT,
track TEXT
)
''');
await db.execute('''
@@ -134,6 +137,11 @@ class DbHelper {
''');
} catch (_) {}
}
if (oldVersion < 6) {
try { await db.execute('ALTER TABLE songs ADD COLUMN jahr TEXT'); } catch (_) {}
try { await db.execute('ALTER TABLE songs ADD COLUMN genre TEXT'); } catch (_) {}
try { await db.execute('ALTER TABLE songs ADD COLUMN track TEXT'); } catch (_) {}
}
},
);
}
@@ -361,12 +369,14 @@ class DbHelper {
});
}
Future<void> metadatenAktualisieren(int songId, {String? titel, String? kuenstler, String? album}) async {
Future<void> metadatenAktualisieren(int songId, {String? titel, String? kuenstler, String? album, String? jahr, String? genre}) async {
final d = await db;
final update = <String, dynamic>{};
if (titel != null) update['titel'] = titel;
if (kuenstler != null) update['kuenstler'] = kuenstler;
if (album != null) update['album'] = album;
if (jahr != null) update['jahr'] = jahr;
if (genre != null) update['genre'] = genre;
if (update.isNotEmpty) {
await d.update('songs', update, where: 'id = ?', whereArgs: [songId]);
}