Added audio only conference layout

This commit is contained in:
Sylvain Berfini 2022-02-23 14:02:03 +01:00
parent 8bcb0278ee
commit 97574157ed
8 changed files with 192 additions and 2 deletions

View file

@ -133,6 +133,10 @@ class ConferenceWaitingRoomViewModel : ViewModel() {
}
fun start() {
// Hide menus
audioRoutesSelected.value = false
layoutMenuSelected.value = false
joinInProgress.value = true
joinConferenceEvent.value = Event(callParams)
}

View file

@ -48,6 +48,9 @@ class ConferencesSettingsViewModel : GenericSettingsViewModel() {
labels.add(prefs.getString(R.string.conference_display_mode_mosaic))
layoutValues.add(ConferenceLayout.Grid.toInt())
labels.add(prefs.getString(R.string.conference_display_mode_audio_only))
layoutValues.add(ConferenceLayout.Legacy.toInt()) // TODO: FIXME: Use AudioOnly
layoutLabels.value = labels
layoutIndex.value = layoutValues.indexOf(core.defaultConferenceLayout.toInt())
}

View file

@ -115,6 +115,14 @@ class ActiveCallOrConferenceFragment : GenericFragment<VoipActiveCallOrConferenc
}
}
conferenceViewModel.conferenceAudioOnlyDisplayMode.observe(
viewLifecycleOwner
) {
if (it) {
startTimer(R.id.audio_only_conference_timer)
}
}
conferenceViewModel.conferenceParticipantDevices.observe(
viewLifecycleOwner
) {
@ -239,6 +247,13 @@ class ActiveCallOrConferenceFragment : GenericFragment<VoipActiveCallOrConferenc
startTimer(R.id.grid_conference_timer)
}
binding.stubbedConferenceAudioOnlyLayout.setOnInflateListener { _, inflated ->
Log.i("[Call] Audio only conference layout inflated")
val binding = DataBindingUtil.bind<ViewDataBinding>(inflated)
binding?.lifecycleOwner = viewLifecycleOwner
startTimer(R.id.audio_only_conference_timer)
}
binding.stubbedAudioRoutes.setOnInflateListener { _, inflated ->
val binding = DataBindingUtil.bind<ViewDataBinding>(inflated)
binding?.lifecycleOwner = viewLifecycleOwner

View file

@ -74,6 +74,20 @@ class ConferenceLayoutFragment : GenericFragment<VoipConferenceLayoutFragmentBin
}
}
conferenceViewModel.conferenceAudioOnlyDisplayMode.observe(
viewLifecycleOwner
) {
if (it) {
Log.i("[Conference] Trying to change conference layout to AudioOnly")
val conference = conferenceViewModel.conference.value
if (conference != null) {
conference.layout = ConferenceLayout.Legacy // TODO: FIXME: Use AudioOnly
} else {
Log.e("[Conference] Conference is null in ConferenceViewModel")
}
}
}
conferenceViewModel.conferenceParticipantDevices.observe(
viewLifecycleOwner
) {

View file

@ -64,7 +64,7 @@ class ConferenceViewModel : ViewModel() {
updateParticipantsList(conference)
val count = conferenceParticipants.value.orEmpty().size
if (count > maxParticipantsForMosaicLayout) {
if (count > maxParticipantsForMosaicLayout && conferenceMosaicDisplayMode.value == true) {
Log.w("[Conference] More than $maxParticipantsForMosaicLayout participants ($count), forcing active speaker layout")
conferenceMosaicDisplayMode.value = false
conferenceActiveSpeakerDisplayMode.value = true
@ -292,8 +292,9 @@ class ConferenceViewModel : ViewModel() {
private fun updateConferenceLayout(conference: Conference) {
val layout = conference.layout
conferenceMosaicDisplayMode.value = layout == ConferenceLayout.Grid || layout == ConferenceLayout.Legacy
conferenceMosaicDisplayMode.value = layout == ConferenceLayout.Grid
conferenceActiveSpeakerDisplayMode.value = layout == ConferenceLayout.ActiveSpeaker
conferenceAudioOnlyDisplayMode.value = layout == ConferenceLayout.Legacy // TODO: FIXME: Use AudioOnly layout
Log.i("[Conference] Conference current layout is: $layout")
}

View file

@ -354,6 +354,9 @@ class CoreContext(val context: Context, coreConfig: Config) {
core.isVibrationOnIncomingCallEnabled = true
core.config.setBool("app", "incoming_call_vibration", false)
}
if (core.defaultConferenceLayout == ConferenceLayout.Legacy) {
core.defaultConferenceLayout = ConferenceLayout.ActiveSpeaker
}
initUserCertificates()

View file

@ -59,6 +59,16 @@
app:conferenceViewModel="@{conferenceViewModel}"
app:controlsViewModel="@{controlsViewModel}"/>
<ViewStub
android:id="@+id/stubbed_conference_audio_only_layout"
android:layout="@layout/voip_conference_audio_only"
android:visibility="@{conferenceViewModel.conferenceAudioOnlyDisplayMode &amp;&amp; conferenceViewModel.conferenceExists &amp;&amp; !callsViewModel.currentCallData.isActiveAndNotInConference ? View.VISIBLE : View.GONE, default=gone}"
app:inflatedVisibility="@{conferenceViewModel.conferenceAudioOnlyDisplayMode &amp;&amp; conferenceViewModel.conferenceExists &amp;&amp; !callsViewModel.currentCallData.isActiveAndNotInConference ? View.VISIBLE : View.GONE}"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:conferenceViewModel="@{conferenceViewModel}"
app:controlsViewModel="@{controlsViewModel}"/>
<include
android:id="@+id/remote_layout"
layout="@layout/voip_call"

View file

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<import type="android.view.View" />
<variable
name="conferenceViewModel"
type="org.linphone.activities.voip.viewmodels.ConferenceViewModel" />
<variable
name="controlsViewModel"
type="org.linphone.activities.voip.viewmodels.ControlsViewModel" />
<variable
name="inflatedVisibility"
type="Integer" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="@{inflatedVisibility}">
<LinearLayout
android:id="@+id/header"
android:visibility="@{controlsViewModel.fullScreenMode || controlsViewModel.pipMode ? View.GONE : View.VISIBLE}"
android:layout_width="match_parent"
android:layout_height="@dimen/voip_call_header_height"
android:layout_marginBottom="10dp"
android:layout_alignParentTop="true"
android:gravity="center_vertical"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/call_header_title"
android:maxLines="1"
android:ellipsize="end"
android:text="@{conferenceViewModel.subject, default=@string/conference_default_title}"/>
<Chronometer
android:id="@+id/audio_only_conference_timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/call_header_subtitle" />
</LinearLayout>
<ImageView
android:onClick="@{() -> conferenceViewModel.toggleRecording()}"
android:selected="@{conferenceViewModel.isRecording}"
android:layout_height="40dp"
android:layout_width="40dp"
android:background="@drawable/button_call_recording_background"
android:src="@drawable/icon_call_record"
android:contentDescription="@string/content_description_toggle_recording"
android:padding="7dp"
android:layout_marginEnd="10dp"/>
<ImageView
android:onClick="@{() -> conferenceViewModel.pauseConference()}"
android:selected="@{conferenceViewModel.isConferenceLocallyPaused}"
android:enabled="@{!conferenceViewModel.conferenceCreationPending}"
android:layout_height="40dp"
android:layout_width="40dp"
android:background="@drawable/button_toggle_background"
android:src="@drawable/icon_pause"
android:contentDescription="@string/content_description_pause_call"
android:padding="5dp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/remote_recording"
android:visibility="@{conferenceViewModel.isRemotelyRecorded ? View.VISIBLE : View.GONE, default=gone}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/header"
android:orientation="horizontal"
android:gravity="center"
android:layout_marginBottom="10dp"
android:background="@drawable/shape_remote_recording_background">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/voip_remote_recording"
android:contentDescription="@null"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
style="@style/call_remote_recording_font"
android:layout_marginStart="10dp"
android:text="@string/call_remote_recording"/>
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:background="@drawable/shape_remote_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/remote_recording"
android:layout_above="@id/miniatures">
<include
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="10dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHeight_max="200dp"
app:data="@{conferenceViewModel.speakingParticipant}"
layout="@layout/voip_contact_avatar"/>
<TextView
android:text="@{conferenceViewModel.speakingParticipant.contact.fullName ?? conferenceViewModel.speakingParticipant.displayName}"
style="@style/call_remote_name_font"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginStart="10dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>
</layout>