diff --git a/vector/src/main/java/im/vector/riotx/core/error/ErrorFormatter.kt b/vector/src/main/java/im/vector/riotx/core/error/ErrorFormatter.kt index 29506cf880..c943a86fbc 100644 --- a/vector/src/main/java/im/vector/riotx/core/error/ErrorFormatter.kt +++ b/vector/src/main/java/im/vector/riotx/core/error/ErrorFormatter.kt @@ -35,13 +35,14 @@ class ErrorFormatter @Inject constructor(private val stringProvider: StringProvi return when (throwable) { null -> null is Failure.NetworkConnection -> { - if (throwable.ioException is SocketTimeoutException) { - stringProvider.getString(R.string.error_network_timeout) - } else if (throwable.ioException is UnknownHostException) { - // Invalid homeserver? - stringProvider.getString(R.string.login_error_unknown_host) - } else { - stringProvider.getString(R.string.error_no_network) + when { + throwable.ioException is SocketTimeoutException -> + stringProvider.getString(R.string.error_network_timeout) + throwable.ioException is UnknownHostException -> + // Invalid homeserver? + stringProvider.getString(R.string.login_error_unknown_host) + else -> + stringProvider.getString(R.string.error_no_network) } } is Failure.ServerError -> { @@ -57,6 +58,15 @@ class ErrorFormatter @Inject constructor(private val stringProvider: StringProvi throwable.error.code == MatrixError.USER_IN_USE -> { stringProvider.getString(R.string.login_signup_error_user_in_use) } + throwable.error.code == MatrixError.BAD_JSON -> { + stringProvider.getString(R.string.login_error_bad_json) + } + throwable.error.code == MatrixError.NOT_JSON -> { + stringProvider.getString(R.string.login_error_not_json) + } + throwable.error.code == MatrixError.LIMIT_EXCEEDED -> { + stringProvider.getString(R.string.login_error_limit_exceeded) + } else -> { throwable.error.message.takeIf { it.isNotEmpty() } ?: throwable.error.code.takeIf { it.isNotEmpty() } diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginActivity.kt index a0b718f134..e7cb90f5df 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginActivity.kt @@ -27,8 +27,11 @@ import com.airbnb.mvrx.viewModel import com.airbnb.mvrx.withState import im.vector.matrix.android.api.auth.registration.FlowResult import im.vector.matrix.android.api.auth.registration.Stage +import im.vector.matrix.android.api.failure.Failure +import im.vector.matrix.android.api.failure.MatrixError import im.vector.riotx.R import im.vector.riotx.core.di.ScreenComponent +import im.vector.riotx.core.error.ErrorFormatter import im.vector.riotx.core.extensions.addFragment import im.vector.riotx.core.extensions.addFragmentToBackstack import im.vector.riotx.core.platform.VectorBaseActivity @@ -38,6 +41,7 @@ import im.vector.riotx.features.login.terms.LoginTermsFragmentArgument import im.vector.riotx.features.login.terms.toLocalizedLoginTerms import kotlinx.android.synthetic.main.activity_login.* import javax.inject.Inject +import javax.net.ssl.HttpsURLConnection /** * The LoginActivity manages the fragment navigation and also display the loading View @@ -48,6 +52,7 @@ class LoginActivity : VectorBaseActivity() { private lateinit var loginSharedActionViewModel: LoginSharedActionViewModel @Inject lateinit var loginViewModelFactory: LoginViewModel.Factory + @Inject lateinit var errorFormatter: ErrorFormatter override fun injectWith(injector: ScreenComponent) { injector.inject(this) @@ -124,9 +129,31 @@ class LoginActivity : VectorBaseActivity() { } } } + is LoginViewEvents.RegistrationError -> displayRegistrationError(loginViewEvents.throwable) } } + private fun displayRegistrationError(throwable: Throwable) { + val message = when(throwable) { + is Failure.ServerError -> { + if(throwable.error.code == MatrixError.FORBIDDEN + && throwable.httpCode == HttpsURLConnection.HTTP_FORBIDDEN /* 403 */) { + getString(R.string.login_registration_disabled) + } else { + null + } + } + else -> null + } + ?: errorFormatter.toHumanReadable(throwable) + + AlertDialog.Builder(this) + .setTitle(R.string.dialog_title_error) + .setMessage(message) + .setPositiveButton(R.string.ok, null) + .show() + } + private fun onLoginFlowRetrieved() { addFragmentToBackstack(R.id.loginFragmentContainer, LoginSignUpSignInSelectionFragment::class.java) } diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginViewEvents.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginViewEvents.kt index b8b7965c77..b7351feead 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginViewEvents.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginViewEvents.kt @@ -24,4 +24,5 @@ import im.vector.matrix.android.api.auth.registration.FlowResult */ sealed class LoginViewEvents { data class RegistrationFlowResult(val flowResult: FlowResult) : LoginViewEvents() + data class RegistrationError(val throwable: Throwable) : LoginViewEvents() } diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt index 6cc73233a7..49676b4a35 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt @@ -489,7 +489,16 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi registrationWizard = registrationService.getOrCreateRegistrationWizard(homeServerConnectionConfigFinal) currentTask = registrationWizard?.getRegistrationFlow(object : MatrixCallback { + override fun onSuccess(data: RegistrationResult) { + /* + // Simulate registration disabled + onFailure(Failure.ServerError(MatrixError( + code = MatrixError.FORBIDDEN, + message = "Registration is disabled" + ), 403)) + */ + setState { copy( asyncRegistration = Success(data) @@ -503,6 +512,9 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi } override fun onFailure(failure: Throwable) { + // Notify the user + _viewEvents.post(LoginViewEvents.RegistrationError(failure)) + // TODO Handled JobCancellationException setState { copy( diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml index 8a013a255b..958ebec6cc 100644 --- a/vector/src/main/res/values/strings_riotX.xml +++ b/vector/src/main/res/values/strings_riotX.xml @@ -46,6 +46,7 @@ Sign in to %1$s Sign Up Sign In + Sign In with SSO Modular Address Address @@ -56,6 +57,7 @@ An error occurred when loading the page: %1$s (%2$d) The application is not able to signin to this homeserver. The homeserver supports the following signin type(s): %1$s.\n\nDo you want to signin using a web client? + Sorry, the homeserver does not accept new account creation. The application is not able to create an account on this homeserver.\n\nDo you want to signup using a web client?