forked from melod1n/fast-messenger
refactor: simplify app bootstrap and root errors
This commit is contained in:
@@ -2,7 +2,6 @@ package dev.meloda.fast
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.os.LocaleListCompat
|
||||
@@ -38,6 +37,7 @@ interface MainViewModel {
|
||||
val startDestination: StateFlow<Any?>
|
||||
val isNeedToReplaceWithAuth: StateFlow<Boolean>
|
||||
val currentUser: StateFlow<VkUser?>
|
||||
val baseError: StateFlow<BaseError?>
|
||||
|
||||
val isNeedToShowNotificationsDeniedDialog: StateFlow<Boolean>
|
||||
val isNeedToShowNotificationsRationaleDialog: StateFlow<Boolean>
|
||||
@@ -45,6 +45,7 @@ interface MainViewModel {
|
||||
val isNeedToRequestNotifications: StateFlow<Boolean>
|
||||
|
||||
fun onError(error: BaseError)
|
||||
fun onErrorConsumed()
|
||||
|
||||
fun onNavigatedToAuth()
|
||||
|
||||
@@ -73,6 +74,7 @@ class MainViewModelImpl(
|
||||
override val startDestination = MutableStateFlow<Any?>(null)
|
||||
override val isNeedToReplaceWithAuth = MutableStateFlow(false)
|
||||
override val currentUser = MutableStateFlow<VkUser?>(null)
|
||||
override val baseError = MutableStateFlow<BaseError?>(null)
|
||||
|
||||
override val isNeedToShowNotificationsDeniedDialog = MutableStateFlow(false)
|
||||
override val isNeedToShowNotificationsRationaleDialog = MutableStateFlow(false)
|
||||
@@ -93,9 +95,15 @@ class MainViewModelImpl(
|
||||
isNeedToReplaceWithAuth.update { true }
|
||||
}
|
||||
|
||||
else -> Unit // TODO: 21-Mar-25, Danil Nikolaev: show error in ui
|
||||
else -> {
|
||||
baseError.update { error }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onErrorConsumed() {
|
||||
baseError.update { null }
|
||||
}
|
||||
|
||||
override fun onNavigatedToAuth() {
|
||||
isNeedToReplaceWithAuth.update { false }
|
||||
@@ -207,8 +215,6 @@ class MainViewModelImpl(
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val currentAccount = getCurrentAccountUseCase()
|
||||
|
||||
Log.d("MainViewModel", "currentAccount: $currentAccount")
|
||||
|
||||
if (currentAccount != null) {
|
||||
UserConfig.apply {
|
||||
this.userId = currentAccount.userId
|
||||
|
||||
@@ -9,7 +9,6 @@ import android.content.res.Configuration
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import androidx.activity.SystemBarStyle
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
@@ -65,9 +64,6 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
setContent {
|
||||
val viewModel: MainViewModel = koinViewModel<MainViewModelImpl>()
|
||||
LaunchedEffect(viewModel) {
|
||||
Log.d("VM_CREATE", "onCreate: viewModel: $viewModel")
|
||||
}
|
||||
|
||||
LifecycleResumeEffect(true) {
|
||||
viewModel.onAppResumed(intent)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package dev.meloda.fast.presentation
|
||||
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import dev.meloda.fast.model.BaseError
|
||||
import dev.meloda.fast.ui.R
|
||||
|
||||
@Composable
|
||||
fun RootErrorDialog(
|
||||
baseError: BaseError?,
|
||||
onDismiss: () -> Unit,
|
||||
onConfirm: () -> Unit,
|
||||
) {
|
||||
if (baseError == null) return
|
||||
|
||||
val errorText = when (baseError) {
|
||||
BaseError.ConnectionError -> "Connection error"
|
||||
BaseError.InternalError -> "Internal error"
|
||||
BaseError.UnknownError -> "Unknown error"
|
||||
is BaseError.SimpleError -> baseError.message
|
||||
BaseError.SessionExpired -> "Session expired"
|
||||
BaseError.AccountBlocked -> "Account blocked"
|
||||
}
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text(text = stringResource(id = R.string.warning)) },
|
||||
text = { Text(text = errorText) },
|
||||
confirmButton = {
|
||||
TextButton(onClick = onConfirm) {
|
||||
Text(text = stringResource(id = R.string.try_again))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -4,16 +4,12 @@ import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import androidx.activity.compose.LocalActivity
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@@ -92,9 +88,6 @@ fun RootScreen(
|
||||
val longPollStateToApply by longPollController.stateToApply.collectAsStateWithLifecycle()
|
||||
|
||||
val viewModel: MainViewModel = koinViewModel<MainViewModelImpl>()
|
||||
LaunchedEffect(viewModel) {
|
||||
Log.d("VM_CREATE", "RootScreen(): viewModel: $viewModel")
|
||||
}
|
||||
|
||||
val currentUser: VkUser? by viewModel.currentUser.collectAsStateWithLifecycle()
|
||||
|
||||
@@ -126,13 +119,11 @@ fun RootScreen(
|
||||
}
|
||||
|
||||
LifecycleResumeEffect(longPollStateToApply) {
|
||||
Log.d("LongPollMainActivity", "longPollStateToApply: $longPollStateToApply")
|
||||
if (longPollStateToApply != LongPollState.Background) {
|
||||
if (longPollStateToApply.isLaunched() && longPollCurrentState.isLaunched()
|
||||
&& longPollCurrentState != longPollStateToApply
|
||||
) {
|
||||
toggleLongPollService(false, null)
|
||||
Log.d("LongPoll", "recreate()")
|
||||
}
|
||||
|
||||
toggleLongPollService(
|
||||
@@ -241,6 +232,7 @@ fun RootScreen(
|
||||
val context = LocalContext.current
|
||||
val startDestination by viewModel.startDestination.collectAsStateWithLifecycle()
|
||||
val isNeedToOpenAuth by viewModel.isNeedToReplaceWithAuth.collectAsStateWithLifecycle()
|
||||
val baseError by viewModel.baseError.collectAsStateWithLifecycle()
|
||||
val isNeedToShowDeniedDialog by viewModel.isNeedToShowNotificationsDeniedDialog.collectAsStateWithLifecycle()
|
||||
val isNeedToShowRationaleDialog by viewModel.isNeedToShowNotificationsRationaleDialog.collectAsStateWithLifecycle()
|
||||
|
||||
@@ -304,6 +296,12 @@ fun RootScreen(
|
||||
)
|
||||
}
|
||||
|
||||
RootErrorDialog(
|
||||
baseError = baseError,
|
||||
onDismiss = viewModel::onErrorConsumed,
|
||||
onConfirm = viewModel::onErrorConsumed
|
||||
)
|
||||
|
||||
if (startDestination != null) {
|
||||
CompositionLocalProvider(
|
||||
LocalNavRootController provides navController,
|
||||
|
||||
@@ -25,6 +25,7 @@ internal fun Project.configureKotlinAndroid(
|
||||
|
||||
commonExtension.apply {
|
||||
compileSdk = getVersionInt("compileSdk")
|
||||
buildToolsVersion = "36.1.0"
|
||||
}
|
||||
|
||||
configureKotlin<KotlinAndroidProjectExtension>()
|
||||
|
||||
Reference in New Issue
Block a user