refactor: show queue from side in desktop

This commit is contained in:
Kingkor Roy Tirtho 2023-11-08 18:51:19 +06:00
parent da04f068f9
commit a1cc44759b
4 changed files with 333 additions and 319 deletions

View File

@ -5,10 +5,10 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotify/spotify.dart' hide Offset; import 'package:spotify/spotify.dart' hide Offset;
import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/components/player/player_queue.dart';
import 'package:spotube/components/player/sibling_tracks_sheet.dart'; import 'package:spotube/components/player/sibling_tracks_sheet.dart';
import 'package:spotube/components/shared/adaptive/adaptive_pop_sheet_list.dart'; import 'package:spotube/components/shared/adaptive/adaptive_pop_sheet_list.dart';
import 'package:spotube/components/shared/heart_button.dart'; import 'package:spotube/components/shared/heart_button.dart';
import 'package:spotube/extensions/constrains.dart';
import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/context.dart';
import 'package:spotube/extensions/duration.dart'; import 'package:spotube/extensions/duration.dart';
import 'package:spotube/models/local_track.dart'; import 'package:spotube/models/local_track.dart';
@ -35,6 +35,7 @@ class PlayerActions extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, ref) { Widget build(BuildContext context, ref) {
final mediaQuery = MediaQuery.of(context);
final playlist = ref.watch(ProxyPlaylistNotifier.provider); final playlist = ref.watch(ProxyPlaylistNotifier.provider);
final isLocalTrack = playlist.activeTrack is LocalTrack; final isLocalTrack = playlist.activeTrack is LocalTrack;
ref.watch(downloadManagerProvider); ref.watch(downloadManagerProvider);
@ -86,23 +87,7 @@ class PlayerActions extends HookConsumerWidget {
tooltip: context.l10n.queue, tooltip: context.l10n.queue,
onPressed: playlist.activeTrack != null onPressed: playlist.activeTrack != null
? () { ? () {
showModalBottomSheet( Scaffold.of(context).openEndDrawer();
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 PlayerQueue(floating: floatingQueue);
},
);
} }
: null, : null,
), ),
@ -119,6 +104,7 @@ class PlayerActions extends HookConsumerWidget {
isScrollControlled: true, isScrollControlled: true,
backgroundColor: Colors.black12, backgroundColor: Colors.black12,
barrierColor: Colors.black12, barrierColor: Colors.black12,
elevation: 0,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
), ),

View File

