@@ -34,6 +34,7 @@ import 'package:musify/utilities/async_loader.dart';
3434import 'package:musify/utilities/common_variables.dart' ;
3535import 'package:musify/utilities/flutter_toast.dart' ;
3636import 'package:musify/utilities/offline_playlist_dialogs.dart' ;
37+ import 'package:musify/utilities/playlist_dialogs.dart' ;
3738import 'package:musify/utilities/playlist_image_picker.dart' ;
3839import 'package:musify/utilities/utils.dart' ;
3940import 'package:musify/widgets/confirmation_dialog.dart' ;
@@ -157,7 +158,7 @@ class _LibraryPageState extends State<LibraryPage> {
157158 ),
158159 IconButton (
159160 padding: const EdgeInsets .symmetric (horizontal: 2 ),
160- onPressed: _showAddPlaylistDialog ,
161+ onPressed: () => showCreatePlaylistDialog (context) ,
161162 icon: Icon (
162163 FluentIcons .add_24_filled,
163164 color: colorScheme.onSurfaceVariant,
@@ -232,7 +233,7 @@ class _LibraryPageState extends State<LibraryPage> {
232233 icon: FluentIcons .add_circle_24_filled,
233234 actionButton: IconButton (
234235 padding: const EdgeInsets .only (right: 5 ),
235- onPressed: _showAddPlaylistDialog ,
236+ onPressed: () => showCreatePlaylistDialog (context) ,
236237 icon: Icon (
237238 FluentIcons .add_24_filled,
238239 color: colorScheme.onSurfaceVariant,
@@ -374,271 +375,6 @@ class _LibraryPageState extends State<LibraryPage> {
374375 );
375376 }
376377
377- void _showAddPlaylistDialog () => showDialog (
378- context: context,
379- builder: (BuildContext context) {
380- var id = '' ;
381- var customPlaylistName = '' ;
382- var isYouTubeMode = true ;
383- String ? imageUrl;
384- String ? imageBase64;
385-
386- return StatefulBuilder (
387- builder: (context, dialogSetState) {
388- final colorScheme = Theme .of (context).colorScheme;
389-
390- Future <void > _pickImage () async {
391- final result = await pickImage ();
392- if (result != null ) {
393- dialogSetState (() {
394- imageBase64 = result;
395- imageUrl = null ;
396- });
397- }
398- }
399-
400- Widget _imagePreview () {
401- return buildImagePreview (
402- imageBase64: imageBase64,
403- imageUrl: imageUrl,
404- );
405- }
406-
407- return AlertDialog (
408- backgroundColor: colorScheme.surface,
409- surfaceTintColor: Colors .transparent,
410- shape: RoundedRectangleBorder (
411- borderRadius: BorderRadius .circular (28 ),
412- ),
413- title: Text (
414- context.l10n! .addPlaylist,
415- style: TextStyle (
416- color: colorScheme.onSurface,
417- fontWeight: FontWeight .w600,
418- ),
419- ),
420- content: SingleChildScrollView (
421- child: Column (
422- mainAxisSize: MainAxisSize .min,
423- children: < Widget > [
424- Container (
425- decoration: BoxDecoration (
426- color: colorScheme.surfaceContainerLow,
427- borderRadius: BorderRadius .circular (16 ),
428- ),
429- padding: const EdgeInsets .all (4 ),
430- child: Row (
431- children: [
432- Expanded (
433- child: GestureDetector (
434- onTap: () {
435- dialogSetState (() {
436- isYouTubeMode = true ;
437- id = '' ;
438- customPlaylistName = '' ;
439- imageUrl = null ;
440- imageBase64 = null ;
441- });
442- },
443- child: AnimatedContainer (
444- duration: const Duration (milliseconds: 200 ),
445- padding: const EdgeInsets .symmetric (vertical: 12 ),
446- decoration: BoxDecoration (
447- color: isYouTubeMode
448- ? colorScheme.primaryContainer
449- : Colors .transparent,
450- borderRadius: BorderRadius .circular (12 ),
451- ),
452- child: Row (
453- mainAxisAlignment: MainAxisAlignment .center,
454- children: [
455- Icon (
456- FluentIcons .globe_20_filled,
457- size: 20 ,
458- color: isYouTubeMode
459- ? colorScheme.onPrimaryContainer
460- : colorScheme.onSurfaceVariant,
461- ),
462- const SizedBox (width: 8 ),
463- Text (
464- 'YouTube' ,
465- style: TextStyle (
466- color: isYouTubeMode
467- ? colorScheme.onPrimaryContainer
468- : colorScheme.onSurfaceVariant,
469- fontWeight: isYouTubeMode
470- ? FontWeight .w600
471- : FontWeight .w500,
472- ),
473- ),
474- ],
475- ),
476- ),
477- ),
478- ),
479- Expanded (
480- child: GestureDetector (
481- onTap: () {
482- dialogSetState (() {
483- isYouTubeMode = false ;
484- id = '' ;
485- customPlaylistName = '' ;
486- imageUrl = null ;
487- imageBase64 = null ;
488- });
489- },
490- child: AnimatedContainer (
491- duration: const Duration (milliseconds: 200 ),
492- padding: const EdgeInsets .symmetric (vertical: 12 ),
493- decoration: BoxDecoration (
494- color: ! isYouTubeMode
495- ? colorScheme.primaryContainer
496- : Colors .transparent,
497- borderRadius: BorderRadius .circular (12 ),
498- ),
499- child: Row (
500- mainAxisAlignment: MainAxisAlignment .center,
501- children: [
502- Icon (
503- FluentIcons .person_20_filled,
504- size: 20 ,
505- color: ! isYouTubeMode
506- ? colorScheme.onPrimaryContainer
507- : colorScheme.onSurfaceVariant,
508- ),
509- const SizedBox (width: 8 ),
510- Text (
511- context.l10n! .custom,
512- style: TextStyle (
513- color: ! isYouTubeMode
514- ? colorScheme.onPrimaryContainer
515- : colorScheme.onSurfaceVariant,
516- fontWeight: ! isYouTubeMode
517- ? FontWeight .w600
518- : FontWeight .w500,
519- ),
520- ),
521- ],
522- ),
523- ),
524- ),
525- ),
526- ],
527- ),
528- ),
529- const SizedBox (height: 20 ),
530- if (isYouTubeMode)
531- TextField (
532- decoration: InputDecoration (
533- labelText: context.l10n! .youtubePlaylistLinkOrId,
534- prefixIcon: Icon (
535- FluentIcons .link_20_regular,
536- color: colorScheme.onSurfaceVariant,
537- ),
538- border: OutlineInputBorder (
539- borderRadius: BorderRadius .circular (12 ),
540- ),
541- filled: true ,
542- fillColor: colorScheme.surfaceContainerLow,
543- ),
544- onChanged: (value) {
545- id = value;
546- },
547- )
548- else ...[
549- TextField (
550- decoration: InputDecoration (
551- labelText: context.l10n! .customPlaylistName,
552- prefixIcon: Icon (
553- FluentIcons .text_field_20_regular,
554- color: colorScheme.onSurfaceVariant,
555- ),
556- border: OutlineInputBorder (
557- borderRadius: BorderRadius .circular (12 ),
558- ),
559- filled: true ,
560- fillColor: colorScheme.surfaceContainerLow,
561- ),
562- onChanged: (value) {
563- customPlaylistName = value;
564- },
565- ),
566- if (imageBase64 == null ) ...[
567- const SizedBox (height: 12 ),
568- TextField (
569- decoration: InputDecoration (
570- labelText: context.l10n! .customPlaylistImgUrl,
571- prefixIcon: Icon (
572- FluentIcons .image_20_regular,
573- color: colorScheme.onSurfaceVariant,
574- ),
575- border: OutlineInputBorder (
576- borderRadius: BorderRadius .circular (12 ),
577- ),
578- filled: true ,
579- fillColor: colorScheme.surfaceContainerLow,
580- ),
581- onChanged: (value) {
582- imageUrl = value;
583- imageBase64 = null ;
584- dialogSetState (() {});
585- },
586- ),
587- ],
588- const SizedBox (height: 12 ),
589- if (imageUrl == null ) ...[
590- buildImagePickerRow (
591- context,
592- _pickImage,
593- imageBase64 != null ,
594- ),
595- _imagePreview (),
596- ],
597- ],
598- ],
599- ),
600- ),
601- actions: < Widget > [
602- TextButton (
603- onPressed: () => Navigator .pop (context),
604- child: Text (
605- context.l10n! .cancel,
606- style: TextStyle (color: colorScheme.onSurfaceVariant),
607- ),
608- ),
609- FilledButton .icon (
610- onPressed: () async {
611- if (isYouTubeMode && id.isNotEmpty) {
612- showToast (context, await addUserPlaylist (id, context));
613- } else if (! isYouTubeMode && customPlaylistName.isNotEmpty) {
614- showToast (
615- context,
616- createCustomPlaylist (
617- customPlaylistName,
618- imageBase64 ?? imageUrl,
619- context,
620- ),
621- );
622- } else {
623- showToast (
624- context,
625- '${context .l10n !.provideIdOrNameError }.' ,
626- );
627- }
628-
629- if (! mounted) return ;
630- Navigator .pop (context);
631- },
632- icon: const Icon (FluentIcons .add_20_filled),
633- label: Text (context.l10n! .add),
634- ),
635- ],
636- );
637- },
638- );
639- },
640- );
641-
642378 void _showRemoveOfflinePlaylistDialog (Map playlist) {
643379 final playlistId = playlist['ytid' ]? .toString () ?? '' ;
644380 if (playlistId.isEmpty) return ;
0 commit comments