@@ -110,22 +110,26 @@ public final class ContactSelectionListFragment extends LoggingFragment
110110 public static final String SELECTION_LIMITS = "selection_limits" ;
111111 public static final String CURRENT_SELECTION = "current_selection" ;
112112 public static final String HIDE_COUNT = "hide_count" ;
113+ public static final String CAN_SELECT_SELF = "can_select_self" ;
114+ public static final String DISPLAY_CHIPS = "display_chips" ;
115+
116+ private ConstraintLayout constraintLayout ;
117+ private TextView emptyText ;
118+ private OnContactSelectedListener onContactSelectedListener ;
119+ private SwipeRefreshLayout swipeRefresh ;
120+ private View showContactsLayout ;
121+ private Button showContactsButton ;
122+ private TextView showContactsDescription ;
123+ private ProgressWheel showContactsProgress ;
124+ private String cursorFilter ;
125+ private RecyclerView recyclerView ;
126+ private RecyclerViewFastScroller fastScroller ;
127+ private ContactSelectionListAdapter cursorRecyclerViewAdapter ;
128+ private ChipGroup chipGroup ;
129+ private HorizontalScrollView chipGroupScrollContainer ;
130+ private WarningTextView groupLimit ;
131+ private OnSelectionLimitReachedListener onSelectionLimitReachedListener ;
113132
114- private ConstraintLayout constraintLayout ;
115- private TextView emptyText ;
116- private OnContactSelectedListener onContactSelectedListener ;
117- private SwipeRefreshLayout swipeRefresh ;
118- private View showContactsLayout ;
119- private Button showContactsButton ;
120- private TextView showContactsDescription ;
121- private ProgressWheel showContactsProgress ;
122- private String cursorFilter ;
123- private RecyclerView recyclerView ;
124- private RecyclerViewFastScroller fastScroller ;
125- private ContactSelectionListAdapter cursorRecyclerViewAdapter ;
126- private ChipGroup chipGroup ;
127- private HorizontalScrollView chipGroupScrollContainer ;
128- private WarningTextView groupLimit ;
129133
130134 @ Nullable private FixedViewsAdapter headerAdapter ;
131135 @ Nullable private FixedViewsAdapter footerAdapter ;
@@ -136,6 +140,7 @@ public final class ContactSelectionListFragment extends LoggingFragment
136140 private Set <RecipientId > currentSelection ;
137141 private boolean isMulti ;
138142 private boolean hideCount ;
143+ private boolean canSelectSelf ;
139144
140145 @ Override
141146 public void onAttach (@ NonNull Context context ) {
@@ -148,6 +153,14 @@ public void onAttach(@NonNull Context context) {
148153 if (context instanceof ScrollCallback ) {
149154 scrollCallback = (ScrollCallback ) context ;
150155 }
156+
157+ if (context instanceof OnContactSelectedListener ) {
158+ onContactSelectedListener = (OnContactSelectedListener ) context ;
159+ }
160+
161+ if (context instanceof OnSelectionLimitReachedListener ) {
162+ onSelectionLimitReachedListener = (OnSelectionLimitReachedListener ) context ;
163+ }
151164 }
152165
153166 @ Override
@@ -217,6 +230,7 @@ public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHo
217230 hideCount = intent .getBooleanExtra (HIDE_COUNT , false );
218231 selectionLimit = intent .getParcelableExtra (SELECTION_LIMITS );
219232 isMulti = selectionLimit != null ;
233+ canSelectSelf = intent .getBooleanExtra (CAN_SELECT_SELF , !isMulti );
220234
221235 if (!isMulti ) {
222236 selectionLimit = SelectionLimits .NO_LIMITS ;
@@ -295,7 +309,7 @@ private void initializeCursor() {
295309 }
296310
297311 recyclerView .setAdapter (concatenateAdapter );
298- recyclerView .addItemDecoration (new StickyHeaderDecoration (concatenateAdapter , true , true ));
312+ recyclerView .addItemDecoration (new StickyHeaderDecoration (concatenateAdapter , true , true , 0 ));
299313 recyclerView .addOnScrollListener (new RecyclerView .OnScrollListener () {
300314 @ Override
301315 public void onScrollStateChanged (@ NonNull RecyclerView recyclerView , int newState ) {
@@ -464,14 +478,18 @@ public void onItemClick(ContactSelectionListItem contact) {
464478 SelectedContact selectedContact = contact .isUsernameType () ? SelectedContact .forUsername (contact .getRecipientId ().orNull (), contact .getNumber ())
465479 : SelectedContact .forPhone (contact .getRecipientId ().orNull (), contact .getNumber ());
466480
467- if (isMulti && Recipient .self ().getId ().equals (selectedContact .getOrCreateRecipientId (requireContext ()))) {
481+ if (! canSelectSelf && Recipient .self ().getId ().equals (selectedContact .getOrCreateRecipientId (requireContext ()))) {
468482 Toast .makeText (requireContext (), R .string .ContactSelectionListFragment_you_do_not_need_to_add_yourself_to_the_group , Toast .LENGTH_SHORT ).show ();
469483 return ;
470484 }
471485
472486 if (!isMulti || !cursorRecyclerViewAdapter .isSelectedContact (selectedContact )) {
473487 if (selectionHardLimitReached ()) {
474- GroupLimitDialog .showHardLimitMessage (requireContext ());
488+ if (onSelectionLimitReachedListener != null ) {
489+ onSelectionLimitReachedListener .onHardLimitReached (selectionLimit .getHardLimit ());
490+ } else {
491+ GroupLimitDialog .showHardLimitMessage (requireContext ());
492+ }
475493 return ;
476494 }
477495
@@ -489,11 +507,11 @@ public void onItemClick(ContactSelectionListItem contact) {
489507 if (onContactSelectedListener != null ) {
490508 if (onContactSelectedListener .onBeforeContactSelected (Optional .of (recipient .getId ()), null )) {
491509 markContactSelected (selected );
492- cursorRecyclerViewAdapter .notifyItemChanged ( recyclerView . getChildAdapterPosition ( contact ), ContactSelectionListAdapter .PAYLOAD_SELECTION_CHANGE );
510+ cursorRecyclerViewAdapter .notifyItemRangeChanged ( 0 , cursorRecyclerViewAdapter . getItemCount ( ), ContactSelectionListAdapter .PAYLOAD_SELECTION_CHANGE );
493511 }
494512 } else {
495513 markContactSelected (selected );
496- cursorRecyclerViewAdapter .notifyItemChanged ( recyclerView . getChildAdapterPosition ( contact ), ContactSelectionListAdapter .PAYLOAD_SELECTION_CHANGE );
514+ cursorRecyclerViewAdapter .notifyItemRangeChanged ( 0 , cursorRecyclerViewAdapter . getItemCount ( ), ContactSelectionListAdapter .PAYLOAD_SELECTION_CHANGE );
497515 }
498516 } else {
499517 new AlertDialog .Builder (requireContext ())
@@ -507,16 +525,16 @@ public void onItemClick(ContactSelectionListItem contact) {
507525 if (onContactSelectedListener != null ) {
508526 if (onContactSelectedListener .onBeforeContactSelected (contact .getRecipientId (), contact .getNumber ())) {
509527 markContactSelected (selectedContact );
510- cursorRecyclerViewAdapter .notifyItemChanged ( recyclerView . getChildAdapterPosition ( contact ), ContactSelectionListAdapter .PAYLOAD_SELECTION_CHANGE );
528+ cursorRecyclerViewAdapter .notifyItemRangeChanged ( 0 , cursorRecyclerViewAdapter . getItemCount ( ), ContactSelectionListAdapter .PAYLOAD_SELECTION_CHANGE );
511529 }
512530 } else {
513531 markContactSelected (selectedContact );
514- cursorRecyclerViewAdapter .notifyItemChanged ( recyclerView . getChildAdapterPosition ( contact ), ContactSelectionListAdapter .PAYLOAD_SELECTION_CHANGE );
532+ cursorRecyclerViewAdapter .notifyItemRangeChanged ( 0 , cursorRecyclerViewAdapter . getItemCount ( ), ContactSelectionListAdapter .PAYLOAD_SELECTION_CHANGE );
515533 }
516534 }
517535 } else {
518536 markContactUnselected (selectedContact );
519- cursorRecyclerViewAdapter .notifyItemChanged ( recyclerView . getChildAdapterPosition ( contact ), ContactSelectionListAdapter .PAYLOAD_SELECTION_CHANGE );
537+ cursorRecyclerViewAdapter .notifyItemRangeChanged ( 0 , cursorRecyclerViewAdapter . getItemCount ( ), ContactSelectionListAdapter .PAYLOAD_SELECTION_CHANGE );
520538
521539 if (onContactSelectedListener != null ) {
522540 onContactSelectedListener .onContactDeselected (contact .getRecipientId (), contact .getNumber ());
@@ -611,7 +629,11 @@ private void addChip(@NonNull ContactChip chip) {
611629 chipGroup .addView (chip );
612630 updateGroupLimit (getChipCount ());
613631 if (selectionWarningLimitReachedExactly ()) {
614- GroupLimitDialog .showRecommendedLimitMessage (requireContext ());
632+ if (onSelectionLimitReachedListener != null ) {
633+ onSelectionLimitReachedListener .onSuggestedLimitReached (selectionLimit .getRecommendedLimit ());
634+ } else {
635+ GroupLimitDialog .showRecommendedLimitMessage (requireContext ());
636+ }
615637 }
616638 }
617639
@@ -633,6 +655,10 @@ private void registerChipRecipientObserver(@NonNull ContactChip chip, @Nullable
633655 }
634656
635657 private void setChipGroupVisibility (int visibility ) {
658+ if (!requireActivity ().getIntent ().getBooleanExtra (DISPLAY_CHIPS , true )) {
659+ return ;
660+ }
661+
636662 TransitionManager .beginDelayedTransition (constraintLayout , new AutoTransition ().setDuration (CHIP_GROUP_REVEAL_DURATION_MS ));
637663
638664 ConstraintSet constraintSet = new ConstraintSet ();
@@ -641,10 +667,6 @@ private void setChipGroupVisibility(int visibility) {
641667 constraintSet .applyTo (constraintLayout );
642668 }
643669
644- public void setOnContactSelectedListener (OnContactSelectedListener onContactSelectedListener ) {
645- this .onContactSelectedListener = onContactSelectedListener ;
646- }
647-
648670 public void setOnRefreshListener (SwipeRefreshLayout .OnRefreshListener onRefreshListener ) {
649671 this .swipeRefresh .setOnRefreshListener (onRefreshListener );
650672 }
@@ -660,6 +682,11 @@ public interface OnContactSelectedListener {
660682 void onContactDeselected (Optional <RecipientId > recipientId , String number );
661683 }
662684
685+ public interface OnSelectionLimitReachedListener {
686+ void onSuggestedLimitReached (int limit );
687+ void onHardLimitReached (int limit );
688+ }
689+
663690 public interface ListCallback {
664691 void onInvite ();
665692 void onNewGroup (boolean forceV1 );
0 commit comments