mirror of
https://github.com/oxen-io/session-android.git
synced 2025-06-09 08:18:34 +00:00
Add feature flag driven group recommended size and hard size limits.
This commit is contained in:
parent
5eace49739
commit
b4b1e5b605
@ -21,6 +21,7 @@ import android.Manifest;
|
||||
import android.animation.LayoutTransition;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
@ -29,7 +30,6 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.CycleInterpolator;
|
||||
import android.widget.Button;
|
||||
import android.widget.HorizontalScrollView;
|
||||
import android.widget.TextView;
|
||||
@ -56,6 +56,7 @@ import com.google.android.material.chip.ChipGroup;
|
||||
import com.pnikosis.materialishprogress.ProgressWheel;
|
||||
|
||||
import org.thoughtcrime.securesms.components.RecyclerViewFastScroller;
|
||||
import org.thoughtcrime.securesms.components.emoji.WarningTextView;
|
||||
import org.thoughtcrime.securesms.contacts.ContactChip;
|
||||
import org.thoughtcrime.securesms.contacts.ContactSelectionListAdapter;
|
||||
import org.thoughtcrime.securesms.contacts.ContactSelectionListItem;
|
||||
@ -63,6 +64,8 @@ import org.thoughtcrime.securesms.contacts.ContactsCursorLoader;
|
||||
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader.DisplayMode;
|
||||
import org.thoughtcrime.securesms.contacts.SelectedContact;
|
||||
import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper;
|
||||
import org.thoughtcrime.securesms.groups.SelectionLimits;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupLimitDialog;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
@ -82,7 +85,6 @@ import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@ -106,7 +108,7 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
||||
public static final String MULTI_SELECT = "multi_select";
|
||||
public static final String REFRESHABLE = "refreshable";
|
||||
public static final String RECENTS = "recents";
|
||||
public static final String SELECTION_LIMIT = "selection_limit";
|
||||
public static final String SELECTION_LIMITS = "selection_limits";
|
||||
public static final String CURRENT_SELECTION = "current_selection";
|
||||
|
||||
private ConstraintLayout constraintLayout;
|
||||
@ -123,15 +125,16 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
||||
private ContactSelectionListAdapter cursorRecyclerViewAdapter;
|
||||
private ChipGroup chipGroup;
|
||||
private HorizontalScrollView chipGroupScrollContainer;
|
||||
private TextView groupLimit;
|
||||
private WarningTextView groupLimit;
|
||||
|
||||
@Nullable private FixedViewsAdapter headerAdapter;
|
||||
@Nullable private FixedViewsAdapter footerAdapter;
|
||||
@Nullable private ListCallback listCallback;
|
||||
@Nullable private ScrollCallback scrollCallback;
|
||||
private GlideRequests glideRequests;
|
||||
private int selectionLimit;
|
||||
private SelectionLimits selectionLimit = SelectionLimits.NO_LIMITS;
|
||||
private Set<RecipientId> currentSelection;
|
||||
private boolean isMulti;
|
||||
|
||||
@Override
|
||||
public void onAttach(@NonNull Context context) {
|
||||
@ -206,9 +209,25 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
||||
}
|
||||
});
|
||||
|
||||
swipeRefresh.setEnabled(requireActivity().getIntent().getBooleanExtra(REFRESHABLE, true));
|
||||
Intent intent = requireActivity().getIntent();
|
||||
|
||||
swipeRefresh.setEnabled(intent.getBooleanExtra(REFRESHABLE, true));
|
||||
|
||||
selectionLimit = intent.getParcelableExtra(SELECTION_LIMITS);
|
||||
isMulti = intent.getBooleanExtra(MULTI_SELECT, false);
|
||||
|
||||
if (isMulti) {
|
||||
if (selectionLimit == null) {
|
||||
throw new AssertionError("Selection limits not supplied in args for multi-select");
|
||||
}
|
||||
} else {
|
||||
if (selectionLimit != null) {
|
||||
throw new AssertionError("Selection limits supplied in args for a non-multi selection use");
|
||||
} else {
|
||||
selectionLimit = SelectionLimits.NO_LIMITS;
|
||||
}
|
||||
}
|
||||
|
||||
selectionLimit = requireActivity().getIntent().getIntExtra(SELECTION_LIMIT, NO_LIMIT);
|
||||
currentSelection = getCurrentSelection();
|
||||
|
||||
updateGroupLimit(getChipCount());
|
||||
@ -217,12 +236,10 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
||||
}
|
||||
|
||||
private void updateGroupLimit(int chipCount) {
|
||||
if (selectionLimit != NO_LIMIT) {
|
||||
groupLimit.setText(String.format(Locale.getDefault(), "%d/%d", currentSelection.size() + chipCount, selectionLimit));
|
||||
groupLimit.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
groupLimit.setVisibility(View.GONE);
|
||||
}
|
||||
int members = currentSelection.size() + chipCount;
|
||||
groupLimit.setText(getResources().getQuantityString(R.plurals.ContactSelectionListFragment_d_members, members, members));
|
||||
groupLimit.setVisibility(isMulti ? View.VISIBLE : View.GONE);
|
||||
groupLimit.setWarning(selectionWarningLimitExceeded());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -254,7 +271,7 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
||||
}
|
||||
|
||||
public boolean isMulti() {
|
||||
return requireActivity().getIntent().getBooleanExtra(MULTI_SELECT, false);
|
||||
return isMulti;
|
||||
}
|
||||
|
||||
private void initializeCursor() {
|
||||
@ -264,7 +281,7 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
||||
glideRequests,
|
||||
null,
|
||||
new ListClickListener(),
|
||||
isMulti(),
|
||||
isMulti,
|
||||
currentSelection);
|
||||
|
||||
RecyclerViewConcatenateAdapterStickyHeader concatenateAdapter = new RecyclerViewConcatenateAdapterStickyHeader();
|
||||
@ -450,15 +467,14 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
||||
SelectedContact selectedContact = contact.isUsernameType() ? SelectedContact.forUsername(contact.getRecipientId().orNull(), contact.getNumber())
|
||||
: SelectedContact.forPhone(contact.getRecipientId().orNull(), contact.getNumber());
|
||||
|
||||
if (isMulti() && Recipient.self().getId().equals(selectedContact.getOrCreateRecipientId(requireContext()))) {
|
||||
if (isMulti && Recipient.self().getId().equals(selectedContact.getOrCreateRecipientId(requireContext()))) {
|
||||
Toast.makeText(requireContext(), R.string.ContactSelectionListFragment_you_do_not_need_to_add_yourself_to_the_group, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isMulti() || !cursorRecyclerViewAdapter.isSelectedContact(selectedContact)) {
|
||||
if (selectionLimitReached()) {
|
||||
Toast.makeText(requireContext(), R.string.ContactSelectionListFragment_the_group_is_full, Toast.LENGTH_SHORT).show();
|
||||
groupLimit.animate().scaleX(1.3f).scaleY(1.3f).setInterpolator(new CycleInterpolator(0.5f)).start();
|
||||
if (!isMulti || !cursorRecyclerViewAdapter.isSelectedContact(selectedContact)) {
|
||||
if (selectionHardLimitReached()) {
|
||||
GroupLimitDialog.showHardLimitMessage(requireContext());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -486,7 +502,7 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
||||
new AlertDialog.Builder(requireContext())
|
||||
.setTitle(R.string.ContactSelectionListFragment_username_not_found)
|
||||
.setMessage(getString(R.string.ContactSelectionListFragment_s_is_not_a_signal_user, contact.getNumber()))
|
||||
.setPositiveButton(R.string.ContactSelectionListFragment_okay, (dialog, which) -> dialog.dismiss())
|
||||
.setPositiveButton(android.R.string.ok, (dialog, which) -> dialog.dismiss())
|
||||
.show();
|
||||
}
|
||||
});
|
||||
@ -508,16 +524,25 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
||||
if (onContactSelectedListener != null) {
|
||||
onContactSelectedListener.onContactDeselected(contact.getRecipientId(), contact.getNumber());
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean selectionLimitReached() {
|
||||
return getChipCount() + currentSelection.size() >= selectionLimit;
|
||||
private boolean selectionHardLimitReached() {
|
||||
return getChipCount() + currentSelection.size() >= selectionLimit.getHardLimit();
|
||||
}
|
||||
|
||||
private boolean selectionWarningLimitReachedExactly() {
|
||||
return getChipCount() + currentSelection.size() == selectionLimit.getRecommendedLimit();
|
||||
}
|
||||
|
||||
private boolean selectionWarningLimitExceeded() {
|
||||
return getChipCount() + currentSelection.size() > selectionLimit.getRecommendedLimit();
|
||||
}
|
||||
|
||||
private void markContactSelected(@NonNull SelectedContact selectedContact) {
|
||||
cursorRecyclerViewAdapter.addSelectedContact(selectedContact);
|
||||
if (isMulti()) {
|
||||
if (isMulti) {
|
||||
addChipForSelectedContact(selectedContact);
|
||||
}
|
||||
}
|
||||
@ -588,6 +613,9 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
||||
private void addChip(@NonNull ContactChip chip) {
|
||||
chipGroup.addView(chip);
|
||||
updateGroupLimit(getChipCount());
|
||||
if (selectionWarningLimitReachedExactly()) {
|
||||
GroupLimitDialog.showRecommendedLimitMessage(requireContext());
|
||||
}
|
||||
}
|
||||
|
||||
private int getChipCount() {
|
||||
|
@ -0,0 +1,49 @@
|
||||
package org.thoughtcrime.securesms.components.emoji;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.appcompat.widget.AppCompatTextView;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
||||
public final class WarningTextView extends AppCompatTextView {
|
||||
|
||||
@ColorInt private final int originalTextColor;
|
||||
@ColorInt private final int warningTextColor;
|
||||
|
||||
private boolean warning;
|
||||
|
||||
public WarningTextView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public WarningTextView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public WarningTextView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
|
||||
TypedArray styledAttributes = context.obtainStyledAttributes(attrs, R.styleable.WarningTextView, 0, 0);
|
||||
warningTextColor = styledAttributes.getColor(R.styleable.WarningTextView_warning_text_color, 0);
|
||||
|
||||
styledAttributes.recycle();
|
||||
|
||||
styledAttributes = context.obtainStyledAttributes(attrs, new int[]{ android.R.attr.textColor });
|
||||
|
||||
originalTextColor = styledAttributes.getColor(0, 0);
|
||||
|
||||
styledAttributes.recycle();
|
||||
}
|
||||
|
||||
public void setWarning(boolean warning) {
|
||||
if (this.warning != warning) {
|
||||
this.warning = warning;
|
||||
setTextColor(warning ? warningTextColor : originalTextColor);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.thoughtcrime.securesms.BuildConfig;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.SelectionLimits;
|
||||
import org.thoughtcrime.securesms.jobs.RemoteConfigRefreshJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
@ -50,7 +51,8 @@ public final class FeatureFlags {
|
||||
private static final String USERNAMES = "android.usernames";
|
||||
private static final String GROUPS_V2_JOIN_VERSION = "android.groupsv2.joinVersion";
|
||||
private static final String GROUPS_V2_LINKS_VERSION = "android.groupsv2.manageGroupLinksVersion";
|
||||
private static final String GROUPS_V2_CAPACITY = "global.groupsv2.maxGroupSize";
|
||||
private static final String GROUPS_V2_RECOMMENDED_LIMIT = "global.groupsv2.maxGroupSize";
|
||||
private static final String GROUPS_V2_HARD_LIMIT = "global.groupsv2.groupSizeHardLimit";
|
||||
private static final String INTERNAL_USER = "android.internalUser";
|
||||
private static final String VERIFY_V2 = "android.verifyV2";
|
||||
private static final String PHONE_NUMBER_PRIVACY_VERSION = "android.phoneNumberPrivacyVersion";
|
||||
@ -64,7 +66,8 @@ public final class FeatureFlags {
|
||||
*/
|
||||
|
||||
private static final Set<String> REMOTE_CAPABLE = Sets.newHashSet(
|
||||
GROUPS_V2_CAPACITY,
|
||||
GROUPS_V2_RECOMMENDED_LIMIT,
|
||||
GROUPS_V2_HARD_LIMIT,
|
||||
GROUPS_V2_JOIN_VERSION,
|
||||
GROUPS_V2_LINKS_VERSION,
|
||||
INTERNAL_USER,
|
||||
@ -177,8 +180,9 @@ public final class FeatureFlags {
|
||||
/**
|
||||
* Maximum number of members allowed in a group.
|
||||
*/
|
||||
public static int gv2GroupCapacity() {
|
||||
return getInteger(GROUPS_V2_CAPACITY, 151);
|
||||
public static SelectionLimits groupLimits() {
|
||||
return new SelectionLimits(getInteger(GROUPS_V2_RECOMMENDED_LIMIT, 151),
|
||||
getInteger(GROUPS_V2_HARD_LIMIT, 1001));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,14 +110,15 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
<org.thoughtcrime.securesms.components.emoji.WarningTextView
|
||||
android:id="@+id/group_limit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body2"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="@+id/chipGroupScrollContainer"
|
||||
app:layout_constraintStart_toStartOf="@+id/chipGroupScrollContainer"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:warning_text_color="@color/core_red"
|
||||
tools:text="999/999"
|
||||
tools:visibility="visible" />
|
||||
|
||||
|
@ -588,4 +588,8 @@
|
||||
<declare-styleable name="ConversationScrollToView">
|
||||
<attr name="cstv_scroll_button_src" format="reference" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="WarningTextView">
|
||||
<attr name="warning_text_color" format="color|reference" />
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
|
@ -1711,9 +1711,15 @@
|
||||
<string name="ContactSelectionListFragment_error_retrieving_contacts_check_your_network_connection">Error retrieving contacts, check your network connection</string>
|
||||
<string name="ContactSelectionListFragment_username_not_found">Username not found</string>
|
||||
<string name="ContactSelectionListFragment_s_is_not_a_signal_user">"%1$s" is not a Signal user. Please check the username and try again.</string>
|
||||
<string name="ContactSelectionListFragment_okay">Okay</string>
|
||||
<string name="ContactSelectionListFragment_the_group_is_full">The group is full</string>
|
||||
<string name="ContactSelectionListFragment_you_do_not_need_to_add_yourself_to_the_group">You do not need to add yourself to the group</string>
|
||||
<string name="ContactSelectionListFragment_maximum_group_size_reached">Maximum group size reached</string>
|
||||
<string name="ContactSelectionListFragment_signal_groups_can_have_a_maximum_of_d_members">Signal groups can have a maximum of %1$d members.</string>
|
||||
<string name="ContactSelectionListFragment_recommended_member_limit_reached">Recommended member limit reached</string>
|
||||
<string name="ContactSelectionListFragment_signal_groups_perform_best_with_d_members_or_fewer">Signal groups perform best with %1$d members or fewer. Adding more members will cause delays sending and receiving messages.</string>
|
||||
<plurals name="ContactSelectionListFragment_d_members">
|
||||
<item quantity="one">%1$d member</item>
|
||||
<item quantity="other">%1$d members</item>
|
||||
</plurals>
|
||||
|
||||
<!-- blocked_contacts_fragment -->
|
||||
<string name="blocked_contacts_fragment__no_blocked_contacts">No blocked contacts</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user