refactor: dialogs to shadcn dialog

This commit is contained in:
Kingkor Roy Tirtho 2025-01-05 08:58:57 +06:00
parent af295be8c6
commit bbad701c07
12 changed files with 124 additions and 125 deletions

View File

@ -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/components/image/universal_image.dart';
import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/constrains.dart';
import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/context.dart';
@ -9,13 +8,15 @@ class ConfirmDownloadDialog extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AlertDialog( final screenSize = MediaQuery.sizeOf(context);
title: Padding(
padding: const EdgeInsets.all(15), return ConstrainedBox(
child: Row( constraints: BoxConstraints(maxWidth: Breakpoints.sm),
child: AlertDialog(
title: Row(
spacing: 10,
children: [ children: [
Text(context.l10n.are_you_sure), Text(context.l10n.are_you_sure),
const SizedBox(width: 10),
const UniversalImage( const UniversalImage(
path: path:
"https://c.tenor.com/kHcmsxlKHEAAAAAM/rock-one-eyebrow-raised-rock-staring.gif", "https://c.tenor.com/kHcmsxlKHEAAAAAM/rock-one-eyebrow-raised-rock-staring.gif",
@ -24,58 +25,53 @@ class ConfirmDownloadDialog extends StatelessWidget {
) )
], ],
), ),
), content: Expanded(
content: Container( flex: screenSize.smAndUp ? 0 : 1,
padding: const EdgeInsets.all(15), child: SingleChildScrollView(
constraints: BoxConstraints(maxWidth: Breakpoints.sm), child: Column(
child: SingleChildScrollView( mainAxisSize: MainAxisSize.min,
child: Column( crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min, children: [
crossAxisAlignment: CrossAxisAlignment.start, Text(
children: [ context.l10n.download_warning,
Text( textAlign: TextAlign.justify,
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,
), ),
textAlign: TextAlign.justify, const SizedBox(height: 10),
), Text(
const SizedBox(height: 10), context.l10n.download_ip_ban_warning,
Text( style: const TextStyle(
context.l10n.by_clicking_accept_terms, color: Colors.red,
), fontWeight: FontWeight.bold,
const SizedBox(height: 10), ),
BulletPoint(context.l10n.download_agreement_1), textAlign: TextAlign.justify,
const SizedBox(height: 10), ),
BulletPoint(context.l10n.download_agreement_2), const SizedBox(height: 10),
const SizedBox(height: 10), Text(
BulletPoint(context.l10n.download_agreement_3), 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),
),
],
); );
} }
} }

View File

@ -1,4 +1,4 @@
import 'package:flutter/material.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/context.dart';
Future<bool> showPromptDialog({ Future<bool> showPromptDialog({
@ -16,13 +16,13 @@ Future<bool> showPromptDialog({
content: Text(message), content: Text(message),
actions: [ actions: [
if (cancelText != null) if (cancelText != null)
OutlinedButton( Button.outline(
onPressed: () => Navigator.of(context).pop(false), onPressed: () => Navigator.of(context).pop(false),
child: Text( child: Text(
cancelText == "Cancel" ? context.l10n.cancel : cancelText, cancelText == "Cancel" ? context.l10n.cancel : cancelText,
), ),
), ),
FilledButton( Button.primary(
child: Text(okText == "Ok" ? context.l10n.ok : okText), child: Text(okText == "Ok" ? context.l10n.ok : okText),
onPressed: () => Navigator.of(context).pop(true), onPressed: () => Navigator.of(context).pop(true),
), ),

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/context.dart';
@ -13,45 +13,35 @@ class ReplaceDownloadedDialog extends ConsumerWidget {
@override @override
Widget build(BuildContext context, ref) { Widget build(BuildContext context, ref) {
final groupValue = ref.watch(replaceDownloadedFileState); final groupValue = ref.watch(replaceDownloadedFileState);
final theme = Theme.of(context);
final replaceAll = ref.watch(replaceDownloadedFileState); final replaceAll = ref.watch(replaceDownloadedFileState);
return AlertDialog( return AlertDialog(
title: Text(context.l10n.track_exists(track.name ?? "")), title: Text(context.l10n.track_exists(track.name ?? "")),
content: Column( content: RadioGroup(
mainAxisSize: MainAxisSize.min, value: groupValue,
children: [ onChanged: (value) {
Text(context.l10n.do_you_want_to_replace), ref.read(replaceDownloadedFileState.notifier).state = value;
RadioListTile<bool>( },
dense: true, child: Column(
contentPadding: EdgeInsets.zero, mainAxisSize: MainAxisSize.min,
activeColor: theme.colorScheme.primary, crossAxisAlignment: CrossAxisAlignment.start,
value: true, children: [
groupValue: groupValue, Text(context.l10n.do_you_want_to_replace),
onChanged: (value) { const Gap(16),
if (value != null) { RadioItem<bool>(
ref.read(replaceDownloadedFileState.notifier).state = true; value: true,
} trailing: Text(context.l10n.replace_downloaded_tracks),
}, ),
title: Text(context.l10n.replace_downloaded_tracks), const Gap(8),
), RadioItem<bool>(
RadioListTile<bool>( value: false,
dense: true, trailing: Text(context.l10n.skip_download_tracks),
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),
),
],
), ),
actions: [ actions: [
OutlinedButton( Button.outline(
onPressed: replaceAll == true onPressed: replaceAll == true
? null ? null
: () { : () {
@ -59,7 +49,7 @@ class ReplaceDownloadedDialog extends ConsumerWidget {
}, },
child: Text(context.l10n.skip), child: Text(context.l10n.skip),
), ),
FilledButton( Button.primary(
onPressed: replaceAll == false onPressed: replaceAll == false
? null ? null
: () { : () {

View File

@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/context.dart';
import 'package:spotube/provider/connect/clients.dart'; import 'package:spotube/provider/connect/clients.dart';
@ -16,31 +16,31 @@ class SelectDeviceDialog extends HookConsumerWidget {
return AlertDialog( return AlertDialog(
title: Text(context.l10n.choose_the_device), title: Text(context.l10n.choose_the_device),
insetPadding: const EdgeInsets.all(16), content: RadioGroup(
content: Column( value: isRemoteService.value,
mainAxisSize: MainAxisSize.min, onChanged: (value) {
children: [ isRemoteService.value = value;
Text(context.l10n.multiple_device_connected), },
RadioListTile.adaptive( child: Column(
title: Text(remoteService.name), mainAxisSize: MainAxisSize.min,
value: true, crossAxisAlignment: CrossAxisAlignment.start,
groupValue: isRemoteService.value, children: [
onChanged: (value) { Text(context.l10n.multiple_device_connected),
isRemoteService.value = value!; const Gap(16),
}, RadioItem(
), trailing: Text(remoteService.name),
RadioListTile.adaptive( value: true,
title: Text(context.l10n.this_device), ),
value: false, const Gap(8),
groupValue: isRemoteService.value, RadioItem(
onChanged: (value) { trailing: Text(context.l10n.this_device),
isRemoteService.value = !value!; value: false,
}, ),
), ],
], ),
), ),
actions: [ actions: [
TextButton( Button.primary(
onPressed: () { onPressed: () {
Navigator.of(context).pop(isRemoteService.value); Navigator.of(context).pop(isRemoteService.value);
}, },
@ -51,7 +51,8 @@ class SelectDeviceDialog extends HookConsumerWidget {
} }
} }
Future<bool> showSelectDeviceDialog(BuildContext context, WidgetRef ref) async { Future<bool?> showSelectDeviceDialog(
BuildContext context, WidgetRef ref) async {
final connectClients = ref.read(connectClientsProvider); final connectClients = ref.read(connectClientsProvider);
if (connectClients.asData?.value.resolvedService == null) { if (connectClients.asData?.value.resolvedService == null) {
@ -63,5 +64,5 @@ Future<bool> showSelectDeviceDialog(BuildContext context, WidgetRef ref) async {
builder: (context) => const SelectDeviceDialog(), builder: (context) => const SelectDeviceDialog(),
); );
return isRemote ?? false; return isRemote;
} }

View File

@ -97,12 +97,13 @@ class TrackPresentationActionsSection extends HookConsumerWidget {
case "download": case "download":
{ {
final confirmed = audioSource == AudioSource.piped || final confirmed = audioSource == AudioSource.piped ||
await showDialog( (await showDialog<bool?>(
context: context, context: context,
builder: (context) { builder: (context) {
return const ConfirmDownloadDialog(); return const ConfirmDownloadDialog();
}, },
); ) ??
false);
if (confirmed != true) return; if (confirmed != true) return;
downloader.batchAddToQueue(tracks); downloader.batchAddToQueue(tracks);
notifier.deselectAllTracks(); notifier.deselectAllTracks();

View File

@ -40,6 +40,7 @@ UseActionCallbacks useActionCallbacks(WidgetRef ref) {
if (!context.mounted) return; if (!context.mounted) return;
final isRemoteDevice = await showSelectDeviceDialog(context, ref); final isRemoteDevice = await showSelectDeviceDialog(context, ref);
if (isRemoteDevice == null) return;
if (isRemoteDevice) { if (isRemoteDevice) {
final allTracks = await options.pagination.onFetchAll(); final allTracks = await options.pagination.onFetchAll();
final remotePlayback = ref.read(connectProvider.notifier); final remotePlayback = ref.read(connectProvider.notifier);
@ -90,6 +91,7 @@ UseActionCallbacks useActionCallbacks(WidgetRef ref) {
if (!context.mounted) return; if (!context.mounted) return;
final isRemoteDevice = await showSelectDeviceDialog(context, ref); final isRemoteDevice = await showSelectDeviceDialog(context, ref);
if (isRemoteDevice == null) return;
if (isRemoteDevice) { if (isRemoteDevice) {
final allTracks = await options.pagination.onFetchAll(); final allTracks = await options.pagination.onFetchAll();
final remotePlayback = ref.read(connectProvider.notifier); final remotePlayback = ref.read(connectProvider.notifier);

View File

@ -37,6 +37,7 @@ Future<void> Function(Track track, int index) useTrackTilePlayCallback(
} }
final isRemoteDevice = await showSelectDeviceDialog(context, ref); final isRemoteDevice = await showSelectDeviceDialog(context, ref);
if (isRemoteDevice == null) return;
if (isRemoteDevice) { if (isRemoteDevice) {
final remotePlayback = ref.read(connectProvider.notifier); final remotePlayback = ref.read(connectProvider.notifier);

View File

@ -91,6 +91,7 @@ class AlbumCard extends HookConsumerWidget {
if (fetchedTracks.isEmpty || !context.mounted) return; if (fetchedTracks.isEmpty || !context.mounted) return;
final isRemoteDevice = await showSelectDeviceDialog(context, ref); final isRemoteDevice = await showSelectDeviceDialog(context, ref);
if (isRemoteDevice == null) return;
if (isRemoteDevice) { if (isRemoteDevice) {
final remotePlayback = ref.read(connectProvider.notifier); final remotePlayback = ref.read(connectProvider.notifier);
await remotePlayback.load( await remotePlayback.load(

View File

@ -94,6 +94,7 @@ class PlaylistCard extends HookConsumerWidget {
if (fetchedInitialTracks.isEmpty || !context.mounted) return; if (fetchedInitialTracks.isEmpty || !context.mounted) return;
final isRemoteDevice = await showSelectDeviceDialog(context, ref); final isRemoteDevice = await showSelectDeviceDialog(context, ref);
if (isRemoteDevice == null) return;
if (isRemoteDevice) { if (isRemoteDevice) {
final remotePlayback = ref.read(connectProvider.notifier); final remotePlayback = ref.read(connectProvider.notifier);
final allTracks = await fetchAllTracks(); final allTracks = await fetchAllTracks();

View File

@ -44,6 +44,9 @@ class ArtistPageTopTracks extends HookConsumerWidget {
currentTrack ??= tracks.first; currentTrack ??= tracks.first;
final isRemoteDevice = await showSelectDeviceDialog(context, ref); final isRemoteDevice = await showSelectDeviceDialog(context, ref);
if (isRemoteDevice == null) return;
if (isRemoteDevice) { if (isRemoteDevice) {
final remotePlayback = ref.read(connectProvider.notifier); final remotePlayback = ref.read(connectProvider.notifier);
final remotePlaylist = ref.read(queueProvider); final remotePlaylist = ref.read(queueProvider);

View File

@ -188,6 +188,7 @@ class ConnectControlPage extends HookConsumerWidget {
SliverToBoxAdapter( SliverToBoxAdapter(
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
spacing: 20,
children: [ children: [
Tooltip( Tooltip(
tooltip: TooltipContainer( tooltip: TooltipContainer(

View File

@ -55,6 +55,8 @@ class SearchTracksSection extends HookConsumerWidget {
final isRemoteDevice = final isRemoteDevice =
await showSelectDeviceDialog(context, ref); await showSelectDeviceDialog(context, ref);
if (isRemoteDevice == null) return;
if (isRemoteDevice) { if (isRemoteDevice) {
final remotePlayback = ref.read(connectProvider.notifier); final remotePlayback = ref.read(connectProvider.notifier);
final remotePlaylist = ref.read(queueProvider); final remotePlaylist = ref.read(queueProvider);