mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 18:00:02 +01:00
Add feature flag driven group recommended size and hard size limits.
This commit is contained in:
committed by
Cody Henthorne
parent
5eace49739
commit
b4b1e5b605
@@ -0,0 +1,65 @@
|
||||
package org.thoughtcrime.securesms.groups;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
public final class SelectionLimits implements Parcelable {
|
||||
public static final int NO_LIMIT = Integer.MAX_VALUE;
|
||||
|
||||
public static final SelectionLimits NO_LIMITS = new SelectionLimits(NO_LIMIT, NO_LIMIT);
|
||||
|
||||
private final int recommendedLimit;
|
||||
private final int hardLimit;
|
||||
|
||||
public SelectionLimits(int recommendedLimit, int hardLimit) {
|
||||
this.recommendedLimit = recommendedLimit;
|
||||
this.hardLimit = hardLimit;
|
||||
}
|
||||
|
||||
public int getRecommendedLimit() {
|
||||
return recommendedLimit;
|
||||
}
|
||||
|
||||
public int getHardLimit() {
|
||||
return hardLimit;
|
||||
}
|
||||
|
||||
public boolean hasRecommendedLimit() {
|
||||
return recommendedLimit != NO_LIMIT;
|
||||
}
|
||||
|
||||
public boolean hasHardLimit() {
|
||||
return hardLimit != NO_LIMIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(recommendedLimit);
|
||||
dest.writeInt(hardLimit);
|
||||
}
|
||||
|
||||
public static final Creator<SelectionLimits> CREATOR = new Creator<SelectionLimits>() {
|
||||
@Override
|
||||
public SelectionLimits createFromParcel(Parcel in) {
|
||||
return new SelectionLimits(in.readInt(), in.readInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionLimits[] newArray(int size) {
|
||||
return new SelectionLimits[size];
|
||||
}
|
||||
};
|
||||
|
||||
public SelectionLimits excludingSelf() {
|
||||
return excluding(1);
|
||||
}
|
||||
|
||||
public SelectionLimits excluding(int count) {
|
||||
return new SelectionLimits(recommendedLimit - count, hardLimit - count);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.thoughtcrime.securesms.groups.ui;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
|
||||
public final class GroupLimitDialog {
|
||||
|
||||
public static void showHardLimitMessage(@NonNull Context context) {
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(R.string.ContactSelectionListFragment_maximum_group_size_reached)
|
||||
.setMessage(context.getString(R.string.ContactSelectionListFragment_signal_groups_can_have_a_maximum_of_d_members, FeatureFlags.groupLimits().getHardLimit()))
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
public static void showRecommendedLimitMessage(@NonNull Context context) {
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(R.string.ContactSelectionListFragment_recommended_member_limit_reached)
|
||||
.setMessage(context.getString(R.string.ContactSelectionListFragment_signal_groups_perform_best_with_d_members_or_fewer, FeatureFlags.groupLimits().getRecommendedLimit()))
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,6 @@ public final class AddToGroupsActivity extends ContactSelectionActivity {
|
||||
intent.putExtra(EXTRA_RECIPIENT_ID, recipientId);
|
||||
|
||||
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, ContactsCursorLoader.DisplayMode.FLAG_ACTIVE_GROUPS);
|
||||
intent.putExtra(ContactSelectionListFragment.SELECTION_LIMIT, ContactSelectionListFragment.NO_LIMIT);
|
||||
|
||||
intent.putParcelableArrayListExtra(ContactSelectionListFragment.CURRENT_SELECTION, new ArrayList<>(currentGroupsMemberOf));
|
||||
|
||||
|
||||
@@ -56,8 +56,7 @@ public class CreateGroupActivity extends ContactSelectionActivity {
|
||||
: ContactsCursorLoader.DisplayMode.FLAG_PUSH;
|
||||
|
||||
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, displayMode);
|
||||
intent.putExtra(ContactSelectionListFragment.SELECTION_LIMIT, SignalStore.internalValues().gv2DoNotCreateGv2Groups() ? ContactSelectionListFragment.NO_LIMIT
|
||||
: FeatureFlags.gv2GroupCapacity() - 1);
|
||||
intent.putExtra(ContactSelectionListFragment.SELECTION_LIMITS, FeatureFlags.groupLimits().excludingSelf());
|
||||
|
||||
return intent;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.thoughtcrime.securesms.groups.GroupProtoUtil;
|
||||
import org.thoughtcrime.securesms.groups.MembershipNotSuitableForV2Exception;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupChangeErrorCallback;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason;
|
||||
import org.thoughtcrime.securesms.groups.SelectionLimits;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
@@ -44,8 +45,8 @@ final class ManageGroupRepository {
|
||||
private final GroupId groupId;
|
||||
|
||||
ManageGroupRepository(@NonNull Context context, @NonNull GroupId groupId) {
|
||||
this.context = context;
|
||||
this.groupId = groupId;
|
||||
this.context = context;
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
public GroupId getGroupId() {
|
||||
@@ -68,9 +69,9 @@ final class ManageGroupRepository {
|
||||
|
||||
members.addAll(pendingMembers);
|
||||
|
||||
return new GroupCapacityResult(members, FeatureFlags.gv2GroupCapacity());
|
||||
return new GroupCapacityResult(members, FeatureFlags.groupLimits());
|
||||
} else {
|
||||
return new GroupCapacityResult(groupRecord.getMembers(), ContactSelectionListFragment.NO_LIMIT);
|
||||
return new GroupCapacityResult(groupRecord.getMembers(), FeatureFlags.groupLimits());
|
||||
}
|
||||
}, onGroupCapacityLoaded::accept);
|
||||
}
|
||||
@@ -186,33 +187,39 @@ final class ManageGroupRepository {
|
||||
|
||||
static final class GroupCapacityResult {
|
||||
private final List<RecipientId> members;
|
||||
private final int totalCapacity;
|
||||
private final SelectionLimits selectionLimits;
|
||||
|
||||
GroupCapacityResult(@NonNull List<RecipientId> members, int totalCapacity) {
|
||||
this.members = members;
|
||||
this.totalCapacity = totalCapacity;
|
||||
GroupCapacityResult(@NonNull List<RecipientId> members, @NonNull SelectionLimits selectionLimits) {
|
||||
this.members = members;
|
||||
this.selectionLimits = selectionLimits;
|
||||
}
|
||||
|
||||
public @NonNull List<RecipientId> getMembers() {
|
||||
return members;
|
||||
}
|
||||
|
||||
public int getTotalCapacity() {
|
||||
return totalCapacity;
|
||||
}
|
||||
|
||||
public int getSelectionLimit() {
|
||||
if (totalCapacity == ContactSelectionListFragment.NO_LIMIT) {
|
||||
return totalCapacity;
|
||||
if (!selectionLimits.hasHardLimit()) {
|
||||
return ContactSelectionListFragment.NO_LIMIT;
|
||||
}
|
||||
|
||||
boolean containsSelf = members.indexOf(Recipient.self().getId()) != -1;
|
||||
|
||||
return totalCapacity - (containsSelf ? 1 : 0);
|
||||
return selectionLimits.getHardLimit() - (containsSelf ? 1 : 0);
|
||||
}
|
||||
|
||||
public int getSelectionWarning() {
|
||||
if (!selectionLimits.hasRecommendedLimit()) {
|
||||
return ContactSelectionListFragment.NO_LIMIT;
|
||||
}
|
||||
|
||||
boolean containsSelf = members.indexOf(Recipient.self().getId()) != -1;
|
||||
|
||||
return selectionLimits.getRecommendedLimit() - (containsSelf ? 1 : 0);
|
||||
}
|
||||
|
||||
public int getRemainingCapacity() {
|
||||
return totalCapacity - members.size();
|
||||
return selectionLimits.getHardLimit() - members.size();
|
||||
}
|
||||
|
||||
public @NonNull ArrayList<RecipientId> getMembersWithoutSelf() {
|
||||
|
||||
@@ -27,9 +27,11 @@ import org.thoughtcrime.securesms.database.loaders.MediaLoader;
|
||||
import org.thoughtcrime.securesms.database.loaders.ThreadMediaLoader;
|
||||
import org.thoughtcrime.securesms.groups.GroupAccessControl;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.groups.SelectionLimits;
|
||||
import org.thoughtcrime.securesms.groups.LiveGroup;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupErrors;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupLimitDialog;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry;
|
||||
import org.thoughtcrime.securesms.groups.ui.addmembers.AddMembersActivity;
|
||||
import org.thoughtcrime.securesms.groups.ui.managegroup.dialogs.GroupMentionSettingDialog;
|
||||
@@ -306,12 +308,12 @@ public class ManageGroupViewModel extends ViewModel {
|
||||
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();
|
||||
GroupLimitDialog.showHardLimitMessage(fragment.requireContext());
|
||||
} else {
|
||||
Intent intent = new Intent(fragment.requireActivity(), AddMembersActivity.class);
|
||||
intent.putExtra(AddMembersActivity.GROUP_ID, manageGroupRepository.getGroupId().toString());
|
||||
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, ContactsCursorLoader.DisplayMode.FLAG_PUSH);
|
||||
intent.putExtra(ContactSelectionListFragment.SELECTION_LIMIT, capacity.getSelectionLimit());
|
||||
intent.putExtra(ContactSelectionListFragment.SELECTION_LIMITS, new SelectionLimits(capacity.getSelectionWarning(), capacity.getSelectionLimit()));
|
||||
intent.putParcelableArrayListExtra(ContactSelectionListFragment.CURRENT_SELECTION, capacity.getMembersWithoutSelf());
|
||||
fragment.startActivityForResult(intent, resultCode);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user