fix: auto codec, force-ping button, relay delete button
1. Auto codec: new "Auto" position on quality slider (JNI index 7). When selected, the engine uses the relay's chosen_profile from CallAnswer instead of the local preference. Slider now has 8 positions: Studio 64k → Auto → Codec2 1.2k. 2. Force ping: added refresh button (↻) in Manage Relays dialog header. Calls pingAllServers() to re-check all relays on demand. 3. Delete relay fix: the X button was inside a Surface(onClick=...) which swallowed the touch event. Replaced with a separate Surface that properly intercepts the click. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -485,6 +485,7 @@ fun InCallScreen(
|
||||
onSelect = { idx -> viewModel.selectServer(idx) },
|
||||
onDelete = { idx -> viewModel.removeServer(idx) },
|
||||
onAdd = { addr, label -> viewModel.addServer(addr, label) },
|
||||
onRefresh = { viewModel.pingAllServers() },
|
||||
onDismiss = { showManageRelays = false }
|
||||
)
|
||||
}
|
||||
@@ -513,6 +514,7 @@ private fun ManageRelaysDialog(
|
||||
onSelect: (Int) -> Unit,
|
||||
onDelete: (Int) -> Unit,
|
||||
onAdd: (String, String) -> Unit,
|
||||
onRefresh: () -> Unit,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
var addName by remember { mutableStateOf("") }
|
||||
@@ -528,14 +530,26 @@ private fun ManageRelaysDialog(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text("Manage Relays", color = Color.White, fontWeight = FontWeight.Bold)
|
||||
Surface(
|
||||
onClick = onDismiss,
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
color = DarkSurface2,
|
||||
modifier = Modifier.size(32.dp)
|
||||
) {
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
Text("\u00D7", color = TextDim, fontSize = 18.sp)
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
Surface(
|
||||
onClick = onRefresh,
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
color = DarkSurface2,
|
||||
modifier = Modifier.size(32.dp)
|
||||
) {
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
Text("\u21BB", color = TextDim, fontSize = 16.sp)
|
||||
}
|
||||
}
|
||||
Surface(
|
||||
onClick = onDismiss,
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
color = DarkSurface2,
|
||||
modifier = Modifier.size(32.dp)
|
||||
) {
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
Text("\u00D7", color = TextDim, fontSize = 18.sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -590,13 +604,17 @@ private fun ManageRelaysDialog(
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
"\u00D7",
|
||||
color = TextDim,
|
||||
fontSize = 18.sp,
|
||||
modifier = Modifier.clickable { onDelete(idx) }
|
||||
)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Surface(
|
||||
onClick = { onDelete(idx) },
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
color = Color.Transparent,
|
||||
modifier = Modifier.size(32.dp)
|
||||
) {
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
Text("\u00D7", color = TextDim, fontSize = 18.sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,19 +245,19 @@ fun SettingsScreen(
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
// Quality selection — slider from best (studio 64k) to worst (codec2 1.2k)
|
||||
// Quality selection — slider from best (studio 64k) to worst (codec2 1.2k) + auto
|
||||
val qualityLabels = listOf(
|
||||
"Studio 64k", "Studio 48k", "Studio 32k", "Opus 24k",
|
||||
"Opus 6k", "Codec2 1.2k", "Codec2 3.2k"
|
||||
"Studio 64k", "Studio 48k", "Studio 32k", "Auto",
|
||||
"Opus 24k", "Opus 6k", "Codec2 3.2k", "Codec2 1.2k"
|
||||
)
|
||||
// Map slider position to JNI profile int:
|
||||
// 0=Studio64k(6), 1=Studio48k(5), 2=Studio32k(4), 3=Opus24k(0),
|
||||
// 4=Opus6k(1), 5=Codec2_1.2k(2), 6=Codec2_3.2k(3)
|
||||
val sliderToProfile = intArrayOf(6, 5, 4, 0, 1, 2, 3)
|
||||
val profileToSlider = mapOf(6 to 0, 5 to 1, 4 to 2, 0 to 3, 1 to 4, 2 to 5, 3 to 6)
|
||||
// 0=Studio64k(6), 1=Studio48k(5), 2=Studio32k(4), 3=Auto(7),
|
||||
// 4=Opus24k(0), 5=Opus6k(1), 6=Codec2_3.2k(3), 7=Codec2_1.2k(2)
|
||||
val sliderToProfile = intArrayOf(6, 5, 4, 7, 0, 1, 3, 2)
|
||||
val profileToSlider = mapOf(6 to 0, 5 to 1, 4 to 2, 7 to 3, 0 to 4, 1 to 5, 3 to 6, 2 to 7)
|
||||
val qualityColors = listOf(
|
||||
Color(0xFF22C55E), Color(0xFF4ADE80), Color(0xFF86EFAC), Color(0xFFA3E635),
|
||||
Color(0xFFFACC15), Color(0xFF991B1B), Color(0xFFE97320)
|
||||
Color(0xFFA3E635), Color(0xFFFACC15), Color(0xFFE97320), Color(0xFF991B1B)
|
||||
)
|
||||
val currentCodec by viewModel.codecChoice.collectAsState()
|
||||
val sliderPos = profileToSlider[currentCodec] ?: 3
|
||||
@@ -276,8 +276,8 @@ fun SettingsScreen(
|
||||
Slider(
|
||||
value = sliderPos.toFloat(),
|
||||
onValueChange = { viewModel.setCodecChoice(sliderToProfile[it.toInt()]) },
|
||||
valueRange = 0f..6f,
|
||||
steps = 5,
|
||||
valueRange = 0f..7f,
|
||||
steps = 6,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
Row(
|
||||
|
||||
Reference in New Issue
Block a user