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:
Hermes (Server)
2026-07-31 15:42:54 +02:00
parent b3aedc53f9
commit 8b6a04ead8
18 changed files with 767 additions and 503 deletions
+13 -2
View File
@@ -1,7 +1,9 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';
import '../services/player_service.dart';
import '../models/song.dart';
import '../utils/farb_theme.dart';
class MiniPlayer extends StatefulWidget {
@@ -18,6 +20,7 @@ class _MiniPlayerState extends State<MiniPlayer> {
bool _spielt = false;
StreamSubscription<Duration>? _posSub;
StreamSubscription<PlayerState>? _stateSub;
StreamSubscription<Song?>? _songSub;
@override
void initState() {
@@ -36,12 +39,17 @@ class _MiniPlayerState extends State<MiniPlayer> {
});
}
});
// Sofortige UI-Aktualisierung bei jedem Songwechsel
_songSub = _player.onSongWechsel.listen((_) {
if (mounted) setState(() {});
});
}
@override
void dispose() {
_posSub?.cancel();
_stateSub?.cancel();
_songSub?.cancel();
super.dispose();
}
@@ -52,6 +60,7 @@ class _MiniPlayerState extends State<MiniPlayer> {
final progress = _dauer.inSeconds > 0
? _position.inSeconds / _dauer.inSeconds : 0.0;
final hatCover = song.coverPfad != null && File(song.coverPfad!).existsSync();
return Container(
margin: const EdgeInsets.symmetric(horizontal: 16),
@@ -67,13 +76,15 @@ class _MiniPlayerState extends State<MiniPlayer> {
padding: const EdgeInsets.fromLTRB(12, 10, 12, 6),
child: Row(
children: [
// Cover
// Cover mit Fallback auf Notensymbol
ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Container(
width: 36, height: 36,
color: MeloTheme.rot,
child: const Center(child: Text('', style: TextStyle(fontSize: 16))),
child: hatCover
? Image.file(File(song.coverPfad!), fit: BoxFit.cover)
: const Center(child: Text('', style: TextStyle(fontSize: 16))),
),
),
const SizedBox(width: 10),