UI text: revised 문서 반영 — 전체 텍스트 통일
[Placement] - Alignment Complete → Start Scanning - sensor → VesiScan (초기 안내) - Raise/Lower the sensor → Slide up/down - Move left/right → Slide left/right - Fine-tune → Optimizing, Checking LR → Centering - Optimal position! → In position! - Position lost/detached → Restart above pubic bone. - Past optimum → Too far, Lost signal → Signal lost [Donut] - Void/Catheterize → Voided/Catheterized - Auto → Auto Scan, Stop → Stop Scan, Spot → Single Scan - Voiding recorded → Recorded - 한글 다이얼로그 → 영어 (Disconnect and remove pairing.) - Sensor Position Issue → Position lost, Go to Alignment → Realign Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+10
-10
@@ -949,7 +949,7 @@ fun PiezoMonitoringView(appState: AppState) {
|
||||
lastVolumeMl = 0.0
|
||||
maxVolumeMl = 0.0
|
||||
resetMeasurement()
|
||||
android.widget.Toast.makeText(context, "Voiding recorded", android.widget.Toast.LENGTH_SHORT).show()
|
||||
android.widget.Toast.makeText(context, "Recorded", android.widget.Toast.LENGTH_SHORT).show()
|
||||
},
|
||||
enabled = !isSpotInProgress && !isAutoMeasuring,
|
||||
modifier = Modifier.weight(1.3f).height(btnHeight),
|
||||
@@ -960,8 +960,8 @@ fun PiezoMonitoringView(appState: AppState) {
|
||||
)
|
||||
) {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Text("Void /", fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = MlPrimary)
|
||||
Text("Catheterization", fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = MlPrimary)
|
||||
Text("Voided", fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = MlPrimary)
|
||||
Text("Catheterized", fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = MlPrimary)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -979,9 +979,9 @@ fun PiezoMonitoringView(appState: AppState) {
|
||||
)
|
||||
) {
|
||||
if (isAutoMeasuring) {
|
||||
Text("Stop", fontSize = 14.sp, fontWeight = FontWeight.SemiBold, color = Color.White)
|
||||
Text("Stop Scan", fontSize = 14.sp, fontWeight = FontWeight.SemiBold, color = Color.White)
|
||||
} else {
|
||||
Text("Automatic", fontSize = 14.sp, fontWeight = FontWeight.SemiBold, color = Color.White)
|
||||
Text("Auto Scan", fontSize = 14.sp, fontWeight = FontWeight.SemiBold, color = Color.White)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1032,7 +1032,7 @@ fun PiezoMonitoringView(appState: AppState) {
|
||||
if (isSpotInProgress) {
|
||||
CircularProgressIndicator(color = Color.White, modifier = Modifier.size(18.dp), strokeWidth = 2.dp)
|
||||
} else {
|
||||
Text("Spot", fontSize = 14.sp, fontWeight = FontWeight.SemiBold, color = Color.White)
|
||||
Text("Single Scan", fontSize = 14.sp, fontWeight = FontWeight.SemiBold, color = Color.White)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1286,7 +1286,7 @@ fun PiezoMonitoringView(appState: AppState) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { showDisconnectConfirm = false },
|
||||
title = { Text("Delete Pairing") },
|
||||
text = { Text("기기 연결을 해제하고 페어링 정보를 삭제합니다.") },
|
||||
text = { Text("Disconnect and remove pairing.") },
|
||||
confirmButton = {
|
||||
TextButton(onClick = {
|
||||
showDisconnectConfirm = false; showSettings = false
|
||||
@@ -1328,14 +1328,14 @@ fun PiezoMonitoringView(appState: AppState) {
|
||||
if (showRealignPrompt) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { showRealignPrompt = false },
|
||||
title = { Text("Sensor Position Issue") },
|
||||
text = { Text("The sensor may have shifted from the optimal position. Please re-run Sensor Alignment to ensure accurate measurements.") },
|
||||
title = { Text("Position lost") },
|
||||
text = { Text("Sensor may have shifted. Restart from alignment.") },
|
||||
confirmButton = {
|
||||
Button(onClick = {
|
||||
showRealignPrompt = false
|
||||
autoFailCount = 0
|
||||
appState.currentScreen = com.example.medilightv2android.AppScreen.PLACEMENT_GUIDE
|
||||
}) { Text("Go to Alignment") }
|
||||
}) { Text("Realign") }
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = { showRealignPrompt = false; autoFailCount = 0 }) {
|
||||
|
||||
+37
-37
@@ -120,7 +120,7 @@ fun PlacementGuideView(appState: AppState) {
|
||||
lastHintChangeMs = 0L
|
||||
lastGuidePhase = PlacementPhase.VERTICAL
|
||||
phaseHoldScans = 0
|
||||
directionHint = "Place the sensor above the pubic bone, then press Start"
|
||||
directionHint = "Place VesiScan above the pubic bone, then press Start"
|
||||
directionIcon = ""
|
||||
lastCv = Double.NaN
|
||||
for (i in 0 until 6) { channelDetected[i] = false; channelUrineLen[i] = 0 }
|
||||
@@ -225,8 +225,8 @@ fun PlacementGuideView(appState: AppState) {
|
||||
val displayHint = buildString {
|
||||
val hint = directionHint.ifEmpty { " " }
|
||||
append(hint)
|
||||
if (hint.startsWith("Raise") || hint.startsWith("Lower") || hint.startsWith("Move") ||
|
||||
hint.startsWith("Fine-tune") || hint.startsWith("Checking") || hint.startsWith("Adjust")) {
|
||||
if (hint.startsWith("Slide") || hint.startsWith("Optimizing") ||
|
||||
hint.startsWith("Centering") || hint.startsWith("Adjust")) {
|
||||
append(dots)
|
||||
}
|
||||
if (appState.isDevMode && !lastCv.isNaN()) {
|
||||
@@ -602,7 +602,7 @@ fun PlacementGuideView(appState: AppState) {
|
||||
val detachResult = if (fullCh.size >= 6) DetachmentDetection.detect(buffers) else null
|
||||
|
||||
if (detachResult != null && detachResult.isDetached) {
|
||||
directionHint = "Sensor detached. Place above pubic bone, then press Start"
|
||||
directionHint = "Sensor detached. Restart above pubic bone."
|
||||
directionIcon = "" // 화살표 없음
|
||||
placementScore = 0
|
||||
isContinuousMode = false
|
||||
@@ -690,7 +690,7 @@ fun PlacementGuideView(appState: AppState) {
|
||||
|
||||
// GREEN hold 중이면 힌트 강제 유지
|
||||
if (greenHeld) {
|
||||
directionHint = "Optimal position!"
|
||||
directionHint = "In position!"
|
||||
directionIcon = "checkmark.circle"
|
||||
placementPhase = PlacementPhase.GREEN
|
||||
if (!guideResult.cv.isNaN()) lastCv = guideResult.cv
|
||||
@@ -707,7 +707,7 @@ fun PlacementGuideView(appState: AppState) {
|
||||
greenFailCount++
|
||||
if (greenFailCount < 3) {
|
||||
// 아직 이탈 안 함 — GREEN 유지
|
||||
directionHint = "Optimal position!"
|
||||
directionHint = "In position!"
|
||||
directionIcon = "checkmark.circle"
|
||||
placementPhase = PlacementPhase.GREEN
|
||||
} else {
|
||||
@@ -716,7 +716,7 @@ fun PlacementGuideView(appState: AppState) {
|
||||
greenLockedAtMs = 0L
|
||||
greenFailCount = 0
|
||||
if (lastLedMode != 5) { bleManager.sendLedMode(5); lastLedMode = 5 }
|
||||
directionHint = "Position lost. Place sensor above pubic bone, then press Start"
|
||||
directionHint = "Position lost. Restart above pubic bone."
|
||||
directionIcon = "" // 화살표 없음
|
||||
placementScore = 10
|
||||
placementPhase = PlacementPhase.VERTICAL
|
||||
@@ -810,7 +810,7 @@ fun PlacementGuideView(appState: AppState) {
|
||||
}
|
||||
}
|
||||
|
||||
// Alignment Complete button (스캔 진행 중에만)
|
||||
// Start Scanning button (스캔 진행 중에만)
|
||||
if (!waitingForStart) Button(
|
||||
onClick = {
|
||||
isContinuousMode = false
|
||||
@@ -828,7 +828,7 @@ fun PlacementGuideView(appState: AppState) {
|
||||
) {
|
||||
Icon(Icons.Filled.CheckCircle, contentDescription = null, tint = Color.White)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text("Alignment Complete", fontSize = 16.sp, fontWeight = FontWeight.Bold, color = Color.White)
|
||||
Text("Start Scanning", fontSize = 16.sp, fontWeight = FontWeight.Bold, color = Color.White)
|
||||
}
|
||||
|
||||
// Skip button
|
||||
@@ -1234,7 +1234,7 @@ private fun computePlacementGuide(
|
||||
val detectedCount = detected.count { it }
|
||||
|
||||
if (detectedCount == 0) {
|
||||
return PlacementGuideResult("Raise the sensor up", "arrow.up", 0,
|
||||
return PlacementGuideResult("Slide up", "arrow.up", 0,
|
||||
phase = PlacementPhase.VERTICAL, nextPhase = PlacementPhase.VERTICAL)
|
||||
}
|
||||
|
||||
@@ -1259,9 +1259,9 @@ private fun computePlacementGuide(
|
||||
// Phase 1: nothing detected — start instruction
|
||||
if (centerDetected == 0) {
|
||||
val hint = if (vs.everSawAllFour)
|
||||
"Lost signal — slide back up ↑"
|
||||
"Signal lost — slide up ↑"
|
||||
else
|
||||
"Place sensor near navel, slide slowly down ↓"
|
||||
"Start near navel, slide down slowly ↓"
|
||||
val icon = if (vs.everSawAllFour) "arrow.up" else "arrow.down"
|
||||
return PlacementGuideResult(hint, icon, 5,
|
||||
phase = PlacementPhase.VERTICAL, nextPhase = PlacementPhase.VERTICAL)
|
||||
@@ -1270,7 +1270,7 @@ private fun computePlacementGuide(
|
||||
// Phase 4: was at all-4, now lost a channel → overshoot (boundary)
|
||||
if (vs.everSawAllFour && centerDetected < prev && centerDetected < 4) {
|
||||
vs.boundaryHit = true
|
||||
return PlacementGuideResult("Past optimum — slide back up ↑", "arrow.up", 50,
|
||||
return PlacementGuideResult("Too far — slide up ↑", "arrow.up", 50,
|
||||
phase = PlacementPhase.VERTICAL, nextPhase = PlacementPhase.VERTICAL)
|
||||
}
|
||||
|
||||
@@ -1290,9 +1290,9 @@ private fun computePlacementGuide(
|
||||
phase = PlacementPhase.VERTICAL, nextPhase = PlacementPhase.GREEN)
|
||||
} else {
|
||||
val lrHint = when {
|
||||
l4 > 0 && l5 > 0 && l4 > l5 -> "Move left ←"
|
||||
l4 > 0 && l5 > 0 && l5 > l4 -> "Move right →"
|
||||
else -> "Checking left/right balance..."
|
||||
l4 > 0 && l5 > 0 && l4 > l5 -> "Slide left ←"
|
||||
l4 > 0 && l5 > 0 && l5 > l4 -> "Slide right →"
|
||||
else -> "Centering"
|
||||
}
|
||||
val lrIcon = when {
|
||||
l4 > 0 && l5 > 0 && l4 > l5 -> "arrow.left"
|
||||
@@ -1328,13 +1328,13 @@ private fun computePlacementGuide(
|
||||
val hint: String; val icon: String
|
||||
when {
|
||||
(ch0det || ch1det) && !ch2det && !ch3det -> {
|
||||
hint = "Raise the sensor up"; icon = "arrow.up"
|
||||
hint = "Slide up"; icon = "arrow.up"
|
||||
}
|
||||
(ch3det || ch2det) && !ch0det && !ch1det -> {
|
||||
hint = "Lower the sensor down"; icon = "arrow.down"
|
||||
hint = "Slide down"; icon = "arrow.down"
|
||||
}
|
||||
else -> {
|
||||
hint = "Raise the sensor up"; icon = "arrow.up"
|
||||
hint = "Slide up"; icon = "arrow.up"
|
||||
}
|
||||
}
|
||||
return PlacementGuideResult(hint, icon, centerDetected * 10,
|
||||
@@ -1379,7 +1379,7 @@ private fun computePlacementGuide(
|
||||
val ch5ok = detected.getOrElse(5) { false }
|
||||
|
||||
// 항상 LATERAL 단계를 거침 — 전환 시 항상 Checking 표시
|
||||
val lrHint = "Checking left/right balance..."
|
||||
val lrHint = "Centering"
|
||||
val lrIcon = "checkmark.circle"
|
||||
val score = (40 + ((1.0 - kotlin.math.abs(gradient) / gradientThr) * 20).toInt())
|
||||
.coerceIn(40, 60)
|
||||
@@ -1396,16 +1396,16 @@ private fun computePlacementGuide(
|
||||
val ch4ok = detected.getOrElse(4) { false }
|
||||
val ch5ok = detected.getOrElse(5) { false }
|
||||
// 항상 LATERAL 단계를 거침
|
||||
return PlacementGuideResult("Checking left/right balance...",
|
||||
return PlacementGuideResult("Centering",
|
||||
"checkmark.circle", 50,
|
||||
phase = PlacementPhase.VERTICAL, nextPhase = PlacementPhase.LATERAL)
|
||||
} else if (gradient > 0) {
|
||||
val intensity = if (gradient > 0.8) "Lower the sensor down" else "Lower the sensor slightly"
|
||||
val intensity = if (gradient > 0.8) "Slide down" else "Slide down slightly"
|
||||
return PlacementGuideResult(intensity, "arrow.down",
|
||||
(20 + centerDetected * 5).coerceAtMost(35),
|
||||
phase = PlacementPhase.VERTICAL, nextPhase = PlacementPhase.VERTICAL)
|
||||
} else {
|
||||
val intensity = if (gradient < -0.8) "Raise the sensor up" else "Raise the sensor slightly"
|
||||
val intensity = if (gradient < -0.8) "Slide up" else "Slide up slightly"
|
||||
return PlacementGuideResult(intensity, "arrow.up",
|
||||
(20 + centerDetected * 5).coerceAtMost(35),
|
||||
phase = PlacementPhase.VERTICAL, nextPhase = PlacementPhase.VERTICAL)
|
||||
@@ -1443,10 +1443,10 @@ private fun computePlacementGuide(
|
||||
phase = PlacementPhase.LATERAL, nextPhase = PlacementPhase.GREEN)
|
||||
}
|
||||
return if (lateralOffsetMm > 0) {
|
||||
PlacementGuideResult("Move right →", "arrow.right", 45,
|
||||
PlacementGuideResult("Slide right →", "arrow.right", 45,
|
||||
phase = PlacementPhase.LATERAL, nextPhase = PlacementPhase.LATERAL)
|
||||
} else {
|
||||
PlacementGuideResult("Move left ←", "arrow.left", 45,
|
||||
PlacementGuideResult("Slide left ←", "arrow.left", 45,
|
||||
phase = PlacementPhase.LATERAL, nextPhase = PlacementPhase.LATERAL)
|
||||
}
|
||||
}
|
||||
@@ -1454,12 +1454,12 @@ private fun computePlacementGuide(
|
||||
// 한쪽만 detect → 반대쪽으로 이동 (잡히는 쪽의 반대로)
|
||||
// ch4(왼쪽)만 잡힘 = 기기가 오른쪽 치우침 = 왼쪽으로
|
||||
if (ch4det && !ch5det) {
|
||||
return PlacementGuideResult("Move left ←", "arrow.left", 40,
|
||||
return PlacementGuideResult("Slide left ←", "arrow.left", 40,
|
||||
phase = PlacementPhase.LATERAL, nextPhase = PlacementPhase.LATERAL)
|
||||
}
|
||||
// ch5(오른쪽)만 잡힘 = 기기가 왼쪽 치우침 = 오른쪽으로
|
||||
if (ch5det && !ch4det) {
|
||||
return PlacementGuideResult("Move right →", "arrow.right", 40,
|
||||
return PlacementGuideResult("Slide right →", "arrow.right", 40,
|
||||
phase = PlacementPhase.LATERAL, nextPhase = PlacementPhase.LATERAL)
|
||||
}
|
||||
if (!ch4det && !ch5det) {
|
||||
@@ -1549,7 +1549,7 @@ private fun computePlacementGuide(
|
||||
if (isPass) {
|
||||
val score = ((1.0 - cv / cvThr).coerceIn(0.0, 1.0) * 100).toInt().coerceAtLeast(70)
|
||||
return PlacementGuideResult(
|
||||
"Optimal position!",
|
||||
"In position!",
|
||||
"checkmark.circle", score, cv, true, lrDev, lrPass,
|
||||
phase = PlacementPhase.GREEN, nextPhase = PlacementPhase.GREEN)
|
||||
} else {
|
||||
@@ -1567,25 +1567,25 @@ private fun computePlacementGuide(
|
||||
when {
|
||||
// ch4/ch5 중 하나만 빠짐 → 반대 방향 안내
|
||||
!lrPass && !ch4det && ch5det -> {
|
||||
adjustHint = "Move left ←"; adjustIcon = "arrow.left"
|
||||
adjustHint = "Slide left ←"; adjustIcon = "arrow.left"
|
||||
}
|
||||
!lrPass && ch4det && !ch5det -> {
|
||||
adjustHint = "Move right →"; adjustIcon = "arrow.right"
|
||||
adjustHint = "Slide right →"; adjustIcon = "arrow.right"
|
||||
}
|
||||
!lrPass && !ch4det && !ch5det -> {
|
||||
adjustHint = "Adjust left or right"; adjustIcon = "arrow.right"
|
||||
}
|
||||
!lrPass && lrDev > DEFAULT_LR_DEV_THR -> {
|
||||
adjustHint = "Move left ←"; adjustIcon = "arrow.left"
|
||||
adjustHint = "Slide left ←"; adjustIcon = "arrow.left"
|
||||
}
|
||||
!lrPass && lrDev < -DEFAULT_LR_DEV_THR -> {
|
||||
adjustHint = "Move right →"; adjustIcon = "arrow.right"
|
||||
adjustHint = "Slide right →"; adjustIcon = "arrow.right"
|
||||
}
|
||||
gradient > 0.3 -> {
|
||||
adjustHint = "Lower the sensor down"; adjustIcon = "arrow.down"
|
||||
adjustHint = "Slide down"; adjustIcon = "arrow.down"
|
||||
}
|
||||
gradient < -0.3 -> {
|
||||
adjustHint = "Raise the sensor up"; adjustIcon = "arrow.up"
|
||||
adjustHint = "Slide up"; adjustIcon = "arrow.up"
|
||||
}
|
||||
else -> {
|
||||
// 방향 애매 + CV 미달 → ch별 len 분석으로 방향 제시
|
||||
@@ -1596,13 +1596,13 @@ private fun computePlacementGuide(
|
||||
// 최소 채널이 최대의 60% 미만 → 약한 쪽으로 안내
|
||||
if (minCh <= 1) {
|
||||
// ch0/ch1 약함 → 위로
|
||||
adjustHint = "Raise the sensor slightly"; adjustIcon = "arrow.up"
|
||||
adjustHint = "Slide up slightly"; adjustIcon = "arrow.up"
|
||||
} else {
|
||||
// ch2/ch3 약함 → 아래로
|
||||
adjustHint = "Lower the sensor slightly"; adjustIcon = "arrow.down"
|
||||
adjustHint = "Slide down slightly"; adjustIcon = "arrow.down"
|
||||
}
|
||||
} else {
|
||||
adjustHint = "Fine-tune position"; adjustIcon = "checkmark.circle"
|
||||
adjustHint = "Optimizing"; adjustIcon = "checkmark.circle"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user