Retry join room

This commit is contained in:
Benoit Marty 2019-05-24 17:38:46 +02:00
parent bbf2f96288
commit cd5e808bb6
9 changed files with 77 additions and 16 deletions

View File

@ -93,6 +93,7 @@ abstract class VectorBaseActivity : BaseMvRxActivity() {
}
protected fun Disposable.disposeOnDestroy(): Disposable {
// TODO Ganfra: never disposed...
uiDisposables.add(this)
return this
}

View File

@ -27,6 +27,9 @@ import butterknife.Unbinder
import com.airbnb.mvrx.BaseMvRxFragment
import com.airbnb.mvrx.MvRx
import com.bumptech.glide.util.Util.assertMainThread
import com.google.android.material.snackbar.Snackbar
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import timber.log.Timber
abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed {
@ -78,6 +81,12 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed {
mUnBinder = null
}
override fun onDestroy() {
super.onDestroy()
uiDisposables.dispose()
}
/* ==========================================================================================
* Restorable
* ========================================================================================== */
@ -114,6 +123,16 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed {
return this
}
/* ==========================================================================================
* Disposable
* ========================================================================================== */
private val uiDisposables = CompositeDisposable()
protected fun Disposable.disposeOnDestroy(): Disposable {
uiDisposables.add(this)
return this
}
/* ==========================================================================================
* MENU MANAGEMENT

View File

@ -35,6 +35,7 @@ abstract class PublicRoomItem : VectorEpoxyModel<PublicRoomItem.Holder>() {
enum class JoinState {
NOT_JOINED,
JOINING,
JOINING_ERROR,
JOINED
}
@ -74,9 +75,11 @@ abstract class PublicRoomItem : VectorEpoxyModel<PublicRoomItem.Holder>() {
holder.joinButton.isInvisible = true
}
holder.joiningView.isVisible = joinState == JoinState.JOINING
holder.retryButton.isVisible = joinState == JoinState.JOINING_ERROR
holder.joinedView.isVisible = joinState == JoinState.JOINED
holder.joinButton.setOnClickListener { joinListener?.invoke() }
holder.retryButton.setOnClickListener { joinListener?.invoke() }
}
@ -90,6 +93,7 @@ abstract class PublicRoomItem : VectorEpoxyModel<PublicRoomItem.Holder>() {
val joinedView by bind<View>(R.id.itemPublicRoomJoined)
val joinButton by bind<View>(R.id.itemPublicRoomJoin)
val joiningView by bind<View>(R.id.itemPublicRoomJoining)
val retryButton by bind<View>(R.id.itemPublicRoomRetry)
}
}

View File

@ -82,9 +82,10 @@ class PublicRoomsController(private val stringProvider: StringProvider) : TypedE
roomName(publicRoom.name)
nbOfMembers(publicRoom.numJoinedMembers)
when {
viewState.joinedRoomsIds.contains(publicRoom.roomId) -> joinState(PublicRoomItem.JoinState.JOINED)
viewState.joiningRoomsIds.contains(publicRoom.roomId) -> joinState(PublicRoomItem.JoinState.JOINING)
else -> joinState(PublicRoomItem.JoinState.NOT_JOINED)
viewState.joinedRoomsIds.contains(publicRoom.roomId) -> joinState(PublicRoomItem.JoinState.JOINED)
viewState.joiningRoomsIds.contains(publicRoom.roomId) -> joinState(PublicRoomItem.JoinState.JOINING)
viewState.joiningErrorRoomsIds.contains(publicRoom.roomId) -> joinState(PublicRoomItem.JoinState.JOINING_ERROR)
else -> joinState(PublicRoomItem.JoinState.NOT_JOINED)
}
joinListener {
callback?.onPublicRoomJoin(publicRoom)

View File

@ -17,29 +17,30 @@
package im.vector.riotredesign.features.roomdirectory
import android.os.Bundle
import android.text.Editable
import android.view.View
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import com.airbnb.epoxy.EpoxyVisibilityTracker
import com.airbnb.mvrx.activityViewModel
import com.airbnb.mvrx.withState
import com.google.android.material.snackbar.Snackbar
import com.jakewharton.rxbinding2.widget.RxTextView
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom
import im.vector.riotredesign.R
import im.vector.riotredesign.core.extensions.addFragmentToBackstack
import im.vector.riotredesign.core.platform.SimpleTextWatcher
import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.features.roomdirectory.picker.RoomDirectoryPickerFragment
import io.reactivex.rxkotlin.subscribeBy
import kotlinx.android.synthetic.main.fragment_public_rooms.*
import org.koin.android.ext.android.get
import timber.log.Timber
import java.util.concurrent.TimeUnit
/**
* What can be improved:
* - When filtering more (when entering new chars), we could filter on result we already have, during the new server request, to avoid empty screen effect
*
* FIXME Rotate screen launch again the request
*
* TODO For Nad:
* Display number of rooms?
* Picto size are not correct
@ -66,12 +67,12 @@ class PublicRoomsFragment : VectorBaseFragment(), PublicRoomsController.Callback
it.setDisplayHomeAsUpEnabled(true)
}
publicRoomsFilter.addTextChangedListener(object : SimpleTextWatcher() {
override fun afterTextChanged(s: Editable) {
// TODO Debounce
viewModel.filterWith(publicRoomsFilter.text.toString())
}
})
RxTextView.textChanges(publicRoomsFilter)
.debounce(500, TimeUnit.MILLISECONDS)
.subscribeBy {
viewModel.filterWith(it.toString())
}
.disposeOnDestroy()
publicRoomsCreateNewRoom.setOnClickListener {
vectorBaseActivity.notImplemented()
@ -80,6 +81,13 @@ class PublicRoomsFragment : VectorBaseFragment(), PublicRoomsController.Callback
publicRoomsChangeDirectory.setOnClickListener {
vectorBaseActivity.addFragmentToBackstack(RoomDirectoryPickerFragment(), R.id.simpleFragmentContainer)
}
viewModel.joinRoomErrorLiveData.observe(this, Observer {
it.getContentIfNotHandled()?.let { throwable ->
Snackbar.make(publicRoomsCoordinator, throwable.localizedMessage, Snackbar.LENGTH_SHORT)
.show()
}
})
}
override fun onActivityCreated(savedInstanceState: Bundle?) {

View File

@ -16,6 +16,8 @@
package im.vector.riotredesign.features.roomdirectory
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.airbnb.mvrx.*
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.Session
@ -28,6 +30,7 @@ import im.vector.matrix.android.api.session.room.model.thirdparty.RoomDirectoryD
import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.rx.rx
import im.vector.riotredesign.core.platform.VectorViewModel
import im.vector.riotredesign.core.utils.LiveEvent
import org.koin.android.ext.android.get
import timber.log.Timber
@ -46,6 +49,11 @@ class RoomDirectoryViewModel(initialState: PublicRoomsViewState,
}
}
private val _joinRoomErrorLiveData = MutableLiveData<LiveEvent<Throwable>>()
val joinRoomErrorLiveData: LiveData<LiveEvent<Throwable>>
get() = _joinRoomErrorLiveData
// TODO Store in ViewState?
private var currentFilter: String = ""
@ -85,7 +93,9 @@ class RoomDirectoryViewModel(initialState: PublicRoomsViewState,
copy(
joinedRoomsIds = joinedRoomIds,
// Remove (newly) joined room id from the joining room list
joiningRoomsIds = joiningRoomsIds.toMutableList().apply { removeAll(joinedRoomIds) }
joiningRoomsIds = joiningRoomsIds.toMutableList().apply { removeAll(joinedRoomIds) },
// Remove (newly) joined room id from the joining room list in error
joiningErrorRoomsIds = joiningErrorRoomsIds.toMutableList().apply { removeAll(joinedRoomIds) }
)
}
}
@ -197,10 +207,13 @@ class RoomDirectoryViewModel(initialState: PublicRoomsViewState,
}
override fun onFailure(failure: Throwable) {
// TODO Notify the user
// Notify the user
_joinRoomErrorLiveData.postValue(LiveEvent(failure))
setState {
copy(
joiningRoomsIds = joiningRoomsIds.toMutableList().apply { remove(publicRoom.roomId) }
joiningRoomsIds = joiningRoomsIds.toMutableList().apply { remove(publicRoom.roomId) },
joiningErrorRoomsIds = joiningErrorRoomsIds.toMutableList().apply { add(publicRoom.roomId) }
)
}
}

View File

@ -30,6 +30,8 @@ data class PublicRoomsViewState(
val hasMore: Boolean = false,
// List of roomIds that the user wants to join
val joiningRoomsIds: List<String> = emptyList(),
// List of roomIds that the user wants to join, but an error occurred
val joiningErrorRoomsIds: List<String> = emptyList(),
// List of joined roomId,
val joinedRoomsIds: List<String> = emptyList(),
val roomDirectoryDisplayName: String? = null

View File

@ -3,6 +3,7 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/publicRoomsCoordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/pale_grey">

View File

@ -93,6 +93,18 @@
app:layout_constraintStart_toStartOf="@+id/itemPublicRoomJoin"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/itemPublicRoomRetry"
style="@style/VectorButtonStyleFlat"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="@string/global_retry"
android:textColor="@color/vector_warning_color"
app:layout_constraintBottom_toTopOf="@+id/itemPublicRoomBottomSeparator"
app:layout_constraintEnd_toEndOf="@+id/itemPublicRoomJoin"
app:layout_constraintStart_toStartOf="@+id/itemPublicRoomJoin"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/itemPublicRoomBottomSeparator"
android:layout_width="0dp"