1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-08 05:47:05 +09:00

DROID-1475 Onboarding | Fix | Do not block back navigation when login with mnemonic failed + Show error message to inform user (#133)

This commit is contained in:
Evgenii Kozlov 2023-07-05 23:15:14 +02:00 committed by GitHub
parent 969b8d1a25
commit 40f77e108d
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 24 deletions

View file

@ -63,7 +63,7 @@ import com.anytypeio.anytype.presentation.onboarding.signup.OnboardingSoulCreati
import com.anytypeio.anytype.ui.onboarding.screens.AuthScreenWrapper
import com.anytypeio.anytype.ui.onboarding.screens.CreateSoulAnimWrapper
import com.anytypeio.anytype.ui.onboarding.screens.CreateSoulWrapper
import com.anytypeio.anytype.ui.onboarding.screens.EnteringTheVoidScreen
import com.anytypeio.anytype.ui.onboarding.screens.signin.EnteringTheVoidScreen
import com.anytypeio.anytype.ui.onboarding.screens.signin.RecoveryScreenWrapper
import com.anytypeio.anytype.ui.onboarding.screens.signup.MnemonicPhraseScreenWrapper
import com.anytypeio.anytype.ui.onboarding.screens.signup.VoidScreenWrapper
@ -236,7 +236,7 @@ class OnboardingFragment : BaseComposeFragment() {
}
) {
currentPage.value = OnboardingPage.ENTER_THE_VOID
enterTheVoid()
enterTheVoid(navController)
}
}
}
@ -310,27 +310,28 @@ class OnboardingFragment : BaseComposeFragment() {
}
@Composable
private fun enterTheVoid() {
private fun enterTheVoid(
navController: NavHostController
) {
val component = componentManager().onboardingLoginSetupComponent.ReleaseOn(
viewLifecycleOwner = viewLifecycleOwner,
state = Lifecycle.State.DESTROYED
)
val vm = daggerViewModel { component.get().getViewModel() }
EnteringTheVoidScreen(
openApp = {},
contentPaddingTop = ContentPaddingTop()
error = vm.error.collectAsState().value,
contentPaddingTop = ContentPaddingTop(),
onSystemBackPressed = vm::onSystemBackPressed
)
LaunchedEffect(Unit) {
vm.navigation.collect { navigation ->
when (navigation) {
OnboardingLoginSetupViewModel.Navigation.Exit -> {
// TODO
navController.popBackStack()
}
OnboardingLoginSetupViewModel.Navigation.NavigateToHomeScreen -> {
findNavController().navigate(R.id.action_openHome)
}
OnboardingLoginSetupViewModel.Navigation.NavigateToMigrationErrorScreen -> {
// TODO
}

View file

@ -1,4 +1,4 @@
package com.anytypeio.anytype.ui.onboarding.screens
package com.anytypeio.anytype.ui.onboarding.screens.signin
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Arrangement
@ -9,17 +9,22 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_ui.OnBoardingTextPrimaryColor
import com.anytypeio.anytype.core_ui.views.Title1
@Composable
fun EnteringTheVoidScreen(
openApp: () -> Unit,
contentPaddingTop: Int
error: String,
contentPaddingTop: Int,
onSystemBackPressed: () -> Unit
) {
Column(
modifier = Modifier
@ -33,8 +38,22 @@ fun EnteringTheVoidScreen(
text = stringResource(id = R.string.onboarding_entering_void_title),
style = Title1.copy(color = OnBoardingTextPrimaryColor)
)
if (error.isNotEmpty()) {
Text(
modifier = Modifier
.fillMaxWidth()
.padding(48.dp),
textAlign = TextAlign.Center,
text = error,
style = TextStyle(
color = colorResource(id = R.color.palette_system_red),
fontFamily = FontFamily.Monospace,
fontSize = 10.sp
)
)
}
}
BackHandler {
// nothing
onSystemBackPressed()
}
}

View file

@ -1,6 +1,5 @@
package com.anytypeio.anytype.presentation.onboarding.login
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
@ -20,11 +19,11 @@ import com.anytypeio.anytype.domain.device.PathProvider
import com.anytypeio.anytype.domain.search.ObjectTypesSubscriptionManager
import com.anytypeio.anytype.domain.search.RelationsSubscriptionManager
import com.anytypeio.anytype.presentation.auth.account.SetupSelectedAccountViewModel
import com.anytypeio.anytype.presentation.auth.model.SelectAccountView
import com.anytypeio.anytype.presentation.extension.proceedWithAccountEvent
import com.anytypeio.anytype.presentation.splash.SplashViewModel
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.take
import kotlinx.coroutines.launch
import timber.log.Timber
@ -41,10 +40,11 @@ class OnboardingLoginSetupViewModel @Inject constructor(
private val configStorage: ConfigStorage
) : ViewModel() {
private val setupState = MutableStateFlow<SetupState>(SetupState.Idle)
val navigation = MutableSharedFlow<Navigation>()
val state by lazy { MutableLiveData<List<SelectAccountView>>() }
val error by lazy { MutableLiveData<String>() }
val error by lazy { MutableStateFlow(NO_ERROR) }
init {
startObservingAccounts()
@ -58,9 +58,9 @@ class OnboardingLoginSetupViewModel @Inject constructor(
result.either(
fnL = { e ->
if (e is AccountIsDeletedException) {
error.postValue("This account is deleted. Try using another account or create a new one.")
error.value = "This account is deleted. Try using another account or create a new one."
} else {
error.postValue("Error while account loading \n ${e.localizedMessage}")
error.value = "Error while account loading \n ${e.localizedMessage}"
}
Timber.e(e, "Error while account loading")
// TODO refact
@ -88,30 +88,32 @@ class OnboardingLoginSetupViewModel @Inject constructor(
private fun proceedWithSelectingAccount(id: String) {
val startTime = System.currentTimeMillis()
viewModelScope.launch {
setupState.value = SetupState.InProgress
selectAccount(
SelectAccount.Params(
id = id,
path = pathProvider.providePath()
)
).process(
failure = {e ->
failure = { e ->
Timber.e(e, "Error while selecting account with id: $id")
setupState.value = SetupState.Failed
when (e) {
is MigrationNeededException -> {
navigateToMigrationErrorScreen()
}
is AccountIsDeletedException -> {
error.postValue("This account is deleted. Try using another account or create a new one.")
error.value = "This account is deleted. Try using another account or create a new one."
}
is NeedToUpdateApplicationException -> {
error.postValue(SplashViewModel.ERROR_NEED_UPDATE)
error.value = SplashViewModel.ERROR_NEED_UPDATE
}
else -> {
// TODO process migration
// migrationMessageJob.cancel()
// isMigrationInProgress.value = false
val msg = e.message ?: "Unknown error"
error.postValue("${SetupSelectedAccountViewModel.ERROR_MESSAGE}: $msg")
error.value = "${SetupSelectedAccountViewModel.ERROR_MESSAGE}: $msg"
}
}
},
@ -165,14 +167,24 @@ class OnboardingLoginSetupViewModel @Inject constructor(
objectTypesSubscriptionManager.onStart()
}
fun onSystemBackPressed() {
if (setupState.value == SetupState.Failed) {
viewModelScope.launch {
navigation.emit(Navigation.Exit)
}
}
}
sealed class Navigation {
object Exit : Navigation()
object NavigateToMigrationErrorScreen : Navigation()
object NavigateToHomeScreen: Navigation()
}
sealed class SideEffect {
// TODO
sealed class SetupState {
object Idle : SetupState()
object InProgress: SetupState()
object Failed: SetupState()
}
class Factory(
@ -202,4 +214,9 @@ class OnboardingLoginSetupViewModel @Inject constructor(
) as T
}
}
companion object {
const val NO_ERROR = ""
const val SOMETHING_WENT_WRONG_ERROR = "Something went wrong. Please, try again."
}
}