diff --git a/lib/components/dialogs/confirm_download_dialog.dart b/lib/components/dialogs/confirm_download_dialog.dart index 897c64cb..a2df0e9c 100644 --- a/lib/components/dialogs/confirm_download_dialog.dart +++ b/lib/components/dialogs/confirm_download_dialog.dart @@ -1,5 +1,4 @@ -import 'package:flutter/material.dart'; - +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; @@ -9,13 +8,15 @@ class ConfirmDownloadDialog extends StatelessWidget { @override Widget build(BuildContext context) { - return AlertDialog( - title: Padding( - padding: const EdgeInsets.all(15), - child: Row( + final screenSize = MediaQuery.sizeOf(context); + + return ConstrainedBox( + constraints: BoxConstraints(maxWidth: Breakpoints.sm), + child: AlertDialog( + title: Row( + spacing: 10, children: [ Text(context.l10n.are_you_sure), - const SizedBox(width: 10), const UniversalImage( path: "https://c.tenor.com/kHcmsxlKHEAAAAAM/rock-one-eyebrow-raised-rock-staring.gif", @@ -24,58 +25,53 @@ class ConfirmDownloadDialog extends StatelessWidget { ) ], ), - ), - content: Container( - padding: const EdgeInsets.all(15), - constraints: BoxConstraints(maxWidth: Breakpoints.sm), - child: SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - context.l10n.download_warning, - textAlign: TextAlign.justify, - ), - const SizedBox(height: 10), - Text( - context.l10n.download_ip_ban_warning, - style: const TextStyle( - color: Colors.red, - fontWeight: FontWeight.bold, + content: Expanded( + flex: screenSize.smAndUp ? 0 : 1, + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + context.l10n.download_warning, + textAlign: TextAlign.justify, ), - textAlign: TextAlign.justify, - ), - const SizedBox(height: 10), - Text( - context.l10n.by_clicking_accept_terms, - ), - const SizedBox(height: 10), - BulletPoint(context.l10n.download_agreement_1), - const SizedBox(height: 10), - BulletPoint(context.l10n.download_agreement_2), - const SizedBox(height: 10), - BulletPoint(context.l10n.download_agreement_3), - ], + const SizedBox(height: 10), + Text( + context.l10n.download_ip_ban_warning, + style: const TextStyle( + color: Colors.red, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.justify, + ), + const SizedBox(height: 10), + Text( + context.l10n.by_clicking_accept_terms, + ), + const SizedBox(height: 10), + BulletPoint(context.l10n.download_agreement_1), + const SizedBox(height: 10), + BulletPoint(context.l10n.download_agreement_2), + const SizedBox(height: 10), + BulletPoint(context.l10n.download_agreement_3), + ], + ), ), ), + actions: [ + Button.outline( + child: Text(context.l10n.decline), + onPressed: () { + Navigator.pop(context, false); + }, + ), + Button.destructive( + onPressed: () => Navigator.of(context).pop(true), + child: Text(context.l10n.accept), + ), + ], ), - actions: [ - OutlinedButton( - child: Text(context.l10n.decline), - onPressed: () { - Navigator.pop(context, false); - }, - ), - FilledButton( - style: FilledButton.styleFrom( - foregroundColor: Colors.white, - backgroundColor: Colors.red, - ), - onPressed: () => Navigator.of(context).pop(true), - child: Text(context.l10n.accept), - ), - ], ); } } diff --git a/lib/components/dialogs/prompt_dialog.dart b/lib/components/dialogs/prompt_dialog.dart index 30a63bcf..3498bf02 100644 --- a/lib/components/dialogs/prompt_dialog.dart +++ b/lib/components/dialogs/prompt_dialog.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/extensions/context.dart'; Future showPromptDialog({ @@ -16,13 +16,13 @@ Future showPromptDialog({ content: Text(message), actions: [ if (cancelText != null) - OutlinedButton( + Button.outline( onPressed: () => Navigator.of(context).pop(false), child: Text( cancelText == "Cancel" ? context.l10n.cancel : cancelText, ), ), - FilledButton( + Button.primary( child: Text(okText == "Ok" ? context.l10n.ok : okText), onPressed: () => Navigator.of(context).pop(true), ), diff --git a/lib/components/dialogs/replace_downloaded_dialog.dart b/lib/components/dialogs/replace_downloaded_dialog.dart index 00461d34..3a0f3a1d 100644 --- a/lib/components/dialogs/replace_downloaded_dialog.dart +++ b/lib/components/dialogs/replace_downloaded_dialog.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/extensions/context.dart'; @@ -13,45 +13,35 @@ class ReplaceDownloadedDialog extends ConsumerWidget { @override Widget build(BuildContext context, ref) { final groupValue = ref.watch(replaceDownloadedFileState); - final theme = Theme.of(context); final replaceAll = ref.watch(replaceDownloadedFileState); return AlertDialog( title: Text(context.l10n.track_exists(track.name ?? "")), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text(context.l10n.do_you_want_to_replace), - RadioListTile( - dense: true, - contentPadding: EdgeInsets.zero, - activeColor: theme.colorScheme.primary, - value: true, - groupValue: groupValue, - onChanged: (value) { - if (value != null) { - ref.read(replaceDownloadedFileState.notifier).state = true; - } - }, - title: Text(context.l10n.replace_downloaded_tracks), - ), - RadioListTile( - dense: true, - contentPadding: EdgeInsets.zero, - activeColor: theme.colorScheme.primary, - value: false, - groupValue: groupValue, - onChanged: (value) { - if (value != null) { - ref.read(replaceDownloadedFileState.notifier).state = false; - } - }, - title: Text(context.l10n.skip_download_tracks), - ), - ], + content: RadioGroup( + value: groupValue, + onChanged: (value) { + ref.read(replaceDownloadedFileState.notifier).state = value; + }, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(context.l10n.do_you_want_to_replace), + const Gap(16), + RadioItem( + value: true, + trailing: Text(context.l10n.replace_downloaded_tracks), + ), + const Gap(8), + RadioItem( + value: false, + trailing: Text(context.l10n.skip_download_tracks), + ), + ], + ), ), actions: [ - OutlinedButton( + Button.outline( onPressed: replaceAll == true ? null : () { @@ -59,7 +49,7 @@ class ReplaceDownloadedDialog extends ConsumerWidget { }, child: Text(context.l10n.skip), ), - FilledButton( + Button.primary( onPressed: replaceAll == false ? null : () { diff --git a/lib/components/dialogs/select_device_dialog.dart b/lib/components/dialogs/select_device_dialog.dart index 3a3bde60..5392a403 100644 --- a/lib/components/dialogs/select_device_dialog.dart +++ b/lib/components/dialogs/select_device_dialog.dart @@ -1,6 +1,6 @@ -import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/connect/clients.dart'; @@ -16,31 +16,31 @@ class SelectDeviceDialog extends HookConsumerWidget { return AlertDialog( title: Text(context.l10n.choose_the_device), - insetPadding: const EdgeInsets.all(16), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text(context.l10n.multiple_device_connected), - RadioListTile.adaptive( - title: Text(remoteService.name), - value: true, - groupValue: isRemoteService.value, - onChanged: (value) { - isRemoteService.value = value!; - }, - ), - RadioListTile.adaptive( - title: Text(context.l10n.this_device), - value: false, - groupValue: isRemoteService.value, - onChanged: (value) { - isRemoteService.value = !value!; - }, - ), - ], + content: RadioGroup( + value: isRemoteService.value, + onChanged: (value) { + isRemoteService.value = value; + }, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(context.l10n.multiple_device_connected), + const Gap(16), + RadioItem( + trailing: Text(remoteService.name), + value: true, + ), + const Gap(8), + RadioItem( + trailing: Text(context.l10n.this_device), + value: false, + ), + ], + ), ), actions: [ - TextButton( + Button.primary( onPressed: () { Navigator.of(context).pop(isRemoteService.value); }, @@ -51,7 +51,8 @@ class SelectDeviceDialog extends HookConsumerWidget { } } -Future showSelectDeviceDialog(BuildContext context, WidgetRef ref) async { +Future showSelectDeviceDialog( + BuildContext context, WidgetRef ref) async { final connectClients = ref.read(connectClientsProvider); if (connectClients.asData?.value.resolvedService == null) { @@ -63,5 +64,5 @@ Future showSelectDeviceDialog(BuildContext context, WidgetRef ref) async { builder: (context) => const SelectDeviceDialog(), ); - return isRemote ?? false; + return isRemote; } diff --git a/lib/components/track_presentation/presentation_actions.dart b/lib/components/track_presentation/presentation_actions.dart index 41f518d0..01228524 100644 --- a/lib/components/track_presentation/presentation_actions.dart +++ b/lib/components/track_presentation/presentation_actions.dart @@ -97,12 +97,13 @@ class TrackPresentationActionsSection extends HookConsumerWidget { case "download": { final confirmed = audioSource == AudioSource.piped || - await showDialog( - context: context, - builder: (context) { - return const ConfirmDownloadDialog(); - }, - ); + (await showDialog( + context: context, + builder: (context) { + return const ConfirmDownloadDialog(); + }, + ) ?? + false); if (confirmed != true) return; downloader.batchAddToQueue(tracks); notifier.deselectAllTracks(); diff --git a/lib/components/track_presentation/use_action_callbacks.dart b/lib/components/track_presentation/use_action_callbacks.dart index e9b9c98e..0012594a 100644 --- a/lib/components/track_presentation/use_action_callbacks.dart +++ b/lib/components/track_presentation/use_action_callbacks.dart @@ -40,6 +40,7 @@ UseActionCallbacks useActionCallbacks(WidgetRef ref) { if (!context.mounted) return; final isRemoteDevice = await showSelectDeviceDialog(context, ref); + if (isRemoteDevice == null) return; if (isRemoteDevice) { final allTracks = await options.pagination.onFetchAll(); final remotePlayback = ref.read(connectProvider.notifier); @@ -90,6 +91,7 @@ UseActionCallbacks useActionCallbacks(WidgetRef ref) { if (!context.mounted) return; final isRemoteDevice = await showSelectDeviceDialog(context, ref); + if (isRemoteDevice == null) return; if (isRemoteDevice) { final allTracks = await options.pagination.onFetchAll(); final remotePlayback = ref.read(connectProvider.notifier); diff --git a/lib/components/track_presentation/use_track_tile_play_callback.dart b/lib/components/track_presentation/use_track_tile_play_callback.dart index 261d01d8..74608205 100644 --- a/lib/components/track_presentation/use_track_tile_play_callback.dart +++ b/lib/components/track_presentation/use_track_tile_play_callback.dart @@ -37,6 +37,7 @@ Future Function(Track track, int index) useTrackTilePlayCallback( } final isRemoteDevice = await showSelectDeviceDialog(context, ref); + if (isRemoteDevice == null) return; if (isRemoteDevice) { final remotePlayback = ref.read(connectProvider.notifier); diff --git a/lib/modules/album/album_card.dart b/lib/modules/album/album_card.dart index 86935698..2efacbfd 100644 --- a/lib/modules/album/album_card.dart +++ b/lib/modules/album/album_card.dart @@ -91,6 +91,7 @@ class AlbumCard extends HookConsumerWidget { if (fetchedTracks.isEmpty || !context.mounted) return; final isRemoteDevice = await showSelectDeviceDialog(context, ref); + if (isRemoteDevice == null) return; if (isRemoteDevice) { final remotePlayback = ref.read(connectProvider.notifier); await remotePlayback.load( diff --git a/lib/modules/playlist/playlist_card.dart b/lib/modules/playlist/playlist_card.dart index 945f3571..43f2ee4e 100644 --- a/lib/modules/playlist/playlist_card.dart +++ b/lib/modules/playlist/playlist_card.dart @@ -94,6 +94,7 @@ class PlaylistCard extends HookConsumerWidget { if (fetchedInitialTracks.isEmpty || !context.mounted) return; final isRemoteDevice = await showSelectDeviceDialog(context, ref); + if (isRemoteDevice == null) return; if (isRemoteDevice) { final remotePlayback = ref.read(connectProvider.notifier); final allTracks = await fetchAllTracks(); diff --git a/lib/pages/artist/section/top_tracks.dart b/lib/pages/artist/section/top_tracks.dart index d52ed470..5ef68c9c 100644 --- a/lib/pages/artist/section/top_tracks.dart +++ b/lib/pages/artist/section/top_tracks.dart @@ -44,6 +44,9 @@ class ArtistPageTopTracks extends HookConsumerWidget { currentTrack ??= tracks.first; final isRemoteDevice = await showSelectDeviceDialog(context, ref); + + if (isRemoteDevice == null) return; + if (isRemoteDevice) { final remotePlayback = ref.read(connectProvider.notifier); final remotePlaylist = ref.read(queueProvider); diff --git a/lib/pages/connect/control/control.dart b/lib/pages/connect/control/control.dart index b92a5482..afe68b16 100644 --- a/lib/pages/connect/control/control.dart +++ b/lib/pages/connect/control/control.dart @@ -188,6 +188,7 @@ class ConnectControlPage extends HookConsumerWidget { SliverToBoxAdapter( child: Row( mainAxisAlignment: MainAxisAlignment.center, + spacing: 20, children: [ Tooltip( tooltip: TooltipContainer( diff --git a/lib/pages/search/sections/tracks.dart b/lib/pages/search/sections/tracks.dart index c0daa853..bacbbb57 100644 --- a/lib/pages/search/sections/tracks.dart +++ b/lib/pages/search/sections/tracks.dart @@ -55,6 +55,8 @@ class SearchTracksSection extends HookConsumerWidget { final isRemoteDevice = await showSelectDeviceDialog(context, ref); + if (isRemoteDevice == null) return; + if (isRemoteDevice) { final remotePlayback = ref.read(connectProvider.notifier); final remotePlaylist = ref.read(queueProvider);