From 4ffd42d3ff69d8b98d2246897cec3c8dddb3469d Mon Sep 17 00:00:00 2001 From: Valeri Gokadze Date: Sun, 17 Dec 2023 14:38:53 +0400 Subject: [PATCH] Improve: Improved mini player (swipe up to expand) --- .../metadata/android/en-US/changelogs/74.txt | 10 ++ lib/widgets/mini_player.dart | 149 +++++++++--------- 2 files changed, 85 insertions(+), 74 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/74.txt diff --git a/fastlane/metadata/android/en-US/changelogs/74.txt b/fastlane/metadata/android/en-US/changelogs/74.txt new file mode 100644 index 000000000..a4cccc5a7 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/74.txt @@ -0,0 +1,10 @@ +Bug fixes + + + + +Enhancements + +- Improved mini player (swipe up to expand) +- Update Portuguese translation +- Made various quality and performance improvements for app stability and speed \ No newline at end of file diff --git a/lib/widgets/mini_player.dart b/lib/widgets/mini_player.dart index 106310356..ce81e8fda 100644 --- a/lib/widgets/mini_player.dart +++ b/lib/widgets/mini_player.dart @@ -5,59 +5,54 @@ import 'package:flutter/material.dart'; import 'package:musify/main.dart'; import 'package:musify/screens/now_playing_page.dart'; import 'package:musify/style/app_themes.dart'; +import 'package:musify/widgets/marque.dart'; import 'package:musify/widgets/no_artwork_cube.dart'; -class MiniPlayer extends StatelessWidget { +class MiniPlayer extends StatefulWidget { MiniPlayer({required this.metadata}); final MediaItem metadata; + @override + _MiniPlayerState createState() => _MiniPlayerState(); +} + +class _MiniPlayerState extends State { @override Widget build(BuildContext context) { - return Container( - height: 75, - decoration: BoxDecoration( - color: colorScheme.onSecondary, - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(18), - topRight: Radius.circular(18), - ), - ), - child: Row( - children: [ - _buildExpandButton(context), - _buildArtwork(), - _buildMetadata(), - const Spacer(), - StreamBuilder( - stream: audioHandler.playbackState, - builder: (context, snapshot) { - return Padding( - padding: const EdgeInsets.only(right: 8), - child: _buildPlaybackIconButton(snapshot.data), - ); - }, + return GestureDetector( + onVerticalDragUpdate: (details) { + if (details.primaryDelta! < 0) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const NowPlayingPage(), + ), + ); + } + }, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 12), + height: 75, + decoration: BoxDecoration( + color: colorScheme.onSecondary, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(18), + topRight: Radius.circular(18), ), - ], - ), - ); - } - - Widget _buildExpandButton(BuildContext context) { - return IconButton( - padding: const EdgeInsets.symmetric(horizontal: 15), - icon: Icon( - FluentIcons.arrow_up_24_filled, - size: 22, - color: Theme.of(context).colorScheme.primary, + ), + child: Row( + children: [ + _buildArtwork(), + _buildMetadata(), + StreamBuilder( + stream: audioHandler.playbackState, + builder: (context, snapshot) { + return _buildPlaybackIconButton(snapshot.data); + }, + ), + ], + ), ), - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const NowPlayingPage(), - ), - ); - }, ); } @@ -67,7 +62,7 @@ class MiniPlayer extends StatelessWidget { child: ClipRRect( borderRadius: BorderRadius.circular(8), child: CachedNetworkImage( - imageUrl: metadata.artUri.toString(), + imageUrl: widget.metadata.artUri.toString(), fit: BoxFit.cover, width: 55, height: 55, @@ -80,34 +75,37 @@ class MiniPlayer extends StatelessWidget { } Widget _buildMetadata() { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - _truncateText(metadata.title, 15), - style: TextStyle( - color: colorScheme.primary, - fontSize: 17, - fontWeight: FontWeight.w600, - ), + return Flexible( + child: Padding( + padding: const EdgeInsets.only(right: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + MarqueeWidget( + child: Text( + widget.metadata.title, + style: TextStyle( + color: colorScheme.primary, + fontSize: 17, + fontWeight: FontWeight.w600, + ), + ), + ), + MarqueeWidget( + child: Text( + widget.metadata.artist.toString(), + style: TextStyle( + color: colorScheme.primary, + fontSize: 15, + ), + ), + ), + ], ), - Text( - _truncateText(metadata.artist.toString(), 15), - style: TextStyle( - color: colorScheme.primary, - fontSize: 15, - ), - ), - ], + ), ); } - - String _truncateText(String text, int maxLength) { - return text.length > maxLength - ? '${text.substring(0, maxLength)}...' - : text; - } } Widget _buildPlaybackIconButton(PlaybackState? playerState) { @@ -132,10 +130,13 @@ Widget _buildPlaybackIconButton(PlaybackState? playerState) { onPressed = () => audioHandler.seek(Duration.zero); } - return IconButton( - icon: Icon(icon, color: colorScheme.primary), - iconSize: 45, - onPressed: onPressed, + return InkWell( + onTap: onPressed, splashColor: Colors.transparent, + child: Icon( + icon, + color: colorScheme.primary, + size: 40, + ), ); }