mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 01:40:07 +01:00
Add additional call links moderation ui.
This commit is contained in:
@@ -11,7 +11,9 @@ import org.signal.ringrtc.GroupCall
|
||||
import org.signal.ringrtc.PeekInfo
|
||||
import org.thoughtcrime.securesms.database.CallLinkTable
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.events.CallParticipant
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.CallLinkRoomId
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState
|
||||
import org.whispersystems.signalservice.api.push.ServiceId
|
||||
@@ -58,18 +60,19 @@ class CallLinkConnectedActionProcessor(
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun handleSetCallLinkJoinRequestAccepted(currentState: WebRtcServiceState, participant: Recipient): WebRtcServiceState {
|
||||
override fun handleSetCallLinkJoinRequestAccepted(currentState: WebRtcServiceState, participant: RecipientId): WebRtcServiceState {
|
||||
Log.i(tag, "handleSetCallLinkJoinRequestAccepted():")
|
||||
|
||||
val groupCall: GroupCall = currentState.callInfoState.requireGroupCall()
|
||||
val recipient = Recipient.resolved(participant)
|
||||
|
||||
return try {
|
||||
groupCall.approveUser(participant.requireAci().rawUuid)
|
||||
groupCall.approveUser(recipient.requireAci().rawUuid)
|
||||
|
||||
currentState
|
||||
.builder()
|
||||
.changeCallInfoState()
|
||||
.setPendingParticipantApproved(participant)
|
||||
.setPendingParticipantApproved(recipient)
|
||||
.build()
|
||||
} catch (e: CallException) {
|
||||
Log.w(tag, "Failed to approve user.", e)
|
||||
@@ -78,22 +81,51 @@ class CallLinkConnectedActionProcessor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleSetCallLinkJoinRequestRejected(currentState: WebRtcServiceState, participant: Recipient): WebRtcServiceState {
|
||||
override fun handleSetCallLinkJoinRequestRejected(currentState: WebRtcServiceState, participant: RecipientId): WebRtcServiceState {
|
||||
Log.i(tag, "handleSetCallLinkJoinRequestRejected():")
|
||||
|
||||
val groupCall: GroupCall = currentState.callInfoState.requireGroupCall()
|
||||
val recipient = Recipient.resolved(participant)
|
||||
|
||||
return try {
|
||||
groupCall.denyUser(participant.requireAci().rawUuid)
|
||||
groupCall.denyUser(recipient.requireAci().rawUuid)
|
||||
|
||||
currentState
|
||||
.builder()
|
||||
.changeCallInfoState()
|
||||
.setPendingParticipantRejected(participant)
|
||||
.setPendingParticipantRejected(recipient)
|
||||
.build()
|
||||
} catch (e: CallException) {
|
||||
Log.w(tag, "Failed to deny user.", e)
|
||||
currentState
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleRemoveFromCallLink(currentState: WebRtcServiceState, participant: CallParticipant): WebRtcServiceState {
|
||||
Log.i(tag, "handleRemoveFromCallLink():")
|
||||
|
||||
val groupCall: GroupCall = currentState.callInfoState.requireGroupCall()
|
||||
|
||||
try {
|
||||
groupCall.removeClient(participant.callParticipantId.demuxId)
|
||||
} catch (e: CallException) {
|
||||
Log.w(tag, "Failed to remove user.", e)
|
||||
}
|
||||
|
||||
return currentState
|
||||
}
|
||||
|
||||
override fun handleBlockFromCallLink(currentState: WebRtcServiceState, participant: CallParticipant): WebRtcServiceState {
|
||||
Log.i(tag, "handleBlockFromCallLink():")
|
||||
|
||||
val groupCall: GroupCall = currentState.callInfoState.requireGroupCall()
|
||||
|
||||
try {
|
||||
groupCall.blockClient(participant.callParticipantId.demuxId)
|
||||
} catch (e: CallException) {
|
||||
Log.w(tag, "Failed to block user.", e)
|
||||
}
|
||||
|
||||
return currentState
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,12 +21,17 @@ data class PendingParticipantCollection(
|
||||
private val nowProvider: () -> Duration = { System.currentTimeMillis().milliseconds }
|
||||
) {
|
||||
|
||||
companion object {
|
||||
private val MAX_DENIALS = 2
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new collection with the given recipients applied to it with the following rules:
|
||||
*
|
||||
* 1. If the recipient is already in the collection, ignore it
|
||||
* 1. Otherwise, insert the recipient at the end of the colleciton in the pending state
|
||||
* 1. Otherwise, insert the recipient at the end of the collection in the pending state
|
||||
* 1. Any recipients in the resulting collection that are [State.PENDING] and NOT in the passed recipient list are removed.
|
||||
* 1. Any recipients in the resulting collection that are [State.DENIED] and have a denial count less than [MAX_DENIALS] is moved to [State.PENDING]
|
||||
*/
|
||||
fun withRecipients(recipients: List<Recipient>): PendingParticipantCollection {
|
||||
val now = nowProvider()
|
||||
@@ -38,25 +43,36 @@ data class PendingParticipantCollection(
|
||||
)
|
||||
}
|
||||
|
||||
val recipientIds = recipients.map { it.id }
|
||||
val newEntryMap = (participantMap + newEntries).filterNot { it.value.state == State.PENDING && it.key !in recipientIds }
|
||||
val submittedIdSet = recipients.map { it.id }.toSet()
|
||||
val newEntryMap = (participantMap + newEntries)
|
||||
.filterNot { it.value.state == State.PENDING && it.key !in submittedIdSet }
|
||||
.mapValues {
|
||||
if (it.value.state == State.DENIED && it.key in submittedIdSet && it.value.denialCount < MAX_DENIALS) {
|
||||
it.value.copy(state = State.PENDING, stateChangeAt = now)
|
||||
} else {
|
||||
it.value
|
||||
}
|
||||
}
|
||||
|
||||
return copy(participantMap = newEntryMap)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new collection with the given recipient marked as [State.APPROVED]
|
||||
* Creates a new collection with the given recipient marked as [State.APPROVED].
|
||||
* Resets the denial count for that recipient.
|
||||
*/
|
||||
fun withApproval(recipient: Recipient): PendingParticipantCollection {
|
||||
val now = nowProvider()
|
||||
val entry = Entry(
|
||||
recipient = recipient,
|
||||
state = State.APPROVED,
|
||||
stateChangeAt = now
|
||||
)
|
||||
val entry = participantMap[recipient.id] ?: return this
|
||||
|
||||
return copy(
|
||||
participantMap = participantMap + (recipient.id to entry)
|
||||
participantMap = participantMap + (
|
||||
recipient.id to entry.copy(
|
||||
denialCount = 0,
|
||||
state = State.APPROVED,
|
||||
stateChangeAt = now
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -65,14 +81,16 @@ data class PendingParticipantCollection(
|
||||
*/
|
||||
fun withDenial(recipient: Recipient): PendingParticipantCollection {
|
||||
val now = nowProvider()
|
||||
val entry = Entry(
|
||||
recipient = recipient,
|
||||
state = State.DENIED,
|
||||
stateChangeAt = now
|
||||
)
|
||||
val entry = participantMap[recipient.id] ?: return this
|
||||
|
||||
return copy(
|
||||
participantMap = participantMap + (recipient.id to entry)
|
||||
participantMap = participantMap + (
|
||||
recipient.id to entry.copy(
|
||||
denialCount = entry.denialCount + 1,
|
||||
state = State.DENIED,
|
||||
stateChangeAt = now
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -103,7 +121,8 @@ data class PendingParticipantCollection(
|
||||
data class Entry(
|
||||
val recipient: Recipient,
|
||||
val state: State,
|
||||
val stateChangeAt: Duration
|
||||
val stateChangeAt: Duration,
|
||||
val denialCount: Int = 0
|
||||
)
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.thoughtcrime.securesms.database.GroupTable;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.GroupRecord;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.events.CallParticipant;
|
||||
import org.thoughtcrime.securesms.events.GroupCallPeekEvent;
|
||||
import org.thoughtcrime.securesms.events.WebRtcViewModel;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
@@ -354,19 +355,19 @@ private void processStateless(@NonNull Function1<WebRtcEphemeralState, WebRtcEph
|
||||
process((s, p) -> p.handleDropCall(s, callId));
|
||||
}
|
||||
|
||||
public void setCallLinkJoinRequestAccepted(@NonNull Recipient participant) {
|
||||
public void setCallLinkJoinRequestAccepted(@NonNull RecipientId participant) {
|
||||
process((s, p) -> p.handleSetCallLinkJoinRequestAccepted(s, participant));
|
||||
}
|
||||
|
||||
public void setCallLinkJoinRequestRejected(@NonNull Recipient participant) {
|
||||
public void setCallLinkJoinRequestRejected(@NonNull RecipientId participant) {
|
||||
process((s, p) -> p.handleSetCallLinkJoinRequestRejected(s, participant));
|
||||
}
|
||||
|
||||
public void removeFromCallLink(@NonNull Recipient participant) {
|
||||
public void removeFromCallLink(@NonNull CallParticipant participant) {
|
||||
process((s, p) -> p.handleRemoveFromCallLink(s, participant));
|
||||
}
|
||||
|
||||
public void blockFromCallLink(@NonNull Recipient participant) {
|
||||
public void blockFromCallLink(@NonNull CallParticipant participant) {
|
||||
process((s, p) -> p.handleBlockFromCallLink(s, participant));
|
||||
}
|
||||
|
||||
|
||||
@@ -877,25 +877,25 @@ public abstract class WebRtcActionProcessor {
|
||||
|
||||
//region Call Links
|
||||
|
||||
protected @NonNull WebRtcServiceState handleSetCallLinkJoinRequestAccepted(@NonNull WebRtcServiceState currentState, @NonNull Recipient participant) {
|
||||
protected @NonNull WebRtcServiceState handleSetCallLinkJoinRequestAccepted(@NonNull WebRtcServiceState currentState, @NonNull RecipientId participant) {
|
||||
Log.i(tag, "handleSetCallLinkJoinRequestAccepted not processed");
|
||||
|
||||
return currentState;
|
||||
}
|
||||
|
||||
protected @NonNull WebRtcServiceState handleSetCallLinkJoinRequestRejected(@NonNull WebRtcServiceState currentState, @NonNull Recipient participant) {
|
||||
protected @NonNull WebRtcServiceState handleSetCallLinkJoinRequestRejected(@NonNull WebRtcServiceState currentState, @NonNull RecipientId participant) {
|
||||
Log.i(tag, "handleSetCallLinkJoinRequestRejected not processed");
|
||||
|
||||
return currentState;
|
||||
}
|
||||
|
||||
protected @NonNull WebRtcServiceState handleRemoveFromCallLink(@NonNull WebRtcServiceState currentState, @NonNull Recipient participant) {
|
||||
protected @NonNull WebRtcServiceState handleRemoveFromCallLink(@NonNull WebRtcServiceState currentState, @NonNull CallParticipant participant) {
|
||||
Log.i(tag, "handleRemoveFromCallLink not processed");
|
||||
|
||||
return currentState;
|
||||
}
|
||||
|
||||
protected @NonNull WebRtcServiceState handleBlockFromCallLink(@NonNull WebRtcServiceState currentState, @NonNull Recipient participant) {
|
||||
protected @NonNull WebRtcServiceState handleBlockFromCallLink(@NonNull WebRtcServiceState currentState, @NonNull CallParticipant participant) {
|
||||
Log.i(tag, "handleBlockFromCallLink not processed");
|
||||
|
||||
return currentState;
|
||||
|
||||
Reference in New Issue
Block a user