Call transfer should put other side on hold while the transfer is being selected and unhold when the user cancels selection.

This commit is contained in:
David Langley 2022-01-27 15:16:46 +00:00
parent d127e0c39d
commit 79b11623b5
9 changed files with 43 additions and 10 deletions

1
changelog.d/5081.bugfix Normal file
View file

@ -0,0 +1 @@
Selecting Transfer in a call should immediately put the the other person on hold until the call connects or the Transfer is cancelled.

View file

@ -16,6 +16,7 @@
package im.vector.app.features.call package im.vector.app.features.call
import android.app.Activity
import android.app.KeyguardManager import android.app.KeyguardManager
import android.app.PictureInPictureParams import android.app.PictureInPictureParams
import android.content.Context import android.content.Context
@ -43,6 +44,7 @@ import com.google.android.material.card.MaterialCardView
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.utils.PERMISSIONS_FOR_AUDIO_IP_CALL import im.vector.app.core.utils.PERMISSIONS_FOR_AUDIO_IP_CALL
@ -57,8 +59,10 @@ 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.displayname.getBestName import im.vector.app.features.displayname.getBestName
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.RoomDetailAction
import im.vector.app.features.home.room.detail.RoomDetailActivity import im.vector.app.features.home.room.detail.RoomDetailActivity
import im.vector.app.features.home.room.detail.RoomDetailArgs import im.vector.app.features.home.room.detail.RoomDetailArgs
import im.vector.app.features.widgets.WidgetActivity
import io.github.hyuwah.draggableviewlib.DraggableView import io.github.hyuwah.draggableviewlib.DraggableView
import io.github.hyuwah.draggableviewlib.setupDraggable import io.github.hyuwah.draggableviewlib.setupDraggable
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ -67,7 +71,9 @@ import org.matrix.android.sdk.api.logger.LoggerTag
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.MxPeerConnectionState import org.matrix.android.sdk.api.session.call.MxPeerConnectionState
import org.matrix.android.sdk.api.session.call.TurnServerResponse import org.matrix.android.sdk.api.session.call.TurnServerResponse
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.call.EndCallReason import org.matrix.android.sdk.api.session.room.model.call.EndCallReason
import org.matrix.android.sdk.api.session.room.model.message.MessageStickerContent
import org.webrtc.EglBase import org.webrtc.EglBase
import org.webrtc.RendererCommon import org.webrtc.RendererCommon
import timber.log.Timber import timber.log.Timber
@ -518,13 +524,19 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
} }
is VectorCallViewEvents.ShowCallTransferScreen -> { is VectorCallViewEvents.ShowCallTransferScreen -> {
val callId = withState(callViewModel) { it.callId } val callId = withState(callViewModel) { it.callId }
navigator.openCallTransfer(this, callId) navigator.openCallTransfer(this, callTransferActivityResultLauncher, callId)
} }
null -> { null -> {
} }
} }
} }
private val callTransferActivityResultLauncher = registerStartForActivityResult { activityResult ->
if(activityResult.resultCode == Activity.RESULT_CANCELED) {
callViewModel.handle(VectorCallViewActions.CallTransferSelectionCancelled)
}
}
private fun onErrorTimoutConnect(turn: TurnServerResponse?) { private fun onErrorTimoutConnect(turn: TurnServerResponse?) {
Timber.tag(loggerTag.value).d("onErrorTimoutConnect $turn") Timber.tag(loggerTag.value).d("onErrorTimoutConnect $turn")
// TODO ask to use default stun, etc... // TODO ask to use default stun, etc...

View file

@ -36,5 +36,6 @@ sealed class VectorCallViewActions : VectorViewModelAction {
object ToggleCamera : VectorCallViewActions() object ToggleCamera : VectorCallViewActions()
object ToggleHDSD : VectorCallViewActions() object ToggleHDSD : VectorCallViewActions()
object InitiateCallTransfer : VectorCallViewActions() object InitiateCallTransfer : VectorCallViewActions()
object CallTransferSelectionCancelled : VectorCallViewActions()
object TransferCall : VectorCallViewActions() object TransferCall : VectorCallViewActions()
} }

View file

@ -319,10 +319,14 @@ class VectorCallViewModel @AssistedInject constructor(
call?.sendDtmfDigit(action.digit) call?.sendDtmfDigit(action.digit)
} }
VectorCallViewActions.InitiateCallTransfer -> { VectorCallViewActions.InitiateCallTransfer -> {
call?.updateRemoteOnHold(true)
_viewEvents.post( _viewEvents.post(
VectorCallViewEvents.ShowCallTransferScreen VectorCallViewEvents.ShowCallTransferScreen
) )
} }
VectorCallViewActions.CallTransferSelectionCancelled -> {
call?.updateRemoteOnHold(false)
}
VectorCallViewActions.TransferCall -> { VectorCallViewActions.TransferCall -> {
handleCallTransfer() handleCallTransfer()
} }

View file

