diff --git a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsController.kt b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsController.kt index 3dda8f5e35..331bff0b4a 100644 --- a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsController.kt +++ b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsController.kt @@ -25,6 +25,7 @@ import com.airbnb.mvrx.Success import im.vector.app.R import im.vector.app.core.epoxy.loadingItem import im.vector.app.core.epoxy.noResultItem +import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.getFormattedValue import im.vector.app.core.resources.ColorProvider @@ -37,12 +38,15 @@ import im.vector.app.features.discovery.settingsEditTextItem import im.vector.app.features.discovery.settingsInfoItem import im.vector.app.features.discovery.settingsInformationItem import im.vector.app.features.discovery.settingsSectionTitleItem +import org.matrix.android.sdk.api.failure.Failure +import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.session.identity.ThreePid import javax.inject.Inject class ThreePidsSettingsController @Inject constructor( private val stringProvider: StringProvider, - private val colorProvider: ColorProvider + private val colorProvider: ColorProvider, + private val errorFormatter: ErrorFormatter ) : TypedEpoxyController() { interface InteractionListener { @@ -116,7 +120,7 @@ class ThreePidsSettingsController @Inject constructor( } } - pendingList.forEach { buildPendingThreePid("p_email ", it) } + pendingList.forEach { buildPendingThreePid(data, "p_email ", it) } } when (data.state) { @@ -171,7 +175,7 @@ class ThreePidsSettingsController @Inject constructor( } } - pendingList.forEach { buildPendingThreePid("p_msisdn ", it) } + pendingList.forEach { buildPendingThreePid(data, "p_msisdn ", it) } } when (data.state) { @@ -222,7 +226,7 @@ class ThreePidsSettingsController @Inject constructor( } } - private fun buildPendingThreePid(idPrefix: String, threePid: ThreePid) { + private fun buildPendingThreePid(data: ThreePidsSettingsViewState, idPrefix: String, threePid: ThreePid) { threePidItem { id(idPrefix + threePid.value) // TODO Add an icon for emails @@ -253,6 +257,7 @@ class ThreePidsSettingsController @Inject constructor( id("msisdnVerification${threePid.value}") inputType(InputType.TYPE_CLASS_NUMBER) hint(stringProvider.getString(R.string.settings_text_message_sent_hint)) + errorText(getCodeError(data, threePid)) interactionListener(object : SettingsEditTextItem.Listener { override fun onValidate() { interactionListener?.submitCode(threePid, currentCodes[threePid] ?: "") @@ -271,4 +276,17 @@ class ThreePidsSettingsController @Inject constructor( } } } + + private fun getCodeError(data: ThreePidsSettingsViewState, threePid: ThreePid.Msisdn): String? { + val failure = (data.msisdnValidationRequests[threePid.value] as? Fail)?.error ?: return null + // Wrong code? + // See https://github.com/matrix-org/synapse/issues/8218 + return if (failure is Failure.ServerError + && failure.httpCode == 400 + && failure.error.code == MatrixError.M_UNKNOWN) { + stringProvider.getString(R.string.settings_text_message_sent_wrong_code) + } else { + errorFormatter.toHumanReadable(failure) + } + } } diff --git a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt index 78b20fc26d..0501d77808 100644 --- a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt @@ -18,7 +18,9 @@ package im.vector.app.features.settings.threepids import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.ActivityViewModelContext +import com.airbnb.mvrx.Fail import com.airbnb.mvrx.FragmentViewModelContext +import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import com.squareup.inject.assisted.Assisted @@ -141,6 +143,14 @@ class ThreePidsSettingsViewModel @AssistedInject constructor( private fun handleSubmitCode(action: ThreePidsSettingsAction.SubmitCode) { isLoading(true) + setState { + copy( + msisdnValidationRequests = msisdnValidationRequests.toMutableMap().apply { + put(action.threePid.value, Loading()) + } + ) + } + viewModelScope.launch { // First submit the code session.submitSmsCode(action.threePid, action.code, object : MatrixCallback { @@ -151,9 +161,14 @@ class ThreePidsSettingsViewModel @AssistedInject constructor( } override fun onFailure(failure: Throwable) { - // Wrong code? isLoading(false) - _viewEvents.post(ThreePidsSettingsViewEvents.Failure(failure)) + setState { + copy( + msisdnValidationRequests = msisdnValidationRequests.toMutableMap().apply { + put(action.threePid.value, Fail(failure)) + } + ) + } } }) } diff --git a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewState.kt b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewState.kt index 47590286e0..4233ee1005 100644 --- a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewState.kt +++ b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewState.kt @@ -25,5 +25,6 @@ data class ThreePidsSettingsViewState( val state: ThreePidsSettingsState = ThreePidsSettingsState.Idle, val isLoading: Boolean = false, val threePids: Async> = Uninitialized, - val pendingThreePids: Async> = Uninitialized + val pendingThreePids: Async> = Uninitialized, + val msisdnValidationRequests: Map> = emptyMap() ) : MvRxState