Mini-Player-Wischgeste steuert PlayerExpansionController statt lokalen Versatz
This commit is contained in:
+30
-40
@@ -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: [
|
||||||
|
|||||||
Reference in New Issue
Block a user