Mini-Player-Wischgeste steuert PlayerExpansionController statt lokalen Versatz

This commit is contained in:
Hermes (Server)
2026-08-29 14:54:05 +02:00
parent a1eb5831e0
commit 92148bc97c
+30 -40
View File
@@ -4,7 +4,7 @@ import 'package:provider/provider.dart';
import '../shared/theme.dart'; import '../shared/theme.dart';
import 'audio_handler.dart'; import 'audio_handler.dart';
import 'now_playing_screen.dart'; import 'player_expansion_controller.dart';
import 'wischen.dart'; import 'wischen.dart';
/// Kompakte Wiedergabe-Leiste über der Bottom-Nav. /// Kompakte Wiedergabe-Leiste über der Bottom-Nav.
@@ -52,23 +52,20 @@ class _Leiste extends StatefulWidget {
} }
class _LeisteState extends State<_Leiste> { class _LeisteState extends State<_Leiste> {
/// Wie weit der Finger die Leiste gerade zieht — nur zur Anzeige, die /// Für die horizontale Titel-Wechsel-Geste (unverändert).
/// eigentliche Entscheidung fällt erst bei [onVerticalDragEnd]/ double _horizontalVersatz = 0;
/// [onHorizontalDragEnd]. `dy` bleibt <= 0: nach unten ist unbelegt, ein bool _ziehtHorizontalGerade = false;
/// Mitführen dorthin würde Wirkung vortäuschen, die es nicht gibt.
Offset _versatz = Offset.zero;
bool _ziehtGerade = false;
void _oeffne(BuildContext context) => Navigator.of(context).push( /// Rohe, aufsummierte vertikale Zugstrecke seit Gestenbeginn — exakt wie
MaterialPageRoute(builder: (_) => const NowPlayingScreen()), /// bisher `_versatz.dy`, nur ohne die Optik-Verantwortung (die liegt jetzt
); /// im PlayerExpansionController). Wird für [PlayerExpansionController.
/// dragEnd] gebraucht, das dieselbe rohe Strecke wie wischen.dart erwartet;
/// aus `progress` ließe sich das wegen des Clampings nicht mehr exakt
/// zurückrechnen.
double _vertikaleStrecke = 0;
void _zurueckschnappen() { void _oeffne(BuildContext context) =>
setState(() { context.read<PlayerExpansionController>().open(context);
_ziehtGerade = false;
_versatz = Offset.zero;
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -87,30 +84,26 @@ class _LeisteState extends State<_Leiste> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
GestureDetector( GestureDetector(
// Wischen wie in jeder anderen Musik-App: nach oben öffnet die onVerticalDragStart: (_) => _vertikaleStrecke = 0,
// Vollbild-Wiedergabe, seitwärts wechselt den Titel. Die Leiste onVerticalDragUpdate: (details) {
// folgt dabei sichtbar dem Finger — sonst blieb ein _vertikaleStrecke += details.delta.dy;
// bedächtiges, aber weites Wischen (unter der Schwung-Schwelle) context.read<PlayerExpansionController>().dragBy(details.delta.dy);
// ganz ohne Reaktion.
onVerticalDragUpdate: (details) => setState(() {
_ziehtGerade = true;
final dy = _versatz.dy + details.delta.dy;
_versatz = Offset(_versatz.dx, dy > 0 ? 0 : dy);
}),
onVerticalDragEnd: (details) {
final oeffnet = oeffnetVollbildMitStrecke(
_versatz.dy, details.velocity.pixelsPerSecond.dy);
_zurueckschnappen();
if (oeffnet) _oeffne(context);
}, },
onVerticalDragEnd: (details) => context
.read<PlayerExpansionController>()
.dragEnd(context, _vertikaleStrecke,
details.velocity.pixelsPerSecond.dy),
onHorizontalDragUpdate: (details) => setState(() { onHorizontalDragUpdate: (details) => setState(() {
_ziehtGerade = true; _ziehtHorizontalGerade = true;
_versatz = Offset(_versatz.dx + details.delta.dx, _versatz.dy); _horizontalVersatz += details.delta.dx;
}), }),
onHorizontalDragEnd: (details) { onHorizontalDragEnd: (details) {
final wechsel = titelWechselMitStrecke( final wechsel = titelWechselMitStrecke(
_versatz.dx, details.velocity.pixelsPerSecond.dx); _horizontalVersatz, details.velocity.pixelsPerSecond.dx);
_zurueckschnappen(); setState(() {
_ziehtHorizontalGerade = false;
_horizontalVersatz = 0;
});
switch (wechsel) { switch (wechsel) {
case Wechsel.naechster: case Wechsel.naechster:
handler.skipToNext(); handler.skipToNext();
@@ -123,14 +116,11 @@ class _LeisteState extends State<_Leiste> {
child: InkWell( child: InkWell(
onTap: () => _oeffne(context), onTap: () => _oeffne(context),
child: AnimatedContainer( child: AnimatedContainer(
// Während des Ziehens sofort folgen (keine Verzögerung); duration: _ziehtHorizontalGerade
// beim Loslassen ohne Wirkung sichtbar zurückschnappen.
duration: _ziehtGerade
? Duration.zero ? Duration.zero
: MeloMotion.ruhig(context, MeloMotion.normal), : MeloMotion.ruhig(context, MeloMotion.normal),
curve: MeloMotion.curve, curve: MeloMotion.curve,
transform: transform: Matrix4.translationValues(_horizontalVersatz, 0, 0),
Matrix4.translationValues(_versatz.dx, _versatz.dy, 0),
height: MiniPlayer.hoehe, height: MiniPlayer.hoehe,
child: Row( child: Row(
children: [ children: [