fix(android): StorageCard — simpler OutlinedButton + DropdownMenu

Compile errors on 6ef08ed: ExposedDropdownMenu is an extension on
ExposedDropdownMenuBoxScope and can't be referenced by FQN from
outside a Composable receiver. Rewrote both dropdowns using the
plain OutlinedButton + DropdownMenu pattern wrapped in a small
LabeledDropdown<T> helper, which works without the Scope dance.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-26 17:55:29 -04:00
parent 5455cd5d80
commit c9bf0479ec
@@ -11,17 +11,14 @@ import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -122,12 +119,41 @@ private fun UsageRow(usedBytes: Long) {
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun CapDropdown(label: String, value: Long, onSet: (Long) -> Unit) {
var expanded by remember { mutableStateOf(false) }
val selectedLabel = CAP_OPTIONS.firstOrNull { it.first == value }?.second
?: formatBytes(value)
LabeledDropdown(
label = label,
selectedLabel = selectedLabel,
options = CAP_OPTIONS,
onSelect = onSet,
)
}
@Composable
private fun PrefetchDropdown(value: Int, onSet: (Int) -> Unit) {
val selected = if (value in PREFETCH_OPTIONS) value else PREFETCH_OPTIONS[2]
LabeledDropdown(
label = "Pre-fetch ahead",
selectedLabel = "$selected tracks",
options = PREFETCH_OPTIONS.map { it to "$it tracks" },
onSelect = onSet,
)
}
/**
* Label on the left, button-with-current-value on the right that opens
* a DropdownMenu of [options]. Used by both Cap and Prefetch selectors.
*/
@Composable
private fun <T> LabeledDropdown(
label: String,
selectedLabel: String,
options: List<Pair<T, String>>,
onSelect: (T) -> Unit,
) {
var expanded by remember { mutableStateOf(false) }
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
@@ -138,73 +164,18 @@ private fun CapDropdown(label: String, value: Long, onSet: (Long) -> Unit) {
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.weight(1f),
)
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = it },
) {
TextField(
value = selectedLabel,
onValueChange = {},
readOnly = true,
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
modifier = Modifier.menuAnchor(),
)
ExposedDropdownMenuDefaults.run {
androidx.compose.material3.ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
) {
CAP_OPTIONS.forEach { (bytes, name) ->
DropdownMenuItem(
text = { Text(name) },
onClick = {
expanded = false
onSet(bytes)
},
)
}
}
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun PrefetchDropdown(value: Int, onSet: (Int) -> Unit) {
var expanded by remember { mutableStateOf(false) }
val selected = if (value in PREFETCH_OPTIONS) value else PREFETCH_OPTIONS[2]
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = "Pre-fetch ahead",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.weight(1f),
)
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = it },
) {
TextField(
value = "$selected tracks",
onValueChange = {},
readOnly = true,
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
modifier = Modifier.menuAnchor(),
)
androidx.compose.material3.ExposedDropdownMenu(
OutlinedButton(onClick = { expanded = true }) {
Text(selectedLabel)
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
) {
PREFETCH_OPTIONS.forEach { n ->
options.forEach { (value, name) ->
DropdownMenuItem(
text = { Text("$n tracks") },
text = { Text(name) },
onClick = {
expanded = false
onSet(n)
onSelect(value)
},
)
}