Show contact pictures in recipients dropdown

This commit is contained in:
str4d
2014-07-02 00:38:47 +00:00
parent 87df2ff77c
commit 5f9879eb0f
5 changed files with 84 additions and 39 deletions

1
TODO
View File

@@ -14,6 +14,5 @@ Tasks:
Features:
- Import/export identities
-- Export Destination / make it copyable
- Show contact pictures in recipients dropdown
- Add optional CC: and BCC: fields
- "Empty trash" option in Trash folder

View File

@@ -29,6 +29,7 @@ import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
@@ -40,6 +41,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
@@ -107,7 +109,9 @@ public class NewEmailFragment extends Fragment {
String quoteMsgFolder = getArguments().getString(QUOTE_MSG_FOLDER);
String quoteMsgId = getArguments().getString(QUOTE_MSG_ID);
Email origEmail = null;
String recipientName = null;
String recipientAddr = null;
Bitmap recipientPic = null;
String origSubject = null;
String origContent = null;
String origFrom = null;
@@ -116,8 +120,19 @@ public class NewEmailFragment extends Fragment {
if (origEmail != null) {
mSenderKey = BoteHelper.extractEmailDestination(
BoteHelper.getOneLocalRecipient(origEmail).toString());
recipientAddr = BoteHelper.getNameAndDestination(
String recipient = BoteHelper.getNameAndDestination(
origEmail.getReplyAddress(I2PBote.getInstance().getIdentities()));
recipientName = BoteHelper.extractName(recipient);
recipientAddr = BoteHelper.extractEmailDestination(recipient);
if (recipientAddr == null) { // Assume external address
recipientAddr = recipient;
if (recipientName.isEmpty())
recipientName = recipientAddr;
} else {
if (recipientName.isEmpty()) // Dest with no name
recipientName = recipientAddr.substring(0, 5);
recipientPic = BoteHelper.getPictureForDestination(recipientAddr);
}
origSubject = origEmail.getSubject();
origContent = origEmail.getText();
origFrom = BoteHelper.getShortSenderName(origEmail.getOneFromAddress(), 50);
@@ -144,7 +159,8 @@ public class NewEmailFragment extends Fragment {
List<Person> contacts = new ArrayList<Person>();
try {
for (Contact contact : I2PBote.getInstance().getAddressBook().getAll()) {
contacts.add(new Person(contact.getName(), contact.getBase64Dest()));
contacts.add(new Person(contact.getName(), contact.getBase64Dest(),
BoteHelper.decodePicture(contact.getPictureBase64())));
}
} catch (PasswordException e) {
// TODO handle
@@ -156,20 +172,30 @@ public class NewEmailFragment extends Fragment {
mask = mask.toLowerCase(Locale.US);
return obj.getName().toLowerCase(Locale.US).startsWith(mask) || obj.getAddress().toLowerCase(Locale.US).startsWith(mask);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v;
if (convertView == null)
v = ((LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.listitem_contact, parent, false);
else
v = convertView;
setViewContent(v, position);
return v;
}
private void setViewContent(View v, int position) {
Person person = getItem(position);
((TextView)v.findViewById(R.id.contact_name)).setText(person.getName());
if (person.getPicture() != null)
((ImageView)v.findViewById(R.id.contact_picture))
.setImageBitmap(person.getPicture());
}
};
mRecipients = (ContactsCompletionView) view.findViewById(R.id.recipients);
mRecipients.setAdapter(mAdapter);
if (recipientAddr != null) {
String name = BoteHelper.extractName(recipientAddr);
String address = BoteHelper.extractEmailDestination(recipientAddr);
if (address == null) { // Assume external address
address = recipientAddr;
if (name.isEmpty())
name = address;
} else if (name.isEmpty()) // Dest with no name
name = address.substring(0, 5);
mRecipients.addObject(new Person(name, address));
mRecipients.addObject(new Person(recipientName, recipientAddr, recipientPic));
}
mSubject = (EditText) view.findViewById(R.id.subject);

View File

@@ -35,7 +35,6 @@ public class BoteHelper extends GeneralHelper {
* user, so their name is already "translated".
* @param ctx Android Context to get strings from.
* @param folder The folder.
* @param showNew Should the name contain the number of new messages?
* @return The name of the folder.
* @throws PasswordException
*/
@@ -94,30 +93,45 @@ public class BoteHelper extends GeneralHelper {
String base64dest = extractEmailDestination(address);
if (base64dest != null) {
// Address was found; try address book first
Contact c = getContact(base64dest);
if (c != null) {
// Address is in address book
String pic = c.getPictureBase64();
if (pic != null) {
return decodePicture(pic);
}
} else {
// Address is an identity
EmailIdentity i = getIdentity(base64dest);
if (i != null) {
String pic = i.getPictureBase64();
if (pic != null) {
return decodePicture(pic);
}
}
}
return getPictureForDestination(base64dest);
}
// Address not found anywhere, or found and has no picture
return null;
}
/**
* Get a Bitmap containing the picture for the contact or identity
* corresponding to the given Destination.
* @param base64dest
* @return a Bitmap, or null if no picture was found.
* @throws PasswordException
* @throws IOException
* @throws GeneralSecurityException
*/
public static Bitmap getPictureForDestination(String base64dest) throws PasswordException, IOException, GeneralSecurityException {
// Address was found; try address book first
Contact c = getContact(base64dest);
if (c != null) {
// Address is in address book
String pic = c.getPictureBase64();
if (pic != null) {
return decodePicture(pic);
}
} else {
// Address is an identity
EmailIdentity i = getIdentity(base64dest);
if (i != null) {
String pic = i.getPictureBase64();
if (pic != null) {
return decodePicture(pic);
}
}
}
// Address is not known
return null;
}
public static Bitmap decodePicture(String picB64) {
if (picB64 == null)
return null;

View File

@@ -45,32 +45,34 @@ public class ContactsCompletionView extends TokenCompleteTextView {
// Check if it is a known Destination
Contact c = BoteHelper.getContact(completionText);
if (c != null)
return new Person(c.getName(), c.getBase64Dest());
return new Person(c.getName(), c.getBase64Dest(),
BoteHelper.decodePicture(c.getPictureBase64()));
// Check if it is a name
SortedSet<Contact> contacts = I2PBote.getInstance().getAddressBook().getAll();
for (Contact contact : contacts) {
if (contact.getName().startsWith(completionText))
return new Person(contact.getName(), contact.getBase64Dest());
return new Person(contact.getName(), contact.getBase64Dest(),
BoteHelper.decodePicture(contact.getPictureBase64()));
}
// Try as a new Destination
try {
new EmailDestination(completionText);
return new Person(completionText.substring(0, 5), completionText);
return new Person(completionText.substring(0, 5), completionText, null);
} catch (GeneralSecurityException e) {
// Not a valid Destination
// Assume the user meant an external address
completionText = completionText.replace(" ", "") + "@example.com";
return new Person(completionText, completionText, true);
return new Person(completionText, completionText, null, true);
}
} catch (PasswordException e) {
// TODO handle
completionText = completionText.replace(" ", "") + "@example.com";
return new Person(completionText, completionText, true);
return new Person(completionText, completionText, null, true);
}
} else {
return new Person(completionText, completionText, true);
return new Person(completionText, completionText, null, true);
}
}
}

View File

@@ -1,18 +1,22 @@
package i2p.bote.android.util;
import android.graphics.Bitmap;
import java.io.Serializable;
public class Person implements Serializable {
private static final long serialVersionUID = -2874686247798691378L;
private String name;
private String address;
private Bitmap picture;
private boolean isExternal;
public Person(String n, String a) { this(n, a, false); }
public Person(String n, String a, boolean e) { name = n; address = a; isExternal = e; }
public Person(String n, String a, Bitmap p) { this(n, a, p, false); }
public Person(String n, String a, Bitmap p, boolean e) { name = n; address = a; picture = p; isExternal = e; }
public String getName() { return name; }
public String getAddress() { return address; }
public Bitmap getPicture() { return picture; }
public boolean isExternal() { return isExternal; }
@Override