mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 16:05:18 +00:00
refactor: dialogs to shadcn dialog
This commit is contained in:
parent
af295be8c6
commit
bbad701c07
@ -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),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
),
|
),
|
||||||
|
@ -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
|
||||||
: () {
|
: () {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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(
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
@ -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(
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user