mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 02:15:35 +03:00
Add error feedback when joining space rooms
This commit is contained in:
parent
71b456c57e
commit
e277deece5
7 changed files with 51 additions and 10 deletions
1
newsfragment/3207.bugfix
Normal file
1
newsfragment/3207.bugfix
Normal file
|
@ -0,0 +1 @@
|
|||
Space Explore Rooms no feedback on failed to join
|
|
@ -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) }
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -3403,4 +3403,5 @@
|
|||
|
||||
<string name="teammate_spaces_arent_quite_ready">"Teammate spaces aren’t 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\nWe’ll 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>
|
||||
|
|
Loading…
Reference in a new issue