Enforce a local GV2 capacity limit driven by a feature flag.

This commit is contained in:
Alan Evans
2020-05-29 12:20:07 -03:00
committed by Greyson Parrelli
parent cfcd451db7
commit 9da309ca48
8 changed files with 129 additions and 18 deletions

View File

@@ -44,6 +44,7 @@ public class CreateGroupActivity extends ContactSelectionActivity {
: ContactsCursorLoader.DisplayMode.FLAG_PUSH;
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, displayMode);
intent.putExtra(ContactSelectionListFragment.SELECTION_LIMIT, FeatureFlags.gv2GroupCapacity() - 1);
return intent;
}

View File

@@ -23,14 +23,12 @@ import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.ViewModelProviders;
import org.thoughtcrime.securesms.AvatarPreviewActivity;
import org.thoughtcrime.securesms.ContactSelectionListFragment;
import org.thoughtcrime.securesms.MediaPreviewActivity;
import org.thoughtcrime.securesms.MuteDialog;
import org.thoughtcrime.securesms.PushContactSelectionActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.AvatarImageView;
import org.thoughtcrime.securesms.components.ThreadPhotoRailView;
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader;
import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto;
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
import org.thoughtcrime.securesms.groups.GroupId;
@@ -225,11 +223,7 @@ public class ManageGroupFragment extends Fragment {
disappearingMessagesRow.setOnClickListener(v -> viewModel.handleExpirationSelection());
blockGroup.setOnClickListener(v -> viewModel.blockAndLeave(requireActivity()));
addMembers.setOnClickListener(v -> {
Intent intent = new Intent(requireActivity(), PushContactSelectionActivity.class);
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, ContactsCursorLoader.DisplayMode.FLAG_PUSH);
startActivityForResult(intent, PICK_CONTACT);
});
addMembers.setOnClickListener(v -> viewModel.onAddMembersClick(this, PICK_CONTACT));
viewModel.getMembershipRights().observe(getViewLifecycleOwner(), r -> {
if (r != null) {

View File

@@ -6,7 +6,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.WorkerThread;
import androidx.core.util.Consumer;
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
import org.thoughtcrime.securesms.ContactSelectionListFragment;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.groups.GroupAccessControl;
import org.thoughtcrime.securesms.groups.GroupChangeBusyException;
@@ -21,6 +24,7 @@ import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
@@ -47,6 +51,18 @@ final class ManageGroupRepository {
SignalExecutors.BOUNDED.execute(() -> onGroupStateLoaded.accept(getGroupState()));
}
void getGroupCapacity(@NonNull Consumer<GroupCapacityResult> onGroupCapacityLoaded) {
SimpleTask.run(SignalExecutors.BOUNDED, () -> {
GroupDatabase.GroupRecord groupRecord = DatabaseFactory.getGroupDatabase(context).getGroup(groupId).get();
if (groupRecord.isV2Group()) {
DecryptedGroup decryptedGroup = groupRecord.requireV2GroupProperties().getDecryptedGroup();
return new GroupCapacityResult(decryptedGroup.getMembersCount(), decryptedGroup.getPendingMembersCount(), FeatureFlags.gv2GroupCapacity());
} else {
return new GroupCapacityResult(groupRecord.getMembers().size(), 0, ContactSelectionListFragment.NO_LIMIT);
}
}, onGroupCapacityLoaded::accept);
}
@WorkerThread
private GroupStateResult getGroupState() {
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
@@ -152,4 +168,20 @@ final class ManageGroupRepository {
}
}
static final class GroupCapacityResult {
private final int fullMembers;
private final int pendingMembers;
private final int totalCapacity;
GroupCapacityResult(int fullMembers, int pendingMembers, int totalCapacity) {
this.fullMembers = fullMembers;
this.pendingMembers = pendingMembers;
this.totalCapacity = totalCapacity;
}
public int getRemainingCapacity() {
return totalCapacity - fullMembers - pendingMembers;
}
}
}

View File

@@ -1,11 +1,13 @@
package org.thoughtcrime.securesms.groups.ui.managegroup;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.WorkerThread;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
@@ -14,7 +16,11 @@ import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import org.thoughtcrime.securesms.BlockUnblockDialog;
import org.thoughtcrime.securesms.ContactSelectionListFragment;
import org.thoughtcrime.securesms.ExpirationDialog;
import org.thoughtcrime.securesms.PushContactSelectionActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader;
import org.thoughtcrime.securesms.database.MediaDatabase;
import org.thoughtcrime.securesms.database.loaders.MediaLoader;
import org.thoughtcrime.securesms.database.loaders.ThreadMediaLoader;
@@ -211,6 +217,20 @@ public class ManageGroupViewModel extends ViewModel {
Util.runOnMain(() -> Toast.makeText(context, GroupErrors.getUserDisplayMessage(e), Toast.LENGTH_LONG).show());
}
public void onAddMembersClick(@NonNull Fragment fragment, int resultCode) {
manageGroupRepository.getGroupCapacity(capacity -> {
int remainingCapacity = capacity.getRemainingCapacity();
if (remainingCapacity <= 0) {
Toast.makeText(fragment.requireContext(), R.string.ContactSelectionListFragment_the_group_is_full, Toast.LENGTH_SHORT).show();
} else {
Intent intent = new Intent(fragment.requireActivity(), PushContactSelectionActivity.class);
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, ContactsCursorLoader.DisplayMode.FLAG_PUSH);
intent.putExtra(ContactSelectionListFragment.SELECTION_LIMIT, remainingCapacity);
fragment.startActivityForResult(intent, resultCode);
}
});
}
static final class GroupViewState {
private final long threadId;
@NonNull private final Recipient groupRecipient;