cb8500f6ce
빌드 106 적용: placementFromMonitoring 플래그 + enterPlacementFromMonitoring() / backFromPlacementGuide() 헬퍼 추가. Personalization → Placement → Monitoring 정방향과 Monitoring → Placement 재진입 경로에서 Back 동작이 올바르게 분기되도록 일괄 정리. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
149 lines
7.2 KiB
Kotlin
149 lines
7.2 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
|
|
|
|
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
|
|
AppScreen.DEVICE_SCAN -> appState.currentScreen = AppScreen.HOME
|
|
AppScreen.PIEZO_PERSONALIZATION -> appState.currentScreen = AppScreen.DEVICE_SCAN
|
|
AppScreen.PLACEMENT_GUIDE -> appState.backFromPlacementGuide()
|
|
AppScreen.PIEZO_MONITORING -> appState.currentScreen = AppScreen.PLACEMENT_GUIDE
|
|
// 모니터링 하위 화면 → 모니터링
|
|
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() }
|
|
)
|
|
}
|
|
}
|
|
} |