v2.50.4 — Glow-Pulsation rebuildet + Cover-Crossfade beim Songwechsel
## Fix 1 (MED): Glow-Pulsation rebuildet jetzt wirklich
- now_playing_screen.dart: Cover-Container mit AnimatedBuilder(animation: _glowController) gewrappt — BoxShadow (blur 50–70 / spread 6–12) wird jetzt pro Animations-Tick neu gebaut statt nur bei fremden setStates (Pulsation war vorher nur zufällig über positionStream sichtbar und fror bei Pause/Pufferung ein)
## Fix 2 (MED): Echter Crossfade beim Songwechsel
- _songSub-Listener setzt _hatCover/_coverPfad jetzt SYNCHRON auf false/null (im selben setState) — Hintergrund und Front-Cover zeigen beim Songwechsel kein altes Cover mehr, bis die async Existenz-Prüfung durch ist
- _hintergrundBlur-Key auf den tatsächlichen Cover-Pfad gelegt ('cover-$pfad' statt song.id) — Switcher wechselt erst bei geladenem neuem Cover (Crossfade Gradient→Cover), kein Fade alt→alt + harter Cut mehr
flutter analyze: 0 Issues, Tests 98/98 grün, keine neuen Packages
This commit is contained in:
@@ -91,6 +91,12 @@ class _NowPlayingScreenState extends State<NowPlayingScreen>
|
||||
_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<NowPlayingScreen>
|
||||
);
|
||||
}
|
||||
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<NowPlayingScreen>
|
||||
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),
|
||||
|
||||
Reference in New Issue
Block a user