mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 18:00:02 +01:00
Distinguish between primary and secondary devices in participants list.
This commit is contained in:
committed by
Greyson Parrelli
parent
2d20ceea01
commit
0ccc7e3c06
@@ -1,6 +1,7 @@
|
||||
package org.thoughtcrime.securesms.components.webrtc;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.annimon.stream.Collectors;
|
||||
import com.annimon.stream.Stream;
|
||||
@@ -21,19 +22,19 @@ import java.util.Set;
|
||||
*/
|
||||
public final class CallParticipantListUpdate {
|
||||
|
||||
private final Set<Holder> added;
|
||||
private final Set<Holder> removed;
|
||||
private final Set<Wrapper> added;
|
||||
private final Set<Wrapper> removed;
|
||||
|
||||
CallParticipantListUpdate(@NonNull Set<Holder> added, @NonNull Set<Holder> removed) {
|
||||
CallParticipantListUpdate(@NonNull Set<Wrapper> added, @NonNull Set<Wrapper> removed) {
|
||||
this.added = added;
|
||||
this.removed = removed;
|
||||
}
|
||||
|
||||
public @NonNull Set<Holder> getAdded() {
|
||||
public @NonNull Set<Wrapper> getAdded() {
|
||||
return added;
|
||||
}
|
||||
|
||||
public @NonNull Set<Holder> getRemoved() {
|
||||
public @NonNull Set<Wrapper> getRemoved() {
|
||||
return removed;
|
||||
}
|
||||
|
||||
@@ -68,66 +69,47 @@ public final class CallParticipantListUpdate {
|
||||
public static @NonNull CallParticipantListUpdate computeDeltaUpdate(@NonNull List<CallParticipant> oldList,
|
||||
@NonNull List<CallParticipant> newList)
|
||||
{
|
||||
Set<CallParticipantId> primaries = getPrimaries(oldList, newList);
|
||||
Set<CallParticipantListUpdate.Holder> oldParticipants = Stream.of(oldList)
|
||||
Set<CallParticipantListUpdate.Wrapper> oldParticipants = Stream.of(oldList)
|
||||
.filter(p -> p.getCallParticipantId().getDemuxId() != CallParticipantId.DEFAULT_ID)
|
||||
.map(p -> createHolder(p, primaries.contains(p.getCallParticipantId())))
|
||||
.map(CallParticipantListUpdate::createWrapper)
|
||||
.collect(Collectors.toSet());
|
||||
Set<CallParticipantListUpdate.Holder> newParticipants = Stream.of(newList)
|
||||
Set<CallParticipantListUpdate.Wrapper> newParticipants = Stream.of(newList)
|
||||
.filter(p -> p.getCallParticipantId().getDemuxId() != CallParticipantId.DEFAULT_ID)
|
||||
.map(p -> createHolder(p, primaries.contains(p.getCallParticipantId())))
|
||||
.map(CallParticipantListUpdate::createWrapper)
|
||||
.collect(Collectors.toSet());
|
||||
Set<CallParticipantListUpdate.Holder> added = SetUtil.difference(newParticipants, oldParticipants);
|
||||
Set<CallParticipantListUpdate.Holder> removed = SetUtil.difference(oldParticipants, newParticipants);
|
||||
Set<CallParticipantListUpdate.Wrapper> added = SetUtil.difference(newParticipants, oldParticipants);
|
||||
Set<CallParticipantListUpdate.Wrapper> removed = SetUtil.difference(oldParticipants, newParticipants);
|
||||
|
||||
return new CallParticipantListUpdate(added, removed);
|
||||
}
|
||||
|
||||
static Holder createHolder(@NonNull CallParticipant callParticipant, boolean isPrimary) {
|
||||
return new Holder(callParticipant.getCallParticipantId(), callParticipant.getRecipient(), isPrimary);
|
||||
@VisibleForTesting
|
||||
static Wrapper createWrapper(@NonNull CallParticipant callParticipant) {
|
||||
return new Wrapper(callParticipant);
|
||||
}
|
||||
|
||||
private static @NonNull Set<CallParticipantId> getPrimaries(@NonNull List<CallParticipant> oldList, @NonNull List<CallParticipant> newList) {
|
||||
return Stream.concat(Stream.of(oldList), Stream.of(newList))
|
||||
.map(CallParticipant::getCallParticipantId)
|
||||
.distinctBy(CallParticipantId::getRecipientId)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
static final class Wrapper {
|
||||
private final CallParticipant callParticipant;
|
||||
|
||||
static final class Holder {
|
||||
private final CallParticipantId callParticipantId;
|
||||
private final Recipient recipient;
|
||||
private final boolean isPrimary;
|
||||
|
||||
private Holder(@NonNull CallParticipantId callParticipantId, @NonNull Recipient recipient, boolean isPrimary) {
|
||||
this.callParticipantId = callParticipantId;
|
||||
this.recipient = recipient;
|
||||
this.isPrimary = isPrimary;
|
||||
private Wrapper(@NonNull CallParticipant callParticipant) {
|
||||
this.callParticipant = callParticipant;
|
||||
}
|
||||
|
||||
public @NonNull Recipient getRecipient() {
|
||||
return recipient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Denotes whether this was the first detected instance of this recipient when generating an update. See
|
||||
* {@link CallParticipantListUpdate#computeDeltaUpdate(List, List)}
|
||||
*/
|
||||
public boolean isPrimary() {
|
||||
return isPrimary;
|
||||
public @NonNull CallParticipant getCallParticipant() {
|
||||
return callParticipant;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Holder holder = (Holder) o;
|
||||
return callParticipantId.equals(holder.callParticipantId);
|
||||
Wrapper wrapper = (Wrapper) o;
|
||||
return callParticipant.getCallParticipantId().equals(wrapper.callParticipant.getCallParticipantId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(callParticipantId);
|
||||
return Objects.hash(callParticipant.getCallParticipantId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ public class CallParticipantsListUpdatePopupWindow extends PopupWindow {
|
||||
private final AvatarImageView avatarImageView;
|
||||
private final TextView descriptionTextView;
|
||||
|
||||
private final Set<CallParticipantListUpdate.Holder> pendingAdditions = new HashSet<>();
|
||||
private final Set<CallParticipantListUpdate.Holder> pendingRemovals = new HashSet<>();
|
||||
private final Set<CallParticipantListUpdate.Wrapper> pendingAdditions = new HashSet<>();
|
||||
private final Set<CallParticipantListUpdate.Wrapper> pendingRemovals = new HashSet<>();
|
||||
|
||||
private boolean isEnabled = true;
|
||||
|
||||
@@ -112,18 +112,18 @@ public class CallParticipantsListUpdatePopupWindow extends PopupWindow {
|
||||
avatarImageView.setVisibility(recipient == null ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
private void setDescription(@NonNull Set<CallParticipantListUpdate.Holder> holders, boolean isAdded) {
|
||||
if (holders.isEmpty()) {
|
||||
private void setDescription(@NonNull Set<CallParticipantListUpdate.Wrapper> wrappers, boolean isAdded) {
|
||||
if (wrappers.isEmpty()) {
|
||||
descriptionTextView.setText("");
|
||||
} else {
|
||||
setDescriptionForRecipients(holders, isAdded);
|
||||
setDescriptionForRecipients(wrappers, isAdded);
|
||||
}
|
||||
}
|
||||
|
||||
private void setDescriptionForRecipients(@NonNull Set<CallParticipantListUpdate.Holder> recipients, boolean isAdded) {
|
||||
Iterator<CallParticipantListUpdate.Holder> iterator = recipients.iterator();
|
||||
Context context = getContentView().getContext();
|
||||
String description;
|
||||
private void setDescriptionForRecipients(@NonNull Set<CallParticipantListUpdate.Wrapper> recipients, boolean isAdded) {
|
||||
Iterator<CallParticipantListUpdate.Wrapper> iterator = recipients.iterator();
|
||||
Context context = getContentView().getContext();
|
||||
String description;
|
||||
|
||||
switch (recipients.size()) {
|
||||
case 0:
|
||||
@@ -144,22 +144,14 @@ public class CallParticipantsListUpdatePopupWindow extends PopupWindow {
|
||||
descriptionTextView.setText(description);
|
||||
}
|
||||
|
||||
private @NonNull Recipient getNextRecipient(@NonNull Iterator<CallParticipantListUpdate.Holder> holderIterator) {
|
||||
return holderIterator.next().getRecipient();
|
||||
private @NonNull Recipient getNextRecipient(@NonNull Iterator<CallParticipantListUpdate.Wrapper> wrapperIterator) {
|
||||
return wrapperIterator.next().getCallParticipant().getRecipient();
|
||||
}
|
||||
|
||||
private @NonNull String getNextDisplayName(@NonNull Iterator<CallParticipantListUpdate.Holder> holderIterator) {
|
||||
CallParticipantListUpdate.Holder holder = holderIterator.next();
|
||||
Recipient recipient = holder.getRecipient();
|
||||
private @NonNull String getNextDisplayName(@NonNull Iterator<CallParticipantListUpdate.Wrapper> wrapperIterator) {
|
||||
CallParticipantListUpdate.Wrapper wrapper = wrapperIterator.next();
|
||||
|
||||
if (recipient.isSelf()) {
|
||||
return getContentView().getContext().getString(R.string.CallParticipantsListUpdatePopupWindow__you_on_another_device);
|
||||
} else if (holder.isPrimary()) {
|
||||
return recipient.getDisplayName(getContentView().getContext());
|
||||
} else {
|
||||
return getContentView().getContext().getString(R.string.CallParticipantsListUpdatePopupWindow__s_on_another_device,
|
||||
recipient.getDisplayName(getContentView().getContext()));
|
||||
}
|
||||
return wrapper.getCallParticipant().getRecipientDisplayName(getContentView().getContext());
|
||||
}
|
||||
|
||||
private static @StringRes int getOneMemberDescriptionResourceId(boolean isAdded) {
|
||||
|
||||
@@ -25,8 +25,7 @@ public final class CallParticipantViewState extends RecipientMappingModel<CallPa
|
||||
|
||||
@Override
|
||||
public @NonNull String getName(@NonNull Context context) {
|
||||
return callParticipant.getRecipient().isSelf() ? context.getString(R.string.GroupMembersDialog_you)
|
||||
: super.getName(context);
|
||||
return callParticipant.getRecipientDisplayName(context);
|
||||
}
|
||||
|
||||
public int getVideoMutedVisibility() {
|
||||
|
||||
Reference in New Issue
Block a user