From b4279d76983913c2a5dd62cae5fdca5b58a8b590 Mon Sep 17 00:00:00 2001 From: jjangddu Date: Thu, 2 Apr 2026 13:06:38 +0900 Subject: [PATCH] Fix tab switching in CatheterizeSheet + camera launch timing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CatheterizeSheet: - Replace OutlinedButton with filled Button for tab selection - Selected tab: filled color, unselected: 10% opacity background - Tabs now reliably switch between 수기/음성/카메라 - Camera tab directly calls onCameraRequested + onDismiss PiezoMonitoringView: - Fix camera launch: use pendingCamera + LaunchedEffect to ensure ModalBottomSheet fully closes before camera opens - Prevents state race condition between sheet dismiss and camera show Co-Authored-By: Claude Opus 4.6 (1M context) --- .../ui/views/monitoring/CatheterizeSheet.kt | 59 ++++++++++++------- .../views/monitoring/PiezoMonitoringView.kt | 11 +++- 2 files changed, 48 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/CatheterizeSheet.kt b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/CatheterizeSheet.kt index 218a5c7..d88cad7 100644 --- a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/CatheterizeSheet.kt +++ b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/CatheterizeSheet.kt @@ -124,27 +124,44 @@ fun CatheterizeSheet( // 3 탭 버튼 Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) { - listOf( - Triple("수기", Icons.Default.Edit, Color(0xFFFF9800)), - Triple("음성", Icons.Default.SettingsVoice, Color(0xFF007AFF)), - Triple("카메라", Icons.Default.CameraAlt, Color(0xFF4CAF50)) - ).forEachIndexed { idx, (label, icon, color) -> - val isSelected = selectedTab == idx - OutlinedButton( - onClick = { - selectedTab = idx - if (idx == 2) { onCameraRequested(); onDismiss() } - }, - modifier = Modifier.weight(1f).height(64.dp), - shape = RoundedCornerShape(12.dp), - colors = ButtonDefaults.outlinedButtonColors( - containerColor = if (isSelected) color.copy(alpha = 0.1f) else Color.Transparent - ) - ) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Icon(icon, null, tint = color, modifier = Modifier.size(20.dp)) - Text(label, fontSize = 11.sp, color = color, fontWeight = FontWeight.SemiBold) - } + // 수기 + Button( + onClick = { selectedTab = 0 }, + modifier = Modifier.weight(1f).height(64.dp), + shape = RoundedCornerShape(12.dp), + colors = ButtonDefaults.buttonColors( + containerColor = if (selectedTab == 0) Color(0xFFFF9800) else Color(0xFFFF9800).copy(alpha = 0.1f) + ) + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Icon(Icons.Default.Edit, null, Modifier.size(20.dp), tint = if (selectedTab == 0) Color.White else Color(0xFFFF9800)) + Text("수기", fontSize = 11.sp, fontWeight = FontWeight.SemiBold, color = if (selectedTab == 0) Color.White else Color(0xFFFF9800)) + } + } + // 음성 + Button( + onClick = { selectedTab = 1 }, + modifier = Modifier.weight(1f).height(64.dp), + shape = RoundedCornerShape(12.dp), + colors = ButtonDefaults.buttonColors( + containerColor = if (selectedTab == 1) Color(0xFF007AFF) else Color(0xFF007AFF).copy(alpha = 0.1f) + ) + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Icon(Icons.Default.SettingsVoice, null, Modifier.size(20.dp), tint = if (selectedTab == 1) Color.White else Color(0xFF007AFF)) + Text("음성", fontSize = 11.sp, fontWeight = FontWeight.SemiBold, color = if (selectedTab == 1) Color.White else Color(0xFF007AFF)) + } + } + // 카메라 + Button( + onClick = { onCameraRequested(); onDismiss() }, + modifier = Modifier.weight(1f).height(64.dp), + shape = RoundedCornerShape(12.dp), + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF4CAF50).copy(alpha = 0.1f)) + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Icon(Icons.Default.CameraAlt, null, Modifier.size(20.dp), tint = Color(0xFF4CAF50)) + Text("카메라", fontSize = 11.sp, fontWeight = FontWeight.SemiBold, color = Color(0xFF4CAF50)) } } } diff --git a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt index 226f284..837153b 100644 --- a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt +++ b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt @@ -132,13 +132,22 @@ fun PiezoMonitoringView(appState: AppState) { ) } + // 카메라 요청 대기 상태 + var pendingCamera by remember { mutableStateOf(false) } + LaunchedEffect(pendingCamera) { + if (pendingCamera) { + pendingCamera = false + showUrineCamera = true + } + } + // 배뇨 기록 시트 (수기/음성/카메라) if (showCatheterizeSheet) { CatheterizeSheet( onDismiss = { showCatheterizeSheet = false }, onCameraRequested = { showCatheterizeSheet = false - showUrineCamera = true + pendingCamera = true }, onCatheterized = { appState.resetLevel()