|
|
|
@ -185,35 +185,34 @@ fun InputBar( |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
/* Idle: PTT + send */ |
|
|
|
/* Idle: PTT + send */ |
|
|
|
IconButton( |
|
|
|
Box( |
|
|
|
onClick = { |
|
|
|
modifier = Modifier |
|
|
|
if (!hasMicPerm) { permLauncher.launch(Manifest.permission.RECORD_AUDIO); return@IconButton } |
|
|
|
.size(48.dp) |
|
|
|
}, |
|
|
|
.pointerInput(hasMicPerm) { |
|
|
|
enabled = true, |
|
|
|
|
|
|
|
modifier = Modifier.pointerInput(Unit) { |
|
|
|
|
|
|
|
awaitPointerEventScope { |
|
|
|
awaitPointerEventScope { |
|
|
|
/* wait for the first down */ |
|
|
|
val down = awaitPointerEvent() |
|
|
|
var event = awaitPointerEvent() |
|
|
|
val ch = down.changes.firstOrNull() ?: return@awaitPointerEventScope |
|
|
|
var change = event.changes.firstOrNull() ?: return@awaitPointerEventScope |
|
|
|
if (!ch.pressed) return@awaitPointerEventScope |
|
|
|
if (!change.pressed) return@awaitPointerEventScope |
|
|
|
ch.consume() |
|
|
|
change.consume() |
|
|
|
|
|
|
|
|
|
|
|
if (!hasMicPerm) { |
|
|
|
|
|
|
|
permLauncher.launch(Manifest.permission.RECORD_AUDIO) |
|
|
|
|
|
|
|
return@awaitPointerEventScope |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!hasMicPerm) return@awaitPointerEventScope |
|
|
|
|
|
|
|
onPttPressed() |
|
|
|
onPttPressed() |
|
|
|
var locked = false |
|
|
|
var locked = false |
|
|
|
var totalDragY = 0f |
|
|
|
var totalDragY = 0f |
|
|
|
var lastY = change.position.y |
|
|
|
var lastY = ch.position.y |
|
|
|
|
|
|
|
|
|
|
|
while (true) { |
|
|
|
while (true) { |
|
|
|
event = awaitPointerEvent() |
|
|
|
val event = awaitPointerEvent() |
|
|
|
change = event.changes.firstOrNull() ?: break |
|
|
|
val change = event.changes.firstOrNull() ?: break |
|
|
|
if (change.pressed) { |
|
|
|
if (change.pressed) { |
|
|
|
val dy = change.position.y - lastY |
|
|
|
val dy = change.position.y - lastY |
|
|
|
lastY = change.position.y |
|
|
|
lastY = change.position.y |
|
|
|
totalDragY += dy |
|
|
|
totalDragY += dy |
|
|
|
if (totalDragY < -lockThresholdPx && !locked) { |
|
|
|
if (totalDragY < -lockThresholdPx && !locked) { locked = true; onPttLock() } |
|
|
|
locked = true; onPttLock() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
change.consume() |
|
|
|
change.consume() |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
change.consume(); break |
|
|
|
change.consume(); break |
|
|
|
@ -221,11 +220,14 @@ fun InputBar( |
|
|
|
} |
|
|
|
} |
|
|
|
onPttReleased() |
|
|
|
onPttReleased() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
contentAlignment = Alignment.Center |
|
|
|
) { |
|
|
|
) { |
|
|
|
Text("\uD83C\uDFA4", fontSize = 20.sp) |
|
|
|
Text("\uD83C\uDFA4", fontSize = 20.sp) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Spacer(Modifier.width(4.dp)) |
|
|
|
|
|
|
|
|
|
|
|
Button(onClick = onSend, enabled = enabled && text.isNotBlank()) { |
|
|
|
Button(onClick = onSend, enabled = enabled && text.isNotBlank()) { |
|
|
|
Text("Send") |
|
|
|
Text("Send") |
|
|
|
} |
|
|
|
} |
|
|
|
|