fix(library): overflow menu for refresh/delete/multi-select so title keeps full width; song-count plural
This commit is contained in:
parent
9e84906715
commit
a490b394d3
1 changed files with 76 additions and 37 deletions
|
|
@ -29,6 +29,7 @@ import androidx.compose.material.icons.filled.Check
|
||||||
import androidx.compose.material.icons.filled.Checklist
|
import androidx.compose.material.icons.filled.Checklist
|
||||||
import androidx.compose.material.icons.filled.Close
|
import androidx.compose.material.icons.filled.Close
|
||||||
import androidx.compose.material.icons.filled.Delete
|
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.Favorite
|
||||||
import androidx.compose.material.icons.filled.FavoriteBorder
|
import androidx.compose.material.icons.filled.FavoriteBorder
|
||||||
import androidx.compose.material.icons.filled.MusicNote
|
import androidx.compose.material.icons.filled.MusicNote
|
||||||
|
|
@ -108,6 +109,7 @@ fun LibraryScreen(
|
||||||
var showSearch by remember { mutableStateOf(false) }
|
var showSearch by remember { mutableStateOf(false) }
|
||||||
var searchQuery by remember { mutableStateOf("") }
|
var searchQuery by remember { mutableStateOf("") }
|
||||||
var showImportMenu by remember { mutableStateOf(false) }
|
var showImportMenu by remember { mutableStateOf(false) }
|
||||||
|
var showMoreMenu by remember { mutableStateOf(false) }
|
||||||
var showAppearance by remember { mutableStateOf(false) }
|
var showAppearance by remember { mutableStateOf(false) }
|
||||||
var playlistToDelete by remember { mutableStateOf<PlaylistEntity?>(null) }
|
var playlistToDelete by remember { mutableStateOf<PlaylistEntity?>(null) }
|
||||||
var songForPlaylist by remember { mutableStateOf<SavedSongEntity?>(null) }
|
var songForPlaylist by remember { mutableStateOf<SavedSongEntity?>(null) }
|
||||||
|
|
@ -155,7 +157,14 @@ fun LibraryScreen(
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
title = { Text("Library") },
|
title = {
|
||||||
|
Text(
|
||||||
|
"Library",
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
)
|
||||||
|
},
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
Row(horizontalArrangement = Arrangement.Start) {
|
Row(horizontalArrangement = Arrangement.Start) {
|
||||||
AppHomeButton(onClick = onHome)
|
AppHomeButton(onClick = onHome)
|
||||||
|
|
@ -198,43 +207,73 @@ fun LibraryScreen(
|
||||||
Icon(Icons.Default.Shuffle, contentDescription = "Shuffle play")
|
Icon(Icons.Default.Shuffle, contentDescription = "Shuffle play")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IconButton(
|
// Refresh / delete-folder / multi-select live in one
|
||||||
onClick = { viewModel.refreshImportedFolders() },
|
// overflow menu so the title keeps its full width instead
|
||||||
enabled = !uiState.isImporting,
|
// of wrapping mid-word ("Libr|ary"). All still reachable.
|
||||||
) {
|
Box {
|
||||||
|
IconButton(onClick = { showMoreMenu = true }) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.Refresh,
|
Icons.Default.MoreVert,
|
||||||
contentDescription = "Refresh imported folders",
|
contentDescription = "More library actions",
|
||||||
tint = if (uiState.isImporting) {
|
tint = if (uiState.isMultiSelect) LocalTokens.current.accentFill
|
||||||
LocalTokens.current.textSecondary.copy(alpha = 0.4f)
|
else LocalTokens.current.textSecondary,
|
||||||
} 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,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// 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,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
// Multi-select: combine several folders, shuffle the union.
|
|
||||||
if (tabLabels.size > 1) {
|
if (tabLabels.size > 1) {
|
||||||
IconButton(onClick = {
|
DropdownMenuItem(
|
||||||
|
text = {
|
||||||
|
Text(
|
||||||
|
if (uiState.isMultiSelect) "Exit multi-select"
|
||||||
|
else "Select multiple folders",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onClick = {
|
||||||
|
showMoreMenu = false
|
||||||
if (uiState.isMultiSelect) viewModel.exitMultiSelect()
|
if (uiState.isMultiSelect) viewModel.exitMultiSelect()
|
||||||
else viewModel.enterMultiSelect()
|
else viewModel.enterMultiSelect()
|
||||||
}) {
|
},
|
||||||
|
leadingIcon = {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.Checklist,
|
Icons.Default.Checklist,
|
||||||
contentDescription = if (uiState.isMultiSelect) "Exit playlist selection" else "Select multiple playlists",
|
contentDescription = null,
|
||||||
tint = if (uiState.isMultiSelect) LocalTokens.current.accentFill else LocalTokens.current.textSecondary,
|
tint = if (uiState.isMultiSelect) LocalTokens.current.accentFill
|
||||||
|
else LocalTokens.current.textSecondary,
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IconButton(onClick = { showAppearance = true }) {
|
IconButton(onClick = { showAppearance = true }) {
|
||||||
|
|
@ -298,7 +337,7 @@ fun LibraryScreen(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Text(
|
Text(
|
||||||
text = "${uiState.songs.size} songs",
|
text = "${uiState.songs.size} ${if (uiState.songs.size == 1) "song" else "songs"}",
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
color = LocalTokens.current.textSecondary,
|
color = LocalTokens.current.textSecondary,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue