Specific layout for when conference layout is active speaker & alone or 2
This commit is contained in:
parent
740a935525
commit
1761843c1b
10 changed files with 548 additions and 43 deletions
|
@ -23,6 +23,7 @@ Group changes to describe their impact on the project, as follows:
|
|||
- Android 13 support, using new post notifications & media permissions
|
||||
- Call recordings can be exported
|
||||
- Setting to prevent international prefix from account to be applied to call & chat
|
||||
- Themed app icon is now supported for Android 13+
|
||||
|
||||
### Changed
|
||||
- In-call views have been re-designed
|
||||
|
|
|
@ -21,9 +21,11 @@ package org.linphone.activities.voip.fragments
|
|||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
import android.os.Bundle
|
||||
import android.os.SystemClock
|
||||
import android.view.View
|
||||
import android.view.animation.AccelerateDecelerateInterpolator
|
||||
import android.widget.Chronometer
|
||||
import android.widget.Toast
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
|
@ -31,6 +33,8 @@ import androidx.constraintlayout.widget.ConstraintSet
|
|||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import androidx.navigation.navGraphViewModels
|
||||
import androidx.transition.AutoTransition
|
||||
import androidx.transition.TransitionManager
|
||||
import androidx.window.layout.FoldingFeature
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
|
@ -38,9 +42,6 @@ import org.linphone.LinphoneApplication.Companion.corePreferences
|
|||
import org.linphone.R
|
||||
import org.linphone.activities.*
|
||||
import org.linphone.activities.main.MainActivity
|
||||
import org.linphone.activities.navigateToCallsList
|
||||
import org.linphone.activities.navigateToConferenceLayout
|
||||
import org.linphone.activities.navigateToConferenceParticipants
|
||||
import org.linphone.activities.voip.ConferenceDisplayMode
|
||||
import org.linphone.activities.voip.viewmodels.CallsViewModel
|
||||
import org.linphone.activities.voip.viewmodels.ConferenceViewModel
|
||||
|
@ -90,9 +91,11 @@ class ConferenceCallFragment : GenericFragment<VoipConferenceCallFragmentBinding
|
|||
if (displayMode == ConferenceDisplayMode.ACTIVE_SPEAKER) {
|
||||
if (conferenceViewModel.conferenceExists.value == true) {
|
||||
Log.i("[Conference Call] Local participant is in conference and current layout is active speaker, updating Core's native window id")
|
||||
val window =
|
||||
binding.root.findViewById<RoundCornersTextureView>(R.id.conference_active_speaker_remote_video)
|
||||
val window = binding.root.findViewById<RoundCornersTextureView>(R.id.conference_active_speaker_remote_video)
|
||||
coreContext.core.nativeVideoWindowId = window
|
||||
|
||||
val preview = binding.root.findViewById<RoundCornersTextureView>(R.id.local_preview_video_surface)
|
||||
conferenceViewModel.meParticipant.value?.setTextureView(preview)
|
||||
} else {
|
||||
Log.i("[Conference Call] Either not in conference or current layout isn't active speaker, updating Core's native window id")
|
||||
coreContext.core.nativeVideoWindowId = null
|
||||
|
@ -115,6 +118,22 @@ class ConferenceCallFragment : GenericFragment<VoipConferenceCallFragmentBinding
|
|||
}
|
||||
}
|
||||
|
||||
conferenceViewModel.secondParticipantJoinedEvent.observe(
|
||||
viewLifecycleOwner
|
||||
) {
|
||||
it.consume {
|
||||
switchToActiveSpeakerLayoutForTwoParticipants()
|
||||
}
|
||||
}
|
||||
|
||||
conferenceViewModel.moreThanTwoParticipantsJoinedEvent.observe(
|
||||
viewLifecycleOwner
|
||||
) {
|
||||
it.consume {
|
||||
switchToActiveSpeakerLayoutForMoreThanTwoParticipants()
|
||||
}
|
||||
}
|
||||
|
||||
conferenceViewModel.conference.observe(
|
||||
viewLifecycleOwner
|
||||
) { conference ->
|
||||
|
@ -163,6 +182,8 @@ class ConferenceCallFragment : GenericFragment<VoipConferenceCallFragmentBinding
|
|||
.make(binding.coordinator, R.string.conference_last_user, Snackbar.LENGTH_LONG)
|
||||
.setAnchorView(binding.primaryButtons.hangup)
|
||||
.show()
|
||||
|
||||
switchToActiveSpeakerLayoutWhenAlone()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,9 +299,21 @@ class ConferenceCallFragment : GenericFragment<VoipConferenceCallFragmentBinding
|
|||
controlsViewModel.hideExtraButtons(true)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
if (conferenceViewModel.conferenceCreationPending.value == false) {
|
||||
when (conferenceViewModel.conferenceParticipantDevices.value.orEmpty().size) {
|
||||
1 -> switchToActiveSpeakerLayoutWhenAlone()
|
||||
2 -> switchToActiveSpeakerLayoutForTwoParticipants()
|
||||
else -> switchToActiveSpeakerLayoutForMoreThanTwoParticipants()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun switchToFullScreenIfPossible(conference: Conference) {
|
||||
if (corePreferences.enableFullScreenWhenJoiningVideoConference) {
|
||||
if (conference.currentParams.isVideoEnabled) {
|
||||
if (conference.currentParams.isVideoEnabled && conferenceViewModel.conferenceCreationPending.value == false) {
|
||||
when {
|
||||
conference.me.devices.isEmpty() -> {
|
||||
Log.w("[Conference Call] Conference has video enabled but either our device hasn't joined yet")
|
||||
|
@ -305,10 +338,6 @@ class ConferenceCallFragment : GenericFragment<VoipConferenceCallFragmentBinding
|
|||
startActivity(intent)
|
||||
}
|
||||
|
||||
private fun showSnackBar(resourceId: Int) {
|
||||
Snackbar.make(binding.coordinator, resourceId, Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
private fun startTimer(timerId: Int) {
|
||||
val timer: Chronometer? = binding.root.findViewById(timerId)
|
||||
if (timer == null) {
|
||||
|
@ -349,4 +378,190 @@ class ConferenceCallFragment : GenericFragment<VoipConferenceCallFragmentBinding
|
|||
|
||||
set.applyTo(constraintLayout)
|
||||
}
|
||||
|
||||
private fun animateConstraintLayout(
|
||||
constraintLayout: ConstraintLayout,
|
||||
set: ConstraintSet
|
||||
) {
|
||||
val trans = AutoTransition()
|
||||
trans.duration = 500
|
||||
trans.interpolator = AccelerateDecelerateInterpolator()
|
||||
TransitionManager.beginDelayedTransition(constraintLayout, trans)
|
||||
set.applyTo(constraintLayout)
|
||||
}
|
||||
|
||||
private fun switchToActiveSpeakerLayoutForMoreThanTwoParticipants() {
|
||||
if (conferenceViewModel.conferenceDisplayMode.value != ConferenceDisplayMode.ACTIVE_SPEAKER) return
|
||||
|
||||
val constraintLayout =
|
||||
binding.root.findViewById<ConstraintLayout>(R.id.conference_constraint_layout)
|
||||
?: return
|
||||
val set = ConstraintSet()
|
||||
set.clone(constraintLayout)
|
||||
|
||||
set.clear(R.id.local_participant_background, ConstraintSet.TOP)
|
||||
set.clear(R.id.local_participant_background, ConstraintSet.START)
|
||||
set.clear(R.id.local_participant_background, ConstraintSet.BOTTOM)
|
||||
set.clear(R.id.local_participant_background, ConstraintSet.END)
|
||||
|
||||
val margin = resources.getDimension(R.dimen.voip_active_speaker_miniature_margin).toInt()
|
||||
val portraitOrientation = resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE
|
||||
if (portraitOrientation) {
|
||||
set.connect(
|
||||
R.id.local_participant_background,
|
||||
ConstraintSet.START,
|
||||
R.id.conference_constraint_layout,
|
||||
ConstraintSet.START,
|
||||
margin
|
||||
)
|
||||
set.connect(
|
||||
R.id.local_participant_background,
|
||||
ConstraintSet.BOTTOM,
|
||||
R.id.miniatures,
|
||||
ConstraintSet.BOTTOM,
|
||||
0
|
||||
)
|
||||
set.connect(
|
||||
R.id.local_participant_background,
|
||||
ConstraintSet.TOP,
|
||||
R.id.miniatures,
|
||||
ConstraintSet.TOP,
|
||||
0
|
||||
)
|
||||
} else {
|
||||
set.connect(
|
||||
R.id.local_participant_background,
|
||||
ConstraintSet.TOP,
|
||||
R.id.top_barrier,
|
||||
ConstraintSet.BOTTOM,
|
||||
0
|
||||
)
|
||||
set.connect(
|
||||
R.id.local_participant_background,
|
||||
ConstraintSet.START,
|
||||
R.id.active_speaker_background,
|
||||
ConstraintSet.END,
|
||||
0
|
||||
)
|
||||
set.connect(
|
||||
R.id.local_participant_background,
|
||||
ConstraintSet.END,
|
||||
R.id.scroll_indicator,
|
||||
ConstraintSet.START,
|
||||
0
|
||||
)
|
||||
}
|
||||
|
||||
val size = resources.getDimension(R.dimen.voip_active_speaker_miniature_size).toInt()
|
||||
set.constrainWidth(
|
||||
R.id.local_participant_background,
|
||||
size
|
||||
)
|
||||
set.constrainHeight(
|
||||
R.id.local_participant_background,
|
||||
size
|
||||
)
|
||||
|
||||
if (corePreferences.enableAnimations) {
|
||||
animateConstraintLayout(constraintLayout, set)
|
||||
} else {
|
||||
set.applyTo(constraintLayout)
|
||||
}
|
||||
}
|
||||
|
||||
private fun switchToActiveSpeakerLayoutForTwoParticipants() {
|
||||
if (conferenceViewModel.conferenceDisplayMode.value != ConferenceDisplayMode.ACTIVE_SPEAKER) return
|
||||
|
||||
val constraintLayout =
|
||||
binding.root.findViewById<ConstraintLayout>(R.id.conference_constraint_layout)
|
||||
?: return
|
||||
val set = ConstraintSet()
|
||||
set.clone(constraintLayout)
|
||||
|
||||
set.clear(R.id.local_participant_background, ConstraintSet.TOP)
|
||||
set.clear(R.id.local_participant_background, ConstraintSet.START)
|
||||
set.clear(R.id.local_participant_background, ConstraintSet.BOTTOM)
|
||||
set.clear(R.id.local_participant_background, ConstraintSet.END)
|
||||
|
||||
val margin = resources.getDimension(R.dimen.voip_active_speaker_miniature_margin).toInt()
|
||||
set.connect(
|
||||
R.id.local_participant_background,
|
||||
ConstraintSet.BOTTOM,
|
||||
R.id.conference_constraint_layout,
|
||||
ConstraintSet.BOTTOM,
|
||||
margin
|
||||
)
|
||||
// Don't know why but if we use END instead of RIGHT, margin isn't applied...
|
||||
set.connect(
|
||||
R.id.local_participant_background,
|
||||
ConstraintSet.RIGHT,
|
||||
R.id.conference_constraint_layout,
|
||||
ConstraintSet.RIGHT,
|
||||
margin
|
||||
)
|
||||
|
||||
val size = resources.getDimension(R.dimen.voip_active_speaker_miniature_size).toInt()
|
||||
set.constrainWidth(
|
||||
R.id.local_participant_background,
|
||||
size
|
||||
)
|
||||
set.constrainHeight(
|
||||
R.id.local_participant_background,
|
||||
size
|
||||
)
|
||||
|
||||
if (corePreferences.enableAnimations) {
|
||||
animateConstraintLayout(constraintLayout, set)
|
||||
} else {
|
||||
set.applyTo(constraintLayout)
|
||||
}
|
||||
}
|
||||
|
||||
private fun switchToActiveSpeakerLayoutWhenAlone() {
|
||||
if (conferenceViewModel.conferenceDisplayMode.value != ConferenceDisplayMode.ACTIVE_SPEAKER) return
|
||||
|
||||
val constraintLayout =
|
||||
binding.root.findViewById<ConstraintLayout>(R.id.conference_constraint_layout)
|
||||
?: return
|
||||
val set = ConstraintSet()
|
||||
set.clone(constraintLayout)
|
||||
|
||||
set.connect(
|
||||
R.id.local_participant_background,
|
||||
ConstraintSet.BOTTOM,
|
||||
R.id.conference_constraint_layout,
|
||||
ConstraintSet.BOTTOM,
|
||||
0
|
||||
)
|
||||
set.connect(
|
||||
R.id.local_participant_background,
|
||||
ConstraintSet.END,
|
||||
R.id.conference_constraint_layout,
|
||||
ConstraintSet.END,
|
||||
0
|
||||
)
|
||||
set.connect(
|
||||
R.id.local_participant_background,
|
||||
ConstraintSet.TOP,
|
||||
R.id.top_barrier,
|
||||
ConstraintSet.BOTTOM,
|
||||
0
|
||||
)
|
||||
set.connect(
|
||||
R.id.local_participant_background,
|
||||
ConstraintSet.START,
|
||||
R.id.conference_constraint_layout,
|
||||
ConstraintSet.START,
|
||||
0
|
||||
)
|
||||
|
||||
set.constrainWidth(R.id.local_participant_background, 0)
|
||||
set.constrainHeight(R.id.local_participant_background, 0)
|
||||
|
||||
if (corePreferences.enableAnimations) {
|
||||
animateConstraintLayout(constraintLayout, set)
|
||||
} else {
|
||||
set.applyTo(constraintLayout)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
package org.linphone.activities.voip.viewmodels
|
||||
|
||||
import androidx.lifecycle.MediatorLiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
|
@ -45,13 +46,17 @@ class ConferenceViewModel : ViewModel() {
|
|||
val conferenceParticipants = MutableLiveData<List<ConferenceParticipantData>>()
|
||||
val conferenceParticipantDevices = MutableLiveData<List<ConferenceParticipantDeviceData>>()
|
||||
val conferenceDisplayMode = MutableLiveData<ConferenceDisplayMode>()
|
||||
val activeSpeakerConferenceParticipantDevices = MediatorLiveData<List<ConferenceParticipantDeviceData>>()
|
||||
|
||||
val isRecording = MutableLiveData<Boolean>()
|
||||
val isRemotelyRecorded = MutableLiveData<Boolean>()
|
||||
|
||||
val maxParticipantsForMosaicLayout = corePreferences.maxConferenceParticipantsForMosaicLayout
|
||||
|
||||
val moreThanTwoParticipants = MutableLiveData<Boolean>()
|
||||
|
||||
val speakingParticipant = MutableLiveData<ConferenceParticipantDeviceData>()
|
||||
val meParticipant = MutableLiveData<ConferenceParticipantDeviceData>()
|
||||
|
||||
val participantAdminStatusChangedEvent: MutableLiveData<Event<ConferenceParticipantData>> by lazy {
|
||||
MutableLiveData<Event<ConferenceParticipantData>>()
|
||||
|
@ -65,6 +70,14 @@ class ConferenceViewModel : ViewModel() {
|
|||
MutableLiveData<Event<Boolean>>()
|
||||
}
|
||||
|
||||
val secondParticipantJoinedEvent: MutableLiveData<Event<Boolean>> by lazy {
|
||||
MutableLiveData<Event<Boolean>>()
|
||||
}
|
||||
|
||||
val moreThanTwoParticipantsJoinedEvent: MutableLiveData<Event<Boolean>> by lazy {
|
||||
MutableLiveData<Event<Boolean>>()
|
||||
}
|
||||
|
||||
private val conferenceListener = object : ConferenceListenerStub() {
|
||||
override fun onParticipantAdded(conference: Conference, participant: Participant) {
|
||||
Log.i("[Conference] Participant added: ${participant.address.asStringUriOnly()}")
|
||||
|
@ -77,11 +90,6 @@ class ConferenceViewModel : ViewModel() {
|
|||
|
||||
if (conferenceParticipants.value.orEmpty().isEmpty()) {
|
||||
allParticipantsLeftEvent.value = Event(true)
|
||||
// TODO: FIXME: Temporary workaround when alone in a conference in active speaker layout
|
||||
val meDeviceData = conferenceParticipantDevices.value.orEmpty().firstOrNull()
|
||||
if (meDeviceData != null) {
|
||||
speakingParticipant.value = meDeviceData!!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,6 +99,12 @@ class ConferenceViewModel : ViewModel() {
|
|||
) {
|
||||
Log.i("[Conference] Participant device added: ${participantDevice.address.asStringUriOnly()}")
|
||||
addParticipantDevice(participantDevice)
|
||||
|
||||
if (conferenceParticipantDevices.value.orEmpty().size == 2) {
|
||||
secondParticipantJoinedEvent.value = Event(true)
|
||||
} else if (conferenceParticipantDevices.value.orEmpty().size == 3) {
|
||||
moreThanTwoParticipantsJoinedEvent.value = Event(true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onParticipantDeviceRemoved(
|
||||
|
@ -99,6 +113,10 @@ class ConferenceViewModel : ViewModel() {
|
|||
) {
|
||||
Log.i("[Conference] Participant device removed: ${participantDevice.address.asStringUriOnly()}")
|
||||
removeParticipantDevice(participantDevice)
|
||||
|
||||
if (conferenceParticipantDevices.value.orEmpty().size == 2) {
|
||||
secondParticipantJoinedEvent.value = Event(true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onParticipantAdminStatusChanged(
|
||||
|
@ -208,6 +226,9 @@ class ConferenceViewModel : ViewModel() {
|
|||
|
||||
conferenceParticipants.value = arrayListOf()
|
||||
conferenceParticipantDevices.value = arrayListOf()
|
||||
activeSpeakerConferenceParticipantDevices.addSource(conferenceParticipantDevices) {
|
||||
activeSpeakerConferenceParticipantDevices.value = conferenceParticipantDevices.value.orEmpty().drop(1)
|
||||
}
|
||||
|
||||
subject.value = AppUtils.getString(R.string.conference_default_title)
|
||||
|
||||
|
@ -240,6 +261,7 @@ class ConferenceViewModel : ViewModel() {
|
|||
|
||||
conferenceParticipants.value.orEmpty().forEach(ConferenceParticipantData::destroy)
|
||||
conferenceParticipantDevices.value.orEmpty().forEach(ConferenceParticipantDeviceData::destroy)
|
||||
activeSpeakerConferenceParticipantDevices.value.orEmpty().forEach(ConferenceParticipantDeviceData::destroy)
|
||||
|
||||
super.onCleared()
|
||||
}
|
||||
|
@ -283,7 +305,13 @@ class ConferenceViewModel : ViewModel() {
|
|||
if (conferenceParticipants.value.orEmpty().isEmpty()) {
|
||||
firstToJoinEvent.value = Event(true)
|
||||
}
|
||||
|
||||
updateParticipantsDevicesList(conference)
|
||||
if (conferenceParticipantDevices.value.orEmpty().size == 2) {
|
||||
secondParticipantJoinedEvent.value = Event(true)
|
||||
} else if (conferenceParticipantDevices.value.orEmpty().size > 2) {
|
||||
moreThanTwoParticipantsJoinedEvent.value = Event(true)
|
||||
}
|
||||
|
||||
isConferenceLocallyPaused.value = !conference.isIn
|
||||
isMeAdmin.value = conference.me.isAdmin
|
||||
|
@ -371,6 +399,8 @@ class ConferenceViewModel : ViewModel() {
|
|||
|
||||
conferenceParticipants.value.orEmpty().forEach(ConferenceParticipantData::destroy)
|
||||
conferenceParticipantDevices.value.orEmpty().forEach(ConferenceParticipantDeviceData::destroy)
|
||||
activeSpeakerConferenceParticipantDevices.value.orEmpty().forEach(ConferenceParticipantDeviceData::destroy)
|
||||
|
||||
conferenceParticipants.value = arrayListOf()
|
||||
conferenceParticipantDevices.value = arrayListOf()
|
||||
}
|
||||
|
@ -394,6 +424,7 @@ class ConferenceViewModel : ViewModel() {
|
|||
|
||||
private fun updateParticipantsDevicesList(conference: Conference) {
|
||||
conferenceParticipantDevices.value.orEmpty().forEach(ConferenceParticipantDeviceData::destroy)
|
||||
activeSpeakerConferenceParticipantDevices.value.orEmpty().forEach(ConferenceParticipantDeviceData::destroy)
|
||||
val devices = arrayListOf<ConferenceParticipantDeviceData>()
|
||||
|
||||
val participantsList = conference.participantList
|
||||
|
@ -415,14 +446,12 @@ class ConferenceViewModel : ViewModel() {
|
|||
for (device in conference.me.devices) {
|
||||
Log.i("[Conference] Participant device for myself found: ${device.name} (${device.address.asStringUriOnly()})")
|
||||
val deviceData = ConferenceParticipantDeviceData(device, true)
|
||||
if (devices.isEmpty()) {
|
||||
// TODO: FIXME: Temporary workaround when alone in a conference in active speaker layout
|
||||
speakingParticipant.value = deviceData
|
||||
}
|
||||
devices.add(deviceData)
|
||||
meParticipant.value = deviceData
|
||||
}
|
||||
|
||||
conferenceParticipantDevices.value = devices
|
||||
moreThanTwoParticipants.value = devices.size > 2
|
||||
}
|
||||
|
||||
private fun addParticipantDevice(device: ParticipantDevice) {
|
||||
|
@ -448,6 +477,7 @@ class ConferenceViewModel : ViewModel() {
|
|||
}
|
||||
|
||||
conferenceParticipantDevices.value = sortedDevices
|
||||
moreThanTwoParticipants.value = sortedDevices.size > 2
|
||||
}
|
||||
|
||||
private fun removeParticipantDevice(device: ParticipantDevice) {
|
||||
|
@ -456,6 +486,8 @@ class ConferenceViewModel : ViewModel() {
|
|||
for (participantDevice in conferenceParticipantDevices.value.orEmpty()) {
|
||||
if (participantDevice.participantDevice.address.asStringUriOnly() != device.address.asStringUriOnly()) {
|
||||
devices.add(participantDevice)
|
||||
} else {
|
||||
participantDevice.destroy()
|
||||
}
|
||||
}
|
||||
if (devices.size == conferenceParticipantDevices.value.orEmpty().size) {
|
||||
|
@ -465,6 +497,7 @@ class ConferenceViewModel : ViewModel() {
|
|||
}
|
||||
|
||||
conferenceParticipantDevices.value = devices
|
||||
moreThanTwoParticipants.value = devices.size > 2
|
||||
}
|
||||
|
||||
private fun sortDevicesDataList(devices: List<ConferenceParticipantDeviceData>): ArrayList<ConferenceParticipantDeviceData> {
|
||||
|
|
|
@ -75,7 +75,7 @@ class ControlsViewModel : ViewModel() {
|
|||
|
||||
val proximitySensorEnabled = MediatorLiveData<Boolean>()
|
||||
|
||||
val showTakeSnaptshotButton = MutableLiveData<Boolean>()
|
||||
val showTakeSnapshotButton = MutableLiveData<Boolean>()
|
||||
|
||||
val goToConferenceParticipantsListEvent: MutableLiveData<Event<Boolean>> by lazy {
|
||||
MutableLiveData<Event<Boolean>>()
|
||||
|
@ -436,14 +436,15 @@ class ControlsViewModel : ViewModel() {
|
|||
}
|
||||
|
||||
isVideoEnabled.value = enabled
|
||||
showTakeSnaptshotButton.value = enabled && corePreferences.showScreenshotButton
|
||||
isSwitchCameraAvailable.value = enabled && coreContext.showSwitchCameraButton()
|
||||
isSendingVideo.value = if (coreContext.core.currentCall?.conference != null) {
|
||||
showTakeSnapshotButton.value = enabled && corePreferences.showScreenshotButton
|
||||
var isVideoBeingSent = if (coreContext.core.currentCall?.conference != null) {
|
||||
val videoDirection = coreContext.core.currentCall?.currentParams?.videoDirection
|
||||
videoDirection == MediaDirection.SendRecv || videoDirection == MediaDirection.SendOnly
|
||||
} else {
|
||||
true
|
||||
}
|
||||
isSendingVideo.value = isVideoBeingSent
|
||||
isSwitchCameraAvailable.value = enabled && coreContext.showSwitchCameraButton() && isVideoBeingSent
|
||||
}
|
||||
|
||||
private fun shouldProximitySensorBeEnabled(): Boolean {
|
||||
|
|
|
@ -337,11 +337,18 @@ private suspend fun loadContactPictureWithCoil(
|
|||
size: Int = 0,
|
||||
textSize: Int = 0,
|
||||
color: Int = 0,
|
||||
textColor: Int = 0
|
||||
textColor: Int = 0,
|
||||
defaultAvatar: String? = null
|
||||
) {
|
||||
val context = imageView.context
|
||||
if (contact == null) {
|
||||
imageView.load(R.drawable.icon_single_contact_avatar)
|
||||
if (defaultAvatar != null) {
|
||||
imageView.load(defaultAvatar) {
|
||||
transformations(CircleCropTransformation())
|
||||
}
|
||||
} else {
|
||||
imageView.load(R.drawable.icon_single_contact_avatar)
|
||||
}
|
||||
} else if (contact.showGroupChatAvatar) {
|
||||
imageView.load(AppCompatResources.getDrawable(context, R.drawable.icon_multiple_contacts_avatar))
|
||||
} else {
|
||||
|
@ -430,6 +437,21 @@ fun loadVoipContactPictureWithCoil(imageView: ImageView, contact: ContactDataInt
|
|||
}
|
||||
}
|
||||
|
||||
@BindingAdapter("coilSelfAvatar")
|
||||
fun loadSelfAvatarWithCoil(imageView: ImageView, contact: ContactDataInterface?) {
|
||||
val coroutineScope = contact?.coroutineScope ?: coreContext.coroutineScope
|
||||
coroutineScope.launch {
|
||||
withContext(Dispatchers.Main) {
|
||||
loadContactPictureWithCoil(
|
||||
imageView, contact, false,
|
||||
R.dimen.voip_contact_avatar_max_size, R.dimen.voip_contact_avatar_text_size,
|
||||
R.attr.voipBackgroundColor, R.color.white_color,
|
||||
corePreferences.defaultAccountAvatarPath
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter("coilGoneIfError")
|
||||
fun loadAvatarWithCoil(imageView: ImageView, path: String?) {
|
||||
if (path != null) {
|
||||
|
|
|
@ -50,13 +50,6 @@
|
|||
android:orientation="horizontal"
|
||||
app:layout_constraintGuide_percent="1" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="@{controlsViewModel.fullScreenMode || controlsViewModel.pipMode ? View.GONE : View.VISIBLE}"
|
||||
app:constraint_referenced_ids="remote_name,active_conference_timer,toggle_conference_recording,toggle_pause_conference" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/remote_name"
|
||||
style="@style/call_header_title"
|
||||
|
@ -117,11 +110,18 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:visibility="@{conferenceViewModel.isRemotelyRecorded ? View.VISIBLE : View.GONE, default=gone}" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/active_speaker_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="@{conferenceViewModel.conferenceParticipantDevices.size() == 1 ? View.GONE : View.VISIBLE, default=gone}"
|
||||
app:constraint_referenced_ids="active_speaker_background,speaking_participant_avatar,conference_active_speaker_remote_video,speaking_participant_name" />
|
||||
|
||||
<org.linphone.activities.voip.views.ScrollDotsView
|
||||
android:id="@+id/scroll_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="@{controlsViewModel.pipMode ? View.GONE : View.VISIBLE}"
|
||||
android:visibility="@{controlsViewModel.pipMode || !conferenceViewModel.moreThanTwoParticipants ? View.GONE : View.VISIBLE}"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/top_barrier"
|
||||
app:layout_constraintBottom_toBottomOf="@id/hinge_bottom"
|
||||
|
@ -137,9 +137,11 @@
|
|||
android:id="@+id/miniatures"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/top_barrier"
|
||||
android:layout_marginTop="5dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/local_participant_background"
|
||||
app:layout_constraintEnd_toStartOf="@id/scroll_indicator"
|
||||
app:layout_constraintBottom_toBottomOf="@id/hinge_bottom"
|
||||
android:visibility="@{conferenceViewModel.moreThanTwoParticipants ? View.VISIBLE : View.GONE, default=gone}"
|
||||
android:scrollbars="none">
|
||||
|
||||
<com.google.android.flexbox.FlexboxLayout
|
||||
|
@ -147,7 +149,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:alignItems="stretch"
|
||||
app:entries="@{conferenceViewModel.conferenceParticipantDevices}"
|
||||
app:entries="@{conferenceViewModel.activeSpeakerConferenceParticipantDevices}"
|
||||
app:flexDirection="column"
|
||||
app:flexWrap="nowrap"
|
||||
app:justifyContent="flex_start"
|
||||
|
@ -173,6 +175,7 @@
|
|||
android:layout_height="0dp"
|
||||
android:contentDescription="@null"
|
||||
coilVoipContact="@{conferenceViewModel.speakingParticipant}"
|
||||
android:visibility="@{conferenceViewModel.speakingParticipant.isJoining ? View.GONE : View.VISIBLE}"
|
||||
android:background="@drawable/generated_avatar_bg"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintBottom_toBottomOf="@id/active_speaker_background"
|
||||
|
@ -182,6 +185,16 @@
|
|||
app:layout_constraintTop_toTopOf="@id/active_speaker_background"
|
||||
app:layout_constraintWidth_max="@dimen/voip_contact_avatar_max_size" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/speaking_participant_joining"
|
||||
android:layout_width="@dimen/voip_conference_participant_joining_icon_size_active_speaker"
|
||||
android:layout_height="@dimen/voip_conference_participant_joining_icon_size_active_speaker"
|
||||
android:indeterminate="true"
|
||||
android:indeterminateDrawable="@drawable/icon_spinner_rotating"
|
||||
android:visibility="@{conferenceViewModel.speakingParticipant.isJoining ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintLeft_toLeftOf="@id/active_speaker_background"
|
||||
app:layout_constraintTop_toTopOf="@id/active_speaker_background" />
|
||||
|
||||
<org.linphone.activities.voip.views.RoundCornersTextureView
|
||||
android:id="@+id/conference_active_speaker_remote_video"
|
||||
android:layout_width="0dp"
|
||||
|
@ -203,6 +216,109 @@
|
|||
app:layout_constraintBottom_toBottomOf="@id/active_speaker_background"
|
||||
app:layout_constraintStart_toStartOf="@id/active_speaker_background" />
|
||||
|
||||
<View
|
||||
android:id="@+id/local_participant_background"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/top_barrier"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginTop="@{controlsViewModel.fullScreenMode ? @dimen/margin_0dp : @dimen/voip_active_speaker_top_margin, default=@dimen/voip_active_speaker_top_margin}"
|
||||
android:background="@drawable/shape_remote_background"
|
||||
android:onClick="@{() -> controlsViewModel.toggleFullScreen()}"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/local_participant_avatar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_margin="10dp"
|
||||
android:contentDescription="@null"
|
||||
coilSelfAvatar="@{conferenceViewModel.meParticipant}"
|
||||
android:background="@drawable/generated_avatar_bg"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintBottom_toBottomOf="@id/local_participant_background"
|
||||
app:layout_constraintEnd_toEndOf="@id/local_participant_background"
|
||||
app:layout_constraintHeight_max="@dimen/voip_contact_avatar_max_size"
|
||||
app:layout_constraintStart_toStartOf="@id/local_participant_background"
|
||||
app:layout_constraintTop_toTopOf="@id/local_participant_background"
|
||||
app:layout_constraintWidth_max="@dimen/voip_contact_avatar_max_size" />
|
||||
|
||||
<org.linphone.activities.voip.views.RoundCornersTextureView
|
||||
android:id="@+id/local_preview_video_surface"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:alignTopRight="false"
|
||||
app:displayMode="occupy_all_space"
|
||||
android:visibility="@{conferenceViewModel.meParticipant.isInConference && controlsViewModel.isSendingVideo ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintBottom_toBottomOf="@id/local_participant_background"
|
||||
app:layout_constraintEnd_toEndOf="@id/local_participant_background"
|
||||
app:layout_constraintStart_toStartOf="@id/local_participant_background"
|
||||
app:layout_constraintTop_toTopOf="@id/local_participant_background" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/local_participant_name"
|
||||
style="@style/call_remote_name_font"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:text="@{conferenceViewModel.meParticipant.contact.name ?? conferenceViewModel.meParticipant.displayName}"
|
||||
app:layout_constraintBottom_toBottomOf="@id/local_participant_background"
|
||||
app:layout_constraintStart_toStartOf="@id/local_participant_background"
|
||||
app:layout_constraintEnd_toEndOf="@id/local_participant_background"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/switch_camera"
|
||||
android:layout_width="@dimen/conference_miniature_switch_camera_icon_size"
|
||||
android:layout_height="@dimen/conference_miniature_switch_camera_icon_size"
|
||||
android:layout_margin="5dp"
|
||||
android:contentDescription="@string/content_description_switch_camera"
|
||||
android:onClick="@{() -> controlsViewModel.switchCamera()}"
|
||||
android:src="@drawable/icon_call_camera_switch"
|
||||
android:visibility="@{controlsViewModel.isSwitchCameraAvailable && !controlsViewModel.pipMode && !controlsViewModel.fullScreenMode ? View.VISIBLE : View.GONE}"
|
||||
app:layout_constraintEnd_toEndOf="@id/local_participant_background"
|
||||
app:layout_constraintTop_toTopOf="@id/local_participant_background" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/local_participant_speaking_border"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/shape_conference_active_speaker_border"
|
||||
android:visibility="@{conferenceViewModel.meParticipant.isSpeaking ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintBottom_toBottomOf="@id/local_participant_background"
|
||||
app:layout_constraintLeft_toLeftOf="@id/local_participant_background"
|
||||
app:layout_constraintRight_toRightOf="@id/local_participant_background"
|
||||
app:layout_constraintTop_toTopOf="@id/local_participant_background" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/local_participant_muted"
|
||||
android:layout_width="@dimen/voip_conference_participant_mic_muted_icon_size_active_speaker"
|
||||
android:layout_height="@dimen/voip_conference_participant_mic_muted_icon_size_active_speaker"
|
||||
android:layout_margin="5dp"
|
||||
android:background="@drawable/shape_toggle_pressed_background"
|
||||
android:contentDescription="@string/content_description_conference_participant_mic_muted"
|
||||
android:padding="2dp"
|
||||
android:src="@drawable/icon_mic_muted"
|
||||
android:visibility="@{conferenceViewModel.meParticipant.isMuted ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintLeft_toLeftOf="@id/local_participant_background"
|
||||
app:layout_constraintTop_toTopOf="@id/local_participant_background" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/local_participant_paused"
|
||||
android:layout_width="@dimen/voip_conference_active_speaker_miniature_avatar_size"
|
||||
android:layout_height="@dimen/voip_conference_active_speaker_miniature_avatar_size"
|
||||
android:background="@drawable/shape_button_background"
|
||||
android:contentDescription="@string/content_description_participant_is_paused"
|
||||
android:src="@drawable/icon_pause"
|
||||
android:visibility="@{conferenceViewModel.conferenceCreationPending || conferenceViewModel.meParticipant.isInConference || conferenceViewModel.meParticipant.isJoining ? View.GONE : View.VISIBLE, default=gone}"
|
||||
app:layout_constraintBottom_toBottomOf="@id/local_participant_background"
|
||||
app:layout_constraintEnd_toEndOf="@id/local_participant_background"
|
||||
app:layout_constraintStart_toStartOf="@id/local_participant_background"
|
||||
app:layout_constraintTop_toTopOf="@id/local_participant_background" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</layout>
|
|
@ -136,15 +136,26 @@
|
|||
android:layout_margin="10dp"
|
||||
android:contentDescription="@null"
|
||||
coilVoipContact="@{conferenceViewModel.speakingParticipant}"
|
||||
android:visibility="@{conferenceViewModel.speakingParticipant.isJoining ? View.GONE : View.VISIBLE}"
|
||||
android:background="@drawable/generated_avatar_bg"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintBottom_toTopOf="@id/miniatures"
|
||||
app:layout_constraintBottom_toBottomOf="@id/active_speaker_background"
|
||||
app:layout_constraintEnd_toEndOf="@id/active_speaker_background"
|
||||
app:layout_constraintHeight_max="@dimen/voip_contact_avatar_max_size"
|
||||
app:layout_constraintStart_toStartOf="@id/active_speaker_background"
|
||||
app:layout_constraintTop_toBottomOf="@id/top_barrier"
|
||||
app:layout_constraintTop_toTopOf="@id/active_speaker_background"
|
||||
app:layout_constraintWidth_max="@dimen/voip_contact_avatar_max_size" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/speaking_participant_joining"
|
||||
android:layout_width="@dimen/voip_conference_participant_joining_icon_size_active_speaker"
|
||||
android:layout_height="@dimen/voip_conference_participant_joining_icon_size_active_speaker"
|
||||
android:indeterminate="true"
|
||||
android:indeterminateDrawable="@drawable/icon_spinner_rotating"
|
||||
android:visibility="@{conferenceViewModel.speakingParticipant.isJoining ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintLeft_toLeftOf="@id/active_speaker_background"
|
||||
app:layout_constraintTop_toTopOf="@id/active_speaker_background" />
|
||||
|
||||
<org.linphone.activities.voip.views.RoundCornersTextureView
|
||||
android:id="@+id/conference_active_speaker_remote_video"
|
||||
android:layout_width="0dp"
|
||||
|
@ -170,9 +181,11 @@
|
|||
android:id="@+id/miniatures"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginStart="5dp"
|
||||
app:layout_constraintStart_toEndOf="@id/local_participant_background"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/scroll_indicator"
|
||||
android:visibility="@{conferenceViewModel.moreThanTwoParticipants ? View.VISIBLE : View.GONE, default=gone}"
|
||||
android:scrollbars="none">
|
||||
|
||||
<com.google.android.flexbox.FlexboxLayout
|
||||
|
@ -180,7 +193,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
app:alignItems="stretch"
|
||||
app:entries="@{conferenceViewModel.conferenceParticipantDevices}"
|
||||
app:entries="@{conferenceViewModel.activeSpeakerConferenceParticipantDevices}"
|
||||
app:flexDirection="row"
|
||||
app:flexWrap="nowrap"
|
||||
app:justifyContent="flex_start"
|
||||
|
@ -192,7 +205,7 @@
|
|||
android:id="@+id/scroll_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="@{controlsViewModel.pipMode ? View.GONE : View.VISIBLE}"
|
||||
android:visibility="@{controlsViewModel.pipMode || !conferenceViewModel.moreThanTwoParticipants ? View.GONE : View.VISIBLE, default=gone}"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="@id/hinge_bottom"
|
||||
|
@ -204,6 +217,109 @@
|
|||
app:selectedDot="@{0}"
|
||||
app:selectedDotColor="@color/voip_dark_gray" />
|
||||
|
||||
<View
|
||||
android:id="@+id/local_participant_background"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/top_barrier"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginTop="@{controlsViewModel.fullScreenMode ? @dimen/margin_0dp : @dimen/voip_active_speaker_top_margin, default=@dimen/voip_active_speaker_top_margin}"
|
||||
android:background="@drawable/shape_remote_background"
|
||||
android:onClick="@{() -> controlsViewModel.toggleFullScreen()}"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/local_participant_avatar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_margin="10dp"
|
||||
android:contentDescription="@null"
|
||||
coilSelfAvatar="@{conferenceViewModel.meParticipant}"
|
||||
android:background="@drawable/generated_avatar_bg"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintBottom_toBottomOf="@id/local_participant_background"
|
||||
app:layout_constraintEnd_toEndOf="@id/local_participant_background"
|
||||
app:layout_constraintHeight_max="@dimen/voip_contact_avatar_max_size"
|
||||
app:layout_constraintStart_toStartOf="@id/local_participant_background"
|
||||
app:layout_constraintTop_toTopOf="@id/local_participant_background"
|
||||
app:layout_constraintWidth_max="@dimen/voip_contact_avatar_max_size" />
|
||||
|
||||
<org.linphone.activities.voip.views.RoundCornersTextureView
|
||||
android:id="@+id/local_preview_video_surface"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:alignTopRight="false"
|
||||
app:displayMode="occupy_all_space"
|
||||
android:visibility="@{conferenceViewModel.meParticipant.isInConference && controlsViewModel.isSendingVideo ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintBottom_toBottomOf="@id/local_participant_background"
|
||||
app:layout_constraintEnd_toEndOf="@id/local_participant_background"
|
||||
app:layout_constraintStart_toStartOf="@id/local_participant_background"
|
||||
app:layout_constraintTop_toTopOf="@id/local_participant_background" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/local_participant_name"
|
||||
style="@style/call_remote_name_font"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:text="@{conferenceViewModel.meParticipant.contact.name ?? conferenceViewModel.meParticipant.displayName}"
|
||||
app:layout_constraintBottom_toBottomOf="@id/local_participant_background"
|
||||
app:layout_constraintStart_toStartOf="@id/local_participant_background"
|
||||
app:layout_constraintEnd_toEndOf="@id/local_participant_background"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/switch_camera"
|
||||
android:layout_width="@dimen/conference_miniature_switch_camera_icon_size"
|
||||
android:layout_height="@dimen/conference_miniature_switch_camera_icon_size"
|
||||
android:layout_margin="5dp"
|
||||
android:contentDescription="@string/content_description_switch_camera"
|
||||
android:onClick="@{() -> controlsViewModel.switchCamera()}"
|
||||
android:src="@drawable/icon_call_camera_switch"
|
||||
android:visibility="@{controlsViewModel.isSwitchCameraAvailable && !controlsViewModel.pipMode && !controlsViewModel.fullScreenMode ? View.VISIBLE : View.GONE}"
|
||||
app:layout_constraintEnd_toEndOf="@id/local_participant_background"
|
||||
app:layout_constraintTop_toTopOf="@id/local_participant_background" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/local_participant_speaking_border"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/shape_conference_active_speaker_border"
|
||||
android:visibility="@{conferenceViewModel.meParticipant.isSpeaking ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintBottom_toBottomOf="@id/local_participant_background"
|
||||
app:layout_constraintLeft_toLeftOf="@id/local_participant_background"
|
||||
app:layout_constraintRight_toRightOf="@id/local_participant_background"
|
||||
app:layout_constraintTop_toTopOf="@id/local_participant_background" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/local_participant_muted"
|
||||
android:layout_width="@dimen/voip_conference_participant_mic_muted_icon_size_active_speaker"
|
||||
android:layout_height="@dimen/voip_conference_participant_mic_muted_icon_size_active_speaker"
|
||||
android:layout_margin="5dp"
|
||||
android:background="@drawable/shape_toggle_pressed_background"
|
||||
android:contentDescription="@string/content_description_conference_participant_mic_muted"
|
||||
android:padding="2dp"
|
||||
android:src="@drawable/icon_mic_muted"
|
||||
android:visibility="@{conferenceViewModel.meParticipant.isMuted ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintLeft_toLeftOf="@id/local_participant_background"
|
||||
app:layout_constraintTop_toTopOf="@id/local_participant_background" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/local_participant_paused"
|
||||
android:layout_width="@dimen/voip_conference_active_speaker_miniature_avatar_size"
|
||||
android:layout_height="@dimen/voip_conference_active_speaker_miniature_avatar_size"
|
||||
android:background="@drawable/shape_button_background"
|
||||
android:contentDescription="@string/content_description_participant_is_paused"
|
||||
android:src="@drawable/icon_pause"
|
||||
android:visibility="@{conferenceViewModel.conferenceCreationPending || conferenceViewModel.meParticipant.isInConference || conferenceViewModel.meParticipant.isJoining ? View.GONE : View.VISIBLE, default=gone}"
|
||||
app:layout_constraintBottom_toBottomOf="@id/local_participant_background"
|
||||
app:layout_constraintEnd_toEndOf="@id/local_participant_background"
|
||||
app:layout_constraintStart_toStartOf="@id/local_participant_background"
|
||||
app:layout_constraintTop_toTopOf="@id/local_participant_background" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</layout>
|
|
@ -58,8 +58,8 @@
|
|||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
android:layout_width="@dimen/conference_miniature_switch_camera_icon_size"
|
||||
android:layout_height="@dimen/conference_miniature_switch_camera_icon_size"
|
||||
android:layout_margin="5dp"
|
||||
android:contentDescription="@string/content_description_switch_camera"
|
||||
android:onClick="@{() -> data.switchCamera()}"
|
||||
|
|
|
@ -198,7 +198,7 @@
|
|||
android:onClick="@{() -> callsViewModel.takeSnapshot()}"
|
||||
android:enabled="@{!callsViewModel.currentCallData.isPaused && !callsViewModel.currentCallData.isRemotelyPaused}"
|
||||
android:src="@drawable/icon_call_screenshot"
|
||||
android:visibility="@{!controlsViewModel.showTakeSnaptshotButton || controlsViewModel.fullScreenMode || controlsViewModel.pipMode ? View.GONE : View.VISIBLE}"
|
||||
android:visibility="@{!controlsViewModel.showTakeSnapshotButton || controlsViewModel.fullScreenMode || controlsViewModel.pipMode ? View.GONE : View.VISIBLE}"
|
||||
app:layout_constraintStart_toStartOf="@id/background"
|
||||
app:layout_constraintTop_toBottomOf="@id/record_call" />
|
||||
|
||||
|
|
|
@ -78,4 +78,5 @@
|
|||
<dimen name="chat_message_content_preview_max_width">120dp</dimen>
|
||||
<dimen name="voip_conference_active_speaker_dots_margin">5dp</dimen>
|
||||
<dimen name="conference_waiting_room_buttons_max_width">250dp</dimen>
|
||||
<dimen name="conference_miniature_switch_camera_icon_size">25dp</dimen>
|
||||
</resources>
|
Loading…
Reference in a new issue