android: fix PTT — one Box across all states, release now works; 1s min duration
- PTT Box: same composable identity in idle/recording states (just changes bg color) Gesture coroutine survives recomposition → onPttReleased() fires on finger lift. When locked, Box is replaced by cancel/send IconButtons. - Min voice duration: 500→1000ms (C and ViewModel)
This commit is contained in:
1 parent
90de87b13d
commit
00afc5c80a
3 files changed
+12
-18
No files matched your search
+10
-16
@@ -167,27 +167,20 @@ fun InputBar(
|
||||
Spacer(Modifier.width(4.dp))
|
||||
|
||||
if (isRecording && isRecordingLocked) {
|
||||
/* Locked: cancel + send voice */
|
||||
/* Locked: cancel + send voice — PTT box replaced by action buttons */
|
||||
IconButton(onClick = onVoiceCancel) {
|
||||
Text("\u2715", fontSize = 20.sp, color = Color(0xFFE53935))
|
||||
}
|
||||
IconButton(onClick = onVoiceSend) {
|
||||
Text("\u25B6", fontSize = 20.sp, color = Color(0xFF4CAF50))
|
||||
}
|
||||
} else if (isRecording) {
|
||||
/* Holding: only PTT active */
|
||||
IconButton(
|
||||
onClick = {},
|
||||
enabled = true,
|
||||
modifier = Modifier.background(Color(0xFFE53935), RoundedCornerShape(4.dp))
|
||||
) {
|
||||
Text("\uD83C\uDFA4", fontSize = 20.sp)
|
||||
}
|
||||
} else {
|
||||
/* Idle: PTT + send */
|
||||
/* PTT Box — always present (same identity), just changes appearance */
|
||||
val pttBg = if (isRecording) Color(0xFFE53935) else Color.Transparent
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(48.dp)
|
||||
.background(pttBg, RoundedCornerShape(4.dp))
|
||||
.pointerInput(hasMicPerm) {
|
||||
awaitPointerEventScope {
|
||||
val down = awaitPointerEvent()
|
||||
@@ -223,13 +216,14 @@ fun InputBar(
|
||||
},
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text("\uD83C\uDFA4", fontSize = 20.sp)
|
||||
Text("\uD83C\uDFA4", fontSize = 20.sp, color = if (isRecording) Color.White else Color.Unspecified)
|
||||
}
|
||||
|
||||
Spacer(Modifier.width(4.dp))
|
||||
|
||||
Button(onClick = onSend, enabled = enabled && text.isNotBlank()) {
|
||||
Text("Send")
|
||||
if (!isRecording) {
|
||||
Spacer(Modifier.width(4.dp))
|
||||
Button(onClick = onSend, enabled = enabled && text.isNotBlank()) {
|
||||
Text("Send")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ class ChatViewModel : ViewModel() {
|
||||
|
||||
fun sendVoiceMessage() {
|
||||
val duration = stopVoiceRecording()
|
||||
if (duration < 500) {
|
||||
if (duration < 1000) {
|
||||
LogManager.addLog("INFO", "VM", "voice too short (${duration}ms), discarded")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ int voice_recorder_stop(int* out_duration_ms) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (elapsed_ms < 500) {
|
||||
if (elapsed_ms < 1000) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "voice_recorder_stop: too short %lldms, discarding", (long long)elapsed_ms);
|
||||
voice_cleanup_locked(g_rec);
|
||||
pthread_mutex_unlock(&g_rec->mtx);
|
||||
|
||||
Reference in new issue
Block a user