diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/OngoingCallScreen.kt b/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/OngoingCallScreen.kt index 799cf3e3e55..0c163499973 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/OngoingCallScreen.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/OngoingCallScreen.kt @@ -50,7 +50,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import com.ramcosta.composedestinations.annotation.Destination @@ -81,6 +80,7 @@ import com.wire.android.ui.common.topappbar.WireCenterAlignedTopAppBar import com.wire.android.ui.theme.wireColorScheme import com.wire.android.ui.theme.wireDimensions import com.wire.android.ui.theme.wireTypography +import com.wire.android.util.ui.PreviewMultipleThemes import com.wire.kalium.logic.data.id.ConversationId import java.util.Locale @@ -250,12 +250,8 @@ private fun OngoingCallContent( onSelfVideoPreviewCreated = setVideoPreview, onSelfClearVideoPreview = clearVideoPreview, requestVideoStreams = requestVideoStreams, - onDoubleTap = { selectedUserId, selectedClientId, isSelf -> - selectedParticipantForFullScreen = SelectedParticipant( - userId = selectedUserId, - clientId = selectedClientId, - isSelfUser = isSelf - ) + onDoubleTap = { selectedParticipant -> + selectedParticipantForFullScreen = selectedParticipant shouldOpenFullScreen = !shouldOpenFullScreen } ) @@ -295,7 +291,9 @@ private fun OngoingCallTopBar( .fillMaxWidth() .offset(y = -(5).dp), textAlign = TextAlign.Center, - text = stringResource(id = R.string.calling_constant_bit_rate_indication).uppercase(Locale.getDefault()), + text = stringResource(id = R.string.calling_constant_bit_rate_indication).uppercase( + Locale.getDefault() + ), color = colorsScheme().secondaryText, style = MaterialTheme.wireTypography.title03, ) @@ -353,8 +351,8 @@ private fun CallingControls( } } +@PreviewMultipleThemes @Composable -@Preview fun PreviewOngoingCallTopBar() { OngoingCallTopBar("Default", true) { } } diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/fullscreen/FullScreenTile.kt b/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/fullscreen/FullScreenTile.kt index b9ac4d8d225..67335ac17fb 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/fullscreen/FullScreenTile.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/fullscreen/FullScreenTile.kt @@ -34,7 +34,6 @@ import androidx.compose.ui.draw.clipToBounds import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel @@ -43,6 +42,7 @@ import com.wire.android.ui.calling.SharedCallingViewModel import com.wire.android.ui.calling.ongoing.OngoingCallViewModel.Companion.DOUBLE_TAP_TOAST_DISPLAY_TIME import com.wire.android.ui.calling.ongoing.participantsview.ParticipantTile import com.wire.android.ui.common.dimensions +import com.wire.android.util.ui.PreviewMultipleThemes import kotlinx.coroutines.delay @Composable @@ -74,6 +74,8 @@ fun FullScreenTile( ), participantTitleState = it, isSelfUser = selectedParticipant.isSelfUser, + isSelfUserCameraOn = selectedParticipant.isSelfUserCameraOn, + isSelfUserMuted = selectedParticipant.isSelfUserMuted, shouldFill = false, isZoomingEnabled = true, onSelfUserVideoPreviewCreated = sharedCallingViewModel::setVideoPreview, @@ -98,7 +100,7 @@ fun FullScreenTile( } } -@Preview +@PreviewMultipleThemes @Composable fun PreviewFullScreenVideoCall() { FullScreenTile( diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/fullscreen/SelectedParticipant.kt b/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/fullscreen/SelectedParticipant.kt index fa7d0f9882a..d6a37fefd21 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/fullscreen/SelectedParticipant.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/fullscreen/SelectedParticipant.kt @@ -22,5 +22,7 @@ import com.wire.kalium.logic.data.user.UserId data class SelectedParticipant( val userId: UserId = UserId("", ""), val clientId: String = "", - val isSelfUser: Boolean = false + val isSelfUser: Boolean = false, + val isSelfUserCameraOn: Boolean = false, + val isSelfUserMuted: Boolean = false ) diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/participantsview/ParticipantTile.kt b/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/participantsview/ParticipantTile.kt index 1a86367f16d..a27fa7f1a7c 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/participantsview/ParticipantTile.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/participantsview/ParticipantTile.kt @@ -79,6 +79,7 @@ import com.wire.android.ui.common.dimensions import com.wire.android.ui.home.conversationslist.model.Membership import com.wire.android.ui.theme.wireColorScheme import com.wire.android.ui.theme.wireTypography +import com.wire.android.util.ui.PreviewMultipleThemes import com.wire.kalium.logic.data.id.QualifiedID @Composable @@ -90,6 +91,8 @@ fun ParticipantTile( isSelfUser: Boolean, shouldFill: Boolean = true, isZoomingEnabled: Boolean = false, + isSelfUserMuted: Boolean, + isSelfUserCameraOn: Boolean, onSelfUserVideoPreviewCreated: (view: View) -> Unit, onClearSelfUserVideoPreview: () -> Unit ) { @@ -114,7 +117,7 @@ fun ParticipantTile( if (isSelfUser) { CameraPreview( - isCameraOn = participantTitleState.isCameraOn, + isCameraOn = isSelfUserCameraOn, onSelfUserVideoPreviewCreated = onSelfUserVideoPreviewCreated, onClearSelfUserVideoPreview = onClearSelfUserVideoPreview ) @@ -139,7 +142,7 @@ fun ParticipantTile( bottom.linkTo(parent.bottom) start.linkTo(parent.start) }, - isMuted = participantTitleState.isMuted, + isMuted = if (isSelfUser) isSelfUserMuted else participantTitleState.isMuted, hasEstablishedAudio = participantTitleState.hasEstablishedAudio ) @@ -216,12 +219,12 @@ private fun CameraPreview( setShouldFill(false) } } - AndroidView(factory = { - val frameLayout = FrameLayout(it) - onSelfUserVideoPreviewCreated(videoPreview) - frameLayout.addView(videoPreview) - frameLayout - }) + AndroidView( + factory = { videoPreview }, + update = { + onSelfUserVideoPreviewCreated(videoPreview) + } + ) } else { onClearSelfUserVideoPreview() } @@ -419,11 +422,13 @@ fun PreviewParticipantTile() { ), onClearSelfUserVideoPreview = {}, onSelfUserVideoPreviewCreated = {}, - isSelfUser = false + isSelfUser = false, + isSelfUserMuted = false, + isSelfUserCameraOn = false ) } -@Preview +@PreviewMultipleThemes @Composable fun PreviewParticipantTalking() { ParticipantTile( @@ -442,11 +447,13 @@ fun PreviewParticipantTalking() { ), onClearSelfUserVideoPreview = {}, onSelfUserVideoPreviewCreated = {}, - isSelfUser = false + isSelfUser = false, + isSelfUserMuted = false, + isSelfUserCameraOn = false ) } -@Preview +@PreviewMultipleThemes @Composable fun PreviewParticipantConnecting() { ParticipantTile( @@ -467,6 +474,8 @@ fun PreviewParticipantConnecting() { ), onClearSelfUserVideoPreview = {}, onSelfUserVideoPreviewCreated = {}, - isSelfUser = false + isSelfUser = false, + isSelfUserMuted = false, + isSelfUserCameraOn = false ) } diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/participantsview/ParticipantsTiles.kt b/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/participantsview/ParticipantsTiles.kt index f4c3b4c23b9..adc282c94e4 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/participantsview/ParticipantsTiles.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/participantsview/ParticipantsTiles.kt @@ -37,19 +37,23 @@ import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.wire.android.ui.calling.model.UICallParticipant +import com.wire.android.ui.calling.ongoing.fullscreen.SelectedParticipant import com.wire.android.ui.calling.ongoing.participantsview.gridview.GroupCallGrid import com.wire.android.ui.calling.ongoing.participantsview.horizentalview.CallingHorizontalView import com.wire.android.ui.common.colorsScheme import com.wire.android.ui.common.dimensions import com.wire.android.ui.theme.wireDimensions -import com.wire.kalium.logic.data.user.UserId +import com.wire.android.util.ui.PreviewMultipleThemes + +private const val MAX_TILES_PER_PAGE = 8 +private const val MAX_ITEMS_FOR_HORIZONTAL_VIEW = 3 @OptIn(ExperimentalFoundationApi::class) @Composable @@ -61,7 +65,7 @@ fun VerticalCallingPager( onSelfVideoPreviewCreated: (view: View) -> Unit, onSelfClearVideoPreview: () -> Unit, requestVideoStreams: (participants: List) -> Unit, - onDoubleTap: (userId: UserId, clientId: String, isSelfUser: Boolean) -> Unit + onDoubleTap: (selectedParticipant: SelectedParticipant) -> Unit ) { Column( modifier = Modifier @@ -78,7 +82,9 @@ fun VerticalCallingPager( ) { pageIndex -> if (participants.isNotEmpty()) { - val participantsChunkedList = participants.chunked(MAX_TILES_PER_PAGE) + val participantsChunkedList = remember(participants) { + participants.chunked(MAX_TILES_PER_PAGE) + } val participantsWithCameraOn by rememberUpdatedState(participants.count { it.isCameraOn }) val participantsWithScreenShareOn by rememberUpdatedState(participants.count { it.isSharingScreen }) @@ -90,14 +96,18 @@ fun VerticalCallingPager( requestVideoStreams(participantsChunkedList[pagerState.currentPage]) } - if (participantsChunkedList[pageIndex].size <= MAX_ITEMS_FOR_ONE_ON_ONE_VIEW) { + if (participantsChunkedList[pageIndex].size <= MAX_ITEMS_FOR_HORIZONTAL_VIEW) { CallingHorizontalView( participants = participantsChunkedList[pageIndex], pageIndex = pageIndex, isSelfUserMuted = isSelfUserMuted, isSelfUserCameraOn = isSelfUserCameraOn, contentHeight = contentHeight, - onSelfVideoPreviewCreated = onSelfVideoPreviewCreated, + onSelfVideoPreviewCreated = { + if (pagerState.currentPage == 0) { + onSelfVideoPreviewCreated(it) + } + }, onSelfClearVideoPreview = onSelfClearVideoPreview, onDoubleTap = onDoubleTap ) @@ -108,7 +118,11 @@ fun VerticalCallingPager( isSelfUserMuted = isSelfUserMuted, isSelfUserCameraOn = isSelfUserCameraOn, contentHeight = contentHeight, - onSelfVideoPreviewCreated = onSelfVideoPreviewCreated, + onSelfVideoPreviewCreated = { + if (pagerState.currentPage == 0) { + onSelfVideoPreviewCreated(it) + } + }, onSelfClearVideoPreview = onSelfClearVideoPreview, onDoubleTap = onDoubleTap ) @@ -152,11 +166,8 @@ private fun pagesCount(size: Int): Int { } else pages } -private const val MAX_TILES_PER_PAGE = 8 -private const val MAX_ITEMS_FOR_ONE_ON_ONE_VIEW = 3 - +@PreviewMultipleThemes @Composable -@Preview fun PreviewVerticalCallingPager() { VerticalCallingPager( participants = listOf(), @@ -166,6 +177,6 @@ fun PreviewVerticalCallingPager() { onSelfVideoPreviewCreated = {}, onSelfClearVideoPreview = {}, requestVideoStreams = {}, - onDoubleTap = { _, _, _ -> } + onDoubleTap = { } ) } diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/participantsview/gridview/CallingGridView.kt b/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/participantsview/gridview/CallingGridView.kt index 79b1729faec..cf1f5a1d098 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/participantsview/gridview/CallingGridView.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/participantsview/gridview/CallingGridView.kt @@ -32,22 +32,20 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.items import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import com.wire.android.ui.calling.ConversationName -import com.wire.android.ui.calling.getConversationName import com.wire.android.ui.calling.model.UICallParticipant +import com.wire.android.ui.calling.ongoing.fullscreen.SelectedParticipant import com.wire.android.ui.calling.ongoing.participantsview.ParticipantTile import com.wire.android.ui.common.dimensions import com.wire.android.ui.home.conversationslist.model.Membership import com.wire.android.ui.theme.wireDimensions import com.wire.kalium.logic.data.id.QualifiedID -import com.wire.kalium.logic.data.user.UserId @OptIn(ExperimentalFoundationApi::class) @Composable @@ -59,7 +57,7 @@ fun GroupCallGrid( contentHeight: Dp, onSelfVideoPreviewCreated: (view: View) -> Unit, onSelfClearVideoPreview: () -> Unit, - onDoubleTap: (userId: UserId, clientId: String, isSelfUser: Boolean) -> Unit + onDoubleTap: (selectedParticipant: SelectedParticipant) -> Unit ) { val config = LocalConfiguration.current @@ -78,17 +76,13 @@ fun GroupCallGrid( ) { participant -> // since we are getting participants by chunk of 8 items, // we need to check that we are on first page for self user - val isSelfUser = pageIndex == 0 && participants.first() == participant - + val isSelfUser = remember(pageIndex, participants.first()) { + pageIndex == 0 && participants.first() == participant + } // We need the number of tiles rows needed to calculate their height - val numberOfTilesRows = tilesRowsCount(participants.size) - val isCameraOn = if (isSelfUser) { - isSelfUserCameraOn - } else participant.isCameraOn - // for self user we don't need to get the muted value from participants list - // if we do, this will show visuals with some delay - val isMuted = if (isSelfUser) isSelfUserMuted - else participant.isMuted + val numberOfTilesRows = remember(participants.size) { + tilesRowsCount(participants.size) + } // if we have more than 6 participants then we reduce avatar size val userAvatarSize = if (participants.size <= 6 || config.screenHeightDp > MIN_SCREEN_HEIGHT) { @@ -96,50 +90,39 @@ fun GroupCallGrid( } else { dimensions().onGoingCallUserAvatarMinimizedSize } - val usernameString = when (val conversationName = getConversationName(participant.name)) { - is ConversationName.Known -> conversationName.name - is ConversationName.Unknown -> stringResource(id = conversationName.resourceId) - } - val participantState = UICallParticipant( - id = participant.id, - clientId = participant.clientId, - name = usernameString, - isMuted = isMuted, - isSpeaking = participant.isSpeaking, - isCameraOn = isCameraOn, - isSharingScreen = participant.isSharingScreen, - avatar = participant.avatar, - membership = participant.membership, - hasEstablishedAudio = participant.hasEstablishedAudio - ) - val tileHeight = (contentHeight - dimensions().spacing4x) / numberOfTilesRows + val spacing4x = dimensions().spacing4x + val tileHeight = remember(numberOfTilesRows) { + (contentHeight - spacing4x) / numberOfTilesRows + } ParticipantTile( modifier = Modifier - .pointerInput(Unit) { + .pointerInput(isSelfUserCameraOn, isSelfUserMuted) { detectTapGestures( onDoubleTap = { - onDoubleTap(participantState.id, participantState.clientId, isSelfUser) + onDoubleTap( + SelectedParticipant( + userId = participant.id, + clientId = participant.clientId, + isSelfUser = isSelfUser, + isSelfUserCameraOn = isSelfUserCameraOn, + isSelfUserMuted = isSelfUserMuted + ) + ) } ) } .height(tileHeight) .animateItemPlacement(tween(durationMillis = 200)), - participantTitleState = participantState, - onGoingCallTileUsernameMaxWidth = MaterialTheme.wireDimensions.onGoingCallTileUsernameMaxWidth, + participantTitleState = participant, + onGoingCallTileUsernameMaxWidth = dimensions().onGoingCallTileUsernameMaxWidth, avatarSize = userAvatarSize, isSelfUser = isSelfUser, - onSelfUserVideoPreviewCreated = { - if (isSelfUser) { - onSelfVideoPreviewCreated(it) - } - }, - onClearSelfUserVideoPreview = { - if (isSelfUser) { - onSelfClearVideoPreview() - } - } + isSelfUserMuted = isSelfUserMuted, + isSelfUserCameraOn = isSelfUserCameraOn, + onSelfUserVideoPreviewCreated = onSelfVideoPreviewCreated, + onClearSelfUserVideoPreview = onSelfClearVideoPreview ) } } @@ -196,6 +179,6 @@ fun PreviewGroupCallGrid() { isSelfUserCameraOn = false, onSelfVideoPreviewCreated = { }, onSelfClearVideoPreview = { }, - onDoubleTap = { _, _, _ -> {} } + onDoubleTap = { } ) } diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/participantsview/horizentalview/CallingHorizontalView.kt b/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/participantsview/horizentalview/CallingHorizontalView.kt index d8bce80b47f..3f3ba87cc6d 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/participantsview/horizentalview/CallingHorizontalView.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/participantsview/horizentalview/CallingHorizontalView.kt @@ -32,17 +32,19 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.Dp -import com.wire.android.ui.calling.ConversationName -import com.wire.android.ui.calling.getConversationName +import androidx.compose.ui.unit.dp import com.wire.android.ui.calling.model.UICallParticipant +import com.wire.android.ui.calling.ongoing.fullscreen.SelectedParticipant import com.wire.android.ui.calling.ongoing.participantsview.ParticipantTile import com.wire.android.ui.common.dimensions +import com.wire.android.ui.home.conversationslist.model.Membership import com.wire.android.ui.theme.wireDimensions -import com.wire.kalium.logic.data.user.UserId +import com.wire.android.util.ui.PreviewMultipleThemes +import com.wire.kalium.logic.data.id.QualifiedID @OptIn(ExperimentalFoundationApi::class) @Composable @@ -54,7 +56,7 @@ fun CallingHorizontalView( contentHeight: Dp, onSelfVideoPreviewCreated: (view: View) -> Unit, onSelfClearVideoPreview: () -> Unit, - onDoubleTap: (userId: UserId, clientId: String, isSelfUser: Boolean) -> Unit + onDoubleTap: (selectedParticipant: SelectedParticipant) -> Unit ) { LazyColumn( @@ -68,62 +70,80 @@ fun CallingHorizontalView( items(items = participants, key = { it.id.toString() + it.clientId }) { participant -> // since we are getting participants by chunk of 8 items, // we need to check that we are on first page for self user - val isSelfUser = pageIndex == 0 && participants.first() == participant - - val isCameraOn = if (isSelfUser) { - isSelfUserCameraOn - } else { - participant.isCameraOn - } - val isMuted = if (isSelfUser) { - isSelfUserMuted - } else { - participant.isMuted + val isSelfUser = remember(pageIndex, participants.first()) { + pageIndex == 0 && participants.first() == participant } - - val username = when (val conversationName = getConversationName(participant.name)) { - is ConversationName.Known -> conversationName.name - is ConversationName.Unknown -> stringResource(id = conversationName.resourceId) + val spacing4x = dimensions().spacing4x + val tileHeight = remember(participants.size) { + (contentHeight - spacing4x) / participants.size } - val participantState = UICallParticipant( - id = participant.id, - clientId = participant.clientId, - name = username, - isMuted = isMuted, - isSpeaking = participant.isSpeaking, - isCameraOn = isCameraOn, - isSharingScreen = participant.isSharingScreen, - avatar = participant.avatar, - membership = participant.membership, - hasEstablishedAudio = participant.hasEstablishedAudio - ) - - val tileHeight = (contentHeight - dimensions().spacing4x) / participants.size - ParticipantTile( modifier = Modifier - .pointerInput(Unit) { + .pointerInput(isSelfUserCameraOn, isSelfUserMuted) { detectTapGestures( onDoubleTap = { - onDoubleTap(participantState.id, participantState.clientId, isSelfUser) + onDoubleTap( + SelectedParticipant( + userId = participant.id, + clientId = participant.clientId, + isSelfUser = isSelfUser, + isSelfUserCameraOn = isSelfUserCameraOn, + isSelfUserMuted = isSelfUserMuted + ) + ) } ) } .fillMaxWidth() .height(tileHeight) .animateItemPlacement(tween(durationMillis = 200)), - participantTitleState = participantState, + participantTitleState = participant, isSelfUser = isSelfUser, - onSelfUserVideoPreviewCreated = { - if (isSelfUser) onSelfVideoPreviewCreated(it) - }, - onClearSelfUserVideoPreview = { - if (isSelfUser) { - onSelfClearVideoPreview() - } - } + isSelfUserMuted = isSelfUserMuted, + isSelfUserCameraOn = isSelfUserCameraOn, + onSelfUserVideoPreviewCreated = onSelfVideoPreviewCreated, + onClearSelfUserVideoPreview = onSelfClearVideoPreview ) } } } + +@PreviewMultipleThemes +@Composable +fun PreviewCallingHorizontalView() { + val participant1 = UICallParticipant( + id = QualifiedID("", ""), + clientId = "client-id", + name = "user name", + isMuted = true, + isSpeaking = false, + isCameraOn = false, + isSharingScreen = false, + avatar = null, + membership = Membership.Admin, + hasEstablishedAudio = true + ) + val participant2 = UICallParticipant( + id = QualifiedID("", ""), + clientId = "client-id", + name = "user name 2", + isMuted = true, + isSpeaking = false, + isCameraOn = false, + isSharingScreen = false, + avatar = null, + membership = Membership.Admin, + hasEstablishedAudio = true + ) + CallingHorizontalView( + participants = listOf(participant1, participant2), + pageIndex = 0, + isSelfUserMuted = true, + isSelfUserCameraOn = false, + contentHeight = 500.dp, + onSelfVideoPreviewCreated = {}, + onSelfClearVideoPreview = {}, + onDoubleTap = { } + ) +}