diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2daccaa..00c67f4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -12,8 +12,8 @@ android { applicationId = "pl.firmatpp.kierowca" minSdk = 26 targetSdk = 35 - versionCode = 13 - versionName = "1.0.12" + versionCode = 14 + versionName = "1.0.13" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" buildConfigField("String", "API_BASE_URL", "\"https://api-intranet.firmatpp.pl/api/\"") diff --git a/app/src/main/java/pl/firmatpp/kierowca/ui/DriverApp.kt b/app/src/main/java/pl/firmatpp/kierowca/ui/DriverApp.kt index 2c8ae65..6ec3d82 100644 --- a/app/src/main/java/pl/firmatpp/kierowca/ui/DriverApp.kt +++ b/app/src/main/java/pl/firmatpp/kierowca/ui/DriverApp.kt @@ -135,7 +135,7 @@ fun DriverApp(viewModel: DriverViewModel) { val lifecycleOwner = LocalLifecycleOwner.current var appInForeground by remember { mutableStateOf(true) } - BackHandler(enabled = state.screen != DriverScreen.Phone && state.screen != DriverScreen.Routes) { + BackHandler(enabled = state.screen != DriverScreen.Initializing && state.screen != DriverScreen.Phone && state.screen != DriverScreen.Routes) { viewModel.back() } DisposableEffect(lifecycleOwner, state.screen) { @@ -168,6 +168,7 @@ fun DriverApp(viewModel: DriverViewModel) { Box(Modifier.fillMaxSize().background(TppColors.Surface)) { when (state.screen) { + DriverScreen.Initializing -> StartupScreen() DriverScreen.Phone -> PhoneScreen(state, viewModel::requestOtp) DriverScreen.Otp -> OtpScreen(state, viewModel::updateOtpCode, viewModel::verifyOtp, viewModel::back) DriverScreen.Routes -> RoutesScreen( @@ -182,7 +183,7 @@ fun DriverApp(viewModel: DriverViewModel) { DriverScreen.Photo -> PhotoScreen(state, viewModel::back) } - if (state.loading) { + if (state.loading && state.screen != DriverScreen.Initializing) { Box(Modifier.fillMaxSize().background(Color.White.copy(alpha = 0.42f)), contentAlignment = Alignment.Center) { CircularProgressIndicator(color = TppColors.Forest) } @@ -190,6 +191,37 @@ fun DriverApp(viewModel: DriverViewModel) { } } +@Composable +private fun StartupScreen() { + Column( + Modifier + .fillMaxSize() + .statusBarsPadding() + .navigationBarsPadding() + .padding(32.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + Image( + painter = painterResource(R.drawable.tpp5), + contentDescription = "Firma TPP", + contentScale = ContentScale.Fit, + modifier = Modifier + .fillMaxWidth() + .height(120.dp), + ) + Spacer(Modifier.height(32.dp)) + CircularProgressIndicator(color = TppColors.Forest) + Spacer(Modifier.height(20.dp)) + Text( + "Sprawdzanie sesji", + color = TppColors.Muted, + fontFamily = FontFamily.Monospace, + fontWeight = FontWeight.SemiBold, + ) + } +} + @Composable private fun PhoneScreen(state: DriverUiState, onSubmit: (String) -> Unit) { var phoneDigits by remember(state.phone) { mutableStateOf(polishPhoneDigits(state.phone)) } diff --git a/app/src/main/java/pl/firmatpp/kierowca/ui/DriverViewModel.kt b/app/src/main/java/pl/firmatpp/kierowca/ui/DriverViewModel.kt index a97d21e..c276518 100644 --- a/app/src/main/java/pl/firmatpp/kierowca/ui/DriverViewModel.kt +++ b/app/src/main/java/pl/firmatpp/kierowca/ui/DriverViewModel.kt @@ -15,11 +15,11 @@ import pl.firmatpp.kierowca.data.model.DriverDto import pl.firmatpp.kierowca.data.model.DriverRouteDto import pl.firmatpp.kierowca.data.model.RoutePhotoDto -enum class DriverScreen { Phone, Otp, Routes, Profile, Detail, Photo } +enum class DriverScreen { Initializing, Phone, Otp, Routes, Profile, Detail, Photo } data class DriverUiState( - val screen: DriverScreen = DriverScreen.Phone, - val loading: Boolean = false, + val screen: DriverScreen = DriverScreen.Initializing, + val loading: Boolean = true, val refreshing: Boolean = false, val phone: String = "", val otpCode: String = "", @@ -45,7 +45,11 @@ class DriverViewModel(application: Application) : AndroidViewModel(application) init { viewModelScope.launch { - if (repository.hasToken()) refreshRoutes() else _state.update { it.copy(loading = false) } + if (repository.hasToken()) { + refreshRoutes() + } else { + _state.update { it.copy(screen = DriverScreen.Phone, loading = false) } + } } } @@ -106,7 +110,12 @@ class DriverViewModel(application: Application) : AndroidViewModel(application) ) } }.onFailure { throwable -> - _state.update { it.copy(error = throwable.message ?: "Wystapil blad.") } + _state.update { + it.copy( + screen = if (it.screen == DriverScreen.Initializing) DriverScreen.Phone else it.screen, + error = throwable.message ?: "Wystapil blad.", + ) + } } _state.update { @@ -178,7 +187,7 @@ class DriverViewModel(application: Application) : AndroidViewModel(application) fun logout() = runLoading { repository.logout() - _state.update { DriverUiState(screen = DriverScreen.Phone) } + _state.update { DriverUiState(screen = DriverScreen.Phone, loading = false) } } private fun runLoading(block: suspend () -> Unit) { diff --git a/app/src/test/java/pl/firmatpp/kierowca/ui/DriverUiStateTest.kt b/app/src/test/java/pl/firmatpp/kierowca/ui/DriverUiStateTest.kt new file mode 100644 index 0000000..6cb74d0 --- /dev/null +++ b/app/src/test/java/pl/firmatpp/kierowca/ui/DriverUiStateTest.kt @@ -0,0 +1,15 @@ +package pl.firmatpp.kierowca.ui + +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test + +class DriverUiStateTest { + @Test + fun startsOnInitializingScreenBeforeTokenCheckCompletes() { + val state = DriverUiState() + + assertEquals(DriverScreen.Initializing, state.screen) + assertTrue(state.loading) + } +}