From 9d14517202d5c9d993a947808bf0c6520ed54ea3 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 10 Jun 2023 22:15:23 +0600 Subject: [PATCH] feat: reactive volume slider and slicker bottom bar with lowered height --- lib/collections/spotube_icons.dart | 4 + .../player/player_track_details.dart | 4 +- lib/components/root/bottom_player.dart | 155 ++++++++++-------- lib/themes/theme.dart | 1 + 4 files changed, 91 insertions(+), 73 deletions(-) diff --git a/lib/collections/spotube_icons.dart b/lib/collections/spotube_icons.dart index 1fce30ec8..612f23a1e 100644 --- a/lib/collections/spotube_icons.dart +++ b/lib/collections/spotube_icons.dart @@ -82,4 +82,8 @@ abstract class SpotubeIcons { static const piped = FeatherIcons.cloud; static const magic = Icons.auto_fix_high_outlined; static const selectionCheck = Icons.checklist_rounded; + static const volumeHigh = FeatherIcons.volume2; + static const volumeMedium = FeatherIcons.volume1; + static const volumeLow = FeatherIcons.volume; + static const volumeMute = FeatherIcons.volumeX; } diff --git a/lib/components/player/player_track_details.dart b/lib/components/player/player_track_details.dart index b44a6d225..5ffaae902 100644 --- a/lib/components/player/player_track_details.dart +++ b/lib/components/player/player_track_details.dart @@ -26,8 +26,8 @@ class PlayerTrackDetails extends HookConsumerWidget { Container( padding: const EdgeInsets.all(6), constraints: const BoxConstraints( - maxWidth: 70, - maxHeight: 70, + maxWidth: 80, + maxHeight: 80, ), child: ClipRRect( borderRadius: BorderRadius.circular(4), diff --git a/lib/components/root/bottom_player.dart b/lib/components/root/bottom_player.dart index d1c9ca625..6f9a7647d 100644 --- a/lib/components/root/bottom_player.dart +++ b/lib/components/root/bottom_player.dart @@ -71,90 +71,103 @@ class BottomPlayer extends HookConsumerWidget { type: MaterialType.transparency, textStyle: theme.textTheme.bodyMedium!, child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded(child: PlayerTrackDetails(albumArt: albumArt)), // controls Flexible( flex: 3, - child: PlayerControls(), + child: Padding( + padding: const EdgeInsets.only(top: 5), + child: PlayerControls(), + ), ), // add to saved tracks - Expanded( - flex: 1, - child: Wrap( - alignment: WrapAlignment.center, - runAlignment: WrapAlignment.center, - children: [ - Container( - height: 20, - constraints: const BoxConstraints(maxWidth: 200), - child: HookBuilder(builder: (context) { - final volumeState = - useStream(audioPlayer.volumeStream).data ?? - audioPlayer.volume; - final volume = useState(volumeState); - - useEffect(() { - if (volume.value != volumeState) { - volume.value = volumeState; + Column( + children: [ + PlayerActions( + extraActions: [ + IconButton( + tooltip: context.l10n.mini_player, + icon: const Icon(SpotubeIcons.miniPlayer), + onPressed: () async { + await DesktopTools.window.setMinimumSize( + const Size(300, 300), + ); + await DesktopTools.window.setAlwaysOnTop(true); + if (!kIsLinux) { + await DesktopTools.window.setHasShadow(false); } - return null; - }, [volumeState]); + await DesktopTools.window + .setAlignment(Alignment.topRight); + await DesktopTools.window + .setSize(const Size(400, 500)); + await Future.delayed( + const Duration(milliseconds: 100), + () async { + GoRouter.of(context).go('/mini-player'); + }, + ); + }, + ), + ], + ), + Container( + height: 40, + constraints: const BoxConstraints(maxWidth: 250), + child: HookBuilder(builder: (context) { + final volume = + useStream(audioPlayer.volumeStream).data ?? + audioPlayer.volume; - return Listener( - onPointerSignal: (event) async { - if (event is PointerScrollEvent) { - if (event.scrollDelta.dy > 0) { - final value = volume.value - .2; - audioPlayer.setVolume(value < 0 ? 0 : value); + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + IconButton( + icon: Icon( + volume == 0 + ? SpotubeIcons.volumeMute + : volume <= 0.2 + ? SpotubeIcons.volumeLow + : volume <= 0.6 + ? SpotubeIcons.volumeMedium + : SpotubeIcons.volumeHigh, + size: 16, + ), + onPressed: () { + if (volume == 0) { + audioPlayer.setVolume(1); } else { - final value = volume.value + .2; - audioPlayer.setVolume(value > 1 ? 1 : value); + audioPlayer.setVolume(0); } - } - }, - child: Slider( - min: 0, - max: 1, - value: volume.value, - onChanged: (v) { - volume.value = v; }, - onChangeEnd: audioPlayer.setVolume, ), - ); - }), - ), - PlayerActions( - extraActions: [ - IconButton( - tooltip: context.l10n.mini_player, - icon: const Icon(SpotubeIcons.miniPlayer), - onPressed: () async { - await DesktopTools.window.setMinimumSize( - const Size(300, 300), - ); - await DesktopTools.window.setAlwaysOnTop(true); - if (!kIsLinux) { - await DesktopTools.window.setHasShadow(false); - } - await DesktopTools.window - .setAlignment(Alignment.topRight); - await DesktopTools.window - .setSize(const Size(400, 500)); - await Future.delayed( - const Duration(milliseconds: 100), - () async { - GoRouter.of(context).go('/mini-player'); - }, - ); - }, - ), - ], - ) - ], - ), + Listener( + onPointerSignal: (event) async { + if (event is PointerScrollEvent) { + if (event.scrollDelta.dy > 0) { + final value = volume - .2; + audioPlayer + .setVolume(value < 0 ? 0 : value); + } else { + final value = volume + .2; + audioPlayer + .setVolume(value > 1 ? 1 : value); + } + } + }, + child: Slider( + min: 0, + max: 1, + value: volume, + onChanged: audioPlayer.setVolume, + ), + ), + ], + ); + }), + ) + ], ) ], ), diff --git a/lib/themes/theme.dart b/lib/themes/theme.dart index c3b648a80..036af9a76 100644 --- a/lib/themes/theme.dart +++ b/lib/themes/theme.dart @@ -48,5 +48,6 @@ ThemeData theme(Color seed, Brightness brightness) { backgroundColor: scheme.onSurface, contentTextStyle: TextStyle(color: scheme.surface), ), + sliderTheme: SliderThemeData(overlayShape: SliderComponentShape.noOverlay), ); }