Room creation Fragment: no more "Retry" action, loading and error displayed in a dialog

This commit is contained in:
Benoit Marty 2020-11-18 14:51:10 +01:00
parent 507d5d3758
commit 514263ae12
8 changed files with 40 additions and 44 deletions

View file

@ -22,7 +22,9 @@ import org.matrix.android.sdk.api.failure.MatrixError
sealed class CreateRoomFailure : Failure.FeatureFailure() { sealed class CreateRoomFailure : Failure.FeatureFailure() {
object CreatedWithTimeout : CreateRoomFailure() object CreatedWithTimeout : CreateRoomFailure()
data class CreatedWithFederationFailure(val matrixError: MatrixError) : CreateRoomFailure() data class CreatedWithFederationFailure(val matrixError: MatrixError) : CreateRoomFailure()
object RoomAliasEmpty: CreateRoomFailure() sealed class RoomAliasError : CreateRoomFailure() {
object RoomAliasNotAvailable: CreateRoomFailure() object AliasEmpty : RoomAliasError()
object RoomAliasInvalid: CreateRoomFailure() object AliasNotAvailable : RoomAliasError()
object AliasInvalid : RoomAliasError()
}
} }

View file

@ -66,7 +66,7 @@ internal class DefaultCreateRoomTask @Inject constructor(
if (params.preset == CreateRoomPreset.PRESET_PUBLIC_CHAT) { if (params.preset == CreateRoomPreset.PRESET_PUBLIC_CHAT) {
if (params.roomAliasName.isNullOrEmpty()) { if (params.roomAliasName.isNullOrEmpty()) {
throw CreateRoomFailure.RoomAliasEmpty throw CreateRoomFailure.RoomAliasError.AliasEmpty
} }
// Check alias availability // Check alias availability
val fullAlias = "#" + params.roomAliasName + ":" + userId.substringAfter(":") val fullAlias = "#" + params.roomAliasName + ":" + userId.substringAfter(":")
@ -85,7 +85,7 @@ internal class DefaultCreateRoomTask @Inject constructor(
} }
?.let { ?.let {
// Alias already exists: error case // Alias already exists: error case
throw CreateRoomFailure.RoomAliasNotAvailable throw CreateRoomFailure.RoomAliasError.AliasNotAvailable
} }
} }
@ -104,7 +104,7 @@ internal class DefaultCreateRoomTask @Inject constructor(
} else if (throwable.httpCode == 400 } else if (throwable.httpCode == 400
&& throwable.error.code == MatrixError.M_UNKNOWN && throwable.error.code == MatrixError.M_UNKNOWN
&& throwable.error.message == "Invalid characters in room alias") { && throwable.error.message == "Invalid characters in room alias") {
throw CreateRoomFailure.RoomAliasInvalid throw CreateRoomFailure.RoomAliasError.AliasInvalid
} }
} }
throw throwable throw throwable

View file

