Files
Melo/lib/library/category_service.dart
T
dustinandClaude Opus 5 7aa98864aa 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
2026-08-20 18:29:45 +02:00

58 lines
1.7 KiB
Dart

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();
}
}