fix the overlapping options in the concurrency dialog

ChoiceGroup emitted its header and option rows as siblings straight into the AlertDialog text slot, and they drew on top of each other, leaving only one radio visible with garbled labels. Wrap the group in its own Column so the rows stack, and cover it with a test that asserts the presets occupy separate rows.
This commit is contained in:
austinried
2026-10-04 00:30:03 +00:00
parent cf6ee00b6f
commit 6f25f426ba
2 changed files with 67 additions and 9 deletions
@@ -323,15 +323,17 @@ private fun <T> ChoiceGroup(
selected: T,
onSelect: (T) -> Unit,
) {
Text(header, style = MaterialTheme.typography.titleSmall, color = MaterialTheme.colorScheme.primary)
options.forEach { (value, label) ->
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth().clickable { onSelect(value) },
) {
RadioButton(selected = value == selected, onClick = { onSelect(value) })
Spacer(Modifier.width(8.dp))
Text(label)
Column {
Text(header, style = MaterialTheme.typography.titleSmall, color = MaterialTheme.colorScheme.primary)
options.forEach { (value, label) ->
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth().clickable { onSelect(value) },
) {
RadioButton(selected = value == selected, onClick = { onSelect(value) })
Spacer(Modifier.width(8.dp))
Text(label)
}
}
}
}
@@ -0,0 +1,56 @@
package com.subtracks.ui.settings
import androidx.activity.ComponentActivity
import androidx.compose.ui.test.junit4.v2.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.github.takahirom.roborazzi.RobolectricDeviceQualifiers
import com.subtracks.data.prefs.StreamQuality
import com.subtracks.ui.theme.SubtracksTheme
import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.annotation.Config
import org.robolectric.annotation.GraphicsMode
@RunWith(AndroidJUnit4::class)
@GraphicsMode(GraphicsMode.Mode.NATIVE)
@Config(qualifiers = RobolectricDeviceQualifiers.PixelXL)
class SettingsConcurrencyDialogTest {
@get:Rule
val composeRule = createAndroidComposeRule<ComponentActivity>()
@Test
fun theConcurrencyDialogListsEachPresetOnItsOwnRow() {
composeRule.setContent {
SubtracksTheme {
SettingsScreen(
sources = emptyList(),
activeSourceId = null,
wifiQuality = StreamQuality(),
mobileQuality = StreamQuality(),
syncConcurrency = 5,
onSelectSource = {},
onDeleteSource = {},
onWifiQualityChange = {},
onMobileQualityChange = {},
onSyncConcurrencyChange = {},
onAddServer = {},
onBack = {},
)
}
}
composeRule.onNodeWithText("Sync concurrency").performClick()
val rows =
listOf("1 (sequential)", "2", "4", "8", "16").map {
composeRule.onNodeWithText(it).fetchSemanticsNode().boundsInRoot
}
rows.zipWithNext().forEach { (above, below) ->
assertTrue("concurrency options overlap: $above vs $below", below.top >= above.bottom)
}
}
}