@@ -72,6 +72,21 @@ class _PlaylistFolderPageState extends State<PlaylistFolderPage> {
7272 ),
7373 color: Theme .of (context).colorScheme.surface,
7474 itemBuilder: (context) => [
75+ PopupMenuItem <String >(
76+ value: 'add' ,
77+ child: Row (
78+ mainAxisSize: MainAxisSize .min,
79+ children: [
80+ Icon (
81+ FluentIcons .add_24_regular,
82+ color: Theme .of (context).colorScheme.primary,
83+ size: 18 ,
84+ ),
85+ const SizedBox (width: 10 ),
86+ Text (context.l10n! .addPlaylist),
87+ ],
88+ ),
89+ ),
7590 PopupMenuItem <String >(
7691 value: 'rename' ,
7792 child: Row (
@@ -109,7 +124,9 @@ class _PlaylistFolderPageState extends State<PlaylistFolderPage> {
109124 ),
110125 ],
111126 onSelected: (value) {
112- if (value == 'rename' ) {
127+ if (value == 'add' ) {
128+ _showAddPlaylistDialog ();
129+ } else if (value == 'rename' ) {
113130 _showRenameFolderDialog ();
114131 } else if (value == 'delete' ) {
115132 _showDeleteFolderDialog ();
@@ -177,6 +194,58 @@ class _PlaylistFolderPageState extends State<PlaylistFolderPage> {
177194 );
178195 }
179196
197+ Future <void > _showAddPlaylistDialog () async {
198+ final customCandidates = getPlaylistsNotInFolders ();
199+ final youtubeCandidates = await getUserPlaylistsNotInFolders ();
200+ final candidates = [...customCandidates, ...youtubeCandidates];
201+
202+ if (! mounted) return ;
203+
204+ if (candidates.isEmpty) {
205+ showToast (context, context.l10n! .noPlaylistsAdded);
206+ return ;
207+ }
208+
209+ await showDialog (
210+ context: context,
211+ builder: (context) => AlertDialog (
212+ title: Text (context.l10n! .addPlaylist),
213+ content: SizedBox (
214+ width: double .maxFinite,
215+ child: ListView .builder (
216+ shrinkWrap: true ,
217+ itemCount: candidates.length,
218+ itemBuilder: (context, index) {
219+ final playlist = candidates[index];
220+ return ListTile (
221+ leading: Icon (
222+ FluentIcons .music_note_2_24_regular,
223+ color: Theme .of (context).colorScheme.primary,
224+ ),
225+ title: Text (
226+ playlist['title' ] ?? '' ,
227+ maxLines: 2 ,
228+ overflow: TextOverflow .ellipsis,
229+ ),
230+ onTap: () {
231+ Navigator .pop (context);
232+ movePlaylistToFolder (playlist, widget.folderId, context);
233+ _loadPlaylists ();
234+ },
235+ );
236+ },
237+ ),
238+ ),
239+ actions: [
240+ TextButton (
241+ onPressed: () => Navigator .pop (context),
242+ child: Text (context.l10n! .cancel),
243+ ),
244+ ],
245+ ),
246+ );
247+ }
248+
180249 void _showRemovePlaylistDialog (Map playlist) {
181250 showDialog (
182251 context: context,
0 commit comments