@@ -133,7 +133,7 @@ fun FavoritesScreen(navController: NavController) {
133133 if (groupName.isNotBlank()) {
134134 // Check if group with same name already exists
135135 val existingGroup = groups.find {
136- it.name.equals(groupName, ignoreCase = true )
136+ it.name.equals(groupName, ignoreCase = true ) && ! it.isDefault
137137 }
138138
139139 if (existingGroup == null ) {
@@ -171,7 +171,7 @@ fun FavoritesScreen(navController: NavController) {
171171 if (groupName.isNotBlank()) {
172172 // Check if group with same name already exists
173173 val existingGroup = groups.find {
174- it.name.equals(groupName, ignoreCase = true )
174+ it.name.equals(groupName, ignoreCase = true ) && ! it.isDefault
175175 }
176176
177177 if (existingGroup == null ) {
@@ -215,6 +215,165 @@ fun FavoritesScreen(navController: NavController) {
215215 )
216216 }
217217
218+ // Dialog for renaming a group
219+ var showRenameGroupDialog by remember { mutableStateOf(false ) }
220+ var groupToRename by remember { mutableStateOf<FavoriteGroup ?>(null ) }
221+ var newGroupName by remember { mutableStateOf(" " ) }
222+
223+ if (showRenameGroupDialog && groupToRename != null ) {
224+ AlertDialog (
225+ onDismissRequest = { showRenameGroupDialog = false },
226+ title = { Text (" Rename Playlist" ) },
227+ text = {
228+ OutlinedTextField (
229+ value = newGroupName,
230+ onValueChange = { newGroupName = it },
231+ label = { Text (" New Playlist Name" ) },
232+ modifier = Modifier .fillMaxWidth(),
233+ singleLine = true ,
234+ keyboardOptions = KeyboardOptions (
235+ imeAction = ImeAction .Done
236+ ),
237+ keyboardActions = KeyboardActions (
238+ onDone = {
239+ if (newGroupName.isNotBlank() && groupToRename != null ) {
240+ // Check if another group with same name already exists
241+ val existingGroup = groups.find {
242+ it.id != groupToRename!! .id &&
243+ it.name.equals(newGroupName, ignoreCase = true ) &&
244+ ! it.isDefault
245+ }
246+
247+ if (existingGroup == null ) {
248+ val updatedGroup = groupToRename!! .copy(name = newGroupName)
249+ StorageUtils .saveFavoriteGroup(context, updatedGroup)
250+ groups = StorageUtils .loadAllFavoriteGroups(context)
251+ showRenameGroupDialog = false
252+ groupToRename = null
253+ newGroupName = " "
254+ // Show success message
255+ android.widget.Toast .makeText(
256+ context,
257+ " Playlist renamed successfully" ,
258+ android.widget.Toast .LENGTH_SHORT
259+ ).show()
260+ } else {
261+ // Show error message
262+ android.widget.Toast .makeText(
263+ context,
264+ " A playlist with this name already exists" ,
265+ android.widget.Toast .LENGTH_SHORT
266+ ).show()
267+ }
268+ }
269+ }
270+ )
271+ )
272+ },
273+ confirmButton = {
274+ TextButton (
275+ onClick = {
276+ if (newGroupName.isNotBlank() && groupToRename != null ) {
277+ // Check if another group with same name already exists
278+ val existingGroup = groups.find {
279+ it.id != groupToRename!! .id &&
280+ it.name.equals(newGroupName, ignoreCase = true ) &&
281+ ! it.isDefault
282+ }
283+
284+ if (existingGroup == null ) {
285+ val updatedGroup = groupToRename!! .copy(name = newGroupName)
286+ StorageUtils .saveFavoriteGroup(context, updatedGroup)
287+ groups = StorageUtils .loadAllFavoriteGroups(context)
288+ showRenameGroupDialog = false
289+ groupToRename = null
290+ newGroupName = " "
291+ // Show success message
292+ android.widget.Toast .makeText(
293+ context,
294+ " Playlist renamed successfully" ,
295+ android.widget.Toast .LENGTH_SHORT
296+ ).show()
297+ } else {
298+ // Show error message
299+ android.widget.Toast .makeText(
300+ context,
301+ " A playlist with this name already exists" ,
302+ android.widget.Toast .LENGTH_SHORT
303+ ).show()
304+ }
305+ }
306+ },
307+ enabled = newGroupName.isNotBlank()
308+ ) {
309+ Text (" Rename" )
310+ }
311+ },
312+ dismissButton = {
313+ TextButton (
314+ onClick = {
315+ showRenameGroupDialog = false
316+ groupToRename = null
317+ newGroupName = " "
318+ }
319+ ) {
320+ Text (" Cancel" )
321+ }
322+ }
323+ )
324+ }
325+
326+ // Dialog for deleting a group
327+ var showDeleteGroupDialog by remember { mutableStateOf(false ) }
328+ var groupToDelete by remember { mutableStateOf<FavoriteGroup ?>(null ) }
329+
330+ if (showDeleteGroupDialog && groupToDelete != null ) {
331+ AlertDialog (
332+ onDismissRequest = { showDeleteGroupDialog = false },
333+ title = { Text (" Delete Playlist" ) },
334+ text = {
335+ Text (" Are you sure you want to delete the playlist \" ${groupToDelete!! .name} \" ? This action cannot be undone." )
336+ },
337+ confirmButton = {
338+ TextButton (
339+ onClick = {
340+ if (groupToDelete != null ) {
341+ StorageUtils .removeFavoriteGroup(context, groupToDelete!! .id)
342+ groups = StorageUtils .loadAllFavoriteGroups(context)
343+
344+ // If the deleted group was the selected group, switch to default
345+ if (selectedGroup?.id == groupToDelete!! .id) {
346+ selectedGroup = groups.firstOrNull { it.isDefault }
347+ favorites = StorageUtils .loadAllFavorites(context)
348+ }
349+
350+ showDeleteGroupDialog = false
351+ groupToDelete = null
352+ // Show success message
353+ android.widget.Toast .makeText(
354+ context,
355+ " Playlist deleted successfully" ,
356+ android.widget.Toast .LENGTH_SHORT
357+ ).show()
358+ }
359+ }
360+ ) {
361+ Text (" Delete" )
362+ }
363+ },
364+ dismissButton = {
365+ TextButton (
366+ onClick = {
367+ showDeleteGroupDialog = false
368+ groupToDelete = null
369+ }
370+ ) {
371+ Text (" Cancel" )
372+ }
373+ }
374+ )
375+ }
376+
218377 // Dialog for moving item to groups (multi-select)
219378 if (showMoveToGroupDialog && selectedItem != null ) {
220379 val item = selectedItem!!
@@ -363,30 +522,74 @@ fun FavoritesScreen(navController: NavController) {
363522 horizontalArrangement = androidx.compose.foundation.layout.Arrangement .spacedBy(8 .dp)
364523 ) {
365524 items(groups) { group ->
366- Card (
367- modifier = Modifier
368- .padding(vertical = 4 .dp)
369- .clickable {
370- selectedGroup = group
371- // Load favorites for this group
372- favorites = if (group.isDefault) {
373- StorageUtils .loadAllFavorites(context)
374- } else {
375- StorageUtils .getFavoritesInGroup(context, group.id)
525+ Box {
526+ var showGroupMenu by remember { mutableStateOf(false ) }
527+
528+ Card (
529+ modifier = Modifier
530+ .padding(vertical = 4 .dp)
531+ .clickable {
532+ selectedGroup = group
533+ // Load favorites for this group
534+ favorites = if (group.isDefault) {
535+ StorageUtils .loadAllFavorites(context)
536+ } else {
537+ StorageUtils .getFavoritesInGroup(context, group.id)
538+ }
539+ },
540+ shape = RoundedCornerShape (16 .dp),
541+ elevation = CardDefaults .cardElevation(defaultElevation = if (selectedGroup?.id == group.id) 4 .dp else 0 .dp),
542+ colors = if (selectedGroup?.id == group.id) {
543+ CardDefaults .cardColors(containerColor = MaterialTheme .colorScheme.primaryContainer)
544+ } else {
545+ CardDefaults .cardColors()
546+ }
547+ ) {
548+ Row (
549+ modifier = Modifier .padding(horizontal = 12 .dp, vertical = 8 .dp),
550+ verticalAlignment = Alignment .CenterVertically
551+ ) {
552+ Text (text = group.name)
553+
554+ // Show menu icon for non-default groups
555+ if (! group.isDefault) {
556+ IconButton (
557+ onClick = { showGroupMenu = true },
558+ modifier = Modifier .size(24 .dp)
559+ ) {
560+ Icon (
561+ imageVector = Icons .Default .MoreVert ,
562+ contentDescription = " Group options" ,
563+ modifier = Modifier .size(16 .dp)
564+ )
565+ }
376566 }
377- },
378- shape = RoundedCornerShape (16 .dp),
379- elevation = CardDefaults .cardElevation(defaultElevation = if (selectedGroup?.id == group.id) 4 .dp else 0 .dp),
380- colors = if (selectedGroup?.id == group.id) {
381- CardDefaults .cardColors(containerColor = MaterialTheme .colorScheme.primaryContainer)
382- } else {
383- CardDefaults .cardColors()
567+ }
568+ }
569+
570+ // Group menu for rename/delete options
571+ DropdownMenu (
572+ expanded = showGroupMenu,
573+ onDismissRequest = { showGroupMenu = false }
574+ ) {
575+ DropdownMenuItem (
576+ text = { Text (" Rename" ) },
577+ onClick = {
578+ groupToRename = group
579+ newGroupName = group.name
580+ showRenameGroupDialog = true
581+ showGroupMenu = false
582+ }
583+ )
584+ DropdownMenuItem (
585+ text = { Text (" Delete" ) },
586+ onClick = {
587+ groupToDelete = group
588+ showDeleteGroupDialog = true
589+ showGroupMenu = false
590+ }
591+ )
384592 }
385- ) {
386- Text (
387- text = group.name,
388- modifier = Modifier .padding(horizontal = 12 .dp, vertical = 8 .dp)
389- )
390593 }
391594 }
392595 }
0 commit comments