Change active call bar + some minor changes in call screen

This commit is contained in:
ganfra 2021-07-01 19:40:36 +02:00
parent 7c033b4090
commit f74a71001a
29 changed files with 395 additions and 463 deletions

View File

@ -44,6 +44,8 @@ allprojects {
includeGroupByRegex 'com\\.github\\.chrisbanes'
// PFLockScreen-Android
includeGroupByRegex 'com\\.github\\.vector-im'
// DraggableView
includeGroupByRegex 'com\\.github\\.hyuwah'
// Chat effects
includeGroupByRegex 'com\\.github\\.jetradarmobile'

View File

@ -28,6 +28,10 @@
<dimen name="pill_min_height">20dp</dimen>
<dimen name="pill_text_padding">4dp</dimen>
<dimen name="call_pip_height">128dp</dimen>
<dimen name="call_pip_width">88dp</dimen>
<dimen name="call_pip_radius">8dp</dimen>
<dimen name="item_form_min_height">76dp</dimen>

View File

@ -396,6 +396,7 @@ dependencies {
implementation "androidx.autofill:autofill:$autofill_version"
implementation 'jp.wasabeef:glide-transformations:4.3.0'
implementation 'com.github.vector-im:PFLockScreen-Android:1.0.0-beta12'
implementation 'com.github.hyuwah:DraggableView:1.0.0'
// Custom Tab
implementation 'androidx.browser:browser:1.3.0'

View File

@ -0,0 +1,156 @@
/*
* Copyright (c) 2021 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.core.ui.views
import android.content.Context
import android.util.AttributeSet
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import com.google.android.material.card.MaterialCardView
import im.vector.app.R
import im.vector.app.databinding.ViewCurrentCallsCardBinding
import im.vector.app.features.call.utils.EglUtils
import im.vector.app.features.call.webrtc.WebRtcCall
import im.vector.app.features.call.webrtc.getOpponentAsMatrixItem
import im.vector.app.features.home.AvatarRenderer
import io.github.hyuwah.draggableviewlib.DraggableView
import io.github.hyuwah.draggableviewlib.setupDraggable
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.call.CallState
import org.webrtc.RendererCommon
class CurrentCallsCardView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : MaterialCardView(context, attrs, defStyleAttr) {
interface Callback {
fun onTapToReturnToCall()
}
private val views: ViewCurrentCallsCardBinding
private var activeCallPipInitialized = false
private var currentCall: WebRtcCall? = null
private var draggableView: DraggableView<CurrentCallsCardView>? = null
lateinit var avatarRenderer: AvatarRenderer
lateinit var session: Session
var callback: Callback? = null
init {
inflate(context, R.layout.view_current_calls_card, this)
isVisible = false
views = ViewCurrentCallsCardBinding.bind(this)
draggableView = setupDraggable().build()
setOnClickListener { callback?.onTapToReturnToCall() }
}
fun render(currentCall: WebRtcCall?, calls: List<WebRtcCall>) {
views.activeCallPiP.let {
this.currentCall?.detachRenderers(listOf(it))
}
this.currentCall = currentCall
if (currentCall != null) {
isVisible = true
when (currentCall.mxCall.state) {
is CallState.LocalRinging, CallState.Idle -> {
isVisible = false
}
is CallState.Connected -> {
views.activeCallProgress.isVisible = false
val isVideoCall = currentCall.mxCall.isVideoCall
if (isVideoCall) {
renderVideoCall(currentCall)
} else {
renderVoiceCall(currentCall, calls)
}
}
else -> {
renderConnectingState(currentCall)
}
}
} else {
// NO ACTIVE CALL
isVisible = false
}
}
private fun renderConnectingState(currentCall: WebRtcCall) {
//TODO show dots
views.activeCallProgress.isVisible = true
views.activeCallPiP.isVisible = false
views.avatarViews.isVisible = false
currentCall.detachRenderers(listOf(views.activeCallPiP))
}
private fun renderVideoCall(currentCall: WebRtcCall) {
initIfNeeded()
views.activeCallPiP.isVisible = true
views.avatarViews.isVisible = false
currentCall.attachViewRenderers(null, views.activeCallPiP, null)
}
private fun renderVoiceCall(currentCall: WebRtcCall, calls: List<WebRtcCall>) {
views.activeCallPiP.isVisible = false
views.avatarViews.isVisible = true
val isActiveCallPaused = currentCall.isLocalOnHold || currentCall.isRemoteOnHold
views.activeCallPausedIcon.isVisible = isActiveCallPaused
val activeOpponentMatrixItem = currentCall.getOpponentAsMatrixItem(session)
if (isActiveCallPaused) {
val colorFilter = ContextCompat.getColor(context, R.color.bg_call_screen_blur)
activeOpponentMatrixItem?.also {
avatarRenderer.renderBlur(it, views.activeCallOpponentAvatar, sampling = 2, rounded = true, colorFilter = colorFilter, addPlaceholder = true)
}
} else {
activeOpponentMatrixItem?.also {
avatarRenderer.render(it, views.activeCallOpponentAvatar)
}
}
val otherConnectedCall = calls.filter {
it.mxCall.state is CallState.Connected
}.firstOrNull {
it != currentCall
}
if (otherConnectedCall != null) {
views.otherCallOpponentAvatar.isVisible = true
views.otherCallPausedIcon.isVisible = true
otherConnectedCall.getOpponentAsMatrixItem(session)?.also { heldOpponentMatrixItem ->
avatarRenderer.render(heldOpponentMatrixItem, views.activeCallOpponentAvatar)
}
} else {
views.otherCallOpponentAvatar.isVisible = false
views.otherCallPausedIcon.isVisible = false
}
}
private fun initIfNeeded() {
if (!activeCallPipInitialized) {
EglUtils.rootEglBase?.let { eglBase ->
views.activeCallPiP.apply {
init(eglBase.eglBaseContext, null)
setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_BALANCED)
setEnableHardwareScaler(true)
setZOrderMediaOverlay(true)
}
activeCallPipInitialized = true
}
}
}
}

View File

@ -1,66 +0,0 @@
/*
* Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.core.ui.views
import android.content.Context
import android.util.AttributeSet
import android.widget.RelativeLayout
import im.vector.app.R
import im.vector.app.databinding.ViewCurrentCallsBinding
import im.vector.app.features.call.webrtc.WebRtcCall
import im.vector.app.features.themes.ThemeUtils
import org.matrix.android.sdk.api.session.call.CallState
class CurrentCallsView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : RelativeLayout(context, attrs, defStyleAttr) {
interface Callback {
fun onTapToReturnToCall()
}
val views: ViewCurrentCallsBinding
var callback: Callback? = null
init {
inflate(context, R.layout.view_current_calls, this)
views = ViewCurrentCallsBinding.bind(this)
setBackgroundColor(ThemeUtils.getColor(context, R.attr.colorPrimary))
setOnClickListener { callback?.onTapToReturnToCall() }
}
fun render(calls: List<WebRtcCall>, formattedDuration: String) {
val connectedCalls = calls.filter {
it.mxCall.state is CallState.Connected
}
val heldCalls = connectedCalls.filter {
it.isLocalOnHold || it.remoteOnHold
}
if (connectedCalls.isEmpty()) return
views.currentCallsInfo.text = if (connectedCalls.size == heldCalls.size) {
resources.getQuantityString(R.plurals.call_only_paused, heldCalls.size, heldCalls.size)
} else {
if (heldCalls.isEmpty()) {
resources.getString(R.string.call_only_active, formattedDuration)
} else {
resources.getQuantityString(R.plurals.call_one_active_and_other_paused, heldCalls.size, formattedDuration, heldCalls.size)
}
}
}
}

View File

@ -1,114 +0,0 @@
/*
* Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.core.ui.views
import androidx.core.view.isVisible
import com.google.android.material.card.MaterialCardView
import im.vector.app.core.epoxy.onClick
import im.vector.app.features.call.utils.EglUtils
import im.vector.app.features.call.webrtc.WebRtcCall
import org.matrix.android.sdk.api.session.call.CallState
import org.webrtc.RendererCommon
import org.webrtc.SurfaceViewRenderer
class KnownCallsViewHolder {
private var activeCallPiP: SurfaceViewRenderer? = null
private var currentCallsView: CurrentCallsView? = null
private var pipWrapper: MaterialCardView? = null
private var currentCall: WebRtcCall? = null
private var calls: List<WebRtcCall> = emptyList()
private var activeCallPipInitialized = false
private val tickListener = object : WebRtcCall.Listener {
override fun onTick(formattedDuration: String) {
currentCallsView?.render(calls, formattedDuration)
}
}
fun updateCall(currentCall: WebRtcCall?, calls: List<WebRtcCall>) {
activeCallPiP?.let {
this.currentCall?.detachRenderers(listOf(it))
}
this.currentCall?.removeListener(tickListener)
this.currentCall = currentCall
this.currentCall?.addListener(tickListener)
this.calls = calls
val hasActiveCall = currentCall?.mxCall?.state is CallState.Connected
if (hasActiveCall) {
val isVideoCall = currentCall?.mxCall?.isVideoCall == true
if (isVideoCall) initIfNeeded()
currentCallsView?.isVisible = !isVideoCall
currentCallsView?.render(calls, currentCall?.formattedDuration() ?: "")
pipWrapper?.isVisible = isVideoCall
activeCallPiP?.isVisible = isVideoCall
activeCallPiP?.let {
currentCall?.attachViewRenderers(null, it, null)
}
} else {
currentCallsView?.isVisible = false
activeCallPiP?.isVisible = false
pipWrapper?.isVisible = false
activeCallPiP?.let {
currentCall?.detachRenderers(listOf(it))
}
}
}
private fun initIfNeeded() {
if (!activeCallPipInitialized && activeCallPiP != null) {
activeCallPiP?.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL)
EglUtils.rootEglBase?.let { eglBase ->
activeCallPiP?.init(eglBase.eglBaseContext, null)
activeCallPiP?.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_BALANCED)
activeCallPiP?.setEnableHardwareScaler(true /* enabled */)
activeCallPiP?.setZOrderMediaOverlay(true)
activeCallPipInitialized = true
}
}
}
fun bind(activeCallPiP: SurfaceViewRenderer,
activeCallView: CurrentCallsView,
pipWrapper: MaterialCardView,
interactionListener: CurrentCallsView.Callback) {
this.activeCallPiP = activeCallPiP
this.currentCallsView = activeCallView
this.pipWrapper = pipWrapper
this.currentCallsView?.callback = interactionListener
pipWrapper.onClick {
interactionListener.onTapToReturnToCall()
}
this.currentCall?.addListener(tickListener)
}
fun unBind() {
activeCallPiP?.let {
currentCall?.detachRenderers(listOf(it))
}
if (activeCallPipInitialized) {
activeCallPiP?.release()
}
this.currentCallsView?.callback = null
this.currentCall?.removeListener(tickListener)
pipWrapper?.setOnClickListener(null)
activeCallPiP = null
currentCallsView = null
pipWrapper = null
}
}

View File

@ -73,7 +73,6 @@ class CallControlsBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetC
private fun renderState(state: VectorCallViewState) {
views.callControlsSwitchCamera.isVisible = state.isVideoCall && state.canSwitchCamera
views.callControlsSwitchCamera.subTitle = getString(if (state.isFrontCamera) R.string.call_camera_front else R.string.call_camera_back)
if (state.isVideoCall) {
views.callControlsToggleSDHD.isVisible = true
if (state.isHD) {

View File

@ -69,7 +69,6 @@ class CallControlsView @JvmOverloads constructor(
interactionListener?.didTapToggleVideo()
}
private fun moreControlOption() {
interactionListener?.didTapMore()
}
@ -77,49 +76,36 @@ class CallControlsView @JvmOverloads constructor(
fun updateForState(state: VectorCallViewState) {
val callState = state.callState.invoke()
if (state.isAudioMuted) {
views.muteIcon.setImageResource(R.drawable.ic_microphone_off)
views.muteIcon.setImageResource(R.drawable.ic_mic_off)
views.muteIcon.contentDescription = resources.getString(R.string.a11y_unmute_microphone)
} else {
views.muteIcon.setImageResource(R.drawable.ic_microphone_on)
views.muteIcon.setImageResource(R.drawable.ic_mic_on)
views.muteIcon.contentDescription = resources.getString(R.string.a11y_mute_microphone)
}
if (state.isVideoEnabled) {
views.videoToggleIcon.setImageResource(R.drawable.ic_video)
views.videoToggleIcon.contentDescription = resources.getString(R.string.a11y_stop_camera)
} else {
views.videoToggleIcon.setImageResource(R.drawable.ic_video_off)
views.videoToggleIcon.setImageResource(R.drawable.ic_video_off)
views.videoToggleIcon.contentDescription = resources.getString(R.string.a11y_start_camera)
}
when (callState) {
is CallState.Idle,
is CallState.Dialing,
is CallState.Answering -> {
views.ringingControls.isVisible = true
views.ringingControlAccept.isVisible = false
views.ringingControlDecline.isVisible = true
views.connectedControls.isVisible = false
}
is CallState.LocalRinging -> {
views.ringingControls.isVisible = true
views.ringingControlAccept.isVisible = true
views.ringingControlDecline.isVisible = true
views.connectedControls.isVisible = false
}
is CallState.Connected -> {
if (callState.iceConnectionState == MxPeerConnectionState.CONNECTED) {
views.ringingControls.isVisible = false
views.connectedControls.isVisible = true
views.videoToggleIcon.isVisible = state.isVideoCall
} else {
views.ringingControls.isVisible = true
views.ringingControlAccept.isVisible = false
views.ringingControlDecline.isVisible = true
views.connectedControls.isVisible = false
}
is CallState.Connected,
is CallState.Dialing,
is CallState.Answering -> {
views.ringingControls.isVisible = false
views.connectedControls.isVisible = true
views.videoToggleIcon.isVisible = state.isVideoCall
views.moreIcon.isVisible = callState is CallState.Connected && callState.iceConnectionState == MxPeerConnectionState.CONNECTED
}
is CallState.Terminated,
null -> {
else -> {
views.ringingControls.isVisible = false
views.connectedControls.isVisible = false
}

View File

@ -35,6 +35,7 @@ import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.MvRx
import com.airbnb.mvrx.viewModel
import com.airbnb.mvrx.withState
import com.google.android.material.card.MaterialCardView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
@ -53,6 +54,8 @@ import im.vector.app.features.call.webrtc.WebRtcCallManager
import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.RoomDetailActivity
import im.vector.app.features.home.room.detail.RoomDetailArgs
import io.github.hyuwah.draggableviewlib.DraggableView
import io.github.hyuwah.draggableviewlib.setupDraggable
import io.reactivex.android.schedulers.AndroidSchedulers
import kotlinx.parcelize.Parcelize
import org.matrix.android.sdk.api.extensions.orFalse
@ -96,6 +99,7 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
}
private var rootEglBase: EglBase? = null
private var pipDraggrableView: DraggableView<MaterialCardView>? = null
var surfaceRenderersAreInitialized = false
@ -188,19 +192,19 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
is CallState.Idle,
is CallState.CreateOffer,
is CallState.LocalRinging,
is CallState.Dialing -> {
is CallState.Dialing -> {
views.callVideoGroup.isInvisible = true
views.callInfoGroup.isVisible = true
views.callToolbar.setSubtitle(R.string.call_ring)
configureCallInfo(state)
}
is CallState.Answering -> {
is CallState.Answering -> {
views.callVideoGroup.isInvisible = true
views.callInfoGroup.isVisible = true
views.callToolbar.setSubtitle(R.string.call_connecting)
configureCallInfo(state)
}
is CallState.Connected -> {
is CallState.Connected -> {
views.callToolbar.subtitle = state.formattedDuration
if (callState.iceConnectionState == MxPeerConnectionState.CONNECTED) {
if (state.isLocalOnHold || state.isRemoteOnHold) {
@ -248,10 +252,10 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
views.callToolbar.setSubtitle(R.string.call_connecting)
}
}
is CallState.Terminated -> {
is CallState.Terminated -> {
finish()
}
null -> {
null -> {
}
}
}
@ -290,7 +294,7 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
addPlaceholder = true
)
views.otherKnownCallLayout.isVisible = true
views.otherSmallIsHeldIcon.isVisible = otherCall?.let { it.isLocalOnHold || it.remoteOnHold }.orFalse()
views.otherSmallIsHeldIcon.isVisible = otherCall?.let { it.isLocalOnHold || it.isRemoteOnHold }.orFalse()
}
}
@ -303,6 +307,7 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
finish()
}
}
pipDraggrableView = views.pipRendererWrapper.setupDraggable().build()
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
@ -322,21 +327,21 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
}
// Init Picture in Picture renderer
views.pipRenderer.init(rootEglBase!!.eglBaseContext, null)
views.pipRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT)
views.pipRenderer.apply {
init(rootEglBase!!.eglBaseContext, null)
setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_BALANCED)
setEnableHardwareScaler(true)
setZOrderMediaOverlay(true)
}
// Init Full Screen renderer
views.fullscreenRenderer.init(rootEglBase!!.eglBaseContext, null)
views.fullscreenRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL)
views.pipRenderer.setZOrderMediaOverlay(true)
views.pipRenderer.setEnableHardwareScaler(true /* enabled */)
views.fullscreenRenderer.setEnableHardwareScaler(true /* enabled */)
callManager.getCallById(callArgs.callId)?.attachViewRenderers(views.pipRenderer, views.fullscreenRenderer,
intent.getStringExtra(EXTRA_MODE)?.takeIf { isFirstCreation() })
views.pipRenderer.setOnClickListener {
views.pipRendererWrapper.setOnClickListener {
callViewModel.handle(VectorCallViewActions.ToggleCamera)
}
surfaceRenderersAreInitialized = true

View File

@ -60,7 +60,7 @@ class VectorCallViewModel @AssistedInject constructor(
setState {
copy(
isLocalOnHold = call?.isLocalOnHold ?: false,
isRemoteOnHold = call?.remoteOnHold ?: false
isRemoteOnHold = call?.isRemoteOnHold ?: false
)
}
}
@ -189,12 +189,14 @@ class VectorCallViewModel @AssistedInject constructor(
}
setState {
copy(
isAudioMuted = webRtcCall.micMuted,
isVideoEnabled = !webRtcCall.videoMuted,
isVideoCall = webRtcCall.mxCall.isVideoCall,
callState = Success(webRtcCall.mxCall.state),
callInfo = webRtcCall.extractCallInfo(),
device = currentSoundDevice ?: CallAudioManager.Device.PHONE,
isLocalOnHold = webRtcCall.isLocalOnHold,
isRemoteOnHold = webRtcCall.remoteOnHold,
isRemoteOnHold = webRtcCall.isRemoteOnHold,
availableDevices = callManager.audioManager.availableDevices,
isFrontCamera = webRtcCall.currentCameraType() == CameraType.FRONT,
canSwitchCamera = webRtcCall.canSwitchCamera(),

View File

@ -164,7 +164,7 @@ class WebRtcCall(
private set
var videoMuted = false
private set
var remoteOnHold = false
var isRemoteOnHold = false
private set
var isLocalOnHold = false
private set
@ -586,12 +586,12 @@ class WebRtcCall(
}
private fun updateMuteStatus() {
val micShouldBeMuted = micMuted || remoteOnHold
val micShouldBeMuted = micMuted || isRemoteOnHold
localAudioTrack?.setEnabled(!micShouldBeMuted)
remoteAudioTrack?.setEnabled(!remoteOnHold)
val vidShouldBeMuted = videoMuted || remoteOnHold
remoteAudioTrack?.setEnabled(!isRemoteOnHold)
val vidShouldBeMuted = videoMuted || isRemoteOnHold
localVideoTrack?.setEnabled(!vidShouldBeMuted)
remoteVideoTrack?.setEnabled(!remoteOnHold)
remoteVideoTrack?.setEnabled(!isRemoteOnHold)
}
/**
@ -617,16 +617,16 @@ class WebRtcCall(
fun updateRemoteOnHold(onHold: Boolean) {
sessionScope?.launch(dispatcher) {
if (remoteOnHold == onHold) return@launch
if (isRemoteOnHold == onHold) return@launch
val direction: RtpTransceiver.RtpTransceiverDirection
if (onHold) {
wasLocalOnHold = isLocalOnHold
remoteOnHold = true
isRemoteOnHold = true
isLocalOnHold = true
direction = RtpTransceiver.RtpTransceiverDirection.SEND_ONLY
timer.pause()
} else {
remoteOnHold = false
isRemoteOnHold = false
isLocalOnHold = wasLocalOnHold
onCallBecomeActive(this@WebRtcCall)
direction = RtpTransceiver.RtpTransceiverDirection.SEND_RECV

View File

@ -22,7 +22,6 @@ import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.core.view.get
import androidx.core.view.isVisible
import androidx.core.view.iterator
import androidx.fragment.app.Fragment
@ -38,9 +37,8 @@ import im.vector.app.core.platform.ToolbarConfigurable
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.ui.views.CurrentCallsView
import im.vector.app.core.ui.views.CurrentCallsCardView
import im.vector.app.core.ui.views.KeysBackupBanner
import im.vector.app.core.ui.views.KnownCallsViewHolder
import im.vector.app.databinding.FragmentHomeDetailBinding
import im.vector.app.features.call.SharedKnownCallsViewModel
import im.vector.app.features.call.VectorCallActivity
@ -58,6 +56,7 @@ import im.vector.app.features.themes.ThemeUtils
import im.vector.app.features.workers.signout.BannerState
import im.vector.app.features.workers.signout.ServerBackupStatusViewModel
import im.vector.app.features.workers.signout.ServerBackupStatusViewState
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.group.model.GroupSummary
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
@ -70,11 +69,12 @@ class HomeDetailFragment @Inject constructor(
private val colorProvider: ColorProvider,
private val alertManager: PopupAlertManager,
private val callManager: WebRtcCallManager,
private val vectorPreferences: VectorPreferences
private val vectorPreferences: VectorPreferences,
private val session: Session
) : VectorBaseFragment<FragmentHomeDetailBinding>(),
KeysBackupBanner.Delegate,
CurrentCallsView.Callback,
ServerBackupStatusViewModel.Factory {
ServerBackupStatusViewModel.Factory,
CurrentCallsCardView.Callback {
private val viewModel: HomeDetailViewModel by fragmentViewModel()
private val unknownDeviceDetectorSharedViewModel: UnknownDeviceDetectorSharedViewModel by activityViewModel()
@ -117,8 +117,6 @@ class HomeDetailFragment @Inject constructor(
return FragmentHomeDetailBinding.inflate(inflater, container, false)
}
private val activeCallViewHolder = KnownCallsViewHolder()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
sharedActionViewModel = activityViewModelProvider.get(HomeSharedActionViewModel::class.java)
@ -190,7 +188,7 @@ class HomeDetailFragment @Inject constructor(
sharedCallActionViewModel
.liveKnownCalls
.observe(viewLifecycleOwner, {
activeCallViewHolder.updateCall(callManager.getCurrentCall(), callManager.getCalls())
views.currentCallsCardView.render(callManager.getCurrentCall(), callManager.getCalls())
invalidateOptionsMenu()
})
}
@ -291,12 +289,11 @@ class HomeDetailFragment @Inject constructor(
}
private fun setupActiveCallView() {
activeCallViewHolder.bind(
views.activeCallPiP,
views.activeCallView,
views.activeCallPiPWrap,
this
)
views.currentCallsCardView.apply {
this.avatarRenderer = this@HomeDetailFragment.avatarRenderer
this.session = this@HomeDetailFragment.session
this.callback = this@HomeDetailFragment
}
}
private fun setupToolbar() {

View File

@ -90,9 +90,8 @@ import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.platform.showOptimizedSnackbar
import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.ui.views.ActiveConferenceView
import im.vector.app.core.ui.views.CurrentCallsView
import im.vector.app.core.ui.views.CurrentCallsCardView
import im.vector.app.core.ui.views.FailedMessagesWarningView
import im.vector.app.core.ui.views.KnownCallsViewHolder
import im.vector.app.core.ui.views.NotificationAreaView
import im.vector.app.core.utils.Debouncer
import im.vector.app.core.utils.DimensionConverter
@ -239,7 +238,7 @@ class RoomDetailFragment @Inject constructor(
AttachmentTypeSelectorView.Callback,
AttachmentsHelper.Callback,
GalleryOrCameraDialogHelper.Listener,
CurrentCallsView.Callback {
CurrentCallsCardView.Callback {
companion object {
/**
@ -298,7 +297,6 @@ class RoomDetailFragment @Inject constructor(
private lateinit var attachmentTypeSelector: AttachmentTypeSelectorView
private var lockSendButton = false
private val knownCallsViewHolder = KnownCallsViewHolder()
private lateinit var emojiPopup: EmojiPopup
@ -344,7 +342,7 @@ class RoomDetailFragment @Inject constructor(
knownCallsViewModel
.liveKnownCalls
.observe(viewLifecycleOwner, {
knownCallsViewHolder.updateCall(callManager.getCurrentCall(), it)
views.currentCallsCardView.render(callManager.getCurrentCall(), it)
invalidateOptionsMenu()
})
@ -687,7 +685,6 @@ class RoomDetailFragment @Inject constructor(
override fun onDestroyView() {
timelineEventController.callback = null
timelineEventController.removeModelBuildListener(modelBuildListener)
views.activeCallView.callback = null
modelBuildListener = null
autoCompleter.clear()
debouncer.cancelAll()
@ -698,7 +695,6 @@ class RoomDetailFragment @Inject constructor(
}
override fun onDestroy() {
knownCallsViewHolder.unBind()
roomDetailViewModel.handle(RoomDetailAction.ExitTrackingUnreadMessagesState)
super.onDestroy()
}
@ -734,12 +730,11 @@ class RoomDetailFragment @Inject constructor(
}
private fun setupActiveCallView() {
knownCallsViewHolder.bind(
views.activeCallPiP,
views.activeCallView,
views.activeCallPiPWrap,
this
)
views.currentCallsCardView.apply {
this.callback = this@RoomDetailFragment
this.avatarRenderer = this@RoomDetailFragment.avatarRenderer
this.session = this@RoomDetailFragment.session
}
}
private fun navigateToEvent(action: RoomDetailViewEvents.NavigateToEvent) {

View File

@ -9,4 +9,5 @@
<path
android:pathData="M12.6666,3.9999L14.3753,2.633C15.03,2.1092 16,2.5754 16,3.4139V8.586C16,9.4245 15.03,9.8906 14.3753,9.3668L12.6666,7.9999V3.9999Z"
android:fillColor="#737D8C"/>
</vector>

View File

@ -1,11 +0,0 @@
<vector android:autoMirrored="true" android:height="40dp"
android:viewportHeight="40" android:viewportWidth="40"
android:width="40dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillAlpha="0.2" android:fillColor="#000000"
android:fillType="evenOdd"
android:pathData="M20,20m-20,0a20,20 0,1 1,40 0a20,20 0,1 1,-40 0"
android:strokeColor="#00000000" android:strokeWidth="1"/>
<path android:fillColor="#FFFFFF" android:fillType="nonZero"
android:pathData="M26.75,15.875L23.75,18.875L23.75,16.25C23.75,15.8375 23.4125,15.5 23,15.5L18.365,15.5L26.75,23.885L26.75,15.875ZM13.4525,12.5L12.5,13.4525L14.5475,15.5L14,15.5C13.5875,15.5 13.25,15.8375 13.25,16.25L13.25,23.75C13.25,24.1625 13.5875,24.5 14,24.5L23,24.5C23.1575,24.5 23.2925,24.44 23.405,24.365L25.7975,26.75L26.75,25.7975L13.4525,12.5Z"
android:strokeColor="#00000000" android:strokeWidth="1"/>
</vector>

View File

@ -1,7 +0,0 @@
<vector android:autoMirrored="true" android:height="18dp"
android:viewportHeight="18" android:viewportWidth="18"
android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FFFFFF" android:fillType="nonZero"
android:pathData="M15.75,4.875L12.75,7.875L12.75,5.25C12.75,4.8375 12.4125,4.5 12,4.5L7.365,4.5L15.75,12.885L15.75,4.875ZM2.4525,1.5L1.5,2.4525L3.5475,4.5L3,4.5C2.5875,4.5 2.25,4.8375 2.25,5.25L2.25,12.75C2.25,13.1625 2.5875,13.5 3,13.5L12,13.5C12.1575,13.5 12.2925,13.44 12.405,13.365L14.7975,15.75L15.75,14.7975L2.4525,1.5Z"
android:strokeColor="#00000000" android:strokeWidth="1"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19,11h-1.7c0,0.74 -0.16,1.43 -0.43,2.05l1.23,1.23c0.56,-0.98 0.9,-2.09 0.9,-3.28zM14.98,11.17c0,-0.06 0.02,-0.11 0.02,-0.17L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v0.18l5.98,5.99zM4.27,3L3,4.27l6.01,6.01L9.01,11c0,1.66 1.33,3 2.99,3 0.22,0 0.44,-0.03 0.65,-0.08l1.66,1.66c-0.71,0.33 -1.5,0.52 -2.31,0.52 -2.76,0 -5.3,-2.1 -5.3,-5.1L5,11c0,3.41 2.72,6.23 6,6.72L11,21h2v-3.28c0.91,-0.13 1.77,-0.45 2.54,-0.9L19.73,21 21,19.73 4.27,3z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,14c1.66,0 2.99,-1.34 2.99,-3L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM17.3,11c0,3 -2.54,5.1 -5.3,5.1S6.7,14 6.7,11L5,11c0,3.41 2.72,6.23 6,6.72L11,21h2v-3.28c3.28,-0.48 6,-3.3 6,-6.72h-1.7z"/>
</vector>

View File

@ -1,41 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="25dp"
android:viewportWidth="24"
android:viewportHeight="25">
<path
android:pathData="M1,2L23,24"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
<path
android:pathData="M15,10.34V5C15.0007,4.256 14.725,3.5383 14.2264,2.9862C13.7277,2.4341 13.0417,2.0869 12.3015,2.0122C11.5613,1.9374 10.8197,2.1403 10.2207,2.5816C9.6217,3.0228 9.208,3.6709 9.06,4.4M9,10V13C9.0005,13.593 9.1768,14.1725 9.5064,14.6653C9.8361,15.1582 10.3045,15.5423 10.8523,15.7691C11.4002,15.996 12.0029,16.0554 12.5845,15.9399C13.1661,15.8243 13.7005,15.539 14.12,15.12L9,10Z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
<path
android:pathData="M16.9999,17.95C16.0237,18.9464 14.7721,19.6285 13.4056,19.9086C12.039,20.1887 10.62,20.0542 9.3304,19.5223C8.0409,18.9903 6.9397,18.0853 6.1681,16.9232C5.3965,15.761 4.9897,14.3949 4.9999,13V11M18.9999,11V13C18.9996,13.4124 18.9628,13.824 18.8899,14.23"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
<path
android:pathData="M12,20V24"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
<path
android:pathData="M8,24H16"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
</vector>

View File

@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,0C10.9391,0 9.9217,0.4214 9.1716,1.1716C8.4214,1.9217 8,2.9391 8,4V12C8,13.0609 8.4214,14.0783 9.1716,14.8284C9.9217,15.5786 10.9391,16 12,16C13.0609,16 14.0783,15.5786 14.8284,14.8284C15.5786,14.0783 16,13.0609 16,12V4C16,2.9391 15.5786,1.9217 14.8284,1.1716C14.0783,0.4214 13.0609,0 12,0ZM10.5858,2.5858C10.9609,2.2107 11.4696,2 12,2C12.5304,2 13.0391,2.2107 13.4142,2.5858C13.7893,2.9609 14,3.4696 14,4V12C14,12.5304 13.7893,13.0391 13.4142,13.4142C13.0391,13.7893 12.5304,14 12,14C11.4696,14 10.9609,13.7893 10.5858,13.4142C10.2107,13.0391 10,12.5304 10,12V4C10,3.4696 10.2107,2.9609 10.5858,2.5858ZM6,10C6,9.4477 5.5523,9 5,9C4.4477,9 4,9.4477 4,10V12C4,14.1217 4.8429,16.1566 6.3432,17.6569C7.6058,18.9195 9.247,19.7165 11,19.9373V22H8C7.4477,22 7,22.4477 7,23C7,23.5523 7.4477,24 8,24H12H16C16.5523,24 17,23.5523 17,23C17,22.4477 16.5523,22 16,22H13V19.9373C14.753,19.7165 16.3942,18.9195 17.6569,17.6569C19.1571,16.1566 20,14.1217 20,12V10C20,9.4477 19.5523,9 19,9C18.4477,9 18,9.4477 18,10V12C18,13.5913 17.3679,15.1174 16.2426,16.2426C15.1174,17.3679 13.5913,18 12,18C10.4087,18 8.8826,17.3679 7.7574,16.2426C6.6321,15.1174 6,13.5913 6,12V10Z"
android:fillColor="#2E2F32"
android:fillType="evenOdd"/>
</vector>

View File

@ -1,10 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="25dp"
android:height="25dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="25"
android:viewportHeight="25">
<path
android:pathData="M0.5,7.5C0.5,5.8432 1.8432,4.5 3.5,4.5H14.5C16.1569,4.5 17.5,5.8432 17.5,7.5V17.5C17.5,19.1569 16.1569,20.5 14.5,20.5H3.5C1.8432,20.5 0.5,19.1569 0.5,17.5V7.5Z"
android:strokeLineJoin="round"
android:fillColor="#000000"/>
<path
android:pathData="M19.5,9.5L22.8753,6.7998C23.5301,6.2759 24.5,6.7421 24.5,7.5806V17.4194C24.5,18.2579 23.5301,18.7241 22.8753,18.2002L19.5,15.5V9.5Z"

View File

@ -1,20 +1,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M10.66,5H14C14.5304,5 15.0391,5.2107 15.4142,5.5858C15.7893,5.9609 16,6.4696 16,7V10.34L17,11.34L23,7V17M16,16V17C16,17.5304 15.7893,18.0391 15.4142,18.4142C15.0391,18.7893 14.5304,19 14,19H3C2.4696,19 1.9609,18.7893 1.5858,18.4142C1.2107,18.0391 1,17.5304 1,17V7C1,6.4696 1.2107,5.9609 1.5858,5.5858C1.9609,5.2107 2.4696,5 3,5H5L16,16Z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#2E2F32"
android:strokeLineCap="round"/>
<path
android:pathData="M1,1L23,23"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#2E2F32"
android:strokeLineCap="round"/>
<vector android:height="24dp" android:viewportHeight="32"
android:viewportWidth="32" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M22.5,20.9l5,3C27.6,24 27.8,24 28,24c0.2,0 0.3,0 0.5,-0.1c0.3,-0.2 0.5,-0.5 0.5,-0.9V9c0,-0.4 -0.2,-0.7 -0.5,-0.9c-0.3,-0.2 -0.7,-0.2 -1,0l-5,3C22.2,11.3 22,11.6 22,12v8C22,20.4 22.2,20.7 22.5,20.9z"/>
<path android:fillColor="#FF000000" android:pathData="M29.7,28.3L20,18.6V11c0,-1.7 -1.3,-3 -3,-3H9.4L3.7,2.3c-0.4,-0.4 -1,-0.4 -1.4,0s-0.4,1 0,1.4l26,26c0.2,0.2 0.5,0.3 0.7,0.3s0.5,-0.1 0.7,-0.3C30.1,29.3 30.1,28.7 29.7,28.3z"/>
<path android:fillColor="#FF000000" android:pathData="M3,11v10c0,1.7 1.3,3 3,3h11c0.8,0 1.5,-0.3 2,-0.8L4.3,8.5C3.5,9.1 3,10 3,11z"/>
</vector>

View File

@ -1,5 +0,0 @@
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M17,10.5V7c0,-0.55 -0.45,-1 -1,-1H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l4,4v-11l-4,4z"/>
</vector>

View File

@ -29,15 +29,24 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<org.webrtc.SurfaceViewRenderer
android:id="@+id/pipRenderer"
android:layout_width="wrap_content"
android:layout_height="144dp"
android:layout_gravity="bottom|end"
android:layout_marginTop="16dp"
<com.google.android.material.card.MaterialCardView
android:id="@+id/pipRendererWrapper"
android:layout_width="@dimen/call_pip_width"
android:layout_height="@dimen/call_pip_height"
app:cardCornerRadius="@dimen/call_pip_radius"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintBottom_toTopOf="@id/callControlsView">
<org.webrtc.SurfaceViewRenderer
android:id="@+id/pipRenderer"
android:layout_width="@dimen/call_pip_width"
android:layout_height="@dimen/call_pip_height"
android:visibility="gone"
tools:visibility="visible" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/callToolbar"
@ -60,15 +69,15 @@
<com.google.android.material.card.MaterialCardView
android:id="@+id/otherKnownCallLayout"
android:layout_width="80dp"
android:layout_height="144dp"
android:layout_width="@dimen/call_pip_width"
android:layout_height="@dimen/call_pip_height"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
android:background="@color/element_background_light"
android:foreground="?attr/selectableItemBackground"
android:visibility="gone"
app:cardBackgroundColor="@color/bg_call_screen"
app:cardCornerRadius="4dp"
app:cardCornerRadius="@dimen/call_pip_radius"
app:cardElevation="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
@ -95,8 +104,8 @@
<ImageView
android:id="@+id/otherMemberAvatar"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_width="120dp"
android:layout_height="120dp"
android:contentDescription="@string/avatar"
android:importantForAccessibility="no"
android:scaleType="centerCrop"
@ -159,7 +168,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="pipRenderer, fullscreenRenderer"
app:constraint_referenced_ids="pipRendererWrapper, fullscreenRenderer"
tools:visibility="invisible" />
<im.vector.app.features.call.CallControlsView

View File

@ -128,41 +128,27 @@
app:layout_constraintTop_toBottomOf="@id/syncStateView"
tools:visibility="visible" />
<im.vector.app.core.ui.views.CurrentCallsView
android:id="@+id/activeCallView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/homeKeysBackupBanner"
tools:visibility="visible" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/roomListContainer"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView"
app:layout_constraintTop_toBottomOf="@+id/activeCallView" />
app:layout_constraintTop_toBottomOf="@+id/homeKeysBackupBanner" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/activeCallPiPWrap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
<im.vector.app.core.ui.views.CurrentCallsCardView
android:id="@+id/currentCallsCardView"
android:layout_width="@dimen/call_pip_width"
android:layout_height="@dimen/call_pip_height"
app:cardElevation="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:clickable="true"
android:focusable="true"
app:cardCornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/activeCallView">
android:foreground="?attr/selectableItemBackground"
app:cardCornerRadius="@dimen/call_pip_radius"
app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView"
app:layout_constraintEnd_toEndOf="parent" />
<org.webrtc.SurfaceViewRenderer
android:id="@+id/activeCallPiP"
android:layout_width="120dp"
android:layout_height="120dp"
android:visibility="gone"
tools:visibility="visible" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNavigationView"

View File

@ -100,20 +100,12 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/appBarLayout" />
<im.vector.app.core.ui.views.CurrentCallsView
android:id="@+id/activeCallView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/syncStateView"
tools:visibility="visible" />
<im.vector.app.core.ui.views.ActiveConferenceView
android:id="@+id/activeConferenceView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/activeCallView"
app:layout_constraintTop_toBottomOf="@id/syncStateView"
tools:visibility="visible" />
<androidx.recyclerview.widget.RecyclerView
@ -193,26 +185,20 @@
app:barrierDirection="top"
app:constraint_referenced_ids="composerLayout,notificationAreaView, failedMessagesWarningView" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/activeCallPiPWrap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
<im.vector.app.core.ui.views.CurrentCallsCardView
android:id="@+id/currentCallsCardView"
android:layout_width="@dimen/call_pip_width"
android:layout_height="@dimen/call_pip_height"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
app:cardElevation="8dp"
android:clickable="true"
android:focusable="true"
app:cardCornerRadius="16dp"
android:foreground="?attr/selectableItemBackground"
app:cardCornerRadius="@dimen/call_pip_radius"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/jumpToReadMarkerView">
app:layout_constraintBottom_toTopOf="@id/failedMessagesWarningView"/>
<org.webrtc.SurfaceViewRenderer
android:id="@+id/activeCallPiP"
android:layout_width="120dp"
android:layout_height="120dp"
android:visibility="gone"
tools:visibility="visible" />
</com.google.android.material.card.MaterialCardView>
<im.vector.app.core.platform.BadgeFloatingActionButton
android:id="@+id/jumpToBottomView"

View File

@ -87,8 +87,8 @@
android:clickable="true"
android:contentDescription="@string/a11y_mute_microphone"
android:focusable="true"
android:padding="16dp"
android:src="@drawable/ic_microphone_off"
android:padding="12dp"
android:src="@drawable/ic_mic_off"
app:backgroundTint="?android:colorBackground"
app:tint="?vctr_content_primary"
tools:ignore="MissingConstraints,MissingPrefix" />
@ -102,8 +102,8 @@
android:clickable="true"
android:contentDescription="@string/a11y_stop_camera"
android:focusable="true"
android:padding="16dp"
android:src="@drawable/ic_call_videocam_off_default"
android:padding="12dp"
android:src="@drawable/ic_video"
app:backgroundTint="?android:colorBackground"
app:tint="?vctr_content_primary"
tools:ignore="MissingConstraints,MissingPrefix" />
@ -139,7 +139,7 @@
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:constraint_referenced_ids="audioSettingsIcon,videoToggleIcon, muteIcon, endCallIcon, moreIcon"
app:constraint_referenced_ids="videoToggleIcon, audioSettingsIcon, muteIcon, endCallIcon, moreIcon"
app:flow_horizontalGap="16dp"
app:flow_horizontalStyle="packed"
app:flow_wrapMode="chain"

View File

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<merge 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:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorPrimary"
android:foreground="?attr/selectableItemBackground"
tools:parentTag="android.widget.RelativeLayout">
<TextView
android:id="@+id/currentCallsInfo"
style="@style/Widget.Vector.TextView.Body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toStartOf="@id/returnToCallButton"
android:drawablePadding="10dp"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingTop="12dp"
android:paddingEnd="16dp"
android:paddingBottom="12dp"
android:text="@string/call_only_active"
android:textColor="?colorOnPrimary"
app:drawableStartCompat="@drawable/ic_call_answer"
app:drawableTint="?colorOnPrimary" />
<Button
android:id="@+id/returnToCallButton"
style="@style/Widget.Vector.Button.Text.OnPrimary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/currentCallsInfo"
android:layout_alignBottom="@+id/currentCallsInfo"
android:layout_alignParentEnd="true"
android:clickable="false"
android:focusable="false"
android:gravity="center"
android:paddingStart="8dp"
android:paddingEnd="16dp"
android:text="@string/action_return"
android:textStyle="bold" />
</merge>

View File

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8"?>
<merge 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:layout_width="@dimen/call_pip_width"
android:layout_height="@dimen/call_pip_height"
android:backgroundTint="@color/bg_call_screen_blur"
android:clickable="true"
android:focusable="true"
app:cardCornerRadius="@dimen/call_pip_radius"
tools:parentTag="com.google.android.material.card.MaterialCardView">
<org.webrtc.SurfaceViewRenderer
android:id="@+id/activeCallPiP"
android:layout_width="@dimen/call_pip_width"
android:layout_height="@dimen/call_pip_height"
android:visibility="gone"
tools:visibility="invisible" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/avatarViews"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<ImageView
android:id="@+id/activeCallOpponentAvatar"
android:layout_width="48dp"
android:layout_height="48dp"
android:importantForAccessibility="no"
android:scaleType="centerCrop"
app:layout_constraintBottom_toTopOf="@+id/otherCallOpponentAvatar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:src="@tools:sample/avatars" />
<ImageView
android:id="@+id/activeCallPausedIcon"
android:layout_width="16dp"
android:layout_height="16dp"
android:importantForAccessibility="no"
android:src="@drawable/ic_call_small_pause"
app:layout_constraintBottom_toBottomOf="@+id/activeCallOpponentAvatar"
app:layout_constraintEnd_toEndOf="@+id/activeCallOpponentAvatar"
app:layout_constraintStart_toStartOf="@+id/activeCallOpponentAvatar"
app:layout_constraintTop_toTopOf="@+id/activeCallOpponentAvatar" />
<ImageView
android:id="@+id/otherCallOpponentAvatar"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="8dp"
android:importantForAccessibility="no"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/activeCallOpponentAvatar"
tools:src="@tools:sample/avatars" />
<ImageView
android:id="@+id/otherCallPausedIcon"
android:layout_width="8dp"
android:layout_height="8dp"
android:importantForAccessibility="no"
android:src="@drawable/ic_call_small_pause"
app:layout_constraintBottom_toBottomOf="@+id/otherCallOpponentAvatar"
app:layout_constraintEnd_toEndOf="@+id/otherCallOpponentAvatar"
app:layout_constraintStart_toStartOf="@+id/otherCallOpponentAvatar"
app:layout_constraintTop_toTopOf="@+id/otherCallOpponentAvatar" />
</androidx.constraintlayout.widget.ConstraintLayout>
<ProgressBar
android:id="@+id/activeCallProgress"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminate="true"
android:indeterminateTint="@color/element_background_light"
android:indeterminateTintMode="src_atop"
android:visibility="gone"
tools:visibility="visible" />
</merge>