@ -44,32 +44,8 @@ class CreateRoomController @Inject constructor(private val stringProvider: Strin
var index = 0 var index = 0
override fun buildModels(viewState: CreateRoomViewState) { override fun buildModels(viewState: CreateRoomViewState) {
when (val asyncCreateRoom = viewState.asyncCreateRoomRequest) { // display the form
is Success -> { buildForm(viewState, viewState.asyncCreateRoomRequest !is Loading)
// Nothing to display, the screen will be closed
}
is Loading -> {
// display the form
buildForm(viewState, false)
loadingItem {
id("loading")
}
}
is Uninitialized -> {
// display the form
buildForm(viewState, true)
}
is Fail -> {
// display the form
buildForm(viewState, true)
// TODO BMA DO NOT COMMIT Update this
errorWithRetryItem {
id("error")
text(errorFormatter.toHumanReadable(asyncCreateRoom.error))
listener { listener?.retry() }
}
}
}
} }
private fun buildForm(viewState: CreateRoomViewState, enableFormElement: Boolean) { private fun buildForm(viewState: CreateRoomViewState, enableFormElement: Boolean) {
@ -133,10 +109,10 @@ class CreateRoomController @Inject constructor(private val stringProvider: Strin
homeServer(":" + viewState.homeServerName) homeServer(":" + viewState.homeServerName)
errorMessage( errorMessage(
when ((viewState.asyncCreateRoomRequest as? Fail)?.error) { when ((viewState.asyncCreateRoomRequest as? Fail)?.error) {
is CreateRoomFailure.RoomAliasEmpty -> R.string.create_room_alias_empty is CreateRoomFailure.RoomAliasError.AliasEmpty -> R.string.create_room_alias_empty
is CreateRoomFailure.RoomAliasNotAvailable -> R.string.create_room_alias_already_in_use is CreateRoomFailure.RoomAliasError.AliasNotAvailable -> R.string.create_room_alias_already_in_use
is CreateRoomFailure.RoomAliasInvalid -> R.string.create_room_alias_invalid is CreateRoomFailure.RoomAliasError.AliasInvalid -> R.string.create_room_alias_invalid
else -> null else -> null
} }
?.let { stringProvider.getString(it) } ?.let { stringProvider.getString(it) }
) )
@ -195,7 +171,6 @@ class CreateRoomController @Inject constructor(private val stringProvider: Strin
fun setIsPublic(isPublic: Boolean) fun setIsPublic(isPublic: Boolean)
fun setAliasLocalPart(aliasLocalPart: String) fun setAliasLocalPart(aliasLocalPart: String)
fun setIsEncrypted(isEncrypted: Boolean) fun setIsEncrypted(isEncrypted: Boolean)
fun retry()
fun toggleShowAdvanced() fun toggleShowAdvanced()
fun setDisableFederation(disableFederation: Boolean) fun setDisableFederation(disableFederation: Boolean)
fun submit() fun submit()

View file

@ -21,6 +21,8 @@ import android.os.Bundle
import android.os.Parcelable import android.os.Parcelable
import android.view.View import android.view.View
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.view.isVisible
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success import com.airbnb.mvrx.Success
import com.airbnb.mvrx.args import com.airbnb.mvrx.args
import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.fragmentViewModel
@ -37,7 +39,8 @@ import im.vector.app.features.roomdirectory.RoomDirectorySharedAction
import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel
import kotlinx.android.parcel.Parcelize import kotlinx.android.parcel.Parcelize
import kotlinx.android.synthetic.main.fragment_create_room.* import kotlinx.android.synthetic.main.fragment_create_room.*
import timber.log.Timber import kotlinx.android.synthetic.main.merge_overlay_waiting_view.*
import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
import javax.inject.Inject import javax.inject.Inject
@Parcelize @Parcelize
@ -66,17 +69,31 @@ class CreateRoomFragment @Inject constructor(
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
vectorBaseActivity.setSupportActionBar(createRoomToolbar) vectorBaseActivity.setSupportActionBar(createRoomToolbar)
sharedActionViewModel = activityViewModelProvider.get(RoomDirectorySharedActionViewModel::class.java) sharedActionViewModel = activityViewModelProvider.get(RoomDirectorySharedActionViewModel::class.java)
setupWaitingView()
setupRecyclerView() setupRecyclerView()
createRoomClose.debouncedClicks { createRoomClose.debouncedClicks {
sharedActionViewModel.post(RoomDirectorySharedAction.Back) sharedActionViewModel.post(RoomDirectorySharedAction.Back)
} }
viewModel.observeViewEvents { viewModel.observeViewEvents {
when (it) { when (it) {
CreateRoomViewEvents.Quit -> vectorBaseActivity.onBackPressed() CreateRoomViewEvents.Quit -> vectorBaseActivity.onBackPressed()
is CreateRoomViewEvents.Failure -> showFailure(it.throwable)
}.exhaustive }.exhaustive
} }
} }
override fun showFailure(throwable: Throwable) {
// Note: RoomAliasError are displayed directly in the form
if (throwable !is CreateRoomFailure.RoomAliasError) {
super.showFailure(throwable)
}
}
private fun setupWaitingView() {
waiting_view_status_text.isVisible = true
waiting_view_status_text.setText(R.string.create_room_in_progress)
}
override fun onDestroyView() { override fun onDestroyView() {
createRoomForm.cleanup() createRoomForm.cleanup()
createRoomController.listener = null createRoomController.listener = null
@ -132,11 +149,6 @@ class CreateRoomFragment @Inject constructor(
viewModel.handle(CreateRoomAction.Create) viewModel.handle(CreateRoomAction.Create)
} }
override fun retry() {
Timber.v("Retry")
viewModel.handle(CreateRoomAction.Create)
}
override fun onBackPressed(toolbarButton: Boolean): Boolean { override fun onBackPressed(toolbarButton: Boolean): Boolean {
return withState(viewModel) { return withState(viewModel) {
return@withState if (!it.isEmpty()) { return@withState if (!it.isEmpty()) {
@ -157,6 +169,7 @@ class CreateRoomFragment @Inject constructor(
override fun invalidate() = withState(viewModel) { state -> override fun invalidate() = withState(viewModel) { state ->
val async = state.asyncCreateRoomRequest val async = state.asyncCreateRoomRequest
waiting_view.isVisible = async is Loading
if (async is Success) { if (async is Success) {
// Navigate to freshly created room // Navigate to freshly created room
navigator.openRoom(requireActivity(), async()) navigator.openRoom(requireActivity(), async())

View file

@ -22,5 +22,6 @@ import im.vector.app.core.platform.VectorViewEvents
* Transient events for room creation screen * Transient events for room creation screen
*/ */
sealed class CreateRoomViewEvents : VectorViewEvents { sealed class CreateRoomViewEvents : VectorViewEvents {
data class Failure(val throwable: Throwable) : CreateRoomViewEvents()
object Quit : CreateRoomViewEvents() object Quit : CreateRoomViewEvents()
} }

View file

@ -36,6 +36,7 @@ import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.raw.RawService import org.matrix.android.sdk.api.raw.RawService
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomPreset import org.matrix.android.sdk.api.session.room.model.create.CreateRoomPreset
@ -221,6 +222,7 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted initialState: Cr
setState { setState {
copy(asyncCreateRoomRequest = Fail(failure)) copy(asyncCreateRoomRequest = Fail(failure))
} }
_viewEvents.post(CreateRoomViewEvents.Failure(failure))
} }
}) })
} }

View file

@ -67,5 +67,7 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<include layout="@layout/merge_overlay_waiting_view" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -2104,6 +2104,7 @@
<string name="create_room_alias_already_in_use">This address is already in use</string> <string name="create_room_alias_already_in_use">This address is already in use</string>
<string name="create_room_alias_empty">Please provide a room address</string> <string name="create_room_alias_empty">Please provide a room address</string>
<string name="create_room_alias_invalid">Some characters are not allowed</string> <string name="create_room_alias_invalid">Some characters are not allowed</string>
<string name="create_room_in_progress">Creating room…</string>
<string name="login_error_threepid_denied">Your email domain is not authorized to register on this server</string> <string name="login_error_threepid_denied">Your email domain is not authorized to register on this server</string>