Fix reaction and state bar placement on new call screen.

This commit is contained in:
Alex Hart
2025-11-05 13:24:08 -04:00
committed by Michelle Tang
parent a79a059816
commit 076b78759e
3 changed files with 72 additions and 36 deletions

View File

@@ -27,7 +27,6 @@ import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -54,6 +53,7 @@ import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.events.CallParticipant
import org.thoughtcrime.securesms.events.GroupCallRaiseHandEvent
import org.thoughtcrime.securesms.events.GroupCallSpeechEvent
import org.thoughtcrime.securesms.recipients.Recipient
import java.util.concurrent.TimeUnit
import kotlin.math.max
import kotlin.time.Duration
@@ -69,9 +69,7 @@ object RaiseHandSnackbar {
@Composable
fun View(webRtcCallViewModel: WebRtcCallViewModel, showCallInfoListener: () -> Unit, modifier: Modifier = Modifier) {
var expansionState by remember { mutableStateOf(ExpansionState(shouldExpand = false, forced = false, collapseTimestamp = Duration.ZERO)) }
val raisedHandsState by remember {
val raisedHandsState: List<GroupCallRaiseHandEvent> by remember {
webRtcCallViewModel.callParticipantsState
.map { state ->
val raisedHands = state.raisedHands.sortedBy {
@@ -90,12 +88,17 @@ object RaiseHandSnackbar {
}
}.collectAsState(initial = emptyList())
val speechEvent by webRtcCallViewModel.groupCallSpeechEvents.collectAsStateWithLifecycle()
val speechEvent: GroupCallSpeechEvent? by webRtcCallViewModel.groupCallSpeechEvents.collectAsStateWithLifecycle()
val state by remember {
derivedStateOf {
RaiseHandState(raisedHands = raisedHandsState, expansionState = expansionState, speechEvent = speechEvent)
}
View(raisedHandsState, speechEvent, showCallInfoListener, modifier)
}
@Composable
fun View(raisedHandsState: List<GroupCallRaiseHandEvent>, speechEvent: GroupCallSpeechEvent?, showCallInfoListener: () -> Unit, modifier: Modifier = Modifier) {
var expansionState by remember { mutableStateOf(ExpansionState(shouldExpand = false, forced = false, collapseTimestamp = Duration.ZERO)) }
val state = remember(raisedHandsState, speechEvent, expansionState) {
RaiseHandState(raisedHands = raisedHandsState, expansionState = expansionState, speechEvent = speechEvent)
}
LaunchedEffect(raisedHandsState, speechEvent) {
@@ -119,7 +122,7 @@ object RaiseHandSnackbar {
@Composable
private fun RaiseHandSnackbarPreview() {
RaiseHand(
state = RaiseHandState(listOf(GroupCallRaiseHandEvent(CallParticipant.EMPTY, System.currentTimeMillis())))
state = RaiseHandState(listOf(GroupCallRaiseHandEvent(CallParticipant(recipient = Recipient(isResolving = false, systemContactName = "Miles Morales")), System.currentTimeMillis())))
)
}
@@ -133,19 +136,20 @@ private fun RaiseHand(
AnimatedVisibility(
visible = state.raisedHands.isNotEmpty(),
enter = fadeIn() + expandIn(expandFrom = Alignment.CenterEnd),
exit = shrinkOut(shrinkTowards = Alignment.CenterEnd) + fadeOut()
exit = shrinkOut(shrinkTowards = Alignment.CenterEnd) + fadeOut(),
modifier = modifier
) {
SignalTheme(
isDarkMode = true
) {
Surface(
modifier = modifier
modifier = Modifier
.padding(horizontal = 16.dp)
.clip(shape = RoundedCornerShape(16.dp, 16.dp, 16.dp, 16.dp))
.background(SignalTheme.colors.colorSurface1)
.animateContentSize()
) {
val boxModifier = modifier
val boxModifier = Modifier
.padding(horizontal = 16.dp)
.clickable(
!state.isExpanded,

View File

@@ -75,8 +75,10 @@ import org.signal.core.util.DimensionUnit
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.webrtc.CallParticipantView
import org.thoughtcrime.securesms.components.webrtc.WebRtcLocalRenderState
import org.thoughtcrime.securesms.components.webrtc.controls.RaiseHandSnackbar
import org.thoughtcrime.securesms.conversation.colors.ChatColorsPalette
import org.thoughtcrime.securesms.events.CallParticipant
import org.thoughtcrime.securesms.events.GroupCallRaiseHandEvent
import org.thoughtcrime.securesms.events.GroupCallReactionEvent
import org.thoughtcrime.securesms.events.WebRtcViewModel
import org.thoughtcrime.securesms.recipients.Recipient
@@ -249,11 +251,6 @@ fun CallScreen(
} else Modifier
)
CallScreenReactionsContainer(
reactions = reactions,
modifier = Modifier.padding(bottom = padding)
)
val onCallInfoClick: () -> Unit = {
scope.launch {
if (scaffoldState.bottomSheetState.currentValue == SheetValue.Expanded) {
@@ -291,25 +288,44 @@ fun CallScreen(
)
}
raiseHandSnackbar(Modifier.fillMaxWidth())
AnimatedCallStateUpdate(
callControlsChange = callScreenState.callControlsChange,
// This content lives "above" the controls sheet and includes raised hands, status updates, etc.
Box(
modifier = Modifier
.align(Alignment.BottomCenter)
.fillMaxSize()
.padding(bottom = padding)
.padding(bottom = 20.dp)
)
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(bottom = 20.dp)
) {
CallScreenReactionsContainer(
reactions = reactions,
modifier = Modifier.weight(1f)
)
val state = remember(callScreenState.pendingParticipantsState) {
callScreenState.pendingParticipantsState
}
raiseHandSnackbar(
Modifier
)
}
if (state != null) {
PendingParticipants(
pendingParticipantsState = state,
pendingParticipantsListener = pendingParticipantsListener
AnimatedCallStateUpdate(
callControlsChange = callScreenState.callControlsChange,
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(bottom = 20.dp)
)
val state = remember(callScreenState.pendingParticipantsState) {
callScreenState.pendingParticipantsState
}
if (state != null) {
PendingParticipants(
pendingParticipantsState = state,
pendingParticipantsListener = pendingParticipantsListener
)
}
}
}
}
@@ -649,7 +665,7 @@ private fun CallScreenPreview() {
Previews.Preview {
CallScreen(
callRecipient = Recipient(systemContactName = "Test User"),
webRtcCallState = WebRtcViewModel.State.CALL_PRE_JOIN,
webRtcCallState = WebRtcViewModel.State.CALL_CONNECTED,
isRemoteVideoOffer = false,
isInPipMode = false,
callScreenState = CallScreenState(
@@ -682,7 +698,24 @@ private fun CallScreenPreview() {
callInfoView = {
Text(text = "Call Info View Preview", modifier = Modifier.alpha(it))
},
raiseHandSnackbar = {},
raiseHandSnackbar = {
RaiseHandSnackbar.View(
raisedHandsState = listOf(
GroupCallRaiseHandEvent(
sender = CallParticipant(
recipient = Recipient(
isResolving = false,
systemContactName = "Miles Morales"
)
),
timestampMillis = System.currentTimeMillis()
)
),
speechEvent = null,
showCallInfoListener = {},
modifier = it
)
},
onNavigationClick = {},
onLocalPictureInPictureClicked = {},
overflowParticipants = participants,

View File

@@ -5,7 +5,6 @@
package org.thoughtcrime.securesms.components.webrtc.v2
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
@@ -42,7 +41,7 @@ fun CallScreenReactionsContainer(
view.isVerticalScrollBarEnabled = false
view
}, modifier = modifier.fillMaxSize().padding(16.dp).padding(bottom = 16.dp)) {
}, modifier = modifier.padding(16.dp)) {
adapter.submitList(reactions.toMutableList())
}
}