diff --git a/lib/screens/now_playing_screen.dart b/lib/screens/now_playing_screen.dart index f8ff20c..64e9371 100644 --- a/lib/screens/now_playing_screen.dart +++ b/lib/screens/now_playing_screen.dart @@ -91,6 +91,12 @@ class _NowPlayingScreenState extends State _zeigeLyrics = false; _lyrics = null; _lyricsLaden = true; + // Cover-Zustand SYNCHRON zurücksetzen: Sonst rendern Hintergrund + // (und Front-Cover) beim Songwechsel kurz das ALTE Cover, bis die + // async Existenz-Prüfung durch ist — der Switcher-Key (song.id) + // wechselt sofort → Fade alt→alt, dann harter Cut aufs neue Cover. + _hatCover = false; + _coverPfad = null; }); _ladeLyricsFuer(song, _ladeGeneration); _ladeFavoritStatus(song); @@ -567,7 +573,11 @@ class _NowPlayingScreenState extends State ); } return ImageFiltered( - key: ValueKey('cover-${song?.id ?? pfad}'), + // Key auf den tatsächlichen Cover-Pfad statt song.id: Der Switcher + // wechselt erst, wenn das NEUE Cover wirklich geladen ist (echter + // Crossfade) — nie vorher (altes Bild unter neuem Key = unsichtbarer + // Fade + harter Cut beim Nachladen). + key: ValueKey('cover-$pfad'), imageFilter: ImageFilter.blur(sigmaX: 45, sigmaY: 45), child: Image.file(File(pfad), fit: BoxFit.cover), ); @@ -636,30 +646,35 @@ class _NowPlayingScreenState extends State mainAxisAlignment: MainAxisAlignment.center, children: [ const SizedBox(height: 16), - // Cover mit Glow - Container( - width: coverGroesse, - height: coverGroesse, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - boxShadow: [ - BoxShadow( - // Glow in der Akzentfarbe des Users, pulsierend bei Wiedergabe - color: MeloTheme.akzent.withValues(alpha: 0.45), - blurRadius: 50 + 20 * _glowController.value, // 50–70 - spreadRadius: 6 + 6 * _glowController.value, // 6–12 - ), - ], - ), - child: ClipRRect( - borderRadius: BorderRadius.circular(20), - child: hatCover - ? Image.file(File(_coverPfad!), fit: BoxFit.cover) - : Container( - color: MeloTheme.rotHell, - child: const Icon(Icons.music_note, - size: 90, color: MeloTheme.rot), - ), + // Cover mit Glow — AnimatedBuilder um den Container: Ohne Listener/ + // Builder würde der BoxShadow nur bei fremden setStates neu gebaut + // (Pulsation zufällig sichtbar, friert bei Pause/Pufferung ein). + AnimatedBuilder( + animation: _glowController, + builder: (context, _) => Container( + width: coverGroesse, + height: coverGroesse, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + // Glow in der Akzentfarbe des Users, pulsierend bei Wiedergabe + color: MeloTheme.akzent.withValues(alpha: 0.45), + blurRadius: 50 + 20 * _glowController.value, // 50–70 + spreadRadius: 6 + 6 * _glowController.value, // 6–12 + ), + ], + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(20), + child: hatCover + ? Image.file(File(_coverPfad!), fit: BoxFit.cover) + : Container( + color: MeloTheme.rotHell, + child: const Icon(Icons.music_note, + size: 90, color: MeloTheme.rot), + ), + ), ), ), const SizedBox(height: 30),