lifting unavailable homeserver rendering to the activity/ftuevariant
- the viewmodel is now responsible for inferring connectivity errors and providing a retry action
This commit is contained in:
parent
100aa24021
commit
ea7df9b673
|
@ -25,8 +25,12 @@ import org.matrix.android.sdk.api.auth.data.Credentials
|
||||||
import org.matrix.android.sdk.api.network.ssl.Fingerprint
|
import org.matrix.android.sdk.api.network.ssl.Fingerprint
|
||||||
|
|
||||||
sealed interface OnboardingAction : VectorViewModelAction {
|
sealed interface OnboardingAction : VectorViewModelAction {
|
||||||
data class OnGetStarted(val onboardingFlow: OnboardingFlow) : OnboardingAction
|
sealed interface SplashAction: OnboardingAction {
|
||||||
data class OnIAlreadyHaveAnAccount(val onboardingFlow: OnboardingFlow) : OnboardingAction
|
val onboardingFlow: OnboardingFlow
|
||||||
|
|
||||||
|
data class OnGetStarted(override val onboardingFlow: OnboardingFlow) : SplashAction
|
||||||
|
data class OnIAlreadyHaveAnAccount(override val onboardingFlow: OnboardingFlow) : SplashAction
|
||||||
|
}
|
||||||
|
|
||||||
data class UpdateServerType(val serverType: ServerType) : OnboardingAction
|
data class UpdateServerType(val serverType: ServerType) : OnboardingAction
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.matrix.android.sdk.api.auth.registration.FlowResult
|
||||||
sealed class OnboardingViewEvents : VectorViewEvents {
|
sealed class OnboardingViewEvents : VectorViewEvents {
|
||||||
data class Loading(val message: CharSequence? = null) : OnboardingViewEvents()
|
data class Loading(val message: CharSequence? = null) : OnboardingViewEvents()
|
||||||
data class Failure(val throwable: Throwable) : OnboardingViewEvents()
|
data class Failure(val throwable: Throwable) : OnboardingViewEvents()
|
||||||
|
data class DeeplinkAuthenticationFailure(val retryAction: OnboardingAction) : OnboardingViewEvents()
|
||||||
|
|
||||||
data class RegistrationFlowResult(val flowResult: FlowResult, val isRegistrationStarted: Boolean) : OnboardingViewEvents()
|
data class RegistrationFlowResult(val flowResult: FlowResult, val isRegistrationStarted: Boolean) : OnboardingViewEvents()
|
||||||
object OutdatedHomeserver : OnboardingViewEvents()
|
object OutdatedHomeserver : OnboardingViewEvents()
|
||||||
|
|
|
@ -27,6 +27,7 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.extensions.cancelCurrentOnSet
|
import im.vector.app.core.extensions.cancelCurrentOnSet
|
||||||
import im.vector.app.core.extensions.configureAndStart
|
import im.vector.app.core.extensions.configureAndStart
|
||||||
|
import im.vector.app.core.extensions.inferNoConnectivity
|
||||||
import im.vector.app.core.extensions.vectorStore
|
import im.vector.app.core.extensions.vectorStore
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
|
@ -56,6 +57,7 @@ import org.matrix.android.sdk.api.auth.login.LoginWizard
|
||||||
import org.matrix.android.sdk.api.auth.registration.FlowResult
|
import org.matrix.android.sdk.api.auth.registration.FlowResult
|
||||||
import org.matrix.android.sdk.api.auth.registration.RegistrationWizard
|
import org.matrix.android.sdk.api.auth.registration.RegistrationWizard
|
||||||
import org.matrix.android.sdk.api.auth.registration.Stage
|
import org.matrix.android.sdk.api.auth.registration.Stage
|
||||||
|
import org.matrix.android.sdk.api.failure.isHomeserverUnavailable
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
@ -133,8 +135,7 @@ class OnboardingViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
override fun handle(action: OnboardingAction) {
|
override fun handle(action: OnboardingAction) {
|
||||||
when (action) {
|
when (action) {
|
||||||
is OnboardingAction.OnGetStarted -> handleSplashAction(action.onboardingFlow)
|
is OnboardingAction.SplashAction -> handleSplashAction(action)
|
||||||
is OnboardingAction.OnIAlreadyHaveAnAccount -> handleSplashAction(action.onboardingFlow)
|
|
||||||
is OnboardingAction.UpdateUseCase -> handleUpdateUseCase(action)
|
is OnboardingAction.UpdateUseCase -> handleUpdateUseCase(action)
|
||||||
OnboardingAction.ResetUseCase -> resetUseCase()
|
OnboardingAction.ResetUseCase -> resetUseCase()
|
||||||
is OnboardingAction.UpdateServerType -> handleUpdateServerType(action)
|
is OnboardingAction.UpdateServerType -> handleUpdateServerType(action)
|
||||||
|
@ -174,9 +175,9 @@ class OnboardingViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleSplashAction(onboardingFlow: OnboardingFlow) {
|
private fun handleSplashAction(action: OnboardingAction.SplashAction) {
|
||||||
setState { copy(onboardingFlow = onboardingFlow) }
|
setState { copy(onboardingFlow = action.onboardingFlow) }
|
||||||
continueToPageAfterSplash(onboardingFlow)
|
continueToPageAfterSplash(action.onboardingFlow)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun continueToPageAfterSplash(onboardingFlow: OnboardingFlow) {
|
private fun continueToPageAfterSplash(onboardingFlow: OnboardingFlow) {
|
||||||
|
@ -629,12 +630,28 @@ class OnboardingViewModel @AssistedInject constructor(
|
||||||
setState { copy(isLoading = true) }
|
setState { copy(isLoading = true) }
|
||||||
runCatching { startAuthenticationFlowUseCase.execute(homeServerConnectionConfig) }.fold(
|
runCatching { startAuthenticationFlowUseCase.execute(homeServerConnectionConfig) }.fold(
|
||||||
onSuccess = { onAuthenticationStartedSuccess(trigger, homeServerConnectionConfig, it, serverTypeOverride) },
|
onSuccess = { onAuthenticationStartedSuccess(trigger, homeServerConnectionConfig, it, serverTypeOverride) },
|
||||||
onFailure = { _viewEvents.post(OnboardingViewEvents.Failure(it)) }
|
onFailure = { onAuthenticationStartError(it, trigger) }
|
||||||
)
|
)
|
||||||
setState { copy(isLoading = false) }
|
setState { copy(isLoading = false) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onAuthenticationStartError(it: Throwable, trigger: OnboardingAction.HomeServerChange) {
|
||||||
|
when {
|
||||||
|
it.isHomeserverUnavailable() && applicationContext.inferNoConnectivity() -> _viewEvents.post(
|
||||||
|
OnboardingViewEvents.Failure(it)
|
||||||
|
)
|
||||||
|
it.isHomeserverUnavailable() && trigger is OnboardingAction.HomeServerChange.SelectHomeServer -> _viewEvents.post(
|
||||||
|
OnboardingViewEvents.DeeplinkAuthenticationFailure(retryAction = trigger.resetToDefaultUrl())
|
||||||
|
)
|
||||||
|
else -> _viewEvents.post(
|
||||||
|
OnboardingViewEvents.Failure(it)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun OnboardingAction.HomeServerChange.SelectHomeServer.resetToDefaultUrl() = copy(homeServerUrl = defaultHomeserverUrl)
|
||||||
|
|
||||||
private suspend fun onAuthenticationStartedSuccess(
|
private suspend fun onAuthenticationStartedSuccess(
|
||||||
trigger: OnboardingAction.HomeServerChange,
|
trigger: OnboardingAction.HomeServerChange,
|
||||||
config: HomeServerConnectionConfig,
|
config: HomeServerConnectionConfig,
|
||||||
|
|
|
@ -17,9 +17,6 @@
|
||||||
package im.vector.app.features.onboarding.ftueauth
|
package im.vector.app.features.onboarding.ftueauth
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
|
||||||
import android.net.ConnectivityManager
|
|
||||||
import android.net.NetworkCapabilities
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
@ -29,8 +26,6 @@ import androidx.lifecycle.DefaultLifecycleObserver
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.viewpager2.widget.ViewPager2
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
import com.airbnb.mvrx.withState
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import com.google.android.material.tabs.TabLayoutMediator
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
import im.vector.app.BuildConfig
|
import im.vector.app.BuildConfig
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
@ -44,7 +39,6 @@ import im.vector.app.features.settings.VectorPreferences
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.failure.isHomeserverUnavailable
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
private const val CAROUSEL_ROTATION_DELAY_MS = 5000L
|
private const val CAROUSEL_ROTATION_DELAY_MS = 5000L
|
||||||
|
@ -130,68 +124,14 @@ class FtueAuthSplashCarouselFragment @Inject constructor(
|
||||||
|
|
||||||
private fun splashSubmit(isAlreadyHaveAccountEnabled: Boolean) {
|
private fun splashSubmit(isAlreadyHaveAccountEnabled: Boolean) {
|
||||||
val getStartedFlow = if (isAlreadyHaveAccountEnabled) OnboardingFlow.SignUp else OnboardingFlow.SignInSignUp
|
val getStartedFlow = if (isAlreadyHaveAccountEnabled) OnboardingFlow.SignUp else OnboardingFlow.SignInSignUp
|
||||||
viewModel.handle(OnboardingAction.OnGetStarted(onboardingFlow = getStartedFlow))
|
viewModel.handle(OnboardingAction.SplashAction.OnGetStarted(onboardingFlow = getStartedFlow))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun alreadyHaveAnAccount() {
|
private fun alreadyHaveAnAccount() {
|
||||||
viewModel.handle(OnboardingAction.OnIAlreadyHaveAnAccount(onboardingFlow = OnboardingFlow.SignIn))
|
viewModel.handle(OnboardingAction.SplashAction.OnIAlreadyHaveAnAccount(onboardingFlow = OnboardingFlow.SignIn))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun resetViewModel() {
|
override fun resetViewModel() {
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(throwable: Throwable) {
|
|
||||||
when {
|
|
||||||
requireContext().inferNoConnectivity() -> super.onError(throwable)
|
|
||||||
throwable.isHomeserverUnavailable() -> {
|
|
||||||
val url = viewModel.getInitialHomeServerUrl().orEmpty()
|
|
||||||
homeserverUnavailableDialog(url) { onContinueFlowWithLoginConfigReset() }
|
|
||||||
}
|
|
||||||
else -> super.onError(throwable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onContinueFlowWithLoginConfigReset() {
|
|
||||||
viewModel.handle(OnboardingAction.ResetDeeplinkConfig)
|
|
||||||
when (val flow = withState(viewModel) { it.onboardingFlow } ?: OnboardingFlow.SignInSignUp) {
|
|
||||||
OnboardingFlow.SignIn -> if (vectorFeatures.isOnboardingCombinedLoginEnabled()) {
|
|
||||||
viewModel.handle(OnboardingAction.OnIAlreadyHaveAnAccount(flow))
|
|
||||||
} else {
|
|
||||||
viewModel.handle(OnboardingAction.OnGetStarted(flow))
|
|
||||||
}
|
|
||||||
else -> viewModel.handle(OnboardingAction.OnGetStarted(flow))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun homeserverUnavailableDialog(url: String, action: () -> Unit) {
|
|
||||||
MaterialAlertDialogBuilder(requireActivity())
|
|
||||||
.setTitle(R.string.dialog_title_error)
|
|
||||||
.setMessage(getString(R.string.login_error_homeserver_from_url_not_found, url))
|
|
||||||
.setPositiveButton(R.string.login_error_homeserver_from_url_not_found_enter_manual) { _, _ -> action() }
|
|
||||||
.setNegativeButton(R.string.action_cancel, null)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Context.inferNoConnectivity(): Boolean {
|
|
||||||
var networkAvailable = false
|
|
||||||
|
|
||||||
val connectivityManager: ConnectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
|
||||||
val network = connectivityManager.activeNetwork
|
|
||||||
val networkCapabilities = connectivityManager.getNetworkCapabilities(network)
|
|
||||||
|
|
||||||
when {
|
|
||||||
networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true -> {
|
|
||||||
networkAvailable = true
|
|
||||||
}
|
|
||||||
networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) == true -> {
|
|
||||||
networkAvailable = true
|
|
||||||
}
|
|
||||||
networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_VPN) == true -> {
|
|
||||||
networkAvailable = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return !networkAvailable
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,6 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import com.airbnb.mvrx.withState
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import im.vector.app.BuildConfig
|
import im.vector.app.BuildConfig
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.databinding.FragmentFtueAuthSplashBinding
|
import im.vector.app.databinding.FragmentFtueAuthSplashBinding
|
||||||
|
@ -31,8 +29,6 @@ import im.vector.app.features.VectorFeatures
|
||||||
import im.vector.app.features.onboarding.OnboardingAction
|
import im.vector.app.features.onboarding.OnboardingAction
|
||||||
import im.vector.app.features.onboarding.OnboardingFlow
|
import im.vector.app.features.onboarding.OnboardingFlow
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import org.matrix.android.sdk.api.failure.Failure
|
|
||||||
import java.net.UnknownHostException
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,34 +71,14 @@ class FtueAuthSplashFragment @Inject constructor(
|
||||||
|
|
||||||
private fun splashSubmit(isAlreadyHaveAccountEnabled: Boolean) {
|
private fun splashSubmit(isAlreadyHaveAccountEnabled: Boolean) {
|
||||||
val getStartedFlow = if (isAlreadyHaveAccountEnabled) OnboardingFlow.SignUp else OnboardingFlow.SignInSignUp
|
val getStartedFlow = if (isAlreadyHaveAccountEnabled) OnboardingFlow.SignUp else OnboardingFlow.SignInSignUp
|
||||||
viewModel.handle(OnboardingAction.OnGetStarted(onboardingFlow = getStartedFlow))
|
viewModel.handle(OnboardingAction.SplashAction.OnGetStarted(onboardingFlow = getStartedFlow))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun alreadyHaveAnAccount() {
|
private fun alreadyHaveAnAccount() {
|
||||||
viewModel.handle(OnboardingAction.OnIAlreadyHaveAnAccount(onboardingFlow = OnboardingFlow.SignIn))
|
viewModel.handle(OnboardingAction.SplashAction.OnIAlreadyHaveAnAccount(onboardingFlow = OnboardingFlow.SignIn))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun resetViewModel() {
|
override fun resetViewModel() {
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(throwable: Throwable) {
|
|
||||||
if (throwable is Failure.NetworkConnection &&
|
|
||||||
throwable.ioException is UnknownHostException) {
|
|
||||||
// Invalid homeserver from URL config
|
|
||||||
val url = viewModel.getInitialHomeServerUrl().orEmpty()
|
|
||||||
MaterialAlertDialogBuilder(requireActivity())
|
|
||||||
.setTitle(R.string.dialog_title_error)
|
|
||||||
.setMessage(getString(R.string.login_error_homeserver_from_url_not_found, url))
|
|
||||||
.setPositiveButton(R.string.login_error_homeserver_from_url_not_found_enter_manual) { _, _ ->
|
|
||||||
val flow = withState(viewModel) { it.onboardingFlow } ?: OnboardingFlow.SignInSignUp
|
|
||||||
viewModel.handle(OnboardingAction.ResetDeeplinkConfig)
|
|
||||||
viewModel.handle(OnboardingAction.OnGetStarted(flow))
|
|
||||||
}
|
|
||||||
.setNegativeButton(R.string.action_cancel, null)
|
|
||||||
.show()
|
|
||||||
} else {
|
|
||||||
super.onError(throwable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,6 @@ import androidx.annotation.ColorRes
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.airbnb.mvrx.withState
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.extensions.getResTintedDrawable
|
import im.vector.app.core.extensions.getResTintedDrawable
|
||||||
import im.vector.app.core.extensions.getTintedDrawable
|
import im.vector.app.core.extensions.getTintedDrawable
|
||||||
|
@ -40,7 +38,6 @@ import im.vector.app.features.login.ServerType
|
||||||
import im.vector.app.features.onboarding.FtueUseCase
|
import im.vector.app.features.onboarding.FtueUseCase
|
||||||
import im.vector.app.features.onboarding.OnboardingAction
|
import im.vector.app.features.onboarding.OnboardingAction
|
||||||
import im.vector.app.features.themes.ThemeProvider
|
import im.vector.app.features.themes.ThemeProvider
|
||||||
import org.matrix.android.sdk.api.failure.isHomeserverUnavailable
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
private const val DARK_MODE_ICON_BACKGROUND_ALPHA = 0.30f
|
private const val DARK_MODE_ICON_BACKGROUND_ALPHA = 0.30f
|
||||||
|
@ -107,38 +104,11 @@ class FtueAuthUseCaseFragment @Inject constructor(
|
||||||
private fun createIcon(@ColorRes tint: Int, icon: Int, isLightMode: Boolean): Drawable {
|
private fun createIcon(@ColorRes tint: Int, icon: Int, isLightMode: Boolean): Drawable {
|
||||||
val context = requireContext()
|
val context = requireContext()
|
||||||
val alpha = when (isLightMode) {
|
val alpha = when (isLightMode) {
|
||||||
true -> LIGHT_MODE_ICON_BACKGROUND_ALPHA
|
true -> LIGHT_MODE_ICON_BACKGROUND_ALPHA
|
||||||
false -> DARK_MODE_ICON_BACKGROUND_ALPHA
|
false -> DARK_MODE_ICON_BACKGROUND_ALPHA
|
||||||
}
|
}
|
||||||
val iconBackground = context.getResTintedDrawable(R.drawable.bg_feature_icon, tint, alpha = alpha)
|
val iconBackground = context.getResTintedDrawable(R.drawable.bg_feature_icon, tint, alpha = alpha)
|
||||||
val whiteLayer = context.getTintedDrawable(R.drawable.bg_feature_icon, Color.WHITE)
|
val whiteLayer = context.getTintedDrawable(R.drawable.bg_feature_icon, Color.WHITE)
|
||||||
return LayerDrawable(arrayOf(whiteLayer, iconBackground, ContextCompat.getDrawable(context, icon)))
|
return LayerDrawable(arrayOf(whiteLayer, iconBackground, ContextCompat.getDrawable(context, icon)))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(throwable: Throwable) {
|
|
||||||
when {
|
|
||||||
requireContext().inferNoConnectivity() -> super.onError(throwable)
|
|
||||||
throwable.isHomeserverUnavailable() -> {
|
|
||||||
val url = viewModel.getInitialHomeServerUrl().orEmpty()
|
|
||||||
homeserverUnavailableDialog(url) { onContinueFlowWithLoginConfigReset() }
|
|
||||||
}
|
|
||||||
else -> super.onError(throwable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onContinueFlowWithLoginConfigReset() {
|
|
||||||
viewModel.handle(OnboardingAction.ResetDeeplinkConfig)
|
|
||||||
withState(viewModel) { it.useCase }?.let {
|
|
||||||
viewModel.handle(OnboardingAction.UpdateUseCase(it))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun homeserverUnavailableDialog(url: String, action: () -> Unit) {
|
|
||||||
MaterialAlertDialogBuilder(requireActivity())
|
|
||||||
.setTitle(R.string.dialog_title_error)
|
|
||||||
.setMessage(getString(R.string.login_error_homeserver_from_url_not_found, url))
|
|
||||||
.setPositiveButton(R.string.login_error_homeserver_from_url_not_found_enter_manual) { _, _ -> action() }
|
|
||||||
.setNegativeButton(R.string.action_cancel, null)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,11 +227,28 @@ class FtueAuthVariant(
|
||||||
option = commonOption
|
option = commonOption
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
OnboardingViewEvents.OnHomeserverEdited -> activity.popBackstack()
|
OnboardingViewEvents.OnHomeserverEdited -> activity.popBackstack()
|
||||||
OnboardingViewEvents.OpenCombinedLogin -> onStartCombinedLogin()
|
OnboardingViewEvents.OpenCombinedLogin -> onStartCombinedLogin()
|
||||||
|
is OnboardingViewEvents.DeeplinkAuthenticationFailure -> onDeeplinkedHomeserverUnavailable(viewEvents)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onDeeplinkedHomeserverUnavailable(viewEvents: OnboardingViewEvents.DeeplinkAuthenticationFailure) {
|
||||||
|
showHomeserverUnavailableDialog(onboardingViewModel.getInitialHomeServerUrl().orEmpty()) {
|
||||||
|
onboardingViewModel.handle(OnboardingAction.ResetDeeplinkConfig)
|
||||||
|
onboardingViewModel.handle(viewEvents.retryAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showHomeserverUnavailableDialog(url: String, action: () -> Unit) {
|
||||||
|
MaterialAlertDialogBuilder(activity)
|
||||||
|
.setTitle(R.string.dialog_title_error)
|
||||||
|
.setMessage(activity.getString(R.string.login_error_homeserver_from_url_not_found, url))
|
||||||
|
.setPositiveButton(R.string.login_error_homeserver_from_url_not_found_enter_manual) { _, _ -> action() }
|
||||||
|
.setNegativeButton(R.string.action_cancel, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
private fun onStartCombinedLogin() {
|
private fun onStartCombinedLogin() {
|
||||||
addRegistrationStageFragmentToBackstack(FtueAuthCombinedLoginFragment::class.java)
|
addRegistrationStageFragmentToBackstack(FtueAuthCombinedLoginFragment::class.java)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,13 +17,17 @@
|
||||||
package im.vector.app.features.onboarding.ftueauth
|
package im.vector.app.features.onboarding.ftueauth
|
||||||
|
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
|
import im.vector.app.R
|
||||||
import im.vector.app.core.extensions.hasContentFlow
|
import im.vector.app.core.extensions.hasContentFlow
|
||||||
|
import im.vector.app.core.extensions.inferNoConnectivity
|
||||||
import im.vector.app.features.login.SignMode
|
import im.vector.app.features.login.SignMode
|
||||||
import im.vector.app.features.onboarding.OnboardingAction
|
import im.vector.app.features.onboarding.OnboardingAction
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import org.matrix.android.sdk.api.failure.isHomeserverUnavailable
|
||||||
|
|
||||||
fun SignMode.toAuthenticateAction(login: String, password: String, initialDeviceName: String): OnboardingAction.AuthenticateAction {
|
fun SignMode.toAuthenticateAction(login: String, password: String, initialDeviceName: String): OnboardingAction.AuthenticateAction {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
|
|
Loading…
Reference in New Issue