From fba3ef8626ed8d294ea046e28e34cf53b7673fd9 Mon Sep 17 00:00:00 2001 From: jjangddu Date: Wed, 2 Sep 2026 17:29:06 +0900 Subject: [PATCH] =?UTF-8?q?fix(clinical):=20=EB=B3=91=EC=9B=90=20=EC=9E=84?= =?UTF-8?q?=EC=83=81=20=EB=AA=A8=EB=93=9C=EC=97=90=EC=84=9C=20=EA=B8=B0?= =?UTF-8?q?=EA=B8=B0=20=EC=97=B0=EA=B2=B0=EB=A1=9C=20=EA=B0=88=20=EA=B8=B8?= =?UTF-8?q?=EC=9D=B4=20=EC=97=86=EC=97=88=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "기기를 먼저 연결해 주세요" 라고 안내만 하고 정작 가는 길이 없었다. 연결이 이 모드의 첫 단계인데, 조작자는 홈까지 되돌아가 일반 흐름을 타고 다시 들어와야 했다. ## 복귀처를 불리언이 아니라 값으로 기기 연결 화면은 여러 곳에서 불려 온다. 원래는 `ClinicalSessionStore.inClinicalFlow` 불리언 하나로 "임상 흐름이면 CLINICAL_HOME, 아니면 HOME" 만 갈랐다. 여기에 병원 모드용 불리언을 하나 더 만들면 그 순간부터 두 깃발이 어긋나기 시작한다. 그래서 `AppState.connectReturnScreen` 에 **어디로 돌아갈지를 값으로** 담는다. null 이면 기존 규칙 그대로라 **기존 호출부는 하나도 건드리지 않았다.** 한 번 쓰면 비운다 (consumeConnectReturn) — 안 비우면 다음에 다른 경로로 들어온 연결 화면까지 엉뚱한 곳으로 보낸다. ## 나가는 길이 셋이라 셋 다 손봤다 · 연결 성공 AppState.deviceConnected() · 시스템 뒤로가기 MainActivity BackHandler · 화면 안 화살표 AppState.backToSensorSelect() 세 번째에서 기존 문제도 드러났다 — 화면 안 화살표는 `inClinicalFlow` 를 보지 않고 늘 HOME 으로 간다. 시스템 뒤로가기와 목적지가 다르다. 기존부터 그랬고 지금 고치면 임상 흐름의 동작이 바뀌므로 그대로 두고 주석으로 남겼다. 복귀처를 지정한 화면만 두 경로가 같아진다. ## 검증 (실기기 23021RAA2Y) 홈 3연타 → 개발자 모드 → [병원 임상 측정] → [기기 연결] → 검색 화면 → 시스템 뒤로가기 / 화면 안 화살표 **둘 다** 병원 임상 화면으로 복귀. 크래시 0건. 연결 성공 경로는 프로브가 없어 아직 확인 못 했다. Co-Authored-By: Claude Opus 5 --- .../java/com/medithings/vesiscan/AppState.kt | 32 +++++++++++++++++++ .../com/medithings/vesiscan/MainActivity.kt | 8 +++-- .../ui/views/clinical/HospitalModeView.kt | 17 ++++++++-- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/medithings/vesiscan/AppState.kt b/app/src/main/java/com/medithings/vesiscan/AppState.kt index ec1a87c..8cab113 100644 --- a/app/src/main/java/com/medithings/vesiscan/AppState.kt +++ b/app/src/main/java/com/medithings/vesiscan/AppState.kt @@ -23,6 +23,26 @@ enum class AppScreen { class AppState(private val context: Context) { var currentScreen by mutableStateOf(AppScreen.ONBOARDING) + + /** + * DEVICE_SCAN 을 끝내고(연결 성공이든 뒤로가기든) 돌아갈 화면. + * + * 기기 연결 화면은 여러 곳에서 불려 오는데, 원래는 `ClinicalSessionStore.inClinicalFlow` + * 불리언 하나로 "임상 흐름이면 CLINICAL_HOME, 아니면 HOME" 만 갈랐다. 부르는 곳이 + * 셋 이상이 되면 불리언을 더 만들게 되고, 그 순간부터 두 깃발이 어긋나기 시작한다. + * + * 그래서 **어디로 돌아갈지를 값으로** 들고 있는다. null 이면 기존 규칙대로 간다 — + * 기존 호출부는 하나도 건드리지 않았다. + * + * 한 번 쓰면 비운다([consumeConnectReturn]). 안 비우면 다음에 다른 경로로 들어온 + * 연결 화면까지 엉뚱한 곳으로 보낸다. + */ + var connectReturnScreen: AppScreen? = null + + /** 복귀 화면을 꺼내며 지운다. 없으면 null. */ + fun consumeConnectReturn(): AppScreen? = + connectReturnScreen.also { connectReturnScreen = null } + var user by mutableStateOf(User()) var sensorMode by mutableStateOf(SensorMode.PIEZO) var bladderLevel by mutableStateOf(BladderLevel()) @@ -121,12 +141,24 @@ class AppState(private val context: Context) { currentScreen = AppScreen.DEVICE_SCAN } + /** + * 기기 연결 화면의 **화면 안 뒤로 화살표**. + * + * ⚠ 시스템 뒤로가기(MainActivity BackHandler)와 목적지가 다르다 — 그쪽은 + * `inClinicalFlow` 를 보고 CLINICAL_HOME 으로 가는데 여기는 늘 HOME 이다. + * 기존부터 그랬고 지금 손대면 임상 흐름의 동작이 바뀌므로 그대로 둔다. + * 다만 복귀처를 지정한 화면([connectReturnScreen])은 두 경로가 같아야 하므로 + * 여기서도 먼저 확인한다. + */ fun backToSensorSelect() { + consumeConnectReturn()?.let { currentScreen = it; return } currentScreen = AppScreen.HOME } fun deviceConnected() { isDeviceConnected = true + // 부른 화면이 복귀처를 지정했으면 그리로 (병원 임상 모드 등). + consumeConnectReturn()?.let { currentScreen = it; return } // 임상 모드에서 BLE 연결 시 ClinicalHome으로 복귀 (Personalization 우회) if (com.medithings.vesiscan.services.ClinicalSessionStore.inClinicalFlow) { currentScreen = AppScreen.CLINICAL_HOME diff --git a/app/src/main/java/com/medithings/vesiscan/MainActivity.kt b/app/src/main/java/com/medithings/vesiscan/MainActivity.kt index 543780d..5a80672 100644 --- a/app/src/main/java/com/medithings/vesiscan/MainActivity.kt +++ b/app/src/main/java/com/medithings/vesiscan/MainActivity.kt @@ -147,9 +147,11 @@ fun MedilightApp(modifier: Modifier = Modifier) { // DeviceScan Back: 임상 흐름이면 ClinicalHome으로, 아니면 HOME AppScreen.DEVICE_SCAN -> appState.currentScreen = - if (com.medithings.vesiscan.services.ClinicalSessionStore.inClinicalFlow) - AppScreen.CLINICAL_HOME - else AppScreen.HOME + // 부른 화면이 복귀처를 지정했으면 그리로 (병원 임상 모드 등). + appState.consumeConnectReturn() + ?: if (com.medithings.vesiscan.services.ClinicalSessionStore.inClinicalFlow) + AppScreen.CLINICAL_HOME + else AppScreen.HOME AppScreen.PIEZO_PERSONALIZATION -> appState.currentScreen = AppScreen.DEVICE_SCAN // 임상 모드 측정 중이면 endMeasurement → ClinicalHome 복귀 AppScreen.PLACEMENT_GUIDE -> diff --git a/app/src/main/java/com/medithings/vesiscan/ui/views/clinical/HospitalModeView.kt b/app/src/main/java/com/medithings/vesiscan/ui/views/clinical/HospitalModeView.kt index fdc158c..94175b7 100644 --- a/app/src/main/java/com/medithings/vesiscan/ui/views/clinical/HospitalModeView.kt +++ b/app/src/main/java/com/medithings/vesiscan/ui/views/clinical/HospitalModeView.kt @@ -223,7 +223,20 @@ fun HospitalModeView(appState: AppState) { Column(Modifier.padding(horizontal = 16.dp)) { - StatusRow(isConnected, deviceName) + Row(verticalAlignment = Alignment.CenterVertically) { + StatusRow(isConnected, deviceName) + Spacer(Modifier.weight(1f)) + // 이 화면에서 바로 연결할 수 있어야 한다. 연결이 이 모드의 첫 단계인데 + // 가는 길이 없으면 홈까지 되돌아가 일반 흐름을 타야 했다. + // 복귀처를 지정해 두면 연결 성공/뒤로가기 모두 이 화면으로 돌아온다. + TextButton( + enabled = !running, + onClick = { + appState.connectReturnScreen = AppScreen.HOSPITAL_MODE + appState.currentScreen = AppScreen.DEVICE_SCAN + }, + ) { Text(if (isConnected) "기기 변경" else "기기 연결", fontWeight = FontWeight.SemiBold) } + } Spacer(Modifier.height(12.dp)) OutlinedTextField( @@ -277,7 +290,7 @@ fun HospitalModeView(appState: AppState) { shape = RoundedCornerShape(14.dp), ) { Text("측정 시작", fontSize = 17.sp, fontWeight = FontWeight.Bold) } - if (!isConnected) Hint("기기를 먼저 연결해 주세요.") + if (!isConnected) Hint("위 [기기 연결] 을 눌러 프로브를 연결해 주세요.") else if (patient.isBlank()) Hint("환자명을 입력해 주세요.") if (okCount > 0 || failCount > 0) {