Show contact pictures in recipients dropdown
This commit is contained in:
1
TODO
1
TODO
@@ -14,6 +14,5 @@ Tasks:
|
|||||||
Features:
|
Features:
|
||||||
- Import/export identities
|
- Import/export identities
|
||||||
-- Export Destination / make it copyable
|
-- Export Destination / make it copyable
|
||||||
- Show contact pictures in recipients dropdown
|
|
||||||
- Add optional CC: and BCC: fields
|
- Add optional CC: and BCC: fields
|
||||||
- "Empty trash" option in Trash folder
|
- "Empty trash" option in Trash folder
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import android.app.AlertDialog;
|
|||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.DialogFragment;
|
import android.support.v4.app.DialogFragment;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
@@ -40,6 +41,7 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
import android.widget.ImageView;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
@@ -107,7 +109,9 @@ public class NewEmailFragment extends Fragment {
|
|||||||
String quoteMsgFolder = getArguments().getString(QUOTE_MSG_FOLDER);
|
String quoteMsgFolder = getArguments().getString(QUOTE_MSG_FOLDER);
|
||||||
String quoteMsgId = getArguments().getString(QUOTE_MSG_ID);
|
String quoteMsgId = getArguments().getString(QUOTE_MSG_ID);
|
||||||
Email origEmail = null;
|
Email origEmail = null;
|
||||||
|
String recipientName = null;
|
||||||
String recipientAddr = null;
|
String recipientAddr = null;
|
||||||
|
Bitmap recipientPic = null;
|
||||||
String origSubject = null;
|
String origSubject = null;
|
||||||
String origContent = null;
|
String origContent = null;
|
||||||
String origFrom = null;
|
String origFrom = null;
|
||||||
@@ -116,8 +120,19 @@ public class NewEmailFragment extends Fragment {
|
|||||||
if (origEmail != null) {
|
if (origEmail != null) {
|
||||||
mSenderKey = BoteHelper.extractEmailDestination(
|
mSenderKey = BoteHelper.extractEmailDestination(
|
||||||
BoteHelper.getOneLocalRecipient(origEmail).toString());
|
BoteHelper.getOneLocalRecipient(origEmail).toString());
|
||||||
recipientAddr = BoteHelper.getNameAndDestination(
|
String recipient = BoteHelper.getNameAndDestination(
|
||||||
origEmail.getReplyAddress(I2PBote.getInstance().getIdentities()));
|
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();
|
origSubject = origEmail.getSubject();
|
||||||
origContent = origEmail.getText();
|
origContent = origEmail.getText();
|
||||||
origFrom = BoteHelper.getShortSenderName(origEmail.getOneFromAddress(), 50);
|
origFrom = BoteHelper.getShortSenderName(origEmail.getOneFromAddress(), 50);
|
||||||
@@ -144,7 +159,8 @@ public class NewEmailFragment extends Fragment {
|
|||||||
List<Person> contacts = new ArrayList<Person>();
|
List<Person> contacts = new ArrayList<Person>();
|
||||||
try {
|
try {
|
||||||
for (Contact contact : I2PBote.getInstance().getAddressBook().getAll()) {
|
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) {
|
} catch (PasswordException e) {
|
||||||
// TODO handle
|
// TODO handle
|
||||||
@@ -156,20 +172,30 @@ public class NewEmailFragment extends Fragment {
|
|||||||
mask = mask.toLowerCase(Locale.US);
|
mask = mask.toLowerCase(Locale.US);
|
||||||
return obj.getName().toLowerCase(Locale.US).startsWith(mask) || obj.getAddress().toLowerCase(Locale.US).startsWith(mask);
|
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 = (ContactsCompletionView) view.findViewById(R.id.recipients);
|
||||||
mRecipients.setAdapter(mAdapter);
|
mRecipients.setAdapter(mAdapter);
|
||||||
if (recipientAddr != null) {
|
if (recipientAddr != null) {
|
||||||
String name = BoteHelper.extractName(recipientAddr);
|
mRecipients.addObject(new Person(recipientName, recipientAddr, recipientPic));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mSubject = (EditText) view.findViewById(R.id.subject);
|
mSubject = (EditText) view.findViewById(R.id.subject);
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ public class BoteHelper extends GeneralHelper {
|
|||||||
* user, so their name is already "translated".
|
* user, so their name is already "translated".
|
||||||
* @param ctx Android Context to get strings from.
|
* @param ctx Android Context to get strings from.
|
||||||
* @param folder The folder.
|
* @param folder The folder.
|
||||||
* @param showNew Should the name contain the number of new messages?
|
|
||||||
* @return The name of the folder.
|
* @return The name of the folder.
|
||||||
* @throws PasswordException
|
* @throws PasswordException
|
||||||
*/
|
*/
|
||||||
@@ -94,6 +93,23 @@ public class BoteHelper extends GeneralHelper {
|
|||||||
String base64dest = extractEmailDestination(address);
|
String base64dest = extractEmailDestination(address);
|
||||||
|
|
||||||
if (base64dest != null) {
|
if (base64dest != null) {
|
||||||
|
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
|
// Address was found; try address book first
|
||||||
Contact c = getContact(base64dest);
|
Contact c = getContact(base64dest);
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
@@ -112,9 +128,7 @@ public class BoteHelper extends GeneralHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
// Address is not known
|
||||||
|
|
||||||
// Address not found anywhere, or found and has no picture
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,32 +45,34 @@ public class ContactsCompletionView extends TokenCompleteTextView {
|
|||||||
// Check if it is a known Destination
|
// Check if it is a known Destination
|
||||||
Contact c = BoteHelper.getContact(completionText);
|
Contact c = BoteHelper.getContact(completionText);
|
||||||
if (c != null)
|
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
|
// Check if it is a name
|
||||||
SortedSet<Contact> contacts = I2PBote.getInstance().getAddressBook().getAll();
|
SortedSet<Contact> contacts = I2PBote.getInstance().getAddressBook().getAll();
|
||||||
for (Contact contact : contacts) {
|
for (Contact contact : contacts) {
|
||||||
if (contact.getName().startsWith(completionText))
|
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 as a new Destination
|
||||||
try {
|
try {
|
||||||
new EmailDestination(completionText);
|
new EmailDestination(completionText);
|
||||||
return new Person(completionText.substring(0, 5), completionText);
|
return new Person(completionText.substring(0, 5), completionText, null);
|
||||||
} catch (GeneralSecurityException e) {
|
} catch (GeneralSecurityException e) {
|
||||||
// Not a valid Destination
|
// Not a valid Destination
|
||||||
// Assume the user meant an external address
|
// Assume the user meant an external address
|
||||||
completionText = completionText.replace(" ", "") + "@example.com";
|
completionText = completionText.replace(" ", "") + "@example.com";
|
||||||
return new Person(completionText, completionText, true);
|
return new Person(completionText, completionText, null, true);
|
||||||
}
|
}
|
||||||
} catch (PasswordException e) {
|
} catch (PasswordException e) {
|
||||||
// TODO handle
|
// TODO handle
|
||||||
completionText = completionText.replace(" ", "") + "@example.com";
|
completionText = completionText.replace(" ", "") + "@example.com";
|
||||||
return new Person(completionText, completionText, true);
|
return new Person(completionText, completionText, null, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return new Person(completionText, completionText, true);
|
return new Person(completionText, completionText, null, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
package i2p.bote.android.util;
|
package i2p.bote.android.util;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
public class Person implements Serializable {
|
public class Person implements Serializable {
|
||||||
private static final long serialVersionUID = -2874686247798691378L;
|
private static final long serialVersionUID = -2874686247798691378L;
|
||||||
private String name;
|
private String name;
|
||||||
private String address;
|
private String address;
|
||||||
|
private Bitmap picture;
|
||||||
private boolean isExternal;
|
private boolean isExternal;
|
||||||
|
|
||||||
public Person(String n, String a) { this(n, a, false); }
|
public Person(String n, String a, Bitmap p) { this(n, a, p, false); }
|
||||||
public Person(String n, String a, boolean e) { name = n; address = a; isExternal = e; }
|
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 getName() { return name; }
|
||||||
public String getAddress() { return address; }
|
public String getAddress() { return address; }
|
||||||
|
public Bitmap getPicture() { return picture; }
|
||||||
public boolean isExternal() { return isExternal; }
|
public boolean isExternal() { return isExternal; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user