@ -36,7 +36,9 @@ class PlayerQueue extends HookConsumerWidget {
final tracks = playlist.tracks; final tracks = playlist.tracks;
final borderRadius = floating final borderRadius = floating
? BorderRadius.circular(10) ? const BorderRadius.only(
topLeft: Radius.circular(10),
)
: const BorderRadius.only( : const BorderRadius.only(
topLeft: Radius.circular(10), topLeft: Radius.circular(10),
topRight: Radius.circular(10), topRight: Radius.circular(10),
@ -80,18 +82,20 @@ class PlayerQueue extends HookConsumerWidget {
return const NotFound(vertical: true); return const NotFound(vertical: true);
} }
return BackdropFilter( return ClipRRect(
borderRadius: borderRadius,
clipBehavior: Clip.hardEdge,
child: BackdropFilter(
filter: ImageFilter.blur( filter: ImageFilter.blur(
sigmaX: 12.0, sigmaX: 15,
sigmaY: 12.0, sigmaY: 15,
), ),
child: Container( child: Container(
margin: EdgeInsets.all(floating ? 8.0 : 0),
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
top: 5.0, top: 5.0,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: theme.scaffoldBackgroundColor.withOpacity(0.5), color: theme.colorScheme.surfaceVariant.withOpacity(0.5),
borderRadius: borderRadius, borderRadius: borderRadius,
), ),
child: CallbackShortcuts( child: CallbackShortcuts(
@ -107,6 +111,7 @@ class PlayerQueue extends HookConsumerWidget {
child: LayoutBuilder(builder: (context, constraints) { child: LayoutBuilder(builder: (context, constraints) {
return Column( return Column(
children: [ children: [
if (!floating)
Container( Container(
height: 5, height: 5,
width: 100, width: 100,
@ -176,7 +181,8 @@ class PlayerQueue extends HookConsumerWidget {
style: FilledButton.styleFrom( style: FilledButton.styleFrom(
backgroundColor: backgroundColor:
theme.scaffoldBackgroundColor.withOpacity(0.5), theme.scaffoldBackgroundColor.withOpacity(0.5),
foregroundColor: theme.textTheme.headlineSmall?.color, foregroundColor:
theme.textTheme.headlineSmall?.color,
), ),
child: Row( child: Row(
children: [ children: [
@ -228,7 +234,8 @@ class PlayerQueue extends HookConsumerWidget {
leadingActions: [ leadingActions: [
ReorderableDragStartListener( ReorderableDragStartListener(
index: i, index: i,
child: const Icon(SpotubeIcons.dragHandle), child:
const Icon(SpotubeIcons.dragHandle),
), ),
], ],
), ),
@ -268,6 +275,7 @@ class PlayerQueue extends HookConsumerWidget {
}), }),
), ),
), ),
),
); );
} }
} }

View File

@ -86,7 +86,8 @@ class SiblingTracksSheet extends HookConsumerWidget {
return null; return null;
}, [playlist.activeTrack]); }, [playlist.activeTrack]);
final itemBuilder = useCallback((YoutubeVideoInfo video) { final itemBuilder = useCallback(
(YoutubeVideoInfo video) {
return ListTile( return ListTile(
title: Text(video.title), title: Text(video.title),
leading: Padding( leading: Padding(
@ -114,14 +115,15 @@ class SiblingTracksSheet extends HookConsumerWidget {
} }
}, },
); );
}, [ },
playlist.isFetching, [playlist.isFetching, playlist.activeTrack, siblings],
playlist.activeTrack, );
siblings,
]);
var mediaQuery = MediaQuery.of(context); var mediaQuery = MediaQuery.of(context);
return SafeArea( return SafeArea(
child: ClipRRect(
borderRadius: borderRadius,
clipBehavior: Clip.hardEdge,
child: BackdropFilter( child: BackdropFilter(
filter: ImageFilter.blur( filter: ImageFilter.blur(
sigmaX: 12.0, sigmaX: 12.0,
@ -131,12 +133,11 @@ class SiblingTracksSheet extends HookConsumerWidget {
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
child: Container( child: Container(
height: isSearching.value && mediaQuery.smAndDown height: isSearching.value && mediaQuery.smAndDown
? mediaQuery.size.height ? mediaQuery.size.height - mediaQuery.padding.top
: mediaQuery.size.height * .6, : mediaQuery.size.height * .6,
margin: const EdgeInsets.all(8.0),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: borderRadius, borderRadius: borderRadius,
color: theme.scaffoldBackgroundColor.withOpacity(.3), color: theme.colorScheme.surfaceVariant.withOpacity(.5),
), ),
child: Scaffold( child: Scaffold(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
@ -238,6 +239,7 @@ class SiblingTracksSheet extends HookConsumerWidget {
), ),
), ),
), ),
),
); );
} }
} }

View File

@ -3,11 +3,13 @@ import 'dart:async';
import 'package:fl_query/fl_query.dart'; import 'package:fl_query/fl_query.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_desktop_tools/flutter_desktop_tools.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/components/player/player_queue.dart';
import 'package:spotube/components/shared/dialogs/replace_downloaded_dialog.dart'; import 'package:spotube/components/shared/dialogs/replace_downloaded_dialog.dart';
import 'package:spotube/components/root/bottom_player.dart'; import 'package:spotube/components/root/bottom_player.dart';
import 'package:spotube/components/root/sidebar.dart'; import 'package:spotube/components/root/sidebar.dart';
@ -164,6 +166,22 @@ class RootApp extends HookConsumerWidget {
child: child, child: child,
), ),
extendBody: true, extendBody: true,
drawerScrimColor: Colors.transparent,
endDrawer: DesktopTools.platform.isDesktop
? Container(
constraints: const BoxConstraints(maxWidth: 800),
decoration: BoxDecoration(
boxShadow: theme.brightness == Brightness.light
? null
: kElevationToShadow[8],
),
margin: const EdgeInsets.only(
top: 40,
bottom: 100,
),
child: const PlayerQueue(floating: true),
)
: null,
bottomNavigationBar: Column( bottomNavigationBar: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [