Convert to ViewEvents -> DevicesViewModel

This commit is contained in:
Benoit Marty 2020-02-07 17:10:57 +01:00
parent c34307ecf7
commit 7f5cc77ee0
5 changed files with 39 additions and 62 deletions

View file

@ -56,7 +56,7 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
val verificationId: String? = null, val verificationId: String? = null,
val roomId: String? = null, val roomId: String? = null,
// Special mode where UX should show loading wheel until other user sends a request/tx // Special mode where UX should show loading wheel until other user sends a request/tx
val waitForIncomingRequest : Boolean = false val waitForIncomingRequest: Boolean = false
) : Parcelable ) : Parcelable
@Inject @Inject
@ -250,7 +250,7 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
} }
} }
val WAITING_SELF_VERIF_TAG : String = "WAITING_SELF_VERIF_TAG" const val WAITING_SELF_VERIF_TAG: String = "WAITING_SELF_VERIF_TAG"
} }
} }

View file

@ -16,14 +16,14 @@
package im.vector.riotx.features.settings.devices package im.vector.riotx.features.settings.devices
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
import im.vector.riotx.core.platform.VectorViewModelAction import im.vector.riotx.core.platform.VectorViewModelAction
sealed class DevicesAction : VectorViewModelAction { sealed class DevicesAction : VectorViewModelAction {
object Retry : DevicesAction() object Retry : DevicesAction()
data class Delete(val deviceId: String) : DevicesAction() data class Delete(val deviceId: String) : DevicesAction()
data class Password(val password: String) : DevicesAction() data class Password(val password: String) : DevicesAction()
data class Rename(val deviceInfo: DeviceInfo, val newName: String) : DevicesAction() data class Rename(val deviceId: String, val newName: String) : DevicesAction()
data class PromptRename(val deviceId: String, val deviceInfo: DeviceInfo? = null) : DevicesAction()
data class VerifyMyDevice(val deviceId: String, val userId: String? = null, val transactionId: String? = null) : DevicesAction() data class PromptRename(val deviceId: String) : DevicesAction()
data class VerifyMyDevice(val deviceId: String) : DevicesAction()
} }

View file

