David Liu

tabs for multiple participants

@@ -44,6 +44,7 @@ dependencies { @@ -44,6 +44,7 @@ dependencies {
44 implementation "androidx.viewpager2:viewpager2:1.0.0" 44 implementation "androidx.viewpager2:viewpager2:1.0.0"
45 implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${versions.androidx_lifecycle}" 45 implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${versions.androidx_lifecycle}"
46 implementation "androidx.lifecycle:lifecycle-common-java8:${versions.androidx_lifecycle}" 46 implementation "androidx.lifecycle:lifecycle-common-java8:${versions.androidx_lifecycle}"
  47 + implementation 'com.google.android.material:material:1.3.0'
47 implementation "com.xwray:groupie:${versions.groupie}" 48 implementation "com.xwray:groupie:${versions.groupie}"
48 implementation "com.xwray:groupie-viewbinding:${versions.groupie}" 49 implementation "com.xwray:groupie-viewbinding:${versions.groupie}"
49 implementation 'com.snakydesign.livedataextensions:lives:1.3.0' 50 implementation 'com.snakydesign.livedataextensions:lives:1.3.0'
@@ -5,6 +5,7 @@ import android.os.Bundle @@ -5,6 +5,7 @@ import android.os.Bundle
5 import android.os.Parcelable 5 import android.os.Parcelable
6 import androidx.appcompat.app.AppCompatActivity 6 import androidx.appcompat.app.AppCompatActivity
7 import com.github.ajalt.timberkt.Timber 7 import com.github.ajalt.timberkt.Timber
  8 +import com.google.android.material.tabs.TabLayoutMediator
8 import com.snakydesign.livedataextensions.combineLatest 9 import com.snakydesign.livedataextensions.combineLatest
9 import com.xwray.groupie.GroupieAdapter 10 import com.xwray.groupie.GroupieAdapter
10 import io.livekit.android.sample.databinding.CallActivityBinding 11 import io.livekit.android.sample.databinding.CallActivityBinding
@@ -19,6 +20,7 @@ class CallActivity : AppCompatActivity() { @@ -19,6 +20,7 @@ class CallActivity : AppCompatActivity() {
19 CallViewModel(args.url, args.token, application) 20 CallViewModel(args.url, args.token, application)
20 } 21 }
21 lateinit var binding: CallActivityBinding 22 lateinit var binding: CallActivityBinding
  23 + var tabLayoutMediator: TabLayoutMediator? = null
22 24
23 override fun onCreate(savedInstanceState: Bundle?) { 25 override fun onCreate(savedInstanceState: Bundle?) {
24 super.onCreate(savedInstanceState) 26 super.onCreate(savedInstanceState)
@@ -29,6 +31,7 @@ class CallActivity : AppCompatActivity() { @@ -29,6 +31,7 @@ class CallActivity : AppCompatActivity() {
29 31
30 // Viewpager setup 32 // Viewpager setup
31 val adapter = GroupieAdapter() 33 val adapter = GroupieAdapter()
  34 +
32 binding.viewPager.apply { 35 binding.viewPager.apply {
33 this.adapter = adapter 36 this.adapter = adapter
34 } 37 }
@@ -38,9 +41,19 @@ class CallActivity : AppCompatActivity() { @@ -38,9 +41,19 @@ class CallActivity : AppCompatActivity() {
38 viewModel.remoteParticipants 41 viewModel.remoteParticipants
39 ) { room, participants -> room to participants } 42 ) { room, participants -> room to participants }
40 .observe(this) { 43 .observe(this) {
  44 +
  45 + tabLayoutMediator?.detach()
  46 + tabLayoutMediator = null
  47 +
41 val (room, participants) = it 48 val (room, participants) = it
42 val items = participants.map { participant -> ParticipantItem(room, participant) } 49 val items = participants.map { participant -> ParticipantItem(room, participant) }
43 adapter.update(items) 50 adapter.update(items)
  51 +
  52 + tabLayoutMediator =
  53 + TabLayoutMediator(binding.tabs, binding.viewPager) { tab, position ->
  54 + tab.text = participants[position].name
  55 + }
  56 + tabLayoutMediator?.attach()
44 } 57 }
45 58
46 val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager 59 val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
@@ -60,7 +73,6 @@ class CallActivity : AppCompatActivity() { @@ -60,7 +73,6 @@ class CallActivity : AppCompatActivity() {
60 } 73 }
61 } 74 }
62 75
63 -  
64 companion object { 76 companion object {
65 const val KEY_ARGS = "args" 77 const val KEY_ARGS = "args"
66 } 78 }
@@ -10,6 +10,8 @@ import io.livekit.android.room.track.RemoteVideoTrackPublication @@ -10,6 +10,8 @@ import io.livekit.android.room.track.RemoteVideoTrackPublication
10 import io.livekit.android.room.track.VideoTrack 10 import io.livekit.android.room.track.VideoTrack
11 import io.livekit.android.room.track.VideoTrackPublication 11 import io.livekit.android.room.track.VideoTrackPublication
12 import io.livekit.android.sample.databinding.ParticipantItemBinding 12 import io.livekit.android.sample.databinding.ParticipantItemBinding
  13 +import org.webrtc.VideoFrame
  14 +import org.webrtc.VideoSink
13 15
14 class ParticipantItem( 16 class ParticipantItem(
15 val room: Room, 17 val room: Room,
@@ -61,6 +63,12 @@ class ParticipantItem( @@ -61,6 +63,12 @@ class ParticipantItem(
61 63
62 videoBound = true 64 videoBound = true
63 Timber.v { "adding renderer to $videoTrack" } 65 Timber.v { "adding renderer to $videoTrack" }
  66 + videoTrack.addRenderer(object : VideoSink {
  67 + override fun onFrame(frame: VideoFrame?) {
  68 + Timber.v { "$frame" }
  69 + }
  70 +
  71 + })
64 videoTrack.addRenderer(viewBinding.renderer) 72 videoTrack.addRenderer(viewBinding.renderer)
65 } 73 }
66 74
1 -<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 1 +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2 + xmlns:app="http://schemas.android.com/apk/res-auto"
2 android:layout_width="match_parent" 3 android:layout_width="match_parent"
3 android:layout_height="match_parent"> 4 android:layout_height="match_parent">
4 5
  6 + <com.google.android.material.tabs.TabLayout
  7 + android:id="@+id/tabs"
  8 + android:layout_width="match_parent"
  9 + android:layout_height="48dp"
  10 + app:layout_constraintTop_toTopOf="parent"
  11 + app:tabMode="auto" />
  12 +
5 <androidx.viewpager2.widget.ViewPager2 13 <androidx.viewpager2.widget.ViewPager2
6 android:id="@+id/view_pager" 14 android:id="@+id/view_pager"
7 android:layout_width="match_parent" 15 android:layout_width="match_parent"
8 - android:layout_height="match_parent" /> 16 + android:layout_height="0dp"
  17 + app:layout_constraintBottom_toBottomOf="parent"
  18 + app:layout_constraintTop_toBottomOf="@id/tabs" />
9 19
10 <!-- 20 <!--
11 <org.webrtc.SurfaceViewRenderer 21 <org.webrtc.SurfaceViewRenderer
@@ -15,4 +25,4 @@ @@ -15,4 +25,4 @@
15 android:layout_gravity="bottom|end" 25 android:layout_gravity="bottom|end"
16 android:layout_margin="16dp" /> 26 android:layout_margin="16dp" />
17 --> 27 -->
18 -</FrameLayout> 28 +</androidx.constraintlayout.widget.ConstraintLayout>