Add error feedback when joining space rooms

This commit is contained in:
Valere 2021-06-16 17:35:00 +02:00
parent 71b456c57e
commit e277deece5
7 changed files with 51 additions and 10 deletions

1
newsfragment/3207.bugfix Normal file
View file

@ -0,0 +1 @@
Space Explore Rooms no feedback on failed to join

View file

@ -17,11 +17,13 @@
package im.vector.app.features.home.room.list
import com.airbnb.mvrx.Async
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import im.vector.app.R
import im.vector.app.core.date.DateFormatKind
import im.vector.app.core.date.VectorDateFormatter
import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.timeline.format.DisplayableEventFormatter
@ -37,7 +39,8 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
private val dateFormatter: VectorDateFormatter,
private val stringProvider: StringProvider,
private val typingHelper: TypingHelper,
private val avatarRenderer: AvatarRenderer) {
private val avatarRenderer: AvatarRenderer,
private val errorFormatter: ErrorFormatter) {
fun create(roomSummary: RoomSummary,
roomChangeMembershipStates: Map<String, ChangeMembershipState>,
@ -55,12 +58,21 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
fun createSuggestion(spaceChildInfo: SpaceChildInfo,
suggestedRoomJoiningStates: Map<String, Async<Unit>>,
listener: RoomListListener?): VectorEpoxyModel<*> {
val error = (suggestedRoomJoiningStates[spaceChildInfo.childRoomId] as? Fail)?.error
return SpaceChildInfoItem_()
.id("sug_${spaceChildInfo.childRoomId}")
.matrixItem(spaceChildInfo.toMatrixItem())
.avatarRenderer(avatarRenderer)
.topic(spaceChildInfo.topic)
.buttonLabel(stringProvider.getString(R.string.join))
.errorLabel(
error?.let {
stringProvider.getString(R.string.error_failed_to_join_room, errorFormatter.toHumanReadable(it))
}
)
.buttonLabel(
if (error != null) stringProvider.getString(R.string.global_retry)
else stringProvider.getString(R.string.join)
)
.loading(suggestedRoomJoiningStates[spaceChildInfo.childRoomId] is Loading)
.memberCount(spaceChildInfo.activeMemberCount ?: 0)
.buttonClickListener { listener?.onJoinSuggestedRoom(spaceChildInfo) }

View file

@ -33,6 +33,7 @@ import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.themes.ThemeUtils
import me.gujun.android.span.image
@ -52,6 +53,7 @@ abstract class SpaceChildInfoItem : VectorEpoxyModel<SpaceChildInfoItem.Holder>(
@EpoxyAttribute var loading: Boolean = false
@EpoxyAttribute var buttonLabel: String? = null
@EpoxyAttribute var errorLabel: String? = null
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemLongClickListener: View.OnLongClickListener? = null
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemClickListener: ClickListener? = null
@ -97,6 +99,8 @@ abstract class SpaceChildInfoItem : VectorEpoxyModel<SpaceChildInfoItem.Holder>(
holder.joinButton.isVisible = true
}
holder.errorTextView.setTextOrHide(errorLabel)
holder.joinButton.onClick {
// local echo
holder.joinButton.isEnabled = false
@ -120,5 +124,6 @@ abstract class SpaceChildInfoItem : VectorEpoxyModel<SpaceChildInfoItem.Holder>(
val descriptionText by bind<TextView>(R.id.suggestedRoomDescription)
val avatarImageView by bind<ImageView>(R.id.roomAvatarImageView)
val rootView by bind<ViewGroup>(R.id.itemRoomLayout)
val errorTextView by bind<TextView>(R.id.inlineErrorText)
}
}

View file

@ -35,6 +35,7 @@ import im.vector.app.features.home.room.list.spaceChildInfoItem
import me.gujun.android.span.span
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.failure.MatrixError.Companion.M_UNRECOGNIZED
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
import org.matrix.android.sdk.api.session.room.model.RoomType
import org.matrix.android.sdk.api.session.room.model.SpaceChildInfo
import org.matrix.android.sdk.api.util.toMatrixItem
@ -127,6 +128,7 @@ class SpaceDirectoryController @Inject constructor(
val isSpace = info.roomType == RoomType.SPACE
val isJoined = data?.joinedRoomsIds?.contains(info.childRoomId) == true
val isLoading = data?.changeMembershipStates?.get(info.childRoomId)?.isInProgress() ?: false
val error = (data?.changeMembershipStates?.get(info.childRoomId) as? ChangeMembershipState.FailedJoining)?.throwable
// if it's known use that matrixItem because it would have a better computed name
val matrixItem = data?.knownRoomSummaries?.find { it.roomId == info.childRoomId }?.toMatrixItem()
?: info.toMatrixItem()
@ -135,11 +137,19 @@ class SpaceDirectoryController @Inject constructor(
matrixItem(matrixItem)
avatarRenderer(host.avatarRenderer)
topic(info.topic)
errorLabel(
error?.let {
host.stringProvider.getString(R.string.error_failed_to_join_room, host.errorFormatter.toHumanReadable(it))
}
)
memberCount(info.activeMemberCount ?: 0)
loading(isLoading)
buttonLabel(
if (isJoined) host.stringProvider.getString(R.string.action_open)
else host.stringProvider.getString(R.string.join)
when {
error != null -> host.stringProvider.getString(R.string.global_retry)
isJoined -> host.stringProvider.getString(R.string.action_open)
else -> host.stringProvider.getString(R.string.join)
}
)
apply {
if (isSpace) {

View file

@ -188,20 +188,21 @@ class SpaceDirectoryViewModel @AssistedInject constructor(
private fun handleJoinOrOpen(spaceChildInfo: SpaceChildInfo) = withState { state ->
val isSpace = spaceChildInfo.roomType == RoomType.SPACE
if (state.joinedRoomsIds.contains(spaceChildInfo.childRoomId)) {
val childId = spaceChildInfo.childRoomId
if (state.joinedRoomsIds.contains(childId)) {
if (isSpace) {
handle(SpaceDirectoryViewAction.ExploreSubSpace(spaceChildInfo))
} else {
_viewEvents.post(SpaceDirectoryViewEvents.NavigateToRoom(spaceChildInfo.childRoomId))
_viewEvents.post(SpaceDirectoryViewEvents.NavigateToRoom(childId))
}
} else {
// join
viewModelScope.launch {
try {
if (isSpace) {
session.spaceService().joinSpace(spaceChildInfo.childRoomId, null, spaceChildInfo.viaServers)
session.spaceService().joinSpace(childId, null, spaceChildInfo.viaServers)
} else {
session.joinRoom(spaceChildInfo.childRoomId, null, spaceChildInfo.viaServers)
session.joinRoom(childId, null, spaceChildInfo.viaServers)
}
} catch (failure: Throwable) {
Timber.e(failure, "## Space: Failed to join room or subspace")

View file

@ -80,7 +80,7 @@
android:layout_marginEnd="8dp"
android:maxWidth="@dimen/button_max_width"
android:text="@string/join"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@id/inlineErrorText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@ -102,6 +102,17 @@
app:barrierDirection="bottom"
app:constraint_referenced_ids="roomAvatarBottomSpace" />
<TextView
android:id="@+id/inlineErrorText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawablePadding="8dp"
android:padding="8dp"
android:textColor="@color/design_default_color_error"
app:drawableStartCompat="@drawable/ic_warning_badge"
app:layout_constraintTop_toBottomOf="@+id/roomBottomBarrier"
tools:text="An error occured while joining" />
<!-- We use vctr_list_separator_system here for a better rendering -->
<View
android:id="@+id/roomDividerView"
@ -111,6 +122,6 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/roomBottomBarrier" />
app:layout_constraintTop_toBottomOf="@+id/inlineErrorText" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -3403,4 +3403,5 @@
<string name="teammate_spaces_arent_quite_ready">"Teammate spaces arent quite ready but you can still give them a try"</string>
<string name="teammate_spaces_might_not_join">"At the moment people might not be able to join any private rooms you make.\n\nWell be improving this as part of the beta, but just wanted to let you know."</string>
<string name="error_failed_to_join_room">Sorry, an error occurred while trying to join: %s</string>
</resources>