mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-05-03 15:11:42 +01:00
Enable remote mute for external users.
This commit is contained in:
@@ -69,7 +69,6 @@ import org.thoughtcrime.securesms.events.GroupCallRaiseHandEvent
|
||||
import org.thoughtcrime.securesms.events.WebRtcViewModel
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.util.RemoteConfig
|
||||
|
||||
/**
|
||||
* Renders information about a call (1:1, group, or call link) and provides actions available for
|
||||
@@ -120,7 +119,6 @@ object CallInfoView {
|
||||
onContactDetails = callbacks::onContactDetails,
|
||||
onViewSafetyNumber = callbacks::onViewSafetyNumber,
|
||||
onGoToChat = callbacks::onGoToChat,
|
||||
isInternalUser = RemoteConfig.internalUser,
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
@@ -169,7 +167,6 @@ private fun CallInfo(
|
||||
onContactDetails: (CallParticipant) -> Unit = {},
|
||||
onViewSafetyNumber: (CallParticipant) -> Unit = {},
|
||||
onGoToChat: (CallParticipant) -> Unit = {},
|
||||
isInternalUser: Boolean = false,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
var selectedParticipant by remember { mutableStateOf<CallParticipant?>(null) }
|
||||
@@ -278,14 +275,10 @@ private fun CallInfo(
|
||||
isSelfAdmin = controlAndInfoState.isSelfAdmin() && !participantsState.inCallLobby,
|
||||
isCallLink = controlAndInfoState.callLink != null,
|
||||
onBlockClicked = onBlock,
|
||||
onParticipantClicked = if (isInternalUser) {
|
||||
{ participant ->
|
||||
if (!participant.recipient.isSelf) {
|
||||
selectedParticipant = participant
|
||||
}
|
||||
onParticipantClicked = { participant ->
|
||||
if (!participant.recipient.isSelf) {
|
||||
selectedParticipant = participant
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14,11 +14,17 @@ import androidx.compose.foundation.pager.VerticalPager
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.movableContentOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.layout.positionInRoot
|
||||
import org.signal.core.ui.compose.AllNightPreviews
|
||||
import org.signal.core.ui.compose.Previews
|
||||
import org.thoughtcrime.securesms.conversation.colors.ChatColorsPalette
|
||||
@@ -33,7 +39,7 @@ fun CallParticipantsPager(
|
||||
pagerState: PagerState,
|
||||
modifier: Modifier = Modifier,
|
||||
onTap: (() -> Unit)? = null,
|
||||
onParticipantLongPress: ((CallParticipant) -> Unit)? = null
|
||||
onParticipantLongPress: ((CallParticipant, Offset) -> Unit)? = null
|
||||
) {
|
||||
if (callParticipantsPagerState.focusedParticipant == null) {
|
||||
return
|
||||
@@ -57,12 +63,15 @@ fun CallParticipantsPager(
|
||||
itemKey = { it.callParticipantId }
|
||||
) { participant, itemModifier ->
|
||||
val longPressModifier = if (!participant.recipient.isSelf && currentOnLongPress.value != null) {
|
||||
itemModifier.pointerInput(participant.callParticipantId) {
|
||||
detectTapGestures(
|
||||
onTap = { currentOnTap.value?.invoke() },
|
||||
onLongPress = { currentOnLongPress.value?.invoke(participant) }
|
||||
)
|
||||
}
|
||||
var itemWindowOrigin by remember(participant.callParticipantId) { mutableStateOf(Offset.Zero) }
|
||||
itemModifier
|
||||
.onGloballyPositioned { coords -> itemWindowOrigin = coords.positionInRoot() }
|
||||
.pointerInput(participant.callParticipantId) {
|
||||
detectTapGestures(
|
||||
onTap = { currentOnTap.value?.invoke() },
|
||||
onLongPress = { local -> currentOnLongPress.value?.invoke(participant, itemWindowOrigin + local) }
|
||||
)
|
||||
}
|
||||
} else {
|
||||
itemModifier
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.statusBarsPadding
|
||||
import androidx.compose.foundation.layout.width
|
||||
@@ -47,6 +48,7 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.layout.onSizeChanged
|
||||
@@ -55,6 +57,7 @@ import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -127,7 +130,6 @@ fun CallScreen(
|
||||
onWifiToCellularPopupDismissed: () -> Unit = {},
|
||||
onSwipeToSpeakerHintDismissed: () -> Unit = {},
|
||||
onRemoteMuteToastDismissed: () -> Unit = {},
|
||||
isInternalUser: Boolean = false,
|
||||
isSelfAdmin: Boolean = false,
|
||||
isCallLink: Boolean = false,
|
||||
onMuteAudio: (CallParticipant) -> Unit = {},
|
||||
@@ -329,13 +331,20 @@ fun CallScreen(
|
||||
}
|
||||
} else if (webRtcCallState.isPassedPreJoin) {
|
||||
var longPressedParticipantId by remember { mutableStateOf<CallParticipantId?>(null) }
|
||||
var longPressWindowOffset by remember { mutableStateOf(Offset.Zero) }
|
||||
var anchorWindowOrigin by remember { mutableStateOf(Offset.Zero) }
|
||||
val longPressedParticipant = longPressedParticipantId?.let { id ->
|
||||
callParticipantsPagerState.callParticipants.find { it.callParticipantId == id }
|
||||
}
|
||||
val density = LocalDensity.current
|
||||
val contextMenuAnchorOffset = remember(longPressWindowOffset, anchorWindowOrigin, density) {
|
||||
val local = longPressWindowOffset - anchorWindowOrigin
|
||||
with(density) { IntOffset(local.x.toInt(), local.y.toInt()) }
|
||||
}
|
||||
|
||||
CallElementsLayout(
|
||||
callGridSlot = {
|
||||
Box {
|
||||
Box(modifier = Modifier.onGloballyPositioned { anchorWindowOrigin = it.positionInRoot() }) {
|
||||
CallParticipantsPager(
|
||||
callParticipantsPagerState = callParticipantsPagerState,
|
||||
pagerState = callScreenController.callParticipantsVerticalPagerState,
|
||||
@@ -356,24 +365,25 @@ fun CallScreen(
|
||||
}
|
||||
}
|
||||
},
|
||||
onParticipantLongPress = if (isInternalUser) {
|
||||
{ participant -> longPressedParticipantId = participant.callParticipantId }
|
||||
} else {
|
||||
null
|
||||
onParticipantLongPress = { participant, windowOffset ->
|
||||
longPressedParticipantId = participant.callParticipantId
|
||||
longPressWindowOffset = windowOffset
|
||||
}
|
||||
)
|
||||
|
||||
ParticipantContextMenu(
|
||||
participant = longPressedParticipant,
|
||||
isSelfAdmin = isSelfAdmin,
|
||||
isCallLink = isCallLink,
|
||||
onDismiss = { longPressedParticipantId = null },
|
||||
onMuteAudio = onMuteAudio,
|
||||
onRemoveFromCall = onRemoveFromCall,
|
||||
onContactDetails = onContactDetails,
|
||||
onViewSafetyNumber = onViewSafetyNumber,
|
||||
onGoToChat = onGoToChat
|
||||
)
|
||||
Box(modifier = Modifier.offset { contextMenuAnchorOffset }) {
|
||||
ParticipantContextMenu(
|
||||
participant = longPressedParticipant,
|
||||
isSelfAdmin = isSelfAdmin,
|
||||
isCallLink = isCallLink,
|
||||
onDismiss = { longPressedParticipantId = null },
|
||||
onMuteAudio = onMuteAudio,
|
||||
onRemoveFromCall = onRemoveFromCall,
|
||||
onContactDetails = onContactDetails,
|
||||
onViewSafetyNumber = onViewSafetyNumber,
|
||||
onGoToChat = onGoToChat
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
pictureInPictureSlot = {
|
||||
|
||||
@@ -49,7 +49,6 @@ import org.thoughtcrime.securesms.reactions.any.ReactWithAnyEmojiBottomSheetDial
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.UpdateCallLinkResult
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcEphemeralState
|
||||
import org.thoughtcrime.securesms.util.RemoteConfig
|
||||
import org.thoughtcrime.securesms.util.WindowUtil
|
||||
import org.thoughtcrime.securesms.webrtc.CallParticipantsViewState
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
@@ -221,7 +220,6 @@ class ComposeCallScreenMediator(private val activity: WebRtcCallActivity, viewMo
|
||||
onSwipeToSpeakerHintDismissed = { callScreenViewModel.callScreenState.update { it.copy(displaySwipeToSpeakerHint = false) } },
|
||||
onRemoteMuteToastDismissed = { callScreenViewModel.callScreenState.update { it.copy(remoteMuteToastMessage = null) } },
|
||||
callParticipantUpdatePopupController = callParticipantUpdatePopupController,
|
||||
isInternalUser = RemoteConfig.internalUser,
|
||||
isSelfAdmin = controlAndInfoState.isSelfAdmin(),
|
||||
isCallLink = controlAndInfoState.callLink != null,
|
||||
onMuteAudio = callInfoCallbacks::onMuteAudio,
|
||||
|
||||
Reference in New Issue
Block a user