WanderndesCover ersetzt Hero-Übergang: Cover wandert live mit progress

This commit is contained in:
Hermes (Server)
2026-08-29 14:50:40 +02:00
parent 9d0cb90a51
commit a1eb5831e0
4 changed files with 161 additions and 12 deletions
+43
View File
@@ -325,6 +325,22 @@ class _HomeShellState extends State<HomeShell>
},
child: const NowPlayingScreen(),
),
StreamBuilder<MediaItem?>(
stream: context.read<MeloAudioHandler>().mediaItem,
builder: (context, snapshot) {
final item = snapshot.data;
if (item == null) return const SizedBox.shrink();
return AnimatedBuilder(
animation: _expansion,
builder: (context, child) => WanderndesCover(
progress: _expansion.progress,
artUri: item.artUri,
miniRect: _miniCoverRect(context),
vollbildRect: _vollbildCoverRect(context),
),
);
},
),
],
),
// Haarlinie darüber: ohne sie geht die Leiste auf schwarzem Grund
@@ -377,4 +393,31 @@ class _HomeShellState extends State<HomeShell>
}
Rect _vollbildRect(BuildContext context) => Offset.zero & MediaQuery.sizeOf(context);
/// Feste 52×52-Größe, linksbündig mit MeloSpace.md-Abstand, vertikal
/// mittig in MiniPlayer.hoehe — Werte aus mini_player.dart übernommen
/// (dortiges Cover entfällt, siehe Task 6 Step 5).
Rect _miniCoverRect(BuildContext context) {
final mini = _miniRect(context);
const seite = 52.0;
final top = mini.top + (MiniPlayer.hoehe - seite) / 2;
return Rect.fromLTWH(mini.left + MeloSpace.md, top, seite, seite);
}
/// Nicht per Formel bestimmbar (Review-Panel-Fund): `_CoverPlatzhalter`
/// sitzt in NowPlayingScreens eigenem responsivem LayoutBuilder — die
/// tatsächliche Position wird stattdessen gemessen, siehe
/// coverPlatzhalterKey.
Rect _vollbildCoverRect(BuildContext context) {
final box = coverPlatzhalterKey.currentContext?.findRenderObject() as RenderBox?;
if (box == null || !box.hasSize) {
// Vor dem ersten Layout (z.B. ganz am Anfang, progress noch 0) —
// Notlösung: Platzhalter mittig im Vollbild-Rechteck annehmen, bis
// der erste Frame mit progress > 0 eine echte Messung liefert.
final voll = _vollbildRect(context);
final seite = voll.width - 48;
return Rect.fromLTWH(voll.left + 24, voll.top + 80, seite, seite);
}
return box.localToGlobal(Offset.zero) & box.size;
}
}