diff --git a/lib/modules/player/sibling_tracks_sheet.dart b/lib/modules/player/sibling_tracks_sheet.dart index 14773156..6f9763b6 100644 --- a/lib/modules/player/sibling_tracks_sheet.dart +++ b/lib/modules/player/sibling_tracks_sheet.dart @@ -10,6 +10,7 @@ import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart'; import 'package:spotube/components/ui/button_tile.dart'; import 'package:spotube/extensions/artist_simple.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/duration.dart'; import 'package:spotube/hooks/utils/use_debounce.dart'; @@ -193,7 +194,11 @@ class SiblingTracksSheet extends HookConsumerWidget { if (!isFetchingActiveTrack && sourceInfo.id != (activeTrack as SourcedTrack).sourceInfo.id) { activeTrackNotifier.swapSibling(sourceInfo); - closeDrawer(context); + if (MediaQuery.sizeOf(context).mdAndUp) { + closeOverlay(context); + } else { + closeDrawer(context); + } } }, ); diff --git a/lib/pages/lyrics/mini_lyrics.dart b/lib/pages/lyrics/mini_lyrics.dart index 8f6ec1fc..9fd54ad6 100644 --- a/lib/pages/lyrics/mini_lyrics.dart +++ b/lib/pages/lyrics/mini_lyrics.dart @@ -1,13 +1,12 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:gap/gap.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:palette_generator/palette_generator.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/modules/player/player_controls.dart'; import 'package:spotube/modules/player/player_queue.dart'; -import 'package:spotube/modules/root/sidebar.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/hooks/utils/use_force_update.dart'; import 'package:spotube/pages/lyrics/plain_lyrics.dart'; @@ -30,6 +29,8 @@ class MiniLyricsPage extends HookConsumerWidget { final playlistQueue = ref.watch(audioPlayerProvider); + final index = useState(0); + final areaActive = useState(false); final hoverMode = useState(true); final showLyrics = useState(true); @@ -43,8 +44,6 @@ class MiniLyricsPage extends HookConsumerWidget { return null; }, []); - - return MouseRegion( onEnter: !hoverMode.value ? null @@ -56,12 +55,11 @@ class MiniLyricsPage extends HookConsumerWidget { : (event) { areaActive.value = false; }, - child: DefaultTabController( - length: 2, - child: Scaffold( - backgroundColor: theme.colorScheme.surface.withOpacity(0.4), - appBar: PreferredSize( - preferredSize: const Size.fromHeight(60), + child: Scaffold( + backgroundColor: theme.colorScheme.background.withOpacity(0.4), + headers: [ + Padding( + padding: const EdgeInsets.all(8.0), child: AnimatedCrossFade( duration: const Duration(milliseconds: 200), crossFadeState: areaActive.value @@ -70,91 +68,90 @@ class MiniLyricsPage extends HookConsumerWidget { secondChild: const SizedBox(), firstChild: DragToMoveArea( child: Row( + spacing: 2, children: [ const Gap(10), - if (!kIsMacOS) - SizedBox( - height: 30, - width: 30, - child: Sidebar.brandLogo(), - ), - const Spacer(), + if (kIsMacOS) const SizedBox(width: 65), if (showLyrics.value) - SizedBox( - height: 30, - child: TabBar( - tabs: [ - Tab(text: context.l10n.synced), - Tab(text: context.l10n.plain), - ], - isScrollable: true, - ), + Tabs( + index: index.value, + onChanged: (i) { + index.value = i; + }, + tabs: [ + Text(context.l10n.synced), + Text(context.l10n.plain), + ], ), const Spacer(), - IconButton( - tooltip: context.l10n.lyrics, - icon: showLyrics.value - ? const Icon(SpotubeIcons.lyrics) - : const Icon(SpotubeIcons.lyricsOff), - style: ButtonStyle( - foregroundColor: showLyrics.value - ? WidgetStateProperty.all(theme.colorScheme.primary) - : null, - ), - onPressed: () async { - showLyrics.value = !showLyrics.value; - areaActive.value = true; - hoverMode.value = false; + Tooltip( + tooltip: + TooltipContainer(child: Text(context.l10n.lyrics)), + child: IconButton( + variance: showLyrics.value + ? ButtonVariance.secondary + : ButtonVariance.ghost, + icon: showLyrics.value + ? const Icon(SpotubeIcons.lyrics) + : const Icon(SpotubeIcons.lyricsOff), + onPressed: () async { + showLyrics.value = !showLyrics.value; + areaActive.value = true; + hoverMode.value = false; - if (kIsDesktop) { - await windowManager.setSize( - showLyrics.value - ? const Size(400, 500) - : const Size(400, 150), - ); - } - }, - ), - IconButton( - tooltip: context.l10n.show_hide_ui_on_hover, - icon: hoverMode.value - ? const Icon(SpotubeIcons.hoverOn) - : const Icon(SpotubeIcons.hoverOff), - style: ButtonStyle( - foregroundColor: hoverMode.value - ? WidgetStateProperty.all(theme.colorScheme.primary) - : null, + if (kIsDesktop) { + await windowManager.setSize( + showLyrics.value + ? const Size(400, 500) + : const Size(400, 150), + ); + } + }, + ), + ), + Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.show_hide_ui_on_hover), + ), + child: IconButton( + variance: hoverMode.value + ? ButtonVariance.secondary + : ButtonVariance.ghost, + icon: hoverMode.value + ? const Icon(SpotubeIcons.hoverOn) + : const Icon(SpotubeIcons.hoverOff), + onPressed: () async { + areaActive.value = true; + hoverMode.value = !hoverMode.value; + }, ), - onPressed: () async { - areaActive.value = true; - hoverMode.value = !hoverMode.value; - }, ), if (kIsDesktop) FutureBuilder( future: windowManager.isAlwaysOnTop(), builder: (context, snapshot) { - return IconButton( - tooltip: context.l10n.always_on_top, - icon: Icon( - snapshot.data == true - ? SpotubeIcons.pinOn - : SpotubeIcons.pinOff, + return Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.always_on_top), ), - style: ButtonStyle( - foregroundColor: snapshot.data == true - ? WidgetStateProperty.all( - theme.colorScheme.primary) - : null, + child: IconButton( + variance: snapshot.data == true + ? ButtonVariance.secondary + : ButtonVariance.ghost, + icon: Icon( + snapshot.data == true + ? SpotubeIcons.pinOn + : SpotubeIcons.pinOff, + ), + onPressed: snapshot.data == null + ? null + : () async { + await windowManager.setAlwaysOnTop( + snapshot.data == true ? false : true, + ); + update(); + }, ), - onPressed: snapshot.data == null - ? null - : () async { - await windowManager.setAlwaysOnTop( - snapshot.data == true ? false : true, - ); - update(); - }, ); }, ), @@ -163,79 +160,90 @@ class MiniLyricsPage extends HookConsumerWidget { ), ), ), - body: Column( - children: [ - if (playlistQueue.activeTrack != null) - Text( - playlistQueue.activeTrack!.name!, - style: theme.textTheme.titleMedium, - ), - if (showLyrics.value) - Expanded( - child: TabBarView( - children: [ - SyncedLyrics( - palette: PaletteColor(theme.colorScheme.surface, 0), - isModal: true, - defaultTextZoom: 65, - ), - PlainLyrics( - palette: PaletteColor(theme.colorScheme.surface, 0), - isModal: true, - defaultTextZoom: 65, - ), - ], - ), - ) - else - const Gap(20), - AnimatedCrossFade( - crossFadeState: areaActive.value - ? CrossFadeState.showFirst - : CrossFadeState.showSecond, - duration: const Duration(milliseconds: 200), - secondChild: const SizedBox(), - firstChild: Row( + ], + child: Column( + children: [ + if (playlistQueue.activeTrack != null) + Text(playlistQueue.activeTrack!.name!).semiBold(), + if (showLyrics.value) + Expanded( + child: IndexedStack( + index: index.value, children: [ - IconButton( + SyncedLyrics( + palette: PaletteColor(theme.colorScheme.background, 0), + isModal: true, + defaultTextZoom: 65, + ), + PlainLyrics( + palette: PaletteColor(theme.colorScheme.background, 0), + isModal: true, + defaultTextZoom: 65, + ), + ], + ), + ) + else + const Gap(20), + AnimatedCrossFade( + crossFadeState: areaActive.value + ? CrossFadeState.showFirst + : CrossFadeState.showSecond, + duration: const Duration(milliseconds: 200), + secondChild: const SizedBox(), + firstChild: Row( + children: [ + Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.queue), + ), + child: IconButton.ghost( icon: const Icon(SpotubeIcons.queue), - tooltip: context.l10n.queue, onPressed: playlistQueue.activeTrack != null ? () { - showModalBottomSheet( + openDrawer( context: context, - isDismissible: true, - enableDrag: true, - isScrollControlled: true, - backgroundColor: Colors.black12, - barrierColor: Colors.black12, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - constraints: BoxConstraints( - maxHeight: - MediaQuery.of(context).size.height * .7, - ), - builder: (context) { - return Consumer(builder: (context, ref, _) { - final playlist = - ref.watch(audioPlayerProvider); - - return PlayerQueue.fromAudioPlayerNotifier( - floating: true, - playlist: playlist, - notifier: ref - .read(audioPlayerProvider.notifier), + barrierDismissible: true, + draggable: true, + barrierColor: Colors.black.withAlpha(100), + borderRadius: BorderRadius.circular(10), + transformBackdrop: false, + position: OverlayPosition.bottom, + surfaceBlur: context.theme.surfaceBlur, + surfaceOpacity: 0.7, + expands: true, + builder: (context) => Consumer( + builder: (context, ref, _) { + final playlist = ref.watch( + audioPlayerProvider, ); - }); - }, + final playlistNotifier = + ref.read(audioPlayerProvider.notifier); + return ConstrainedBox( + constraints: BoxConstraints( + maxHeight: + MediaQuery.of(context).size.height * + 0.8, + ), + child: + PlayerQueue.fromAudioPlayerNotifier( + floating: false, + playlist: playlist, + notifier: playlistNotifier, + ), + ); + }, + ), ); } : null, ), - const Flexible(child: PlayerControls(compact: true)), - IconButton( - tooltip: context.l10n.exit_mini_player, + ), + const Flexible(child: PlayerControls(compact: true)), + Tooltip( + tooltip: TooltipContainer( + child: Text(context.l10n.exit_mini_player)), + child: IconButton.ghost( icon: const Icon(SpotubeIcons.maximize), onPressed: () async { if (!kIsDesktop) return; @@ -262,11 +270,11 @@ class MiniLyricsPage extends HookConsumerWidget { } }, ), - ], - ), - ) - ], - ), + ), + ], + ), + ) + ], ), ), );