@ -43,7 +43,9 @@ import org.thoughtcrime.securesms.util.StickyHeaderDecoration.StickyHeaderAdapte
import org.thoughtcrime.securesms.util.Util ;
import java.util.HashMap ;
import java.util.HashSet ;
import java.util.Map ;
import java.util.Set ;
/ * *
* List adapter to display all contacts and their related information
@ -56,6 +58,9 @@ public class ContactSelectionListAdapter extends CursorRecyclerViewAdapter<ViewH
{
private final static String TAG = ContactSelectionListAdapter . class . getSimpleName ( ) ;
private static final int VIEW_TYPE_CONTACT = 0 ;
private static final int VIEW_TYPE_DIVIDER = 1 ;
private final static int STYLE_ATTRIBUTES [ ] = new int [ ] { R . attr . contact_selection_push_user ,
R . attr . contact_selection_lay_user } ;
@ -65,10 +70,21 @@ public class ContactSelectionListAdapter extends CursorRecyclerViewAdapter<ViewH
private final ItemClickListener clickListener ;
private final GlideRequests glideRequests ;
private final HashMap < Long , String > selectedContacts = new HashMap < > ( ) ;
private final Set < String > selectedContacts = new HashSet < > ( ) ;
public abstract static class ViewHolder extends RecyclerView . ViewHolder {
public ViewHolder ( View itemView ) {
super ( itemView ) ;
}
public abstract void bind ( @NonNull GlideRequests glideRequests , int type , String name , String number , String label , int color , boolean multiSelect ) ;
public abstract void unbind ( @NonNull GlideRequests glideRequests ) ;
public abstract void setChecked ( boolean checked ) ;
}
public static class ViewHolder extends RecyclerView . ViewHolder {
public ViewHolder ( @NonNull final View itemView ,
public static class Contact ViewHolder extends ViewHolder {
Contact ViewHolder( @NonNull final View itemView ,
@Nullable final ItemClickListener clickListener )
{
super ( itemView ) ;
@ -80,10 +96,45 @@ public class ContactSelectionListAdapter extends CursorRecyclerViewAdapter<ViewH
public ContactSelectionListItem getView ( ) {
return ( ContactSelectionListItem ) itemView ;
}
public void bind ( @NonNull GlideRequests glideRequests , int type , String name , String number , String label , int color , boolean multiSelect ) {
getView ( ) . set ( glideRequests , type , name , number , label , color , multiSelect ) ;
}
@Override
public void unbind ( @NonNull GlideRequests glideRequests ) {
getView ( ) . unbind ( glideRequests ) ;
}
@Override
public void setChecked ( boolean checked ) {
getView ( ) . setChecked ( checked ) ;
}
}
public static class DividerViewHolder extends ViewHolder {
private final TextView label ;
DividerViewHolder ( View itemView ) {
super ( itemView ) ;
this . label = itemView . findViewById ( R . id . label ) ;
}
@Override
public void bind ( @NonNull GlideRequests glideRequests , int type , String name , String number , String label , int color , boolean multiSelect ) {
this . label . setText ( name ) ;
}
@Override
public void unbind ( @NonNull GlideRequests glideRequests ) { }
@Override
public void setChecked ( boolean checked ) { }
}
public static class HeaderViewHolder extends RecyclerView . ViewHolder {
public HeaderViewHolder ( View itemView ) {
static class HeaderViewHolder extends RecyclerView . ViewHolder {
HeaderViewHolder( View itemView ) {
super ( itemView ) ;
}
}
@ -106,17 +157,23 @@ public class ContactSelectionListAdapter extends CursorRecyclerViewAdapter<ViewH
public long getHeaderId ( int i ) {
if ( ! isActiveCursor ( ) ) return - 1 ;
return Util . hashCode ( getHeaderString ( i ) , isPush ( i ) ) ;
int contactType = getContactType ( i ) ;
if ( contactType = = ContactsDatabase . DIVIDER_TYPE ) return - 1 ;
return Util . hashCode ( getHeaderString ( i ) , getContactType ( i ) ) ;
}
@Override
public ViewHolder onCreateItemViewHolder ( ViewGroup parent , int viewType ) {
return new ViewHolder ( li . inflate ( R . layout . contact_selection_list_item , parent , false ) , clickListener ) ;
if ( viewType = = VIEW_TYPE_CONTACT ) {
return new ContactViewHolder ( li . inflate ( R . layout . contact_selection_list_item , parent , false ) , clickListener ) ;
} else {
return new DividerViewHolder ( li . inflate ( R . layout . contact_selection_list_divider , parent , false ) ) ;
}
}
@Override
public void onBindItemViewHolder ( ViewHolder viewHolder , @NonNull Cursor cursor ) {
long id = cursor . getLong ( cursor . getColumnIndexOrThrow ( ContactsDatabase . ID_COLUMN ) ) ;
int contactType = cursor . getInt ( cursor . getColumnIndexOrThrow ( ContactsDatabase . CONTACT_TYPE_COLUMN ) ) ;
String name = cursor . getString ( cursor . getColumnIndexOrThrow ( ContactsDatabase . NAME_COLUMN ) ) ;
String number = cursor . getString ( cursor . getColumnIndexOrThrow ( ContactsDatabase . NUMBER_COLUMN ) ) ;
@ -128,11 +185,21 @@ public class ContactSelectionListAdapter extends CursorRecyclerViewAdapter<ViewH
int color = ( contactType = = ContactsDatabase . PUSH_TYPE ) ? drawables . getColor ( 0 , 0xa0000000 ) :
drawables . getColor ( 1 , 0xff000000 ) ;
viewHolder . getView ( ) . unbind ( glideRequests ) ;
viewHolder . getView ( ) . set ( glideRequests , id , contactType , name , number , labelText , color , multiSelect ) ;
viewHolder . getView ( ) . setChecked ( selectedContacts . containsKey ( id ) ) ;
viewHolder . unbind ( glideRequests ) ;
viewHolder . bind ( glideRequests , contactType , name , number , labelText , color , multiSelect ) ;
viewHolder . setChecked ( selectedContacts . contains ( number ) ) ;
}
@Override
public int getItemViewType ( @NonNull Cursor cursor ) {
if ( cursor . getInt ( cursor . getColumnIndexOrThrow ( ContactsDatabase . CONTACT_TYPE_COLUMN ) ) = = ContactsDatabase . DIVIDER_TYPE ) {
return VIEW_TYPE_DIVIDER ;
} else {
return VIEW_TYPE_CONTACT ;
}
}
@Override
public HeaderViewHolder onCreateHeaderViewHolder ( ViewGroup parent ) {
return new HeaderViewHolder ( LayoutInflater . from ( getContext ( ) ) . inflate ( R . layout . contact_selection_recyclerview_header , parent , false ) ) ;
@ -145,7 +212,7 @@ public class ContactSelectionListAdapter extends CursorRecyclerViewAdapter<ViewH
@Override
public void onItemViewRecycled ( ViewHolder holder ) {
holder . getView( ) . unbind( glideRequests ) ;
holder . unbind( glideRequests ) ;
}
@Override
@ -153,7 +220,7 @@ public class ContactSelectionListAdapter extends CursorRecyclerViewAdapter<ViewH
return getHeaderString ( position ) ;
}
public Map< Long , String > getSelectedContacts ( ) {
public Set< String > getSelectedContacts ( ) {
return selectedContacts ;
}
@ -169,8 +236,15 @@ public class ContactSelectionListAdapter extends CursorRecyclerViewAdapter<ViewH
}
private @NonNull String getHeaderString ( int position ) {
int contactType = getContactType ( position ) ;
if ( contactType = = ContactsDatabase . RECENT_TYPE | | contactType = = ContactsDatabase . DIVIDER_TYPE ) {
return " " ;
}
Cursor cursor = getCursorAtPositionOrThrow ( position ) ;
String letter = cursor . getString ( cursor . getColumnIndexOrThrow ( ContactsDatabase . NAME_COLUMN ) ) ;
if ( ! TextUtils . isEmpty ( letter ) ) {
String firstChar = letter . trim ( ) . substring ( 0 , 1 ) . toUpperCase ( ) ;
if ( Character . isLetterOrDigit ( firstChar . codePointAt ( 0 ) ) ) {
@ -181,9 +255,13 @@ public class ContactSelectionListAdapter extends CursorRecyclerViewAdapter<ViewH
return "#" ;
}
private boolean isPush ( int position ) {
private int getContactType ( int position ) {
final Cursor cursor = getCursorAtPositionOrThrow ( position ) ;
return cursor . getInt ( cursor . getColumnIndexOrThrow ( ContactsDatabase . CONTACT_TYPE_COLUMN ) ) = = ContactsDatabase . PUSH_TYPE ;
return cursor . getInt ( cursor . getColumnIndexOrThrow ( ContactsDatabase . CONTACT_TYPE_COLUMN ) ) ;
}
private boolean isPush ( int position ) {
return getContactType ( position ) = = ContactsDatabase . PUSH_TYPE ;
}
public interface ItemClickListener {