diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/CallParticipantsState.kt b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/CallParticipantsState.kt index 812e3adad3..513ded5015 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/CallParticipantsState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/CallParticipantsState.kt @@ -55,13 +55,11 @@ data class CallParticipantsState( get() { val results = allRemoteParticipants.asSequence() .filter { it.isHandRaised } - .distinctBy { it.recipient.id } - .map { GroupCallRaiseHandEvent(it.recipient, it.handRaisedTimestamp) } + .map { GroupCallRaiseHandEvent(it, it.handRaisedTimestamp) } .sortedBy { it.timestamp } .toMutableList() if (localParticipant.isHandRaised) { - results.removeIf { it.sender.id == localParticipant.recipient.id } - results.add(GroupCallRaiseHandEvent(localParticipant.recipient, localParticipant.handRaisedTimestamp)) + results.add(GroupCallRaiseHandEvent(localParticipant, localParticipant.handRaisedTimestamp)) } return results.toImmutableList() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/controls/CallInfoView.kt b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/controls/CallInfoView.kt index 4892b7586a..b8e7f21d4a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/controls/CallInfoView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/controls/CallInfoView.kt @@ -130,7 +130,7 @@ private fun CallInfoPreview() { Surface { val remoteParticipants = listOf(CallParticipant(recipient = Recipient.UNKNOWN)) CallInfo( - participantsState = ParticipantsState(remoteParticipants = remoteParticipants, raisedHands = remoteParticipants.map { GroupCallRaiseHandEvent(it.recipient, System.currentTimeMillis()) }), + participantsState = ParticipantsState(remoteParticipants = remoteParticipants, raisedHands = remoteParticipants.map { GroupCallRaiseHandEvent(it, System.currentTimeMillis()) }), controlAndInfoState = ControlAndInfoState(), onShareLinkClicked = { }, onEditNameClicked = { }, @@ -216,11 +216,13 @@ private fun CallInfo( } items( - items = participantsState.raisedHands, - key = { it.sender.id }, - contentType = { null } + items = participantsState.raisedHands.map { it.sender }, + key = { + val key: Long = it.callParticipantId.demuxId // Due to a bug in how the Compose toolchain inlines saveable states, this Long needs to be set into its own variable within the lambda before being returned. + key + } ) { - HandRaisedRow(recipient = it.sender) + HandRaisedRow(recipient = it.recipient, it.getShortRecipientDisplayName(LocalContext.current), it.isSelf && it.isPrimary) } item { @@ -346,7 +348,7 @@ private fun CallParticipantRowPreview() { private fun HandRaisedRowPreview() { SignalTheme(isDarkMode = true) { Surface { - HandRaisedRow(Recipient.UNKNOWN, canLowerHand = true) + HandRaisedRow(Recipient.UNKNOWN, "Peter Parker", canLowerHand = true) } } } @@ -371,10 +373,10 @@ private fun CallParticipantRow( } @Composable -private fun HandRaisedRow(recipient: Recipient, canLowerHand: Boolean = recipient.isSelf) { +private fun HandRaisedRow(recipient: Recipient, name: String, canLowerHand: Boolean) { CallParticipantRow( initialRecipient = recipient, - name = recipient.getShortDisplayName(LocalContext.current), + name = name, showIcons = true, isVideoEnabled = true, isMicrophoneEnabled = true, diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/controls/RaiseHandSnackbar.kt b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/controls/RaiseHandSnackbar.kt index 5b33eb5293..25b8ba76e3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/controls/RaiseHandSnackbar.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/controls/RaiseHandSnackbar.kt @@ -49,8 +49,8 @@ import org.signal.core.ui.theme.SignalTheme import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.webrtc.WebRtcCallViewModel import org.thoughtcrime.securesms.dependencies.AppDependencies +import org.thoughtcrime.securesms.events.CallParticipant import org.thoughtcrime.securesms.events.GroupCallRaiseHandEvent -import org.thoughtcrime.securesms.recipients.Recipient import java.util.concurrent.TimeUnit /** @@ -65,10 +65,20 @@ object RaiseHandSnackbar { fun View(webRtcCallViewModel: WebRtcCallViewModel, showCallInfoListener: () -> Unit, modifier: Modifier = Modifier) { var expansionState by remember { mutableStateOf(ExpansionState(shouldExpand = false, forced = false)) } - val webRtcState by webRtcCallViewModel.callParticipantsState + val raisedHandsState by webRtcCallViewModel.callParticipantsState .toFlowable(BackpressureStrategy.LATEST) .map { state -> - val raisedHands = state.raisedHands.sortedByDescending { it.timestamp } + val raisedHands = state.raisedHands.sortedBy { + if (it.sender.isSelf) { + if (it.sender.isPrimary) { + 0 + } else { + 1 + } + } else { + it.timestamp + } + } val shouldExpand = RaiseHandState.shouldExpand(raisedHands) if (!expansionState.forced) { expansionState = ExpansionState(shouldExpand, false) @@ -78,7 +88,7 @@ object RaiseHandSnackbar { val state by remember { derivedStateOf { - RaiseHandState(raisedHands = webRtcState, expansionState = expansionState) + RaiseHandState(raisedHands = raisedHandsState, expansionState = expansionState) } } @@ -95,7 +105,7 @@ object RaiseHandSnackbar { @Composable private fun RaiseHandSnackbarPreview() { RaiseHand( - state = RaiseHandState(listOf(GroupCallRaiseHandEvent(Recipient.UNKNOWN, System.currentTimeMillis()))) + state = RaiseHandState(listOf(GroupCallRaiseHandEvent(CallParticipant.EMPTY, System.currentTimeMillis()))) ) } @@ -154,8 +164,7 @@ private fun RaiseHand( .padding(vertical = 16.dp) ) if (state.isExpanded) { - if (state.raisedHands.first().sender.isSelf) { - val context = LocalContext.current + if (state.raisedHands.any { it.sender.isSelf && it.sender.isPrimary }) { TextButton( onClick = { AppDependencies.signalCallManager.raiseHand(false) @@ -188,18 +197,13 @@ private fun getSnackbarText(state: RaiseHandState): String { return if (!state.isExpanded) { pluralStringResource(id = R.plurals.CallRaiseHandSnackbar_raised_hands, count = state.raisedHands.size, getShortDisplayName(state.raisedHands), state.raisedHands.size - 1) } else { - pluralStringResource(id = R.plurals.CallOverflowPopupWindow__raised_a_hand, count = state.raisedHands.size, state.raisedHands.first().sender.getShortDisplayName(LocalContext.current), state.raisedHands.size - 1) + pluralStringResource(id = R.plurals.CallOverflowPopupWindow__raised_a_hand, count = state.raisedHands.size, state.raisedHands.first().sender.getShortRecipientDisplayName(LocalContext.current), state.raisedHands.size - 1) } } @Composable private fun getShortDisplayName(raisedHands: List): String { - val recipient = raisedHands.first().sender - return if (recipient.isSelf) { - stringResource(id = R.string.CallParticipant__you) - } else { - recipient.getShortDisplayName(LocalContext.current) - } + return raisedHands.first().sender.getShortRecipientDisplayName(LocalContext.current) } private data class RaiseHandState( diff --git a/app/src/main/java/org/thoughtcrime/securesms/events/GroupCallRaiseHandEvent.kt b/app/src/main/java/org/thoughtcrime/securesms/events/GroupCallRaiseHandEvent.kt index 3356117f08..2996f4abf5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/events/GroupCallRaiseHandEvent.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/events/GroupCallRaiseHandEvent.kt @@ -5,10 +5,10 @@ package org.thoughtcrime.securesms.events -import org.thoughtcrime.securesms.recipients.Recipient import java.util.concurrent.TimeUnit -data class GroupCallRaiseHandEvent(val sender: Recipient, val timestamp: Long) { +data class GroupCallRaiseHandEvent(val sender: CallParticipant, val timestamp: Long) { + fun getCollapseTimestamp(): Long { return timestamp + TimeUnit.SECONDS.toMillis(LIFESPAN_SECONDS) }