Kategorien (mehrere je Song), Metadaten-Ansicht mit Expertenmodus
- DB-Schema 4: Tabelle song_categories + Spalte categories_edited - Kategorien kommen aus dem Genre-Tag (Trennung an ; , | /), manuell bearbeitbar; von Hand gesetzte Kategorien ueberlebt der naechste Scan - Songzeile zeigt "Kuenstler | Kategorie1 - Kategorie2" - Einstellung "Gleiche Kategorie = gleiches Coverbild" (Standard an) - Metadaten-Sheet mit ausklappbarem Expertenmodus - Neu: categories.dart, category_service.dart, song_detail_sheet.dart, app_settings.dart Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011snPXPafPC5i87o68H14W7
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'categories.dart';
|
||||
import 'database.dart';
|
||||
|
||||
/// Hält die Kategorien aller Songs und das daraus abgeleitete Cover je
|
||||
/// Kategorie an einer Stelle — sonst müsste jede Liederliste beide Streams
|
||||
/// selbst beobachten und die Cover-Zuordnung könnte je Liste abweichen.
|
||||
class CategoryService extends ChangeNotifier {
|
||||
CategoryService(this._db) {
|
||||
_songs = _db.watchSongs().listen((songs) {
|
||||
_allSongs = songs;
|
||||
_recompute();
|
||||
});
|
||||
_categories = _db.watchCategoriesBySong().listen((byId) {
|
||||
_byId = byId;
|
||||
_recompute();
|
||||
});
|
||||
}
|
||||
|
||||
final MeloDb _db;
|
||||
late final StreamSubscription<List<Song>> _songs;
|
||||
late final StreamSubscription<Map<String, List<String>>> _categories;
|
||||
|
||||
List<Song> _allSongs = const [];
|
||||
Map<String, List<String>> _byId = const {};
|
||||
Map<String, String> _covers = const {};
|
||||
|
||||
/// Kategorien eines Songs in gespeicherter Reihenfolge.
|
||||
List<String> of(String songId) => _byId[songId] ?? const [];
|
||||
|
||||
/// Das anzuzeigende Cover eines Songs unter Berücksichtigung der
|
||||
/// Einstellung "Gleiche Kategorie = gleiches Coverbild".
|
||||
String? coverFor(Song song, {required bool groupByCategory}) {
|
||||
return effectiveCover(song, of(song.id), _covers,
|
||||
groupByCategory: groupByCategory);
|
||||
}
|
||||
|
||||
Future<void> setCategories(String songId, List<String> names) =>
|
||||
_db.setCategories(songId, names, byUser: true);
|
||||
|
||||
Future<List<String>> allNames() => _db.allCategoryNames();
|
||||
|
||||
void _recompute() {
|
||||
_covers = categoryCovers(_allSongs, _byId);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_songs.cancel();
|
||||
_categories.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user