fix(library): overflow menu for refresh/delete/multi-select so title keeps full width; song-count plural

This commit is contained in:
avi 2026-09-30 10:23:21 -05:00
commit a490b394d3

View file

@ -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<PlaylistEntity?>(null) }
var songForPlaylist by remember { mutableStateOf<SavedSongEntity?>(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,
)