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:
@@ -8,9 +8,12 @@ import '../models/playlist.dart';
|
||||
import '../utils/farb_theme.dart';
|
||||
import '../utils/user_effekte.dart';
|
||||
import '../services/cloud_service.dart';
|
||||
import '../services/favoriten_service.dart';
|
||||
import '../widgets/mini_player.dart';
|
||||
import '../widgets/melo_header.dart';
|
||||
import '../widgets/statistik_card.dart';
|
||||
import '../widgets/recent_widget.dart';
|
||||
import '../widgets/tag_stats_widget.dart';
|
||||
import '../widgets/tag_leiste.dart';
|
||||
import '../widgets/song_tile.dart';
|
||||
import '../widgets/navidrome_browser.dart';
|
||||
@@ -35,6 +38,7 @@ class _MeloHomeState extends State<MeloHome> {
|
||||
int _aktiverTab = 0;
|
||||
|
||||
String _nutzer = 'Baka'; // Aktueller Nutzer
|
||||
final Future<int> _favoritenZahl = FavoritenService().anzahlFavoriten();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -106,6 +110,8 @@ class _MeloHomeState extends State<MeloHome> {
|
||||
Future<void> _zeigeProfil() async {
|
||||
final p = await SharedPreferences.getInstance();
|
||||
final modus = p.getString('melo_modus') ?? 'cloud';
|
||||
// Cloud-Count VOR dem Dialog auflösen (sonst stünde "Instance of Future" da)
|
||||
final cloudCount = await _cloud.status();
|
||||
if (!mounted) return;
|
||||
showDialog(
|
||||
context: context,
|
||||
@@ -120,7 +126,7 @@ class _MeloHomeState extends State<MeloHome> {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_profilZeile(Icons.music_note, 'Lieder auf Gerät', '${_vm.songs.length}'),
|
||||
_profilZeile(Icons.cloud, 'Cloud-Server', '${_cloud.status().then((s) => s?['total'] ?? 0)}'),
|
||||
_profilZeile(Icons.cloud, 'Cloud-Server', '${cloudCount?['total'] ?? 0}'),
|
||||
const Divider(color: MeloTheme.dunkel2),
|
||||
// Später von "nur lokal" auf Cloud wechseln – jederzeit möglich
|
||||
if (modus == 'lokal') ...[
|
||||
@@ -543,6 +549,16 @@ class _MeloHomeState extends State<MeloHome> {
|
||||
MeloHeader(onDownload: _zeigeDownloadDialog, onSearch: _zeigeSuche, onServer: _zeigeProfil, onSettings: _zeigeEinstellungen),
|
||||
if (_vm.zeigeBotschaft) _botschaftBanner(),
|
||||
_tagBereich(),
|
||||
FutureBuilder<int>(
|
||||
future: _favoritenZahl,
|
||||
builder: (context, snap) => StatistikCard(
|
||||
anzahlSongs: _vm.songs.length,
|
||||
gesamtMB: gesamtMB,
|
||||
gesamtMin: gesamtMin,
|
||||
anzahlFavoriten: snap.data ?? 0,
|
||||
),
|
||||
),
|
||||
RecentWidget(songs: _vm.letzteSongs, onPlay: _vm.spieleSong),
|
||||
Expanded(child: _songListe()),
|
||||
const MiniPlayer(),
|
||||
const SizedBox(height: 8),
|
||||
@@ -803,13 +819,42 @@ class _MeloHomeState extends State<MeloHome> {
|
||||
Widget _tagBereich() {
|
||||
return AnimatedSize(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: _tagsOffen
|
||||
? TagLeiste(
|
||||
child: Column(
|
||||
children: [
|
||||
// Toggle-Kopf: Tag-Leiste ein-/ausklappen (war vorher unerreichbar!)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.label_outline,
|
||||
size: 14, color: MeloTheme.textSekundaer),
|
||||
const SizedBox(width: 6),
|
||||
Text('Tags & Filter',
|
||||
style: const TextStyle(
|
||||
color: MeloTheme.textSekundaer, fontSize: 12)),
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
icon: Icon(
|
||||
_tagsOffen ? Icons.expand_less : Icons.expand_more,
|
||||
size: 18,
|
||||
color: MeloTheme.textSekundaer),
|
||||
onPressed: () => setState(() => _tagsOffen = !_tagsOffen),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (_tagsOffen) ...[
|
||||
TagLeiste(
|
||||
tags: _vm.tags,
|
||||
aktiveTags: _vm.aktiveTags,
|
||||
onTagToggled: _vm.toggleTag,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TagStatsWidget(tagCounts: _vm.tagCounts),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user