82ba3bbcf6
회의 #8 페이지 통합 - 별도 화면(AUTO_SCAN_SETUP) 폐기 — Personalization 한 화면에 3카드: 1) Max Capacity, 2) Catheter Threshold, 3) Auto Scan Interval - 캐릭터 작게 (220→120dp) + 카드 영역 verticalScroll - 'Scan Interval' → 'Auto Scan Interval' 이름 복귀 - 한글 설명 제거 - 흐름: PiezoPersonalization → PlacementGuide (AUTO_SCAN_SETUP 단계 없음) 회의 #9 새 형식 — 모든 위치에서 통일 - 범위 0.5 ~ 10 (sec/min 모드 동일) - 0.5 단위 (이전 200ms/30s 단위) - sec/min 토글 숫자 우측에 위치 - SEC 모드: ms = value × 1000 (예: 1.5sec = 1500ms) - MIN 모드: ms = value × 60000 (예: 1.5min = 90000ms) - 모드 전환 시 같은 숫자 값 유지 (1.5sec ↔ 1.5min) 회의 #10 in-monitoring settings 동일 적용 PiezoMonitoringView 설정 페이지의 Auto Scan Interval 슬라이더도 새 형식으로 갱신. 같은 로직 (unitMode + valueClamped + sec/min 토글 + 0.5 step). 정리: - AppState.AUTO_SCAN_SETUP enum value 제거 - autoScanSetupComplete() 함수 제거 (호출처 없음) - backFromPlacementGuide() → PIEZO_PERSONALIZATION으로 (AUTO_SCAN_SETUP 단계 폐기) - MainActivity 라우팅/Back handler에서 AUTO_SCAN_SETUP 분기 제거 - AutoScanIntervalSetupView.kt 파일 삭제 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
176 lines
9.0 KiB
Kotlin
176 lines
9.0 KiB
Kotlin
package com.example.medilightv2android
|
|
|
|
import android.os.Bundle
|
|
import androidx.activity.ComponentActivity
|
|
import androidx.activity.compose.BackHandler
|
|
import androidx.activity.compose.setContent
|
|
import androidx.activity.enableEdgeToEdge
|
|
import androidx.compose.animation.Crossfade
|
|
import androidx.compose.animation.core.tween
|
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
import androidx.compose.foundation.layout.padding
|
|
import androidx.compose.material3.Scaffold
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.getValue
|
|
import androidx.compose.runtime.mutableStateOf
|
|
import androidx.compose.runtime.remember
|
|
import androidx.compose.runtime.setValue
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.graphics.Color
|
|
import androidx.compose.ui.platform.LocalContext
|
|
import app.rive.runtime.kotlin.core.Rive
|
|
import com.example.medilightv2android.services.KeychainService
|
|
import com.example.medilightv2android.services.NotificationService
|
|
import com.example.medilightv2android.ui.theme.Medilightv2androidTheme
|
|
import com.example.medilightv2android.ui.views.calibration.CalibrationView
|
|
import com.example.medilightv2android.ui.views.connection.DeviceScanView
|
|
import com.example.medilightv2android.ui.views.history.MeasurementHistoryView
|
|
import com.example.medilightv2android.ui.views.home.HomeView
|
|
import com.example.medilightv2android.ui.views.monitoring.PlacementGuideView
|
|
import com.example.medilightv2android.ui.views.monitoring.PiezoMonitoringView
|
|
import com.example.medilightv2android.ui.views.monitoring.VivamyoMonitoringView
|
|
import com.example.medilightv2android.ui.views.monitoring.UrineCameraScreen
|
|
import com.example.medilightv2android.ui.views.monitoring.VoidingDiaryView
|
|
import com.example.medilightv2android.ui.views.onboarding.OnboardingView
|
|
import com.example.medilightv2android.ui.views.personalization.PiezoPersonalizationView
|
|
import com.example.medilightv2android.ui.views.pin.PinMode
|
|
import com.example.medilightv2android.ui.views.pin.PinView
|
|
import com.example.medilightv2android.ui.views.registration.RegistrationView
|
|
import com.example.medilightv2android.ui.views.consent.ConsentView
|
|
import com.example.medilightv2android.ui.views.reminder.ReminderSettingsView
|
|
import com.example.medilightv2android.ui.views.sensorselect.SensorSelectView
|
|
import com.example.medilightv2android.ui.views.clinical.ClinicalHomeView
|
|
import com.example.medilightv2android.ui.views.clinical.ClinicalLiveView
|
|
|
|
class MainActivity : ComponentActivity() {
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
|
|
// Initialize services
|
|
Rive.init(this)
|
|
KeychainService.init(this)
|
|
NotificationService.getInstance(this)
|
|
|
|
enableEdgeToEdge()
|
|
window.addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
|
setContent {
|
|
Medilightv2androidTheme {
|
|
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
|
|
MedilightApp(modifier = Modifier.padding(innerPadding))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
fun MedilightApp(modifier: Modifier = Modifier) {
|
|
val context = LocalContext.current
|
|
val appState = remember { AppState(context) }
|
|
|
|
// HOME에서 뒤로가기 → 앱 종료 확인
|
|
var showExitDialog by remember { mutableStateOf(false) }
|
|
BackHandler(enabled = appState.currentScreen == AppScreen.HOME) {
|
|
showExitDialog = true
|
|
}
|
|
if (showExitDialog) {
|
|
androidx.compose.material3.AlertDialog(
|
|
onDismissRequest = { showExitDialog = false },
|
|
title = { androidx.compose.material3.Text("Exit App") },
|
|
text = { androidx.compose.material3.Text("Are you sure you want to exit?") },
|
|
confirmButton = {
|
|
androidx.compose.material3.TextButton(onClick = { (context as? android.app.Activity)?.finish() }) {
|
|
androidx.compose.material3.Text("Exit", color = Color.Red)
|
|
}
|
|
},
|
|
dismissButton = {
|
|
androidx.compose.material3.TextButton(onClick = { showExitDialog = false }) {
|
|
androidx.compose.material3.Text("Cancel")
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
// 다른 화면에서 뒤로가기 = 바로 전 화면
|
|
BackHandler(enabled = appState.currentScreen != AppScreen.HOME
|
|
&& appState.currentScreen != AppScreen.PIN_ENTRY) {
|
|
when (appState.currentScreen) {
|
|
// 메인 플로우: Home → DeviceScan → Personalization → Placement → Monitoring
|
|
// DeviceScan Back: 임상 흐름이면 ClinicalHome으로, 아니면 HOME
|
|
AppScreen.DEVICE_SCAN ->
|
|
appState.currentScreen =
|
|
if (com.example.medilightv2android.services.ClinicalSessionStore.inClinicalFlow)
|
|
AppScreen.CLINICAL_HOME
|
|
else AppScreen.HOME
|
|
AppScreen.PIEZO_PERSONALIZATION -> appState.currentScreen = AppScreen.DEVICE_SCAN
|
|
// 임상 모드 측정 중이면 endMeasurement → ClinicalHome 복귀
|
|
AppScreen.PLACEMENT_GUIDE ->
|
|
if (com.example.medilightv2android.services.ClinicalSessionStore.currentSession != null) {
|
|
com.example.medilightv2android.services.ClinicalSessionStore.endMeasurement(context)
|
|
appState.currentScreen = AppScreen.CLINICAL_HOME
|
|
} else appState.backFromPlacementGuide()
|
|
AppScreen.PIEZO_MONITORING ->
|
|
if (com.example.medilightv2android.services.ClinicalSessionStore.currentSession != null) {
|
|
com.example.medilightv2android.services.ClinicalSessionStore.endMeasurement(context)
|
|
appState.currentScreen = AppScreen.CLINICAL_HOME
|
|
} else appState.currentScreen = AppScreen.PLACEMENT_GUIDE
|
|
AppScreen.CLINICAL_HOME -> {
|
|
com.example.medilightv2android.services.ClinicalSessionStore.inClinicalFlow = false
|
|
appState.currentScreen = AppScreen.HOME
|
|
}
|
|
AppScreen.CLINICAL_LIVE -> {
|
|
// 측정 폴더 finalize 후 ClinicalHome 복귀
|
|
com.example.medilightv2android.services.ClinicalSessionStore.endMeasurement(context)
|
|
appState.currentScreen = AppScreen.CLINICAL_HOME
|
|
}
|
|
// 모니터링 하위 화면 → 모니터링
|
|
AppScreen.MEASUREMENT_HISTORY -> appState.currentScreen = AppScreen.PIEZO_MONITORING
|
|
AppScreen.VOIDING_DIARY -> appState.currentScreen = AppScreen.PIEZO_MONITORING
|
|
AppScreen.REMINDER_SETTINGS -> appState.currentScreen = AppScreen.PIEZO_MONITORING
|
|
AppScreen.URINE_CAMERA -> appState.currentScreen = AppScreen.PIEZO_MONITORING
|
|
// 기타
|
|
AppScreen.SENSOR_SELECT -> appState.currentScreen = AppScreen.HOME
|
|
AppScreen.VIVAMYO_MONITORING -> appState.currentScreen = AppScreen.HOME
|
|
AppScreen.NIRS_CALIBRATION -> appState.currentScreen = AppScreen.DEVICE_SCAN
|
|
// 온보딩/등록 (뒤로가기 막지 않되 Home으로)
|
|
else -> appState.currentScreen = AppScreen.HOME
|
|
}
|
|
}
|
|
|
|
Crossfade(
|
|
targetState = appState.currentScreen,
|
|
animationSpec = tween(300),
|
|
modifier = modifier,
|
|
label = "screen"
|
|
) { screen ->
|
|
when (screen) {
|
|
AppScreen.ONBOARDING -> OnboardingView(appState)
|
|
AppScreen.CONSENT -> ConsentView(appState)
|
|
AppScreen.REGISTRATION -> RegistrationView(appState)
|
|
AppScreen.HOME -> HomeView(appState)
|
|
AppScreen.SENSOR_SELECT -> SensorSelectView(appState)
|
|
AppScreen.DEVICE_SCAN -> DeviceScanView(appState)
|
|
AppScreen.NIRS_CALIBRATION -> CalibrationView(appState)
|
|
AppScreen.PIEZO_PERSONALIZATION -> PiezoPersonalizationView(appState)
|
|
AppScreen.PLACEMENT_GUIDE -> PlacementGuideView(appState)
|
|
AppScreen.PIN_SETUP -> PinView(appState, PinMode.SETUP, context)
|
|
AppScreen.PIN_ENTRY -> PinView(appState, PinMode.ENTER, context)
|
|
AppScreen.VIVAMYO_MONITORING -> VivamyoMonitoringView(appState)
|
|
AppScreen.PIEZO_MONITORING -> PiezoMonitoringView(appState)
|
|
AppScreen.MEASUREMENT_HISTORY -> MeasurementHistoryView(appState)
|
|
AppScreen.VOIDING_DIARY -> VoidingDiaryView(onBack = { appState.currentScreen = AppScreen.HOME })
|
|
AppScreen.URINE_CAMERA -> UrineCameraScreen(
|
|
onDone = { volume ->
|
|
if (volume != null && volume > 0) appState.resetLevel()
|
|
appState.currentScreen = AppScreen.PIEZO_MONITORING
|
|
},
|
|
onCancel = { appState.currentScreen = AppScreen.PIEZO_MONITORING }
|
|
)
|
|
AppScreen.REMINDER_SETTINGS -> ReminderSettingsView(
|
|
onBack = { appState.backToMonitoring() }
|
|
)
|
|
AppScreen.CLINICAL_HOME -> ClinicalHomeView(appState)
|
|
AppScreen.CLINICAL_LIVE -> ClinicalLiveView(appState)
|
|
}
|
|
}
|
|
} |