mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-24 16:57:50 +00:00
Refactor ContactSelectionListAdapter and associated views.
Fixes #3181 Closes #3197 // FREEBIE
This commit is contained in:
parent
3e890e11d9
commit
636b11abea
@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<org.thoughtcrime.securesms.contacts.ContactSelectionListItem
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:attr/listPreferredItemHeight"
|
||||
android:paddingRight="25dip">
|
||||
@ -16,23 +17,41 @@
|
||||
android:scaleType="centerCrop"
|
||||
android:contentDescription="@string/SingleContactSelectionActivity_contact_photo" />
|
||||
|
||||
<TextView android:id="@+id/number"
|
||||
<LinearLayout
|
||||
android:id="@+id/number_container"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dip"
|
||||
android:layout_marginTop="-8dip"
|
||||
android:layout_marginLeft="14dip"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_toRightOf="@id/contact_photo_image">
|
||||
|
||||
<TextView android:id="@+id/number"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="marquee"
|
||||
android:layout_toRightOf="@id/contact_photo_image"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:fontFamily="sans-serif-light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="10dip"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?contact_selection_label_text"
|
||||
android:fontFamily="sans-serif-light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView android:id="@+id/name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/number"
|
||||
android:layout_above="@id/number_container"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginBottom="1dip"
|
||||
android:layout_marginLeft="14dip"
|
||||
@ -51,4 +70,4 @@
|
||||
android:focusable="false"
|
||||
android:clickable="false" />
|
||||
|
||||
</RelativeLayout>
|
||||
</org.thoughtcrime.securesms.contacts.ContactSelectionListItem>
|
||||
|
@ -380,11 +380,9 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity {
|
||||
|
||||
switch (reqCode) {
|
||||
case PICK_CONTACT:
|
||||
List<ContactData> selected = data.getParcelableArrayListExtra("contacts");
|
||||
for (ContactData contact : selected) {
|
||||
for (ContactAccessor.NumberData numberData : contact.numbers) {
|
||||
Recipient recipient = RecipientFactory.getRecipientsFromString(this, numberData.number, false)
|
||||
.getPrimaryRecipient();
|
||||
List<String> selected = data.getStringArrayListExtra("contacts");
|
||||
for (String contact : selected) {
|
||||
Recipient recipient = RecipientFactory.getRecipientsFromString(this, contact, false).getPrimaryRecipient();
|
||||
|
||||
if (!selectedContacts.contains(recipient) &&
|
||||
(existingContacts == null || !existingContacts.contains(recipient)) &&
|
||||
@ -392,7 +390,6 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity {
|
||||
addSelectedContact(recipient);
|
||||
}
|
||||
}
|
||||
}
|
||||
syncAdapterWithSelectedContacts();
|
||||
break;
|
||||
|
||||
|
@ -24,25 +24,15 @@ import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import org.thoughtcrime.securesms.contacts.ContactAccessor;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.NumberUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.thoughtcrime.securesms.contacts.ContactAccessor.ContactData;
|
||||
|
||||
/**
|
||||
* Activity container for selecting a list of contacts.
|
||||
@ -67,7 +57,6 @@ public class NewConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
@Override
|
||||
protected void onCreate(Bundle icicle, @NonNull MasterSecret masterSecret) {
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
setContentView(R.layout.new_conversation_activity);
|
||||
initializeResources();
|
||||
}
|
||||
@ -94,7 +83,6 @@ public class NewConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
super.onOptionsItemSelected(item);
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_refresh_directory: handleDirectoryRefresh(); return true;
|
||||
case R.id.menu_selection_finished: handleSelectionFinished(); return true;
|
||||
case android.R.id.home: finish(); return true;
|
||||
}
|
||||
return false;
|
||||
@ -104,24 +92,14 @@ public class NewConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
contactsFragment = (PushContactSelectionListFragment) getSupportFragmentManager().findFragmentById(R.id.contact_selection_list_fragment);
|
||||
contactsFragment.setOnContactSelectedListener(new PushContactSelectionListFragment.OnContactSelectedListener() {
|
||||
@Override
|
||||
public void onContactSelected(ContactData contactData) {
|
||||
public void onContactSelected(String number) {
|
||||
Log.i(TAG, "Choosing contact from list.");
|
||||
Recipients recipients = contactDataToRecipients(contactData);
|
||||
Recipients recipients = RecipientFactory.getRecipientsFromString(NewConversationActivity.this, number, true);
|
||||
openNewConversation(recipients);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void handleSelectionFinished() {
|
||||
final Intent resultIntent = getIntent();
|
||||
final List<ContactData> selectedContacts = contactsFragment.getSelectedContacts();
|
||||
if (selectedContacts != null) {
|
||||
resultIntent.putParcelableArrayListExtra("contacts", new ArrayList<>(contactsFragment.getSelectedContacts()));
|
||||
}
|
||||
setResult(RESULT_OK, resultIntent);
|
||||
finish();
|
||||
}
|
||||
|
||||
private void handleDirectoryRefresh() {
|
||||
DirectoryHelper.refreshDirectoryWithProgressDialog(this, new DirectoryHelper.DirectoryUpdateFinishedListener() {
|
||||
@Override
|
||||
@ -131,20 +109,6 @@ public class NewConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
});
|
||||
}
|
||||
|
||||
private Recipients contactDataToRecipients(ContactData contactData) {
|
||||
if (contactData == null || contactData.numbers == null) return null;
|
||||
Recipients recipients = new Recipients(new LinkedList<Recipient>());
|
||||
for (ContactAccessor.NumberData numberData : contactData.numbers) {
|
||||
if (NumberUtil.isValidSmsOrEmailOrGroup(numberData.number)) {
|
||||
Recipients recipientsForNumber = RecipientFactory.getRecipientsFromString(NewConversationActivity.this,
|
||||
numberData.number,
|
||||
false);
|
||||
recipients.getRecipientsList().addAll(recipientsForNumber.getRecipientsList());
|
||||
}
|
||||
}
|
||||
return recipients;
|
||||
}
|
||||
|
||||
private void openNewConversation(Recipients recipients) {
|
||||
if (recipients != null) {
|
||||
Intent intent = new Intent(this, ConversationActivity.class);
|
||||
|
@ -19,7 +19,6 @@ package org.thoughtcrime.securesms;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
@ -30,12 +29,9 @@ import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.thoughtcrime.securesms.contacts.ContactAccessor.ContactData;
|
||||
|
||||
/**
|
||||
* Activity container for selecting a list of contacts.
|
||||
*
|
||||
@ -98,21 +94,16 @@ public class PushContactSelectionActivity extends PassphraseRequiredActionBarAct
|
||||
private void initializeResources() {
|
||||
contactsFragment = (PushContactSelectionListFragment) getSupportFragmentManager().findFragmentById(R.id.contact_selection_list_fragment);
|
||||
contactsFragment.setMultiSelect(true);
|
||||
contactsFragment.setOnContactSelectedListener(new PushContactSelectionListFragment.OnContactSelectedListener() {
|
||||
@Override
|
||||
public void onContactSelected(ContactData contactData) {
|
||||
Log.i(TAG, "Choosing contact from list.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void handleSelectionFinished() {
|
||||
Intent resultIntent = getIntent();
|
||||
List<String> selectedContacts = contactsFragment.getSelectedContacts();
|
||||
|
||||
final Intent resultIntent = getIntent();
|
||||
final List<ContactData> selectedContacts = contactsFragment.getSelectedContacts();
|
||||
if (selectedContacts != null) {
|
||||
resultIntent.putParcelableArrayListExtra("contacts", new ArrayList<ContactData>(contactsFragment.getSelectedContacts()));
|
||||
resultIntent.putStringArrayListExtra("contacts", new ArrayList<>(selectedContacts));
|
||||
}
|
||||
|
||||
setResult(RESULT_OK, resultIntent);
|
||||
finish();
|
||||
}
|
||||
|
@ -19,14 +19,12 @@ package org.thoughtcrime.securesms;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.provider.ContactsContract;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.widget.CursorAdapter;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -35,11 +33,8 @@ import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.thoughtcrime.securesms.contacts.ContactAccessor;
|
||||
import org.thoughtcrime.securesms.contacts.ContactAccessor.ContactData;
|
||||
import org.thoughtcrime.securesms.contacts.ContactSelectionListAdapter;
|
||||
import org.thoughtcrime.securesms.contacts.ContactSelectionListAdapter.ViewHolder;
|
||||
import org.thoughtcrime.securesms.contacts.ContactSelectionListAdapter.DataHolder;
|
||||
import org.thoughtcrime.securesms.contacts.ContactsDatabase;
|
||||
import org.thoughtcrime.securesms.contacts.ContactSelectionListItem;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@ -61,13 +56,12 @@ public class PushContactSelectionListFragment extends Fragment
|
||||
|
||||
private TextView emptyText;
|
||||
|
||||
private Map<Long, ContactData> selectedContacts;
|
||||
private Map<Long, String> selectedContacts;
|
||||
private OnContactSelectedListener onContactSelectedListener;
|
||||
private boolean multi = false;
|
||||
private StickyListHeadersListView listView;
|
||||
private EditText filterEditText;
|
||||
private String cursorFilter;
|
||||
|
||||
private boolean multi = false;
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle icicle) {
|
||||
@ -91,10 +85,10 @@ public class PushContactSelectionListFragment extends Fragment
|
||||
return inflater.inflate(R.layout.push_contact_selection_list_activity, container, false);
|
||||
}
|
||||
|
||||
public List<ContactData> getSelectedContacts() {
|
||||
public List<String> getSelectedContacts() {
|
||||
if (selectedContacts == null) return null;
|
||||
|
||||
List<ContactData> selected = new LinkedList<ContactData>();
|
||||
List<String> selected = new LinkedList<>();
|
||||
selected.addAll(selectedContacts.values());
|
||||
|
||||
return selected;
|
||||
@ -104,23 +98,6 @@ public class PushContactSelectionListFragment extends Fragment
|
||||
this.multi = multi;
|
||||
}
|
||||
|
||||
private void addContact(DataHolder data) {
|
||||
final ContactData contactData = new ContactData(data.id, data.name);
|
||||
final CharSequence label = ContactsContract.CommonDataKinds.Phone.getTypeLabel(getResources(),
|
||||
data.numberType, "");
|
||||
contactData.numbers.add(new ContactAccessor.NumberData(label.toString(), data.number));
|
||||
if (multi) {
|
||||
selectedContacts.put(contactData.id, contactData);
|
||||
}
|
||||
if (onContactSelectedListener != null) {
|
||||
onContactSelectedListener.onContactSelected(contactData);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeContact(DataHolder contactData) {
|
||||
selectedContacts.remove(contactData.id);
|
||||
}
|
||||
|
||||
private void initializeCursor() {
|
||||
ContactSelectionListAdapter adapter = new ContactSelectionListAdapter(getActivity(), null, multi);
|
||||
selectedContacts = adapter.getSelectedContacts();
|
||||
@ -135,7 +112,8 @@ public class PushContactSelectionListFragment extends Fragment
|
||||
listView.setFastScrollEnabled(true);
|
||||
listView.setDrawingListUnderStickyHeader(false);
|
||||
listView.setOnItemClickListener(new ListClickListener());
|
||||
filterEditText = (EditText) getView().findViewById(R.id.filter);
|
||||
|
||||
EditText filterEditText = (EditText) getView().findViewById(R.id.filter);
|
||||
filterEditText.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
||||
@ -185,20 +163,15 @@ public class PushContactSelectionListFragment extends Fragment
|
||||
private class ListClickListener implements AdapterView.OnItemClickListener {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> l, View v, int position, long id) {
|
||||
final DataHolder contactData = (DataHolder) v.getTag(R.id.contact_info_tag);
|
||||
final ViewHolder holder = (ViewHolder) v.getTag(R.id.holder_tag);
|
||||
ContactSelectionListItem contact = (ContactSelectionListItem)v;
|
||||
|
||||
if (holder == null) {
|
||||
Log.w(TAG, "ViewHolder was null, can't proceed with click logic.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (multi) holder.checkBox.toggle();
|
||||
|
||||
if (!multi || holder.checkBox.isChecked()) {
|
||||
addContact(contactData);
|
||||
} else if (multi) {
|
||||
removeContact(contactData);
|
||||
if (!multi || !selectedContacts.containsKey(contact.getContactId())) {
|
||||
selectedContacts.put(contact.getContactId(), contact.getNumber());
|
||||
contact.setChecked(true);
|
||||
if (onContactSelectedListener != null) onContactSelectedListener.onContactSelected(contact.getNumber());
|
||||
} else {
|
||||
selectedContacts.remove(contact.getContactId());
|
||||
contact.setChecked(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -208,6 +181,6 @@ public class PushContactSelectionListFragment extends Fragment
|
||||
}
|
||||
|
||||
public interface OnContactSelectedListener {
|
||||
public void onContactSelected(ContactData contactData);
|
||||
public void onContactSelected(String number);
|
||||
}
|
||||
}
|
||||
|
@ -21,27 +21,15 @@ import android.content.res.TypedArray;
|
||||
import android.database.Cursor;
|
||||
import android.provider.ContactsContract;
|
||||
import android.support.v4.widget.CursorAdapter;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.BitmapWorkerRunnable;
|
||||
import org.thoughtcrime.securesms.util.BitmapWorkerRunnable.AsyncDrawable;
|
||||
import org.thoughtcrime.securesms.util.TaggedFutureTask;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
|
||||
|
||||
@ -53,53 +41,22 @@ import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
|
||||
public class ContactSelectionListAdapter extends CursorAdapter
|
||||
implements StickyListHeadersAdapter
|
||||
{
|
||||
private final static String TAG = "ContactListAdapter";
|
||||
|
||||
private final static ExecutorService photoResolver = Util.newSingleThreadedLifoExecutor();
|
||||
private final static String TAG = ContactSelectionListAdapter.class.getSimpleName();
|
||||
|
||||
private final static int STYLE_ATTRIBUTES[] = new int[]{R.attr.contact_selection_push_user,
|
||||
R.attr.contact_selection_lay_user,
|
||||
R.attr.contact_selection_label_text};
|
||||
R.attr.contact_selection_lay_user};
|
||||
|
||||
private int TYPE_COLUMN = -1;
|
||||
private int NAME_COLUMN = -1;
|
||||
private int NUMBER_COLUMN = -1;
|
||||
private int NUMBER_TYPE_COLUMN = -1;
|
||||
private int LABEL_COLUMN = -1;
|
||||
private int ID_COLUMN = -1;
|
||||
|
||||
private final Context context;
|
||||
private final boolean multiSelect;
|
||||
private final LayoutInflater li;
|
||||
private final TypedArray drawables;
|
||||
private final int scaledPhotoSize;
|
||||
|
||||
private final HashMap<Long, ContactAccessor.ContactData> selectedContacts = new HashMap<>();
|
||||
private final HashMap<Long, String> selectedContacts = new HashMap<>();
|
||||
|
||||
public ContactSelectionListAdapter(Context context, Cursor cursor, boolean multiSelect) {
|
||||
super(context, cursor, 0);
|
||||
this.context = context;
|
||||
this.li = LayoutInflater.from(context);
|
||||
this.drawables = context.obtainStyledAttributes(STYLE_ATTRIBUTES);
|
||||
this.multiSelect = multiSelect;
|
||||
this.scaledPhotoSize = context.getResources().getDimensionPixelSize(R.dimen.contact_selection_photo_size);
|
||||
}
|
||||
|
||||
public static class ViewHolder {
|
||||
public CheckBox checkBox;
|
||||
public TextView name;
|
||||
public TextView number;
|
||||
public ImageView contactPhoto;
|
||||
public int position;
|
||||
}
|
||||
|
||||
public static class DataHolder {
|
||||
public int type;
|
||||
public String name;
|
||||
public String number;
|
||||
public int numberType;
|
||||
public String label;
|
||||
public long id;
|
||||
}
|
||||
|
||||
public static class HeaderViewHolder {
|
||||
@ -108,83 +65,35 @@ public class ContactSelectionListAdapter extends CursorAdapter
|
||||
|
||||
@Override
|
||||
public View newView(Context context, Cursor cursor, ViewGroup parent) {
|
||||
final View v = li.inflate(R.layout.push_contact_selection_list_item, parent, false);
|
||||
final ViewHolder holder = new ViewHolder();
|
||||
|
||||
if (v != null) {
|
||||
holder.name = (TextView) v.findViewById(R.id.name);
|
||||
holder.number = (TextView) v.findViewById(R.id.number);
|
||||
holder.checkBox = (CheckBox) v.findViewById(R.id.check_box);
|
||||
holder.contactPhoto = (ImageView) v.findViewById(R.id.contact_photo_image);
|
||||
|
||||
if (!multiSelect) holder.checkBox.setVisibility(View.GONE);
|
||||
|
||||
v.setTag(R.id.holder_tag, holder);
|
||||
v.setTag(R.id.contact_info_tag, new DataHolder());
|
||||
}
|
||||
return v;
|
||||
return li.inflate(R.layout.push_contact_selection_list_item, parent, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor) {
|
||||
final DataHolder contactData = (DataHolder) view.getTag(R.id.contact_info_tag);
|
||||
final ViewHolder holder = (ViewHolder) view.getTag(R.id.holder_tag);
|
||||
if (holder == null) {
|
||||
Log.w(TAG, "ViewHolder was null. This should not happen.");
|
||||
return;
|
||||
}
|
||||
if (contactData == null) {
|
||||
Log.w(TAG, "DataHolder was null. This should not happen.");
|
||||
return;
|
||||
}
|
||||
if (ID_COLUMN < 0) {
|
||||
populateColumnIndices(cursor);
|
||||
}
|
||||
long id = cursor.getLong(cursor.getColumnIndexOrThrow(ContactsDatabase.ID_COLUMN));
|
||||
int type = cursor.getInt(cursor.getColumnIndexOrThrow(ContactsDatabase.TYPE_COLUMN));
|
||||
String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.NAME_COLUMN));
|
||||
String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.NUMBER_COLUMN));
|
||||
int numberType = cursor.getInt(cursor.getColumnIndexOrThrow(ContactsDatabase.NUMBER_TYPE_COLUMN));
|
||||
String label = cursor.getString(cursor.getColumnIndexOrThrow(ContactsDatabase.LABEL_COLUMN));
|
||||
String labelText = ContactsContract.CommonDataKinds.Phone.getTypeLabel(context.getResources(),
|
||||
numberType, label).toString();
|
||||
|
||||
contactData.type = cursor.getInt(TYPE_COLUMN);
|
||||
contactData.name = cursor.getString(NAME_COLUMN);
|
||||
contactData.number = cursor.getString(NUMBER_COLUMN);
|
||||
contactData.numberType = cursor.getInt(NUMBER_TYPE_COLUMN);
|
||||
contactData.label = cursor.getString(LABEL_COLUMN);
|
||||
contactData.id = cursor.getLong(ID_COLUMN);
|
||||
int color = (type == ContactsDatabase.PUSH_TYPE) ? drawables.getColor(0, 0xa0000000) :
|
||||
drawables.getColor(1, 0xff000000);
|
||||
|
||||
if (contactData.type != ContactsDatabase.PUSH_TYPE) {
|
||||
holder.name.setTextColor(drawables.getColor(1, 0xff000000));
|
||||
holder.number.setTextColor(drawables.getColor(1, 0xff000000));
|
||||
} else {
|
||||
holder.name.setTextColor(drawables.getColor(0, 0xa0000000));
|
||||
holder.number.setTextColor(drawables.getColor(0, 0xa0000000));
|
||||
}
|
||||
|
||||
if (selectedContacts.containsKey(contactData.id)) {
|
||||
holder.checkBox.setChecked(true);
|
||||
} else {
|
||||
holder.checkBox.setChecked(false);
|
||||
}
|
||||
|
||||
holder.name.setText(contactData.name);
|
||||
|
||||
if (contactData.number == null || contactData.number.isEmpty()) {
|
||||
holder.name.setEnabled(false);
|
||||
holder.number.setText("");
|
||||
} else if (contactData.type == ContactsDatabase.PUSH_TYPE) {
|
||||
holder.number.setText(contactData.number);
|
||||
} else {
|
||||
final CharSequence label = ContactsContract.CommonDataKinds.Phone.getTypeLabel(context.getResources(),
|
||||
contactData.numberType, contactData.label);
|
||||
final CharSequence numberWithLabel = contactData.number + " " + label;
|
||||
final Spannable numberLabelSpan = new SpannableString(numberWithLabel);
|
||||
numberLabelSpan.setSpan(new ForegroundColorSpan(drawables.getColor(2, 0xff444444)), contactData.number.length(), numberWithLabel.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
holder.number.setText(numberLabelSpan);
|
||||
}
|
||||
holder.contactPhoto.setImageDrawable(ContactPhotoFactory.getLoadingPhoto(context));
|
||||
if (contactData.id > -1) loadBitmap(contactData.number, holder.contactPhoto);
|
||||
((ContactSelectionListItem)view).unbind();
|
||||
((ContactSelectionListItem)view).set(id, type, name, number, labelText, color, multiSelect);
|
||||
((ContactSelectionListItem)view).setChecked(selectedContacts.containsKey(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getHeaderView(int i, View convertView, ViewGroup viewGroup) {
|
||||
final Cursor c = getCursor();
|
||||
final HeaderViewHolder holder;
|
||||
Cursor cursor = getCursor();
|
||||
|
||||
HeaderViewHolder holder;
|
||||
|
||||
if (convertView == null) {
|
||||
holder = new HeaderViewHolder();
|
||||
convertView = li.inflate(R.layout.push_contact_selection_list_header, viewGroup, false);
|
||||
@ -193,63 +102,26 @@ public class ContactSelectionListAdapter extends CursorAdapter
|
||||
} else {
|
||||
holder = (HeaderViewHolder) convertView.getTag();
|
||||
}
|
||||
c.moveToPosition(i);
|
||||
|
||||
final int type = c.getInt(c.getColumnIndexOrThrow(ContactsDatabase.TYPE_COLUMN));
|
||||
final int headerTextRes;
|
||||
switch (type) {
|
||||
case 1: headerTextRes = R.string.contact_selection_list__header_textsecure_users; break;
|
||||
default: headerTextRes = R.string.contact_selection_list__header_other; break;
|
||||
}
|
||||
holder.text.setText(headerTextRes);
|
||||
cursor.moveToPosition(i);
|
||||
|
||||
int type = cursor.getInt(cursor.getColumnIndexOrThrow(ContactsDatabase.TYPE_COLUMN));
|
||||
|
||||
if (type == ContactsDatabase.PUSH_TYPE) holder.text.setText(R.string.contact_selection_list__header_textsecure_users);
|
||||
else holder.text.setText(R.string.contact_selection_list__header_other);
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getHeaderId(int i) {
|
||||
final Cursor c = getCursor();
|
||||
c.moveToPosition(i);
|
||||
return c.getInt(c.getColumnIndexOrThrow(ContactsDatabase.TYPE_COLUMN));
|
||||
Cursor cursor = getCursor();
|
||||
cursor.moveToPosition(i);
|
||||
|
||||
return cursor.getInt(cursor.getColumnIndexOrThrow(ContactsDatabase.TYPE_COLUMN));
|
||||
}
|
||||
|
||||
public boolean cancelPotentialWork(String number, ImageView imageView) {
|
||||
final TaggedFutureTask<?> bitmapWorkerTask = AsyncDrawable.getBitmapWorkerTask(imageView);
|
||||
|
||||
if (bitmapWorkerTask != null) {
|
||||
final Object tag = bitmapWorkerTask.getTag();
|
||||
if (tag != null && !tag.equals(number)) {
|
||||
bitmapWorkerTask.cancel(true);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// FIXME -- It should be unnecessary to duplicate the existing asynchronous resolution
|
||||
// infrastructure we've built for Recipient objects here.
|
||||
|
||||
public void loadBitmap(String number, ImageView imageView) {
|
||||
if (cancelPotentialWork(number, imageView)) {
|
||||
final BitmapWorkerRunnable runnable = new BitmapWorkerRunnable(context, imageView, number, scaledPhotoSize);
|
||||
final TaggedFutureTask<?> task = new TaggedFutureTask<Void>(runnable, null, number);
|
||||
final AsyncDrawable asyncDrawable = new AsyncDrawable(task);
|
||||
|
||||
imageView.setImageDrawable(asyncDrawable);
|
||||
if (!task.isCancelled()) photoResolver.execute(new FutureTask<Void>(task, null));
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Long,ContactAccessor.ContactData> getSelectedContacts() {
|
||||
public Map<Long, String> getSelectedContacts() {
|
||||
return selectedContacts;
|
||||
}
|
||||
|
||||
private void populateColumnIndices(final Cursor cursor) {
|
||||
this.TYPE_COLUMN = cursor.getColumnIndexOrThrow(ContactsDatabase.TYPE_COLUMN);
|
||||
this.NAME_COLUMN = cursor.getColumnIndexOrThrow(ContactsDatabase.NAME_COLUMN);
|
||||
this.NUMBER_COLUMN = cursor.getColumnIndexOrThrow(ContactsDatabase.NUMBER_COLUMN);
|
||||
this.NUMBER_TYPE_COLUMN = cursor.getColumnIndexOrThrow(ContactsDatabase.NUMBER_TYPE_COLUMN);
|
||||
this.LABEL_COLUMN = cursor.getColumnIndexOrThrow(ContactsDatabase.LABEL_COLUMN);
|
||||
this.ID_COLUMN = cursor.getColumnIndexOrThrow(ContactsDatabase.ID_COLUMN);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,126 @@
|
||||
package org.thoughtcrime.securesms.contacts;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
|
||||
public class ContactSelectionListItem extends RelativeLayout implements Recipient.RecipientModifiedListener {
|
||||
|
||||
private ImageView contactPhotoImage;
|
||||
private TextView numberView;
|
||||
private TextView nameView;
|
||||
private TextView labelView;
|
||||
private CheckBox checkBox;
|
||||
|
||||
private long id;
|
||||
private String number;
|
||||
private Recipient recipient;
|
||||
|
||||
public ContactSelectionListItem(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ContactSelectionListItem(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public ContactSelectionListItem(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
this.contactPhotoImage = (ImageView) findViewById(R.id.contact_photo_image);
|
||||
this.numberView = (TextView) findViewById(R.id.number);
|
||||
this.labelView = (TextView) findViewById(R.id.label);
|
||||
this.nameView = (TextView) findViewById(R.id.name);
|
||||
this.checkBox = (CheckBox) findViewById(R.id.check_box);
|
||||
}
|
||||
|
||||
public void set(long id, int type, String name, String number, String label, int color, boolean multiSelect) {
|
||||
this.id = id;
|
||||
this.number = number;
|
||||
|
||||
if (number != null) {
|
||||
this.recipient = RecipientFactory.getRecipientsFromString(getContext(), number, true)
|
||||
.getPrimaryRecipient();
|
||||
}
|
||||
|
||||
this.nameView.setTextColor(color);
|
||||
this.numberView.setTextColor(color);
|
||||
|
||||
setText(type, name, number, label);
|
||||
setContactPhotoImage(recipient);
|
||||
|
||||
if (multiSelect) this.checkBox.setVisibility(View.VISIBLE);
|
||||
else this.checkBox.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
public void setChecked(boolean selected) {
|
||||
this.checkBox.setChecked(selected);
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
if (recipient != null) {
|
||||
recipient.removeListener(this);
|
||||
recipient = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void setText(int type, String name, String number, String label) {
|
||||
if (number == null || number.isEmpty()) {
|
||||
this.nameView.setEnabled(false);
|
||||
this.numberView.setText("");
|
||||
this.labelView.setVisibility(View.GONE);
|
||||
} else if (type == ContactsDatabase.PUSH_TYPE) {
|
||||
this.numberView.setText(number);
|
||||
this.nameView.setEnabled(true);
|
||||
this.labelView.setVisibility(View.GONE);
|
||||
} else {
|
||||
this.numberView.setText(number);
|
||||
this.nameView.setEnabled(true);
|
||||
this.labelView.setText(label);
|
||||
this.labelView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
this.nameView.setText(name);
|
||||
}
|
||||
|
||||
private void setContactPhotoImage(@Nullable Recipient recipient) {
|
||||
if (recipient!= null) {
|
||||
contactPhotoImage.setImageDrawable(recipient.getContactPhoto());
|
||||
recipient.addListener(this);
|
||||
} else {
|
||||
contactPhotoImage.setImageDrawable(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onModified(final Recipient recipient) {
|
||||
if (this.recipient == recipient) {
|
||||
this.contactPhotoImage.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
contactPhotoImage.setImageDrawable(recipient.getContactPhoto());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public long getContactId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getNumber() {
|
||||
return number;
|
||||
}
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2014 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.DrawableContainer;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.makeramen.RoundedDrawable;
|
||||
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* Runnable to load contact photos if they have them
|
||||
*
|
||||
* @author Jake McGinty
|
||||
*/
|
||||
public class BitmapWorkerRunnable implements Runnable {
|
||||
private final static String TAG = BitmapWorkerRunnable.class.getSimpleName();
|
||||
|
||||
private final WeakReference<ImageView> imageViewReference;
|
||||
private final Context context;
|
||||
private final int size;
|
||||
public final String number;
|
||||
|
||||
public BitmapWorkerRunnable(Context context, ImageView imageView, String number, int size) {
|
||||
this.imageViewReference = new WeakReference<>(imageView);
|
||||
this.context = context;
|
||||
this.size = size;
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final Recipient recipient = RecipientFactory.getRecipientsFromString(context, number, false).getPrimaryRecipient();
|
||||
final Drawable contactPhoto = recipient.getContactPhoto();
|
||||
|
||||
if (contactPhoto != null) {
|
||||
final ImageView imageView = imageViewReference.get();
|
||||
final TaggedFutureTask<?> bitmapWorkerTask = AsyncDrawable.getBitmapWorkerTask(imageView);
|
||||
|
||||
if (bitmapWorkerTask.getTag().equals(number) && imageView != null) {
|
||||
imageView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
imageView.setImageDrawable(contactPhoto);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class AsyncDrawable extends BitmapDrawable {
|
||||
private final WeakReference<TaggedFutureTask<?>> bitmapWorkerTaskReference;
|
||||
|
||||
public AsyncDrawable(TaggedFutureTask<?> bitmapWorkerTask) {
|
||||
bitmapWorkerTaskReference =
|
||||
new WeakReference<TaggedFutureTask<?>>(bitmapWorkerTask);
|
||||
}
|
||||
|
||||
public TaggedFutureTask<?> getBitmapWorkerTask() {
|
||||
return bitmapWorkerTaskReference.get();
|
||||
}
|
||||
|
||||
public static TaggedFutureTask<?> getBitmapWorkerTask(ImageView imageView) {
|
||||
if (imageView != null) {
|
||||
final Drawable drawable = imageView.getDrawable();
|
||||
if (drawable instanceof AsyncDrawable) {
|
||||
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
|
||||
return asyncDrawable.getBitmapWorkerTask();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user