From a490b394d3f0d3c6e9688c5a408a1f27f340a5e5 Mon Sep 17 00:00:00 2001 From: avi Date: Wed, 30 Sep 2026 10:23:21 -0500 Subject: [PATCH] fix(library): overflow menu for refresh/delete/multi-select so title keeps full width; song-count plural --- .../java/com/rada/ui/library/LibraryScreen.kt | 113 ++++++++++++------ 1 file changed, 76 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/com/rada/ui/library/LibraryScreen.kt b/app/src/main/java/com/rada/ui/library/LibraryScreen.kt index 3c0ab77..04db2c6 100644 --- a/app/src/main/java/com/rada/ui/library/LibraryScreen.kt +++ b/app/src/main/java/com/rada/ui/library/LibraryScreen.kt @@ -29,6 +29,7 @@ import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.Checklist import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Delete +import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.filled.Favorite import androidx.compose.material.icons.filled.FavoriteBorder import androidx.compose.material.icons.filled.MusicNote @@ -108,6 +109,7 @@ fun LibraryScreen( var showSearch by remember { mutableStateOf(false) } var searchQuery by remember { mutableStateOf("") } var showImportMenu by remember { mutableStateOf(false) } + var showMoreMenu by remember { mutableStateOf(false) } var showAppearance by remember { mutableStateOf(false) } var playlistToDelete by remember { mutableStateOf(null) } var songForPlaylist by remember { mutableStateOf(null) } @@ -155,7 +157,14 @@ fun LibraryScreen( Scaffold( topBar = { TopAppBar( - title = { Text("Library") }, + title = { + Text( + "Library", + maxLines = 1, + overflow = TextOverflow.Ellipsis, + fontWeight = FontWeight.Bold, + ) + }, navigationIcon = { Row(horizontalArrangement = Arrangement.Start) { AppHomeButton(onClick = onHome) @@ -198,45 +207,75 @@ fun LibraryScreen( Icon(Icons.Default.Shuffle, contentDescription = "Shuffle play") } } - IconButton( - onClick = { viewModel.refreshImportedFolders() }, - enabled = !uiState.isImporting, - ) { - Icon( - Icons.Default.Refresh, - contentDescription = "Refresh imported folders", - tint = if (uiState.isImporting) { - LocalTokens.current.textSecondary.copy(alpha = 0.4f) - } else { - LocalTokens.current.textSecondary - }, - ) - } - // Reliable delete path for the selected folder (besides long-press). - if (uiState.selectedPlaylistId != null) { - allPlaylists.firstOrNull { it.id == uiState.selectedPlaylistId }?.let { selected -> - IconButton(onClick = { playlistToDelete = selected }) { - Icon( - Icons.Default.Delete, - contentDescription = "Delete folder", - tint = LocalTokens.current.textSecondary, + // Refresh / delete-folder / multi-select live in one + // overflow menu so the title keeps its full width instead + // of wrapping mid-word ("Libr|ary"). All still reachable. + Box { + IconButton(onClick = { showMoreMenu = true }) { + Icon( + Icons.Default.MoreVert, + contentDescription = "More library actions", + tint = if (uiState.isMultiSelect) LocalTokens.current.accentFill + else LocalTokens.current.textSecondary, + ) + } + DropdownMenu( + expanded = showMoreMenu, + onDismissRequest = { showMoreMenu = false }, + ) { + DropdownMenuItem( + text = { Text("Refresh imported folders") }, + enabled = !uiState.isImporting, + onClick = { + showMoreMenu = false + viewModel.refreshImportedFolders() + }, + leadingIcon = { Icon(Icons.Default.Refresh, contentDescription = null) }, + ) + if (uiState.selectedPlaylistId != null) { + allPlaylists.firstOrNull { it.id == uiState.selectedPlaylistId } + ?.let { selected -> + DropdownMenuItem( + text = { Text("Delete “${selected.name}”") }, + onClick = { + showMoreMenu = false + playlistToDelete = selected + }, + leadingIcon = { + Icon( + Icons.Default.Delete, + contentDescription = null, + tint = MaterialTheme.colorScheme.error, + ) + }, + ) + } + } + if (tabLabels.size > 1) { + DropdownMenuItem( + text = { + Text( + if (uiState.isMultiSelect) "Exit multi-select" + else "Select multiple folders", + ) + }, + onClick = { + showMoreMenu = false + if (uiState.isMultiSelect) viewModel.exitMultiSelect() + else viewModel.enterMultiSelect() + }, + leadingIcon = { + Icon( + Icons.Default.Checklist, + contentDescription = null, + tint = if (uiState.isMultiSelect) LocalTokens.current.accentFill + else LocalTokens.current.textSecondary, + ) + }, ) } } } - // Multi-select: combine several folders, shuffle the union. - if (tabLabels.size > 1) { - IconButton(onClick = { - if (uiState.isMultiSelect) viewModel.exitMultiSelect() - else viewModel.enterMultiSelect() - }) { - Icon( - Icons.Default.Checklist, - contentDescription = if (uiState.isMultiSelect) "Exit playlist selection" else "Select multiple playlists", - tint = if (uiState.isMultiSelect) LocalTokens.current.accentFill else LocalTokens.current.textSecondary, - ) - } - } IconButton(onClick = { showAppearance = true }) { Icon( Icons.Default.Settings, @@ -298,7 +337,7 @@ fun LibraryScreen( ) } Text( - text = "${uiState.songs.size} songs", + text = "${uiState.songs.size} ${if (uiState.songs.size == 1) "song" else "songs"}", style = MaterialTheme.typography.bodySmall, color = LocalTokens.current.textSecondary, )