@ -17,6 +17,7 @@
package im.vector.riotx.features.settings.devices package im.vector.riotx.features.settings.devices
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
import im.vector.riotx.core.platform.VectorViewEvents import im.vector.riotx.core.platform.VectorViewEvents
/** /**
@ -25,4 +26,14 @@ import im.vector.riotx.core.platform.VectorViewEvents
sealed class DevicesViewEvents : VectorViewEvents { sealed class DevicesViewEvents : VectorViewEvents {
data class Loading(val message: CharSequence? = null) : DevicesViewEvents() data class Loading(val message: CharSequence? = null) : DevicesViewEvents()
data class Failure(val throwable: Throwable) : DevicesViewEvents() data class Failure(val throwable: Throwable) : DevicesViewEvents()
object RequestPassword : DevicesViewEvents()
data class PromptRenameDevice(val deviceInfo: DeviceInfo) : DevicesViewEvents()
data class ShowVerifyDevice(
val userId: String,
val deviceId: String,
val transactionId: String?
) : DevicesViewEvents()
} }

View file

@ -16,8 +16,6 @@
package im.vector.riotx.features.settings.devices package im.vector.riotx.features.settings.devices
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.airbnb.mvrx.Async import com.airbnb.mvrx.Async
import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.FragmentViewModelContext
@ -41,9 +39,7 @@ import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse
import im.vector.matrix.rx.rx import im.vector.matrix.rx.rx
import im.vector.riotx.core.extensions.postLiveEvent
import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.platform.VectorViewModel
import im.vector.riotx.core.utils.LiveEvent
import im.vector.riotx.features.crypto.verification.supportedVerificationMethods import im.vector.riotx.features.crypto.verification.supportedVerificationMethods
data class DevicesViewState( data class DevicesViewState(
@ -76,15 +72,6 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic
private var _currentDeviceId: String? = null private var _currentDeviceId: String? = null
private var _currentSession: String? = null private var _currentSession: String? = null
private val _requestPasswordLiveData = MutableLiveData<LiveEvent<Unit>>()
val requestPasswordLiveData: LiveData<LiveEvent<Unit>>
get() = _requestPasswordLiveData
// Used to communicate back from model to fragment
private val _requestLiveData = MutableLiveData<LiveEvent<Async<DevicesAction>>>()
val fragmentActionLiveData: LiveData<LiveEvent<Async<DevicesAction>>>
get() = _requestLiveData
init { init {
refreshDevicesList() refreshDevicesList()
session.getVerificationService().addListener(this) session.getVerificationService().addListener(this)
@ -187,25 +174,22 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic
private fun handleVerify(action: DevicesAction.VerifyMyDevice) { private fun handleVerify(action: DevicesAction.VerifyMyDevice) {
val txID = session.getVerificationService().requestKeyVerification(supportedVerificationMethods, session.myUserId, listOf(action.deviceId)) val txID = session.getVerificationService().requestKeyVerification(supportedVerificationMethods, session.myUserId, listOf(action.deviceId))
_requestLiveData.postValue(LiveEvent(Success( _viewEvents.post(DevicesViewEvents.ShowVerifyDevice(
action.copy( session.myUserId,
userId = session.myUserId, action.deviceId,
transactionId = txID.transactionId txID.transactionId
) ))
)))
} }
private fun handlePromptRename(action: DevicesAction.PromptRename) = withState { state -> private fun handlePromptRename(action: DevicesAction.PromptRename) = withState { state ->
val info = state.devices.invoke()?.firstOrNull { it.deviceId == action.deviceId } val info = state.devices.invoke()?.firstOrNull { it.deviceId == action.deviceId }
if (info == null) { if (info != null) {
_requestLiveData.postValue(LiveEvent(Uninitialized)) _viewEvents.post(DevicesViewEvents.PromptRenameDevice(info))
} else {
_requestLiveData.postValue(LiveEvent(Success(action.copy(deviceInfo = info))))
} }
} }
private fun handleRename(action: DevicesAction.Rename) { private fun handleRename(action: DevicesAction.Rename) {
session.setDeviceName(action.deviceInfo.deviceId!!, action.newName, object : MatrixCallback<Unit> { session.setDeviceName(action.deviceId, action.newName, object : MatrixCallback<Unit> {
override fun onSuccess(data: Unit) { override fun onSuccess(data: Unit) {
setState { setState {
copy( copy(
@ -261,7 +245,7 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic
) )
} }
_requestPasswordLiveData.postLiveEvent(Unit) _viewEvents.post(DevicesViewEvents.RequestPassword)
} }
} }

View file

@ -23,7 +23,6 @@ import androidx.appcompat.app.AlertDialog
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.airbnb.mvrx.Async import com.airbnb.mvrx.Async
import com.airbnb.mvrx.Loading import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState import com.airbnb.mvrx.withState
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
@ -32,7 +31,6 @@ import im.vector.riotx.core.dialogs.PromptPasswordDialog
import im.vector.riotx.core.extensions.cleanup import im.vector.riotx.core.extensions.cleanup
import im.vector.riotx.core.extensions.configureWith import im.vector.riotx.core.extensions.configureWith
import im.vector.riotx.core.extensions.exhaustive import im.vector.riotx.core.extensions.exhaustive
import im.vector.riotx.core.extensions.observeEvent
import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.core.platform.VectorBaseActivity
import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.platform.VectorBaseFragment
import im.vector.riotx.features.crypto.verification.VerificationBottomSheet import im.vector.riotx.features.crypto.verification.VerificationBottomSheet
@ -64,35 +62,19 @@ class VectorSettingsDevicesFragment @Inject constructor(
recyclerView.configureWith(devicesController, showDivider = true) recyclerView.configureWith(devicesController, showDivider = true)
viewModel.observeViewEvents { viewModel.observeViewEvents {
when (it) { when (it) {
is DevicesViewEvents.Loading -> showLoading(it.message) is DevicesViewEvents.Loading -> showLoading(it.message)
is DevicesViewEvents.Failure -> showFailure(it.throwable) is DevicesViewEvents.Failure -> showFailure(it.throwable)
}.exhaustive is DevicesViewEvents.RequestPassword -> maybeShowDeleteDeviceWithPasswordDialog()
} is DevicesViewEvents.PromptRenameDevice -> displayDeviceRenameDialog(it.deviceInfo)
viewModel.requestPasswordLiveData.observeEvent(this) { is DevicesViewEvents.ShowVerifyDevice -> {
maybeShowDeleteDeviceWithPasswordDialog() // TODO Valere: We should pass the deviceId here
} VerificationBottomSheet.withArgs(
roomId = null,
viewModel.fragmentActionLiveData.observeEvent(this) { async -> otherUserId = it.userId,
when (async) { transactionId = it.transactionId
is Success -> { ).show(childFragmentManager, "REQPOP")
when (val action = async.invoke()) {
is DevicesAction.PromptRename -> {
action.deviceInfo?.let { deviceInfo ->
displayDeviceRenameDialog(deviceInfo)
}
}
is DevicesAction.VerifyMyDevice -> {
if (context is VectorBaseActivity) {
VerificationBottomSheet.withArgs(
roomId = null,
otherUserId = action.userId!!,
transactionId = action.transactionId!!
).show(childFragmentManager, "REQPOP")
}
}
}
} }
} }.exhaustive
} }
} }
@ -152,7 +134,7 @@ class VectorSettingsDevicesFragment @Inject constructor(
.setPositiveButton(R.string.ok) { _, _ -> .setPositiveButton(R.string.ok) { _, _ ->
val newName = input.text.toString() val newName = input.text.toString()
viewModel.handle(DevicesAction.Rename(deviceInfo, newName)) viewModel.handle(DevicesAction.Rename(deviceInfo.deviceId!!, newName))
} }
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
.show() .show()