From c91d8c8efa8b526c64881fa829992b8c250e7c89 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 11 Jun 2023 18:56:39 +0600 Subject: [PATCH] feat: add generated to playlist(s) --- .../dialogs/confirm_download_dialog.dart | 41 +++++++++--------- .../dialogs/playlist_add_track_dialog.dart | 27 +++++++++--- lib/l10n/app_en.arb | 11 ++++- .../playlist_generate_result.dart | 43 ++++++++++++++++--- 4 files changed, 88 insertions(+), 34 deletions(-) diff --git a/lib/components/shared/dialogs/confirm_download_dialog.dart b/lib/components/shared/dialogs/confirm_download_dialog.dart index bf8676f19..0413260c2 100644 --- a/lib/components/shared/dialogs/confirm_download_dialog.dart +++ b/lib/components/shared/dialogs/confirm_download_dialog.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; +import 'package:spotube/extensions/context.dart'; class ConfirmDownloadDialog extends StatelessWidget { const ConfirmDownloadDialog({Key? key}) : super(key: key); @@ -11,10 +12,10 @@ class ConfirmDownloadDialog extends StatelessWidget { title: Padding( padding: const EdgeInsets.all(15), child: Row( - children: const [ - Text("Are you sure?"), - SizedBox(width: 10), - UniversalImage( + 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", height: 40, @@ -29,39 +30,37 @@ class ConfirmDownloadDialog extends StatelessWidget { child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, - children: const [ + children: [ Text( - "If you download all Tracks at bulk you're clearly pirating Music & causing damage to the creative society of Music. I hope you are aware of this. Always, try respecting & supporting Artist's hard work", + context.l10n.download_warning, textAlign: TextAlign.justify, ), - SizedBox(height: 10), + const SizedBox(height: 10), Text( - "BTW, your IP can get blocked on YouTube due excessive download requests than usual. IP block means you can't use YouTube (even if you're logged in) for at least 2-3 months from that IP device. And Spotube doesn't hold any responsibility if this ever happens", - style: TextStyle( + context.l10n.download_ip_ban_warning, + style: const TextStyle( color: Colors.red, fontWeight: FontWeight.bold, ), textAlign: TextAlign.justify, ), - SizedBox(height: 10), + const SizedBox(height: 10), Text( - "By clicking 'accept' you agree to following terms:", + context.l10n.by_clicking_accept_terms, ), - SizedBox(height: 10), - BulletPoint("I know I'm pirating Music. I'm bad"), - SizedBox(height: 10), - BulletPoint( - "I'll support the Artist wherever I can and I'm only doing this because I don't have money to buy their art"), - SizedBox(height: 10), - BulletPoint( - "I'm completely aware that my IP can get blocked on YouTube & I don't hold Spotube or his owners/contributors responsible for any accidents caused by my current action"), + 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: [ OutlinedButton( - child: const Text("Decline"), + child: Text(context.l10n.decline), onPressed: () { Navigator.pop(context, false); }, @@ -72,7 +71,7 @@ class ConfirmDownloadDialog extends StatelessWidget { backgroundColor: Colors.red, ), onPressed: () => Navigator.of(context).pop(true), - child: const Text("Accept"), + child: Text(context.l10n.accept), ), ], ); diff --git a/lib/components/shared/dialogs/playlist_add_track_dialog.dart b/lib/components/shared/dialogs/playlist_add_track_dialog.dart index a02729e97..396e498a6 100644 --- a/lib/components/shared/dialogs/playlist_add_track_dialog.dart +++ b/lib/components/shared/dialogs/playlist_add_track_dialog.dart @@ -3,8 +3,11 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotify/spotify.dart'; +import 'package:spotube/components/shared/image/universal_image.dart'; +import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/spotify_provider.dart'; import 'package:spotube/services/queries/queries.dart'; +import 'package:spotube/utils/type_conversion_utils.dart'; class PlaylistAddTrackDialog extends HookConsumerWidget { final List tracks; @@ -39,21 +42,21 @@ class PlaylistAddTrackDialog extends HookConsumerWidget { .toList(), playlistId), ), - ).then((_) => Navigator.pop(context)); + ).then((_) => Navigator.pop(context, true)); } return AlertDialog( - title: const Text("Add to Playlist"), + title: Text(context.l10n.add_to_playlist), actions: [ OutlinedButton( - child: const Text("Cancel"), + child: Text(context.l10n.cancel), onPressed: () { - Navigator.pop(context); + Navigator.pop(context, false); }, ), FilledButton( onPressed: onAdd, - child: const Text("Add"), + child: Text(context.l10n.add), ), ], content: SizedBox( @@ -67,7 +70,19 @@ class PlaylistAddTrackDialog extends HookConsumerWidget { itemBuilder: (context, index) { final playlist = filteredPlaylists.elementAt(index); return CheckboxListTile( - title: Text(playlist.name!), + secondary: CircleAvatar( + backgroundImage: UniversalImage.imageProvider( + TypeConversionUtils.image_X_UrlString( + playlist.images, + placeholder: ImagePlaceholder.collection, + ), + ), + ), + contentPadding: EdgeInsets.zero, + title: Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Text(playlist.name!), + ), value: playlistsCheck.value[playlist.id] ?? false, onChanged: (val) { playlistsCheck.value = { diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 98298102d..c4b24eaba 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -220,6 +220,15 @@ "moderate": "Moderate", "deselect_all": "Deselect All", "select_all": "Select All", + "are_you_sure": "Are you sure?", "generating_playlist": "Generating your custom playlist...", - "selected_count_tracks": "Selected {count} tracks" + "selected_count_tracks": "Selected {count} tracks", + "download_warning": "If you download all Tracks at bulk you're clearly pirating Music & causing damage to the creative society of Music. I hope you are aware of this. Always, try respecting & supporting Artist's hard work", + "download_ip_ban_warning": "BTW, your IP can get blocked on YouTube due excessive download requests than usual. IP block means you can't use YouTube (even if you're logged in) for at least 2-3 months from that IP device. And Spotube doesn't hold any responsibility if this ever happens", + "by_clicking_accept_terms": "By clicking 'accept' you agree to following terms:", + "download_agreement_1": "I know I'm pirating Music. I'm bad", + "download_agreement_2": "I'll support the Artist wherever I can and I'm only doing this because I don't have money to buy their art", + "download_agreement_3": "I'm completely aware that my IP can get blocked on YouTube & I don't hold Spotube or his owners/contributors responsible for any accidents caused by my current action", + "decline": "Decline", + "accept": "Accept" } \ No newline at end of file diff --git a/lib/pages/library/playlist_generate/playlist_generate_result.dart b/lib/pages/library/playlist_generate/playlist_generate_result.dart index 973f4e61a..653a2263d 100644 --- a/lib/pages/library/playlist_generate/playlist_generate_result.dart +++ b/lib/pages/library/playlist_generate/playlist_generate_result.dart @@ -7,6 +7,7 @@ import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/library/playlist_generate/simple_track_tile.dart'; import 'package:spotube/components/playlist/playlist_create_dialog.dart'; +import 'package:spotube/components/shared/dialogs/playlist_add_track_dialog.dart'; import 'package:spotube/components/shared/page_window_title_bar.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; @@ -31,6 +32,7 @@ class PlaylistGenerateResultPage extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { final router = GoRouter.of(context); + final scaffoldMessenger = ScaffoldMessenger.of(context); final playlistNotifier = ref.watch(ProxyPlaylistNotifier.notifier); final (:seeds, :parameters, :limit, :market) = state; @@ -118,12 +120,13 @@ class PlaylistGenerateResultPage extends HookConsumerWidget { ), ); if (context.mounted) { - ScaffoldMessenger.of(context).showSnackBar( + scaffoldMessenger.showSnackBar( SnackBar( content: Text( - context.l10n.add_count_to_queue( - selectedTracks.value.length, - )), + context.l10n.add_count_to_queue( + selectedTracks.value.length, + ), + ), ), ); } @@ -153,8 +156,36 @@ class PlaylistGenerateResultPage extends HookConsumerWidget { FilledButton.tonalIcon( icon: const Icon(SpotubeIcons.playlistAdd), label: Text(context.l10n.add_to_playlist), - onPressed: - selectedTracks.value.isEmpty ? null : () {}, + onPressed: selectedTracks.value.isEmpty + ? null + : () async { + final hasAdded = await showDialog( + context: context, + builder: (context) => + PlaylistAddTrackDialog( + tracks: selectedTracks.value + .map( + (e) => generatedPlaylist.data! + .firstWhere( + (element) => element.id == e, + ), + ) + .toList(), + ), + ); + + if (context.mounted && hasAdded == true) { + scaffoldMessenger.showSnackBar( + SnackBar( + content: Text( + context.l10n.add_count_to_playlist( + selectedTracks.value.length, + ), + ), + ), + ); + } + }, ) ], ),