Move call transfer actions back to callViewModel via result from callTransferActivity
This commit is contained in:
parent
11986ec9ef
commit
cb37bc56a6
|
@ -54,6 +54,9 @@ import im.vector.app.core.utils.registerForPermissionsResult
|
||||||
import im.vector.app.databinding.ActivityCallBinding
|
import im.vector.app.databinding.ActivityCallBinding
|
||||||
import im.vector.app.features.call.dialpad.CallDialPadBottomSheet
|
import im.vector.app.features.call.dialpad.CallDialPadBottomSheet
|
||||||
import im.vector.app.features.call.dialpad.DialPadFragment
|
import im.vector.app.features.call.dialpad.DialPadFragment
|
||||||
|
import im.vector.app.features.call.transfer.CallTransferActivity
|
||||||
|
import im.vector.app.features.call.transfer.CallTransferResult
|
||||||
|
import im.vector.app.features.call.transfer.CallTransferViewEvents
|
||||||
import im.vector.app.features.call.utils.EglUtils
|
import im.vector.app.features.call.utils.EglUtils
|
||||||
import im.vector.app.features.call.webrtc.WebRtcCall
|
import im.vector.app.features.call.webrtc.WebRtcCall
|
||||||
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
||||||
|
@ -523,14 +526,23 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
|
||||||
val callId = withState(callViewModel) { it.callId }
|
val callId = withState(callViewModel) { it.callId }
|
||||||
navigator.openCallTransfer(this, callTransferActivityResultLauncher, callId)
|
navigator.openCallTransfer(this, callTransferActivityResultLauncher, callId)
|
||||||
}
|
}
|
||||||
|
is VectorCallViewEvents.FailToTransfer -> showSnackbar(getString(R.string.call_transfer_failure))
|
||||||
null -> {
|
null -> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val callTransferActivityResultLauncher = registerStartForActivityResult { activityResult ->
|
private val callTransferActivityResultLauncher = registerStartForActivityResult { activityResult ->
|
||||||
if (activityResult.resultCode == Activity.RESULT_CANCELED) {
|
|
||||||
callViewModel.handle(VectorCallViewActions.CallTransferSelectionCancelled)
|
when(activityResult.resultCode) {
|
||||||
|
Activity.RESULT_CANCELED -> {
|
||||||
|
callViewModel.handle(VectorCallViewActions.CallTransferSelectionCancelled)
|
||||||
|
}
|
||||||
|
Activity.RESULT_OK -> {
|
||||||
|
activityResult.data?.extras?.getParcelable<CallTransferResult>(CallTransferActivity.EXTRA_TRANSFER_RESULT)?.also {
|
||||||
|
callViewModel.handle(VectorCallViewActions.CallTransferSelectionResult(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ package im.vector.app.features.call
|
||||||
|
|
||||||
import im.vector.app.core.platform.VectorViewModelAction
|
import im.vector.app.core.platform.VectorViewModelAction
|
||||||
import im.vector.app.features.call.audio.CallAudioManager
|
import im.vector.app.features.call.audio.CallAudioManager
|
||||||
|
import im.vector.app.features.call.transfer.CallTransferResult
|
||||||
|
|
||||||
sealed class VectorCallViewActions : VectorViewModelAction {
|
sealed class VectorCallViewActions : VectorViewModelAction {
|
||||||
object EndCall : VectorCallViewActions()
|
object EndCall : VectorCallViewActions()
|
||||||
|
@ -37,5 +38,6 @@ sealed class VectorCallViewActions : VectorViewModelAction {
|
||||||
object ToggleHDSD : VectorCallViewActions()
|
object ToggleHDSD : VectorCallViewActions()
|
||||||
object InitiateCallTransfer : VectorCallViewActions()
|
object InitiateCallTransfer : VectorCallViewActions()
|
||||||
object CallTransferSelectionCancelled : VectorCallViewActions()
|
object CallTransferSelectionCancelled : VectorCallViewActions()
|
||||||
|
data class CallTransferSelectionResult(val callTransferResult: CallTransferResult) : VectorCallViewActions()
|
||||||
object TransferCall : VectorCallViewActions()
|
object TransferCall : VectorCallViewActions()
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ sealed class VectorCallViewEvents : VectorViewEvents {
|
||||||
) : VectorCallViewEvents()
|
) : VectorCallViewEvents()
|
||||||
object ShowDialPad : VectorCallViewEvents()
|
object ShowDialPad : VectorCallViewEvents()
|
||||||
object ShowCallTransferScreen : VectorCallViewEvents()
|
object ShowCallTransferScreen : VectorCallViewEvents()
|
||||||
|
object FailToTransfer : VectorCallViewEvents()
|
||||||
// data class CallAnswered(val content: CallAnswerContent) : VectorCallViewEvents()
|
// data class CallAnswered(val content: CallAnswerContent) : VectorCallViewEvents()
|
||||||
// data class CallHangup(val content: CallHangupContent) : VectorCallViewEvents()
|
// data class CallHangup(val content: CallHangupContent) : VectorCallViewEvents()
|
||||||
// object CallAccepted : VectorCallViewEvents()
|
// object CallAccepted : VectorCallViewEvents()
|
||||||
|
|
|
@ -29,13 +29,17 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.extensions.exhaustive
|
import im.vector.app.core.extensions.exhaustive
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.features.call.audio.CallAudioManager
|
import im.vector.app.features.call.audio.CallAudioManager
|
||||||
|
import im.vector.app.features.call.dialpad.DialPadLookup
|
||||||
|
import im.vector.app.features.call.transfer.CallTransferResult
|
||||||
import im.vector.app.features.call.webrtc.WebRtcCall
|
import im.vector.app.features.call.webrtc.WebRtcCall
|
||||||
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
||||||
import im.vector.app.features.call.webrtc.getOpponentAsMatrixItem
|
import im.vector.app.features.call.webrtc.getOpponentAsMatrixItem
|
||||||
|
import im.vector.app.features.createdirect.DirectRoomHelper
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.MatrixPatterns
|
import org.matrix.android.sdk.api.MatrixPatterns
|
||||||
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.call.CallState
|
import org.matrix.android.sdk.api.session.call.CallState
|
||||||
import org.matrix.android.sdk.api.session.call.MxCall
|
import org.matrix.android.sdk.api.session.call.MxCall
|
||||||
|
@ -47,7 +51,9 @@ class VectorCallViewModel @AssistedInject constructor(
|
||||||
@Assisted initialState: VectorCallViewState,
|
@Assisted initialState: VectorCallViewState,
|
||||||
val session: Session,
|
val session: Session,
|
||||||
val callManager: WebRtcCallManager,
|
val callManager: WebRtcCallManager,
|
||||||
val proximityManager: CallProximityManager
|
val proximityManager: CallProximityManager,
|
||||||
|
private val dialPadLookup: DialPadLookup,
|
||||||
|
private val directRoomHelper: DirectRoomHelper,
|
||||||
) : VectorViewModel<VectorCallViewState, VectorCallViewActions, VectorCallViewEvents>(initialState) {
|
) : VectorViewModel<VectorCallViewState, VectorCallViewActions, VectorCallViewEvents>(initialState) {
|
||||||
|
|
||||||
private var call: WebRtcCall? = null
|
private var call: WebRtcCall? = null
|
||||||
|
@ -327,6 +333,9 @@ class VectorCallViewModel @AssistedInject constructor(
|
||||||
VectorCallViewActions.CallTransferSelectionCancelled -> {
|
VectorCallViewActions.CallTransferSelectionCancelled -> {
|
||||||
call?.updateRemoteOnHold(false)
|
call?.updateRemoteOnHold(false)
|
||||||
}
|
}
|
||||||
|
is VectorCallViewActions.CallTransferSelectionResult -> {
|
||||||
|
handleCallTransferSelectionResult(action.callTransferResult)
|
||||||
|
}
|
||||||
VectorCallViewActions.TransferCall -> {
|
VectorCallViewActions.TransferCall -> {
|
||||||
handleCallTransfer()
|
handleCallTransfer()
|
||||||
}
|
}
|
||||||
|
@ -345,6 +354,53 @@ class VectorCallViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleCallTransferSelectionResult(result: CallTransferResult) {
|
||||||
|
when (result) {
|
||||||
|
is CallTransferResult.ConnectWithUserId -> connectWithUserId(result)
|
||||||
|
is CallTransferResult.ConnectWithPhoneNumber -> connectWithPhoneNumber(result)
|
||||||
|
}.exhaustive
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun connectWithUserId(result: CallTransferResult.ConnectWithUserId) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
try {
|
||||||
|
if (result.consultFirst) {
|
||||||
|
val dmRoomId = directRoomHelper.ensureDMExists(result.selectedUserId)
|
||||||
|
callManager.startOutgoingCall(
|
||||||
|
nativeRoomId = dmRoomId,
|
||||||
|
otherUserId = result.selectedUserId,
|
||||||
|
isVideoCall = call?.mxCall?.isVideoCall.orFalse(),
|
||||||
|
transferee = call
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
call?.transferToUser(result.selectedUserId, null)
|
||||||
|
}
|
||||||
|
} catch (failure: Throwable) {
|
||||||
|
_viewEvents.post(VectorCallViewEvents.FailToTransfer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun connectWithPhoneNumber(action: CallTransferResult.ConnectWithPhoneNumber) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
try {
|
||||||
|
val result = dialPadLookup.lookupPhoneNumber(action.phoneNumber)
|
||||||
|
if (action.consultFirst) {
|
||||||
|
callManager.startOutgoingCall(
|
||||||
|
nativeRoomId = result.roomId,
|
||||||
|
otherUserId = result.userId,
|
||||||
|
isVideoCall = call?.mxCall?.isVideoCall.orFalse(),
|
||||||
|
transferee = call
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
call?.transferToUser(result.userId, result.roomId)
|
||||||
|
}
|
||||||
|
} catch (failure: Throwable) {
|
||||||
|
_viewEvents.post(VectorCallViewEvents.FailToTransfer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory : MavericksAssistedViewModelFactory<VectorCallViewModel, VectorCallViewState> {
|
interface Factory : MavericksAssistedViewModelFactory<VectorCallViewModel, VectorCallViewState> {
|
||||||
override fun create(initialState: VectorCallViewState): VectorCallViewModel
|
override fun create(initialState: VectorCallViewState): VectorCallViewModel
|
||||||
|
|
|
@ -57,8 +57,6 @@ class CallTransferActivity : VectorBaseActivity<ActivityCallTransferBinding>() {
|
||||||
callTransferViewModel.observeViewEvents {
|
callTransferViewModel.observeViewEvents {
|
||||||
when (it) {
|
when (it) {
|
||||||
is CallTransferViewEvents.Complete -> handleComplete()
|
is CallTransferViewEvents.Complete -> handleComplete()
|
||||||
CallTransferViewEvents.Loading -> showWaitingView()
|
|
||||||
is CallTransferViewEvents.FailToTransfer -> showSnackbar(getString(R.string.call_transfer_failure))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,25 +80,32 @@ class CallTransferActivity : VectorBaseActivity<ActivityCallTransferBinding>() {
|
||||||
when (views.callTransferTabLayout.selectedTabPosition) {
|
when (views.callTransferTabLayout.selectedTabPosition) {
|
||||||
CallTransferPagerAdapter.USER_LIST_INDEX -> {
|
CallTransferPagerAdapter.USER_LIST_INDEX -> {
|
||||||
val selectedUser = sectionsPagerAdapter.userListFragment?.getCurrentState()?.getSelectedMatrixId()?.firstOrNull() ?: return@debouncedClicks
|
val selectedUser = sectionsPagerAdapter.userListFragment?.getCurrentState()?.getSelectedMatrixId()?.firstOrNull() ?: return@debouncedClicks
|
||||||
val action = CallTransferAction.ConnectWithUserId(views.callTransferConsultCheckBox.isChecked, selectedUser)
|
val result = CallTransferResult.ConnectWithUserId(views.callTransferConsultCheckBox.isChecked, selectedUser)
|
||||||
callTransferViewModel.handle(action)
|
handleComplete(result)
|
||||||
}
|
}
|
||||||
CallTransferPagerAdapter.DIAL_PAD_INDEX -> {
|
CallTransferPagerAdapter.DIAL_PAD_INDEX -> {
|
||||||
val phoneNumber = sectionsPagerAdapter.dialPadFragment?.getRawInput() ?: return@debouncedClicks
|
val phoneNumber = sectionsPagerAdapter.dialPadFragment?.getRawInput() ?: return@debouncedClicks
|
||||||
val action = CallTransferAction.ConnectWithPhoneNumber(views.callTransferConsultCheckBox.isChecked, phoneNumber)
|
val result = CallTransferResult.ConnectWithPhoneNumber(views.callTransferConsultCheckBox.isChecked, phoneNumber)
|
||||||
callTransferViewModel.handle(action)
|
handleComplete(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleComplete() {
|
private fun handleComplete(callTransferResult: CallTransferResult? = null) {
|
||||||
setResult(Activity.RESULT_OK)
|
if (callTransferResult != null) {
|
||||||
|
val intent = Intent().apply {
|
||||||
|
putExtra(EXTRA_TRANSFER_RESULT, callTransferResult)
|
||||||
|
}
|
||||||
|
setResult(RESULT_OK, intent)
|
||||||
|
} else {
|
||||||
|
setResult(RESULT_OK)
|
||||||
|
}
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
const val EXTRA_TRANSFER_RESULT = "EXTRA_TRANSFER_RESULT"
|
||||||
fun newIntent(context: Context, callId: String): Intent {
|
fun newIntent(context: Context, callId: String): Intent {
|
||||||
return Intent(context, CallTransferActivity::class.java).also {
|
return Intent(context, CallTransferActivity::class.java).also {
|
||||||
it.putExtra(Mavericks.KEY_ARG, CallTransferArgs(callId))
|
it.putExtra(Mavericks.KEY_ARG, CallTransferArgs(callId))
|
||||||
|
|
|
@ -16,9 +16,11 @@
|
||||||
|
|
||||||
package im.vector.app.features.call.transfer
|
package im.vector.app.features.call.transfer
|
||||||
|
|
||||||
import im.vector.app.core.platform.VectorViewModelAction
|
import android.os.Parcelable
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
sealed class CallTransferAction : VectorViewModelAction {
|
|
||||||
data class ConnectWithUserId(val consultFirst: Boolean, val selectedUserId: String) : CallTransferAction()
|
sealed class CallTransferResult : Parcelable{
|
||||||
data class ConnectWithPhoneNumber(val consultFirst: Boolean, val phoneNumber: String) : CallTransferAction()
|
@Parcelize data class ConnectWithUserId(val consultFirst: Boolean, val selectedUserId: String) : CallTransferResult()
|
||||||
|
@Parcelize data class ConnectWithPhoneNumber(val consultFirst: Boolean, val phoneNumber: String) : CallTransferResult()
|
||||||
}
|
}
|
|
@ -20,6 +20,4 @@ import im.vector.app.core.platform.VectorViewEvents
|
||||||
|
|
||||||
sealed class CallTransferViewEvents : VectorViewEvents {
|
sealed class CallTransferViewEvents : VectorViewEvents {
|
||||||
object Complete : CallTransferViewEvents()
|
object Complete : CallTransferViewEvents()
|
||||||
object Loading : CallTransferViewEvents()
|
|
||||||
object FailToTransfer : CallTransferViewEvents()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import dagger.assisted.AssistedInject
|
||||||
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.extensions.exhaustive
|
import im.vector.app.core.extensions.exhaustive
|
||||||
|
import im.vector.app.core.platform.EmptyAction
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.features.call.dialpad.DialPadLookup
|
import im.vector.app.features.call.dialpad.DialPadLookup
|
||||||
import im.vector.app.features.call.webrtc.WebRtcCall
|
import im.vector.app.features.call.webrtc.WebRtcCall
|
||||||
|
@ -34,10 +35,8 @@ import org.matrix.android.sdk.api.session.call.CallState
|
||||||
import org.matrix.android.sdk.api.session.call.MxCall
|
import org.matrix.android.sdk.api.session.call.MxCall
|
||||||
|
|
||||||
class CallTransferViewModel @AssistedInject constructor(@Assisted initialState: CallTransferViewState,
|
class CallTransferViewModel @AssistedInject constructor(@Assisted initialState: CallTransferViewState,
|
||||||
private val dialPadLookup: DialPadLookup,
|
|
||||||
private val directRoomHelper: DirectRoomHelper,
|
|
||||||
private val callManager: WebRtcCallManager) :
|
private val callManager: WebRtcCallManager) :
|
||||||
VectorViewModel<CallTransferViewState, CallTransferAction, CallTransferViewEvents>(initialState) {
|
VectorViewModel<CallTransferViewState, EmptyAction, CallTransferViewEvents>(initialState) {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory : MavericksAssistedViewModelFactory<CallTransferViewModel, CallTransferViewState> {
|
interface Factory : MavericksAssistedViewModelFactory<CallTransferViewModel, CallTransferViewState> {
|
||||||
|
@ -68,53 +67,6 @@ class CallTransferViewModel @AssistedInject constructor(@Assisted initialState:
|
||||||
call?.removeListener(callListener)
|
call?.removeListener(callListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handle(action: CallTransferAction) {
|
override fun handle(action: EmptyAction) { }
|
||||||
when (action) {
|
|
||||||
is CallTransferAction.ConnectWithUserId -> connectWithUserId(action)
|
|
||||||
is CallTransferAction.ConnectWithPhoneNumber -> connectWithPhoneNumber(action)
|
|
||||||
}.exhaustive
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun connectWithUserId(action: CallTransferAction.ConnectWithUserId) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
try {
|
|
||||||
if (action.consultFirst) {
|
|
||||||
val dmRoomId = directRoomHelper.ensureDMExists(action.selectedUserId)
|
|
||||||
callManager.startOutgoingCall(
|
|
||||||
nativeRoomId = dmRoomId,
|
|
||||||
otherUserId = action.selectedUserId,
|
|
||||||
isVideoCall = call?.mxCall?.isVideoCall.orFalse(),
|
|
||||||
transferee = call
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
call?.transferToUser(action.selectedUserId, null)
|
|
||||||
}
|
|
||||||
_viewEvents.post(CallTransferViewEvents.Complete)
|
|
||||||
} catch (failure: Throwable) {
|
|
||||||
_viewEvents.post(CallTransferViewEvents.FailToTransfer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun connectWithPhoneNumber(action: CallTransferAction.ConnectWithPhoneNumber) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
try {
|
|
||||||
_viewEvents.post(CallTransferViewEvents.Loading)
|
|
||||||
val result = dialPadLookup.lookupPhoneNumber(action.phoneNumber)
|
|
||||||
if (action.consultFirst) {
|
|
||||||
callManager.startOutgoingCall(
|
|
||||||
nativeRoomId = result.roomId,
|
|
||||||
otherUserId = result.userId,
|
|
||||||
isVideoCall = call?.mxCall?.isVideoCall.orFalse(),
|
|
||||||
transferee = call
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
call?.transferToUser(result.userId, result.roomId)
|
|
||||||
}
|
|
||||||
_viewEvents.post(CallTransferViewEvents.Complete)
|
|
||||||
} catch (failure: Throwable) {
|
|
||||||
_viewEvents.post(CallTransferViewEvents.FailToTransfer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue