mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-21 17:05:39 +03:00
Change active call bar + some minor changes in call screen
This commit is contained in:
parent
7c033b4090
commit
f74a71001a
29 changed files with 395 additions and 463 deletions
|
@ -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'
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
10
vector/src/main/res/drawable/ic_mic_off.xml
Normal file
10
vector/src/main/res/drawable/ic_mic_off.xml
Normal 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>
|
10
vector/src/main/res/drawable/ic_mic_on.xml
Normal file
10
vector/src/main/res/drawable/ic_mic_on.xml
Normal 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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
93
vector/src/main/res/layout/view_current_calls_card.xml
Normal file
93
vector/src/main/res/layout/view_current_calls_card.xml
Normal 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>
|
Loading…
Reference in a new issue