fix voice only call design by workaround.

For now, instead to measure height mixed from xml and compose, assume a fixed height for the xml views (callInfosLinearLayout and callControls) to limit the grid height.
They is not a nice solution and should be replaced once everything is migrated to compose.

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2025-05-07 10:33:58 +02:00
parent d546046d5b
commit 1136508ba2
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
5 changed files with 46 additions and 31 deletions

View File

@ -960,7 +960,8 @@ class CallActivity : CallBaseActivity() {
MaterialTheme { MaterialTheme {
ParticipantGrid( ParticipantGrid(
participants = participantUiStates.toList(), participants = participantUiStates.toList(),
eglBase = rootEglBase!! eglBase = rootEglBase!!,
isVoiceOnlyCall = isVoiceOnlyCall
) { ) {
animateCallControls(true, 0) animateCallControls(true, 0)
} }

View File

@ -148,7 +148,7 @@ class ParticipantDisplayItem(
isStreamEnabled = isStreamEnabled, isStreamEnabled = isStreamEnabled,
raisedHand = raisedHand?.state == true, raisedHand = raisedHand?.state == true,
avatarUrl = urlForAvatar, avatarUrl = urlForAvatar,
mediaStream = mediaStream, mediaStream = mediaStream
) )
} }

View File

@ -10,11 +10,7 @@ package com.nextcloud.talk.call.components
import android.content.res.Configuration import android.content.res.Configuration
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
@ -36,6 +32,7 @@ fun ParticipantGrid(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
eglBase: EglBase?, eglBase: EglBase?,
participants: List<ParticipantUiState>, participants: List<ParticipantUiState>,
isVoiceOnlyCall: Boolean,
onClick: () -> Unit onClick: () -> Unit
) { ) {
val configuration = LocalConfiguration.current val configuration = LocalConfiguration.current
@ -59,13 +56,21 @@ fun ParticipantGrid(
val rows = ceil(participants.size / columns.toFloat()).toInt() val rows = ceil(participants.size / columns.toFloat()).toInt()
val screenHeight = LocalConfiguration.current.screenHeightDp.dp val heightForNonGridComponents = if (isVoiceOnlyCall) {
// this is a workaround for now. It should ~summarize the height of callInfosLinearLayout and callControls
// Once everything is migrated to jetpack, this workaround should be obsolete or solved in a better way
240.dp
} else {
0.dp
}
val gridHeight = LocalConfiguration.current.screenHeightDp.dp - heightForNonGridComponents
val itemSpacing = 8.dp val itemSpacing = 8.dp
val edgePadding = 8.dp val edgePadding = 8.dp
val totalVerticalSpacing = itemSpacing * (rows - 1) val totalVerticalSpacing = itemSpacing * (rows - 1)
val totalVerticalPadding = edgePadding * 2 val totalVerticalPadding = edgePadding * 2
val availableHeight = screenHeight - totalVerticalSpacing - totalVerticalPadding val availableHeight = gridHeight - totalVerticalSpacing - totalVerticalPadding
val rawItemHeight = availableHeight / rows val rawItemHeight = availableHeight / rows
val itemHeight = maxOf(rawItemHeight, minItemHeight) val itemHeight = maxOf(rawItemHeight, minItemHeight)
@ -74,14 +79,14 @@ fun ParticipantGrid(
columns = GridCells.Fixed(columns), columns = GridCells.Fixed(columns),
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.padding(horizontal = edgePadding) // Only horizontal outer padding here .padding(horizontal = edgePadding)
.clickable { onClick() }, .clickable { onClick() },
verticalArrangement = Arrangement.spacedBy(itemSpacing), verticalArrangement = Arrangement.spacedBy(itemSpacing),
horizontalArrangement = Arrangement.spacedBy(itemSpacing), horizontalArrangement = Arrangement.spacedBy(itemSpacing),
contentPadding = PaddingValues(vertical = edgePadding) // vertical padding handled here contentPadding = PaddingValues(vertical = edgePadding)
) { ) {
items( items(
participants.sortedBy { it.isAudioEnabled }.asReversed(), participants,
key = { it.sessionKey } key = { it.sessionKey }
) { participant -> ) { participant ->
ParticipantTile( ParticipantTile(
@ -100,7 +105,8 @@ fun ParticipantGrid(
fun ParticipantGridPreview() { fun ParticipantGridPreview() {
ParticipantGrid( ParticipantGrid(
participants = getTestParticipants(1), participants = getTestParticipants(1),
eglBase = null eglBase = null,
isVoiceOnlyCall = false
) {} ) {}
} }
@ -109,7 +115,8 @@ fun ParticipantGridPreview() {
fun TwoParticipants() { fun TwoParticipants() {
ParticipantGrid( ParticipantGrid(
participants = getTestParticipants(2), participants = getTestParticipants(2),
eglBase = null eglBase = null,
isVoiceOnlyCall = false
) {} ) {}
} }
@ -118,7 +125,8 @@ fun TwoParticipants() {
fun ThreeParticipants() { fun ThreeParticipants() {
ParticipantGrid( ParticipantGrid(
participants = getTestParticipants(3), participants = getTestParticipants(3),
eglBase = null eglBase = null,
isVoiceOnlyCall = false
) {} ) {}
} }
@ -127,7 +135,8 @@ fun ThreeParticipants() {
fun FourParticipants() { fun FourParticipants() {
ParticipantGrid( ParticipantGrid(
participants = getTestParticipants(4), participants = getTestParticipants(4),
eglBase = null eglBase = null,
isVoiceOnlyCall = false
) {} ) {}
} }
@ -136,7 +145,8 @@ fun FourParticipants() {
fun FiveParticipants() { fun FiveParticipants() {
ParticipantGrid( ParticipantGrid(
participants = getTestParticipants(5), participants = getTestParticipants(5),
eglBase = null eglBase = null,
isVoiceOnlyCall = false
) {} ) {}
} }
@ -145,7 +155,8 @@ fun FiveParticipants() {
fun SevenParticipants() { fun SevenParticipants() {
ParticipantGrid( ParticipantGrid(
participants = getTestParticipants(7), participants = getTestParticipants(7),
eglBase = null eglBase = null,
isVoiceOnlyCall = false
) {} ) {}
} }
@ -154,7 +165,8 @@ fun SevenParticipants() {
fun FiftyParticipants() { fun FiftyParticipants() {
ParticipantGrid( ParticipantGrid(
participants = getTestParticipants(50), participants = getTestParticipants(50),
eglBase = null eglBase = null,
isVoiceOnlyCall = false
) {} ) {}
} }
@ -167,7 +179,8 @@ fun FiftyParticipants() {
fun OneParticipantLandscape() { fun OneParticipantLandscape() {
ParticipantGrid( ParticipantGrid(
participants = getTestParticipants(1), participants = getTestParticipants(1),
eglBase = null eglBase = null,
isVoiceOnlyCall = false
) {} ) {}
} }
@ -180,7 +193,8 @@ fun OneParticipantLandscape() {
fun TwoParticipantsLandscape() { fun TwoParticipantsLandscape() {
ParticipantGrid( ParticipantGrid(
participants = getTestParticipants(2), participants = getTestParticipants(2),
eglBase = null eglBase = null,
isVoiceOnlyCall = false
) {} ) {}
} }
@ -193,7 +207,8 @@ fun TwoParticipantsLandscape() {
fun ThreeParticipantsLandscape() { fun ThreeParticipantsLandscape() {
ParticipantGrid( ParticipantGrid(
participants = getTestParticipants(3), participants = getTestParticipants(3),
eglBase = null eglBase = null,
isVoiceOnlyCall = false
) {} ) {}
} }
@ -206,7 +221,8 @@ fun ThreeParticipantsLandscape() {
fun FourParticipantsLandscape() { fun FourParticipantsLandscape() {
ParticipantGrid( ParticipantGrid(
participants = getTestParticipants(4), participants = getTestParticipants(4),
eglBase = null eglBase = null,
isVoiceOnlyCall = false
) {} ) {}
} }
@ -219,7 +235,8 @@ fun FourParticipantsLandscape() {
fun SevenParticipantsLandscape() { fun SevenParticipantsLandscape() {
ParticipantGrid( ParticipantGrid(
participants = getTestParticipants(7), participants = getTestParticipants(7),
eglBase = null eglBase = null,
isVoiceOnlyCall = false
) {} ) {}
} }
@ -232,7 +249,8 @@ fun SevenParticipantsLandscape() {
fun FiftyParticipantsLandscape() { fun FiftyParticipantsLandscape() {
ParticipantGrid( ParticipantGrid(
participants = getTestParticipants(50), participants = getTestParticipants(50),
eglBase = null eglBase = null,
isVoiceOnlyCall = false
) {} ) {}
} }

View File

@ -33,11 +33,7 @@ import com.nextcloud.talk.call.ParticipantUiState
import org.webrtc.EglBase import org.webrtc.EglBase
@Composable @Composable
fun ParticipantTile( fun ParticipantTile(participant: ParticipantUiState, eglBase: EglBase?, modifier: Modifier = Modifier) {
participant: ParticipantUiState,
eglBase: EglBase?,
modifier: Modifier = Modifier
) {
Box( Box(
modifier = modifier modifier = modifier
.clip(RoundedCornerShape(12.dp)) .clip(RoundedCornerShape(12.dp))
@ -110,7 +106,7 @@ fun ParticipantTilePreview() {
isStreamEnabled = true, isStreamEnabled = true,
raisedHand = true, raisedHand = true,
avatarUrl = "", avatarUrl = "",
mediaStream = null, mediaStream = null
) )
ParticipantTile( ParticipantTile(
participant = participant, participant = participant,

View File

@ -18,7 +18,7 @@ import org.webrtc.SurfaceViewRenderer
@Composable @Composable
fun WebRTCVideoView( fun WebRTCVideoView(
participant: ParticipantUiState, participant: ParticipantUiState,
eglBase: EglBase?, eglBase: EglBase?
) { ) {
AndroidView( AndroidView(
factory = { context -> factory = { context ->