From 9f01d7cf67f628fa1554672f9fc06397b0b256de Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Mon, 3 Mar 2025 09:08:04 -0400 Subject: [PATCH] Add reactions feed to compose calling screen. --- .../components/webrtc/v2/CallScreen.kt | 9 +++- .../webrtc/v2/CallScreenReactionsContainer.kt | 47 +++++++++++++++++++ .../webrtc/v2/ComposeCallScreenMediator.kt | 1 + 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/CallScreenReactionsContainer.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/CallScreen.kt b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/CallScreen.kt index 40b5542227..ff6e3b4a53 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/CallScreen.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/CallScreen.kt @@ -60,6 +60,7 @@ import org.signal.core.ui.TriggerAlignedPopupState import org.signal.core.util.DimensionUnit import org.thoughtcrime.securesms.components.webrtc.WebRtcLocalRenderState import org.thoughtcrime.securesms.events.CallParticipant +import org.thoughtcrime.securesms.events.GroupCallReactionEvent import org.thoughtcrime.securesms.events.WebRtcViewModel import org.thoughtcrime.securesms.recipients.Recipient import kotlin.math.max @@ -94,6 +95,7 @@ fun CallScreen( localParticipant: CallParticipant, localRenderState: WebRtcLocalRenderState, callScreenDialogType: CallScreenDialogType, + reactions: List, callInfoView: @Composable (Float) -> Unit, raiseHandSnackbar: @Composable (Modifier) -> Unit, onNavigationClick: () -> Unit, @@ -234,6 +236,10 @@ fun CallScreen( callScreenController = callScreenController ) } + + CallScreenReactionsContainer( + reactions = reactions + ) } val onCallInfoClick: () -> Unit = { @@ -545,7 +551,8 @@ private fun CallScreenPreview() { onNavigationClick = {}, onLocalPictureInPictureClicked = {}, overflowParticipants = emptyList(), - onControlsToggled = {} + onControlsToggled = {}, + reactions = emptyList() ) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/CallScreenReactionsContainer.kt b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/CallScreenReactionsContainer.kt new file mode 100644 index 0000000000..e1fa3b77ce --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/CallScreenReactionsContainer.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2025 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +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 +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView +import androidx.recyclerview.widget.LinearLayoutManager +import org.thoughtcrime.securesms.components.recyclerview.NoTouchingRecyclerView +import org.thoughtcrime.securesms.components.webrtc.WebRtcReactionsAlphaItemDecoration +import org.thoughtcrime.securesms.components.webrtc.WebRtcReactionsItemAnimator +import org.thoughtcrime.securesms.components.webrtc.WebRtcReactionsRecyclerAdapter +import org.thoughtcrime.securesms.events.GroupCallReactionEvent + +/** + * Displays a list of reactions sent during a group call. + * + * Due to how LazyColumn deals with touch events and how Column doesn't have proper + * per-item animation support, we utilize a recycler view as we do in the old call + * screen. + */ +@Composable +fun CallScreenReactionsContainer( + reactions: List +) { + val adapter = remember { WebRtcReactionsRecyclerAdapter() } + AndroidView(factory = { + val view = NoTouchingRecyclerView(it) + view.layoutManager = LinearLayoutManager(it, LinearLayoutManager.VERTICAL, true) + view.adapter = adapter + view.addItemDecoration(WebRtcReactionsAlphaItemDecoration()) + view.itemAnimator = WebRtcReactionsItemAnimator() + view.isClickable = false + view.isVerticalScrollBarEnabled = false + + view + }, modifier = Modifier.fillMaxSize().padding(16.dp).padding(bottom = 16.dp)) { + adapter.submitList(reactions.toMutableList()) + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/ComposeCallScreenMediator.kt b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/ComposeCallScreenMediator.kt index 078b7fbf80..6ba115e8b5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/ComposeCallScreenMediator.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/ComposeCallScreenMediator.kt @@ -133,6 +133,7 @@ class ComposeCallScreenMediator(private val activity: WebRtcCallActivity, viewMo overflowParticipants = callParticipantsState.listParticipants, localParticipant = callParticipantsState.localParticipant, localRenderState = callParticipantsState.localRenderState, + reactions = callParticipantsState.reactions, callScreenDialogType = dialog, callInfoView = { CallInfoView.View(