@ -16,6 +16,7 @@
package im.vector.app.features.call.transfer package im.vector.app.features.call.transfer
import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
@ -55,7 +56,7 @@ class CallTransferActivity : VectorBaseActivity<ActivityCallTransferBinding>() {
callTransferViewModel.observeViewEvents { callTransferViewModel.observeViewEvents {
when (it) { when (it) {
is CallTransferViewEvents.Dismiss -> finish() is CallTransferViewEvents.Complete -> handleComplete()
CallTransferViewEvents.Loading -> showWaitingView() CallTransferViewEvents.Loading -> showWaitingView()
is CallTransferViewEvents.FailToTransfer -> showSnackbar(getString(R.string.call_transfer_failure)) is CallTransferViewEvents.FailToTransfer -> showSnackbar(getString(R.string.call_transfer_failure))
} }
@ -93,6 +94,11 @@ class CallTransferActivity : VectorBaseActivity<ActivityCallTransferBinding>() {
} }
} }
private fun handleComplete() {
setResult(Activity.RESULT_OK)
finish()
}
companion object { companion object {
fun newIntent(context: Context, callId: String): Intent { fun newIntent(context: Context, callId: String): Intent {

View file

@ -19,7 +19,7 @@ package im.vector.app.features.call.transfer
import im.vector.app.core.platform.VectorViewEvents import im.vector.app.core.platform.VectorViewEvents
sealed class CallTransferViewEvents : VectorViewEvents { sealed class CallTransferViewEvents : VectorViewEvents {
object Dismiss : CallTransferViewEvents() object Complete : CallTransferViewEvents()
object Loading : CallTransferViewEvents() object Loading : CallTransferViewEvents()
object FailToTransfer : CallTransferViewEvents() object FailToTransfer : CallTransferViewEvents()
} }

View file

@ -50,14 +50,14 @@ class CallTransferViewModel @AssistedInject constructor(@Assisted initialState:
private val callListener = object : WebRtcCall.Listener { private val callListener = object : WebRtcCall.Listener {
override fun onStateUpdate(call: MxCall) { override fun onStateUpdate(call: MxCall) {
if (call.state is CallState.Ended) { if (call.state is CallState.Ended) {
_viewEvents.post(CallTransferViewEvents.Dismiss) _viewEvents.post(CallTransferViewEvents.Complete)
} }
} }
} }
init { init {
if (call == null) { if (call == null) {
_viewEvents.post(CallTransferViewEvents.Dismiss) _viewEvents.post(CallTransferViewEvents.Complete)
} else { } else {
call.addListener(callListener) call.addListener(callListener)
} }
@ -89,7 +89,7 @@ class CallTransferViewModel @AssistedInject constructor(@Assisted initialState:
} else { } else {
call?.transferToUser(action.selectedUserId, null) call?.transferToUser(action.selectedUserId, null)
} }
_viewEvents.post(CallTransferViewEvents.Dismiss) _viewEvents.post(CallTransferViewEvents.Complete)
} catch (failure: Throwable) { } catch (failure: Throwable) {
_viewEvents.post(CallTransferViewEvents.FailToTransfer) _viewEvents.post(CallTransferViewEvents.FailToTransfer)
} }
@ -111,7 +111,7 @@ class CallTransferViewModel @AssistedInject constructor(@Assisted initialState:
} else { } else {
call?.transferToUser(result.userId, result.roomId) call?.transferToUser(result.userId, result.roomId)
} }
_viewEvents.post(CallTransferViewEvents.Dismiss) _viewEvents.post(CallTransferViewEvents.Complete)
} catch (failure: Throwable) { } catch (failure: Throwable) {
_viewEvents.post(CallTransferViewEvents.FailToTransfer) _viewEvents.post(CallTransferViewEvents.FailToTransfer)
} }

View file

@ -524,9 +524,13 @@ class DefaultNavigator @Inject constructor(
context.startActivity(RoomDevToolActivity.intent(context, roomId)) context.startActivity(RoomDevToolActivity.intent(context, roomId))
} }
override fun openCallTransfer(context: Context, callId: String) { override fun openCallTransfer(
context: Context,
activityResultLauncher: ActivityResultLauncher<Intent>,
callId: String
) {
val intent = CallTransferActivity.newIntent(context, callId) val intent = CallTransferActivity.newIntent(context, callId)
context.startActivity(intent) activityResultLauncher.launch(intent)
} }
override fun openCreatePoll(context: Context, roomId: String, editedEventId: String?, mode: PollMode) { override fun openCreatePoll(context: Context, roomId: String, editedEventId: String?, mode: PollMode) {

View file

@ -149,7 +149,12 @@ interface Navigator {
fun openDevTools(context: Context, roomId: String) fun openDevTools(context: Context, roomId: String)
fun openCallTransfer(context: Context, callId: String) fun openCallTransfer(
context: Context,
activityResultLauncher: ActivityResultLauncher<Intent>,
callId: String
)
fun openCreatePoll(context: Context, roomId: String, editedEventId: String?, mode: PollMode) fun openCreatePoll(context: Context, roomId: String, editedEventId: String?, mode: PollMode)