mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-30 19:56:14 +00:00
Add pending member activity.
This commit is contained in:
committed by
Greyson Parrelli
parent
ef0f26b64c
commit
1290d0ead9
@@ -150,6 +150,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
|
||||
import org.thoughtcrime.securesms.giph.ui.GiphyActivity;
|
||||
import org.thoughtcrime.securesms.groups.ui.LeaveGroupDialog;
|
||||
import org.thoughtcrime.securesms.groups.ui.pendingmemberinvites.PendingMemberInvitesActivity;
|
||||
import org.thoughtcrime.securesms.insights.InsightsLauncher;
|
||||
import org.thoughtcrime.securesms.invites.InviteReminderModel;
|
||||
import org.thoughtcrime.securesms.invites.InviteReminderRepository;
|
||||
@@ -730,6 +731,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
} else {
|
||||
menu.findItem(R.id.menu_distribution_conversation).setChecked(true);
|
||||
}
|
||||
} else if (isActiveV2Group()) {
|
||||
inflater.inflate(R.menu.conversation_push_group_v2_options, menu);
|
||||
} else if (isActiveGroup()) {
|
||||
inflater.inflate(R.menu.conversation_push_group_options, menu);
|
||||
}
|
||||
@@ -835,6 +838,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
case R.id.menu_distribution_broadcast: handleDistributionBroadcastEnabled(item); return true;
|
||||
case R.id.menu_distribution_conversation: handleDistributionConversationEnabled(item); return true;
|
||||
case R.id.menu_edit_group: handleEditPushGroup(); return true;
|
||||
case R.id.menu_pending_members: handlePendingMembers(); return true;
|
||||
case R.id.menu_leave: handleLeavePushGroup(); return true;
|
||||
case R.id.menu_invite: handleInviteLink(); return true;
|
||||
case R.id.menu_mute_notifications: handleMuteNotifications(); return true;
|
||||
@@ -1130,6 +1134,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
startActivityForResult(intent, GROUP_EDIT);
|
||||
}
|
||||
|
||||
private void handlePendingMembers() {
|
||||
startActivity(PendingMemberInvitesActivity.newIntent(ConversationActivity.this, recipient.get().requireGroupId().requireV2()));
|
||||
}
|
||||
|
||||
private void handleDistributionBroadcastEnabled(MenuItem item) {
|
||||
distributionType = ThreadDatabase.DistributionTypes.BROADCAST;
|
||||
item.setChecked(true);
|
||||
@@ -2108,6 +2116,13 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
return record.isPresent() && record.get().isActive();
|
||||
}
|
||||
|
||||
private boolean isActiveV2Group() {
|
||||
if (!isGroupConversation()) return false;
|
||||
|
||||
Optional<GroupRecord> record = DatabaseFactory.getGroupDatabase(this).getGroup(getRecipient().getId());
|
||||
return record.isPresent() && record.get().isActive() && record.get().isV2Group();
|
||||
}
|
||||
|
||||
@SuppressWarnings("SimplifiableIfStatement")
|
||||
private boolean isSelfConversation() {
|
||||
if (!TextSecurePreferences.isPushRegistered(this)) return false;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.thoughtcrime.securesms.groups;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
|
||||
import org.signal.zkgroup.util.UUIDUtil;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public final class GroupProtoUtil {
|
||||
|
||||
private GroupProtoUtil() {
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public static Recipient pendingMemberToRecipient(@NonNull Context context, @NonNull DecryptedPendingMember pendingMember) {
|
||||
return uuidByteStringToRecipient(context, pendingMember.getUuid());
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public static Recipient uuidByteStringToRecipient(@NonNull Context context, @NonNull ByteString uuidByteString) {
|
||||
UUID uuid = UUIDUtil.deserialize(uuidByteString.toByteArray());
|
||||
|
||||
if (uuid.equals(GroupsV2Operations.UNKNOWN_UUID)) {
|
||||
return Recipient.UNKNOWN;
|
||||
}
|
||||
|
||||
return Recipient.externalPush(context, uuid, null);
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ public abstract class GroupMemberEntry {
|
||||
return onClick;
|
||||
}
|
||||
|
||||
public static class FullMember extends GroupMemberEntry {
|
||||
public final static class FullMember extends GroupMemberEntry {
|
||||
|
||||
private final Recipient member;
|
||||
|
||||
@@ -32,4 +32,40 @@ public abstract class GroupMemberEntry {
|
||||
return member;
|
||||
}
|
||||
}
|
||||
|
||||
public final static class PendingMember extends GroupMemberEntry {
|
||||
private final Recipient invitee;
|
||||
private final byte[] inviteeCipherText;
|
||||
|
||||
public PendingMember(@NonNull Recipient invitee, @NonNull byte[] inviteeCipherText) {
|
||||
this.invitee = invitee;
|
||||
this.inviteeCipherText = inviteeCipherText;
|
||||
}
|
||||
|
||||
public Recipient getInvitee() {
|
||||
return invitee;
|
||||
}
|
||||
|
||||
public byte[] getInviteeCipherText() {
|
||||
return inviteeCipherText;
|
||||
}
|
||||
}
|
||||
|
||||
public final static class UnknownPendingMemberCount extends GroupMemberEntry {
|
||||
private Recipient inviter;
|
||||
private int inviteCount;
|
||||
|
||||
public UnknownPendingMemberCount(@NonNull Recipient inviter, int inviteCount) {
|
||||
this.inviter = inviter;
|
||||
this.inviteCount = inviteCount;
|
||||
}
|
||||
|
||||
public Recipient getInviter() {
|
||||
return inviter;
|
||||
}
|
||||
|
||||
public int getInviteCount() {
|
||||
return inviteCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,9 @@ import java.util.Collection;
|
||||
|
||||
final class GroupMemberListAdapter extends RecyclerView.Adapter<GroupMemberListAdapter.ViewHolder> {
|
||||
|
||||
private static final int FULL_MEMBER = 0;
|
||||
private static final int FULL_MEMBER = 0;
|
||||
private static final int OWN_INVITE_PENDING = 1;
|
||||
private static final int OTHER_INVITE_PENDING_COUNT = 2;
|
||||
|
||||
private final ArrayList<GroupMemberEntry> data = new ArrayList<>();
|
||||
|
||||
@@ -35,6 +37,14 @@ final class GroupMemberListAdapter extends RecyclerView.Adapter<GroupMemberListA
|
||||
return new FullMemberViewHolder(LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.group_recipient_list_item,
|
||||
parent, false));
|
||||
case OWN_INVITE_PENDING:
|
||||
return new OwnInvitePendingMemberViewHolder(LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.group_recipient_list_item,
|
||||
parent, false));
|
||||
case OTHER_INVITE_PENDING_COUNT:
|
||||
return new UnknownPendingMemberCountViewHolder(LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.group_recipient_list_item,
|
||||
parent, false));
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
@@ -51,6 +61,10 @@ final class GroupMemberListAdapter extends RecyclerView.Adapter<GroupMemberListA
|
||||
|
||||
if (groupMemberEntry instanceof GroupMemberEntry.FullMember) {
|
||||
return FULL_MEMBER;
|
||||
} else if (groupMemberEntry instanceof GroupMemberEntry.PendingMember) {
|
||||
return OWN_INVITE_PENDING;
|
||||
} else if (groupMemberEntry instanceof GroupMemberEntry.UnknownPendingMemberCount) {
|
||||
return OTHER_INVITE_PENDING_COUNT;
|
||||
}
|
||||
|
||||
throw new AssertionError();
|
||||
@@ -112,4 +126,41 @@ final class GroupMemberListAdapter extends RecyclerView.Adapter<GroupMemberListA
|
||||
bindRecipient(fullMember.getMember());
|
||||
}
|
||||
}
|
||||
|
||||
final static class OwnInvitePendingMemberViewHolder extends ViewHolder {
|
||||
|
||||
OwnInvitePendingMemberViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
void bind(@NonNull GroupMemberEntry memberEntry) {
|
||||
super.bind(memberEntry);
|
||||
|
||||
GroupMemberEntry.PendingMember pendingMember = (GroupMemberEntry.PendingMember) memberEntry;
|
||||
|
||||
bindRecipient(pendingMember.getInvitee());
|
||||
}
|
||||
}
|
||||
|
||||
final static class UnknownPendingMemberCountViewHolder extends ViewHolder {
|
||||
|
||||
UnknownPendingMemberCountViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
void bind(@NonNull GroupMemberEntry memberEntry) {
|
||||
super.bind(memberEntry);
|
||||
GroupMemberEntry.UnknownPendingMemberCount pendingMemberCount = (GroupMemberEntry.UnknownPendingMemberCount) memberEntry;
|
||||
|
||||
Recipient inviter = pendingMemberCount.getInviter();
|
||||
String displayName = inviter.getDisplayName(itemView.getContext());
|
||||
String displayText = context.getResources().getQuantityString(R.plurals.GroupMemberList_invited,
|
||||
pendingMemberCount.getInviteCount(),
|
||||
displayName, pendingMemberCount.getInviteCount());
|
||||
|
||||
bindImageAndText(inviter, displayText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package org.thoughtcrime.securesms.groups.ui.pendingmemberinvites;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
|
||||
public class PendingMemberInvitesActivity extends PassphraseRequiredActionBarActivity {
|
||||
|
||||
private static final String GROUP_ID = "GROUP_ID";
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme();
|
||||
|
||||
public static Intent newIntent(@NonNull Context context, @NonNull GroupId.V2 groupId) {
|
||||
Intent intent = new Intent(context, PendingMemberInvitesActivity.class);
|
||||
intent.putExtra(GROUP_ID, groupId.toString());
|
||||
return intent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreCreate() {
|
||||
dynamicTheme.onCreate(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState, boolean ready) {
|
||||
super.onCreate(savedInstanceState, ready);
|
||||
setContentView(R.layout.group_pending_member_invites_activity);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.container, PendingMemberInvitesFragment.newInstance(GroupId.parse(getIntent().getStringExtra(GROUP_ID)).requireV2()))
|
||||
.commitNow();
|
||||
}
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
dynamicTheme.onResume(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSupportNavigateUp() {
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package org.thoughtcrime.securesms.groups.ui.pendingmemberinvites;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupMemberListView;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class PendingMemberInvitesFragment extends Fragment {
|
||||
|
||||
private static final String GROUP_ID = "GROUP_ID";
|
||||
|
||||
private PendingMemberInvitesViewModel viewModel;
|
||||
private GroupMemberListView youInvited;
|
||||
private GroupMemberListView othersInvited;
|
||||
private View youInvitedEmptyState;
|
||||
private View othersInvitedEmptyState;
|
||||
|
||||
public static PendingMemberInvitesFragment newInstance(@NonNull GroupId.V2 groupId) {
|
||||
PendingMemberInvitesFragment fragment = new PendingMemberInvitesFragment();
|
||||
Bundle args = new Bundle();
|
||||
|
||||
args.putString(GROUP_ID, groupId.toString());
|
||||
fragment.setArguments(args);
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.group_pending_member_invites_fragment, container, false);
|
||||
|
||||
youInvited = view.findViewById(R.id.members_you_invited);
|
||||
othersInvited = view.findViewById(R.id.members_others_invited);
|
||||
youInvitedEmptyState = view.findViewById(R.id.no_pending_from_you);
|
||||
othersInvitedEmptyState = view.findViewById(R.id.no_pending_from_others);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
GroupId.V2 groupId = GroupId.parse(Objects.requireNonNull(requireArguments().getString(GROUP_ID))).requireV2();
|
||||
|
||||
PendingMemberInvitesViewModel.Factory factory = new PendingMemberInvitesViewModel.Factory(requireContext(), groupId);
|
||||
|
||||
viewModel = ViewModelProviders.of(requireActivity(), factory).get(PendingMemberInvitesViewModel.class);
|
||||
|
||||
viewModel.getWhoYouInvited().observe(getViewLifecycleOwner(), invitees -> {
|
||||
youInvited.setMembers(invitees);
|
||||
youInvitedEmptyState.setVisibility(invitees.isEmpty() ? View.VISIBLE : View.GONE);
|
||||
});
|
||||
|
||||
viewModel.getWhoOthersInvited().observe(getViewLifecycleOwner(), invitees -> {
|
||||
othersInvited.setMembers(invitees);
|
||||
othersInvitedEmptyState.setVisibility(invitees.isEmpty() ? View.VISIBLE : View.GONE);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package org.thoughtcrime.securesms.groups.ui.pendingmemberinvites;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PendingMemberInvitesViewModel extends ViewModel {
|
||||
|
||||
private static final String TAG = Log.tag(PendingMemberInvitesViewModel.class);
|
||||
|
||||
private final Context context;
|
||||
private final GroupId groupId;
|
||||
private final PendingMemberRepository pendingMemberRepository;
|
||||
private final MutableLiveData<List<GroupMemberEntry.PendingMember>> whoYouInvited = new MutableLiveData<>();
|
||||
private final MutableLiveData<List<GroupMemberEntry.UnknownPendingMemberCount>> whoOthersInvited = new MutableLiveData<>();
|
||||
|
||||
PendingMemberInvitesViewModel(@NonNull Context context,
|
||||
@NonNull GroupId.V2 groupId,
|
||||
@NonNull PendingMemberRepository pendingMemberRepository)
|
||||
{
|
||||
this.context = context;
|
||||
this.groupId = groupId;
|
||||
this.pendingMemberRepository = pendingMemberRepository;
|
||||
|
||||
pendingMemberRepository.getInvitees(groupId, this::setMembers);
|
||||
}
|
||||
|
||||
public LiveData<List<GroupMemberEntry.PendingMember>> getWhoYouInvited() {
|
||||
return whoYouInvited;
|
||||
}
|
||||
|
||||
public LiveData<List<GroupMemberEntry.UnknownPendingMemberCount>> getWhoOthersInvited() {
|
||||
return whoOthersInvited;
|
||||
}
|
||||
|
||||
private void setInvitees(List<GroupMemberEntry.PendingMember> byYou, List<GroupMemberEntry.UnknownPendingMemberCount> byOthers) {
|
||||
whoYouInvited.postValue(byYou);
|
||||
whoOthersInvited.postValue(byOthers);
|
||||
}
|
||||
|
||||
private void setMembers(PendingMemberRepository.InviteeResult inviteeResult) {
|
||||
List<GroupMemberEntry.PendingMember> byMe = new ArrayList<>(inviteeResult.getByMe().size());
|
||||
List<GroupMemberEntry.UnknownPendingMemberCount> byOthers = new ArrayList<>(inviteeResult.getByOthers().size());
|
||||
|
||||
for (PendingMemberRepository.SinglePendingMemberInvitedByYou pendingMember : inviteeResult.getByMe()) {
|
||||
byMe.add(new GroupMemberEntry.PendingMember(pendingMember.getInvitee(),
|
||||
pendingMember.getInviteeCipherText()));
|
||||
}
|
||||
|
||||
for (PendingMemberRepository.MultiplePendingMembersInvitedByAnother pendingMembers : inviteeResult.getByOthers()) {
|
||||
byOthers.add(new GroupMemberEntry.UnknownPendingMemberCount(pendingMembers.getInviter(),
|
||||
pendingMembers.getUuidCipherTexts().size()));
|
||||
}
|
||||
|
||||
setInvitees(byMe, byOthers);
|
||||
}
|
||||
|
||||
public static class Factory implements ViewModelProvider.Factory {
|
||||
|
||||
private final Context context;
|
||||
private final GroupId.V2 groupId;
|
||||
|
||||
public Factory(@NonNull Context context, @NonNull GroupId.V2 groupId) {
|
||||
this.context = context;
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
|
||||
//noinspection unchecked
|
||||
return (T) new PendingMemberInvitesViewModel(context, groupId, new PendingMemberRepository(context.getApplicationContext()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package org.thoughtcrime.securesms.groups.ui.pendingmemberinvites;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.util.Consumer;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
import com.google.protobuf.ByteString;
|
||||
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
|
||||
import org.signal.zkgroup.util.UUIDUtil;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.groups.GroupProtoUtil;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
final class PendingMemberRepository {
|
||||
|
||||
private final Context context;
|
||||
private final Executor executor;
|
||||
|
||||
PendingMemberRepository(@NonNull Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
this.executor = SignalExecutors.BOUNDED;
|
||||
}
|
||||
|
||||
public void getInvitees(GroupId.V2 groupId, @NonNull Consumer<InviteeResult> onInviteesLoaded) {
|
||||
executor.execute(() -> {
|
||||
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
||||
GroupDatabase.V2GroupProperties v2GroupProperties = groupDatabase.getGroup(groupId).get().requireV2GroupProperties();
|
||||
DecryptedGroup decryptedGroup = v2GroupProperties.getDecryptedGroup();
|
||||
List<DecryptedPendingMember> pendingMembersList = decryptedGroup.getPendingMembersList();
|
||||
List<SinglePendingMemberInvitedByYou> byMe = new ArrayList<>(pendingMembersList.size());
|
||||
List<MultiplePendingMembersInvitedByAnother> byOthers = new ArrayList<>(pendingMembersList.size());
|
||||
ByteString self = ByteString.copyFrom(UUIDUtil.serialize(Recipient.self().getUuid().get()));
|
||||
|
||||
Stream.of(pendingMembersList)
|
||||
.groupBy(DecryptedPendingMember::getAddedByUuid)
|
||||
.forEach(g ->
|
||||
{
|
||||
ByteString inviterUuid = g.getKey();
|
||||
List<DecryptedPendingMember> invitedMembers = g.getValue();
|
||||
|
||||
if (self.equals(inviterUuid)) {
|
||||
for (DecryptedPendingMember pendingMember : invitedMembers) {
|
||||
Recipient invitee = GroupProtoUtil.pendingMemberToRecipient(context, pendingMember);
|
||||
byte[] uuidCipherText = pendingMember.getUuidCipherText().toByteArray();
|
||||
|
||||
byMe.add(new SinglePendingMemberInvitedByYou(invitee, uuidCipherText));
|
||||
}
|
||||
} else {
|
||||
Recipient inviter = GroupProtoUtil.uuidByteStringToRecipient(context, inviterUuid);
|
||||
|
||||
ArrayList<byte[]> uuidCipherTexts = new ArrayList<>(invitedMembers.size());
|
||||
for (DecryptedPendingMember pendingMember : invitedMembers) {
|
||||
uuidCipherTexts.add(pendingMember.getUuidCipherText().toByteArray());
|
||||
}
|
||||
|
||||
byOthers.add(new MultiplePendingMembersInvitedByAnother(inviter, uuidCipherTexts));
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onInviteesLoaded.accept(new InviteeResult(byMe, byOthers));
|
||||
});
|
||||
}
|
||||
|
||||
public static final class InviteeResult {
|
||||
private final List<SinglePendingMemberInvitedByYou> byMe;
|
||||
private final List<MultiplePendingMembersInvitedByAnother> byOthers;
|
||||
|
||||
private InviteeResult(List<SinglePendingMemberInvitedByYou> byMe,
|
||||
List<MultiplePendingMembersInvitedByAnother> byOthers)
|
||||
{
|
||||
this.byMe = byMe;
|
||||
this.byOthers = byOthers;
|
||||
}
|
||||
|
||||
public List<SinglePendingMemberInvitedByYou> getByMe() {
|
||||
return byMe;
|
||||
}
|
||||
|
||||
public List<MultiplePendingMembersInvitedByAnother> getByOthers() {
|
||||
return byOthers;
|
||||
}
|
||||
}
|
||||
|
||||
public final static class SinglePendingMemberInvitedByYou {
|
||||
private final Recipient invitee;
|
||||
private final byte[] inviteeCipherText;
|
||||
|
||||
private SinglePendingMemberInvitedByYou(@NonNull Recipient invitee, @NonNull byte[] inviteeCipherText) {
|
||||
this.invitee = invitee;
|
||||
this.inviteeCipherText = inviteeCipherText;
|
||||
}
|
||||
|
||||
public Recipient getInvitee() {
|
||||
return invitee;
|
||||
}
|
||||
|
||||
public byte[] getInviteeCipherText() {
|
||||
return inviteeCipherText;
|
||||
}
|
||||
}
|
||||
|
||||
public final static class MultiplePendingMembersInvitedByAnother {
|
||||
private final Recipient inviter;
|
||||
private final ArrayList<byte[]> uuidCipherTexts;
|
||||
|
||||
private MultiplePendingMembersInvitedByAnother(@NonNull Recipient inviter, @NonNull ArrayList<byte[]> uuidCipherTexts) {
|
||||
this.inviter = inviter;
|
||||
this.uuidCipherTexts = uuidCipherTexts;
|
||||
}
|
||||
|
||||
public Recipient getInviter() {
|
||||
return inviter;
|
||||
}
|
||||
|
||||
public ArrayList<byte[]> getUuidCipherTexts() {
|
||||
return uuidCipherTexts;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user