1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-24 02:12:15 -05:00

Incorporate review comments.

This commit is contained in:
Danny Baumann 2013-01-05 13:20:46 +01:00
parent b334960355
commit 6f7ec3e401
6 changed files with 122 additions and 115 deletions

View File

@ -1,11 +1,17 @@
package com.fsck.k9.activity; package com.fsck.k9.activity;
import android.content.Context;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.util.Log; import android.util.Log;
import com.fsck.k9.Account;
import com.fsck.k9.K9; import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
import com.fsck.k9.helper.Utility; import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Flag; import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException; import com.fsck.k9.mail.MessagingException;
import java.util.StringTokenizer; import java.util.StringTokenizer;
@ -122,6 +128,31 @@ public class MessageReference implements Parcelable {
'}'; '}';
} }
public Message restoreToLocalMessage(Context context) {
try {
Account account = Preferences.getPreferences(context).getAccount(accountUuid);
if (account != null) {
Folder folder = account.getLocalStore().getFolder(folderName);
if (folder != null) {
Message message = folder.getMessage(uid);
if (message != null) {
return message;
} else {
Log.d(K9.LOG_TAG, "Could not restore message, uid " + uid + " is unknown.");
}
} else {
Log.d(K9.LOG_TAG, "Could not restore message, folder " + folderName + " is unknown.");
}
} else {
Log.d(K9.LOG_TAG, "Could not restore message, account " + accountUuid + " is unknown.");
}
} catch (MessagingException e) {
Log.w(K9.LOG_TAG, "Could not retrieve message for reference.", e);
}
return null;
}
public static final Creator<MessageReference> CREATOR = new Creator<MessageReference>() { public static final Creator<MessageReference> CREATOR = new Creator<MessageReference>() {
@Override @Override
public MessageReference createFromParcel(Parcel source) { public MessageReference createFromParcel(Parcel source) {

View File

@ -200,9 +200,6 @@ public class MessagingController implements Runnable {
// Key is accountUuid:folderName:messageUid , value is unimportant // Key is accountUuid:folderName:messageUid , value is unimportant
private ConcurrentHashMap<String, String> deletedUids = new ConcurrentHashMap<String, String>(); private ConcurrentHashMap<String, String> deletedUids = new ConcurrentHashMap<String, String>();
// maximum length of the message preview text returned by getMessagePreview()
private final static int MAX_PREVIEW_LENGTH = 300;
private static class NotificationData { private static class NotificationData {
int unreadBeforeNotification; int unreadBeforeNotification;
LinkedList<Message> messages; // newest one first LinkedList<Message> messages; // newest one first
@ -4506,40 +4503,17 @@ public class MessagingController implements Runnable {
} }
private static TextAppearanceSpan sEmphasizedSpan; private static TextAppearanceSpan sEmphasizedSpan;
private void ensureEmphasizedSpan(Context context) { private TextAppearanceSpan getEmphasizedSpan(Context context) {
if (sEmphasizedSpan == null) { if (sEmphasizedSpan == null) {
sEmphasizedSpan = new TextAppearanceSpan(context, sEmphasizedSpan = new TextAppearanceSpan(context,
R.style.TextAppearance_StatusBar_EventContent_Emphasized); R.style.TextAppearance_StatusBar_EventContent_Emphasized);
} }
return sEmphasizedSpan;
} }
private CharSequence getMessagePreview(Context context, Message message) { private CharSequence getMessagePreview(Context context, Message message) {
CharSequence subject = getMessageSubject(context, message); CharSequence subject = getMessageSubject(context, message);
String snippet = null; String snippet = message.getPreview();
try {
Part part = MimeUtility.findFirstPartByMimeType(message, "text/html");
if (part != null) {
// We successfully found an HTML part; do the necessary character set decoding.
snippet = MimeUtility.getTextFromPart(part);
if (snippet != null) {
snippet = HtmlConverter.htmlToText(snippet);
}
}
if (snippet == null) {
// no HTML part -> try and get a text part.
part = MimeUtility.findFirstPartByMimeType(message, "text/plain");
if (part != null) {
snippet = MimeUtility.getTextFromPart(part);
}
}
} catch (MessagingException e) {
Log.d(K9.LOG_TAG, "Could not extract message preview", e);
}
if (snippet != null && snippet.length() > MAX_PREVIEW_LENGTH) {
snippet = snippet.substring(0, MAX_PREVIEW_LENGTH);
}
if (TextUtils.isEmpty(subject)) { if (TextUtils.isEmpty(subject)) {
return snippet; return snippet;
@ -4552,14 +4526,12 @@ public class MessagingController implements Runnable {
preview.append('\n'); preview.append('\n');
preview.append(snippet); preview.append(snippet);
ensureEmphasizedSpan(context); preview.setSpan(getEmphasizedSpan(context), 0, subject.length(), 0);
preview.setSpan(sEmphasizedSpan, 0, subject.length(), 0);
return preview; return preview;
} }
private CharSequence buildMessageSummary(Context context, CharSequence sender, CharSequence subject) { private CharSequence buildMessageSummary(Context context, CharSequence sender, CharSequence subject) {
if (sender == null) { if (sender == null) {
return subject; return subject;
} }
@ -4569,8 +4541,7 @@ public class MessagingController implements Runnable {
summary.append(" "); summary.append(" ");
summary.append(subject); summary.append(subject);
ensureEmphasizedSpan(context); summary.setSpan(getEmphasizedSpan(context), 0, sender.length(), 0);
summary.setSpan(sEmphasizedSpan, 0, sender.length(), 0);
return summary; return summary;
} }
@ -4587,17 +4558,14 @@ public class MessagingController implements Runnable {
return Build.VERSION.SDK_INT >= 16; return Build.VERSION.SDK_INT >= 16;
} }
private Message findNewestMessageForNotificationLocked(Account account, NotificationData data) { private Message findNewestMessageForNotificationLocked(Context context,
if (data.messages.size() > 0) { Account account, NotificationData data) {
if (!data.messages.isEmpty()) {
return data.messages.get(0); return data.messages.get(0);
} }
if (data.droppedMessages.size() > 0) { if (!data.droppedMessages.isEmpty()) {
MessageReference ref = data.droppedMessages.get(0); return data.droppedMessages.get(0).restoreToLocalMessage(context);
try {
return account.getLocalStore().getFolder(ref.folderName).getMessage(ref.uid);
} catch (MessagingException e) {
}
} }
return null; return null;
@ -4620,7 +4588,7 @@ public class MessagingController implements Runnable {
if (message == null) { if (message == null) {
/* this can happen if a message we previously notified for is read or deleted remotely */ /* this can happen if a message we previously notified for is read or deleted remotely */
message = findNewestMessageForNotificationLocked(account, data); message = findNewestMessageForNotificationLocked(context, account, data);
updateSilently = true; updateSilently = true;
if (message == null) { if (message == null) {
return; return;
@ -4676,7 +4644,7 @@ public class MessagingController implements Runnable {
getMessageSender(context, account, m), getMessageSender(context, account, m),
getMessageSubject(context, m))); getMessageSubject(context, m)));
} }
if (data.droppedMessages.size() > 0) { if (!data.droppedMessages.isEmpty()) {
style.setSummaryText(context.getString( style.setSummaryText(context.getString(
R.string.notification_additional_messages, data.droppedMessages.size())); R.string.notification_additional_messages, data.droppedMessages.size()));
} }

View File

@ -148,7 +148,52 @@ public abstract class Message implements Part, Body {
public abstract String getPreview(); public abstract String getPreview();
public abstract boolean hasAttachments(); public abstract boolean hasAttachments();
/*
* calculateContentPreview
* Takes a plain text message body as a string.
* Returns a message summary as a string suitable for showing in a message list
*
* A message summary should be about the first 160 characters
* of unique text written by the message sender
* Quoted text, "On $date" and so on will be stripped out.
* All newlines and whitespace will be compressed.
*
*/
public static String calculateContentPreview(String text) {
if (text == null) {
return null;
}
// Only look at the first 8k of a message when calculating
// the preview. This should avoid unnecessary
// memory usage on large messages
if (text.length() > 8192) {
text = text.substring(0, 8192);
}
// try to remove lines of dashes in the preview
text = text.replaceAll("(?m)^----.*?$", "");
// remove quoted text from the preview
text = text.replaceAll("(?m)^[#>].*$", "");
// Remove a common quote header from the preview
text = text.replaceAll("(?m)^On .*wrote.?$", "");
// Remove a more generic quote header from the preview
text = text.replaceAll("(?m)^.*\\w+:$", "");
// Remove horizontal rules.
text = text.replaceAll("\\s*([-=_]{30,}+)\\s*", " ");
// URLs in the preview should just be shown as "..." - They're not
// clickable and they usually overwhelm the preview
text = text.replaceAll("https?://\\S+", "...");
// Don't show newlines in the preview
text = text.replaceAll("(\\r|\\n)+", " ");
// Collapse whitespace in the preview
text = text.replaceAll("\\s+", " ");
// Remove any whitespace at the beginning and end of the string.
text = text.trim();
return (text.length() <= 512) ? text : text.substring(0, 512);
}
public void delete(String trashFolderName) throws MessagingException {} public void delete(String trashFolderName) throws MessagingException {}

View File

@ -23,6 +23,10 @@ import org.apache.james.mime4j.stream.BodyDescriptor;
import org.apache.james.mime4j.stream.Field; import org.apache.james.mime4j.stream.Field;
import org.apache.james.mime4j.stream.MimeConfig; import org.apache.james.mime4j.stream.MimeConfig;
import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.helper.HtmlConverter;
import com.fsck.k9.mail.Address; import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Body; import com.fsck.k9.mail.Body;
import com.fsck.k9.mail.BodyPart; import com.fsck.k9.mail.BodyPart;
@ -591,6 +595,32 @@ public class MimeMessage extends Message {
} }
public String getPreview() { public String getPreview() {
String preview = null;
try {
Part part = MimeUtility.findFirstPartByMimeType(this, "text/html");
if (part != null) {
// We successfully found an HTML part; do the necessary character set decoding.
preview = MimeUtility.getTextFromPart(part);
if (preview != null) {
preview = HtmlConverter.htmlToText(preview);
}
}
if (preview == null) {
// no HTML part -> try and get a text part.
part = MimeUtility.findFirstPartByMimeType(this, "text/plain");
if (part != null) {
preview = MimeUtility.getTextFromPart(part);
}
}
} catch (MessagingException e) {
Log.d(K9.LOG_TAG, "Could not extract message preview", e);
}
if (preview != null) {
return calculateContentPreview(preview);
}
return ""; return "";
} }

View File

@ -2403,7 +2403,7 @@ public class LocalStore extends Store implements Serializable {
html = HtmlConverter.convertEmoji2Img(container.html); html = HtmlConverter.convertEmoji2Img(container.html);
} }
String preview = calculateContentPreview(text); String preview = Message.calculateContentPreview(text);
try { try {
ContentValues cv = new ContentValues(); ContentValues cv = new ContentValues();
@ -2501,7 +2501,7 @@ public class LocalStore extends Store implements Serializable {
String text = container.text; String text = container.text;
String html = HtmlConverter.convertEmoji2Img(container.html); String html = HtmlConverter.convertEmoji2Img(container.html);
String preview = calculateContentPreview(text); String preview = Message.calculateContentPreview(text);
try { try {
db.execSQL("UPDATE messages SET " db.execSQL("UPDATE messages SET "
@ -3010,53 +3010,6 @@ public class LocalStore extends Store implements Serializable {
} }
} }
/*
* calculateContentPreview
* Takes a plain text message body as a string.
* Returns a message summary as a string suitable for showing in a message list
*
* A message summary should be about the first 160 characters
* of unique text written by the message sender
* Quoted text, "On $date" and so on will be stripped out.
* All newlines and whitespace will be compressed.
*
*/
public String calculateContentPreview(String text) {
if (text == null) {
return null;
}
// Only look at the first 8k of a message when calculating
// the preview. This should avoid unnecessary
// memory usage on large messages
if (text.length() > 8192) {
text = text.substring(0, 8192);
}
// try to remove lines of dashes in the preview
text = text.replaceAll("(?m)^----.*?$", "");
// remove quoted text from the preview
text = text.replaceAll("(?m)^[#>].*$", "");
// Remove a common quote header from the preview
text = text.replaceAll("(?m)^On .*wrote.?$", "");
// Remove a more generic quote header from the preview
text = text.replaceAll("(?m)^.*\\w+:$", "");
// Remove horizontal rules.
text = text.replaceAll("\\s*([-=_]{30,}+)\\s*", " ");
// URLs in the preview should just be shown as "..." - They're not
// clickable and they usually overwhelm the preview
text = text.replaceAll("https?://\\S+", "...");
// Don't show newlines in the preview
text = text.replaceAll("(\\r|\\n)+", " ");
// Collapse whitespace in the preview
text = text.replaceAll("\\s+", " ");
// Remove any whitespace at the beginning and end of the string.
text = text.trim();
return (text.length() <= 512) ? text : text.substring(0, 512);
}
@Override @Override
public boolean isInTopGroup() { public boolean isInTopGroup() {
return mInTopGroup; return mInTopGroup;

View File

@ -56,26 +56,6 @@ public class NotificationActionService extends CoreService {
return i; return i;
} }
private static Message getMessageFromRef(final Account account, MessageReference ref) {
try {
Folder folder = account.getLocalStore().getFolder(ref.folderName);
if (folder != null) {
Message message = folder.getMessage(ref.uid);
if (message != null) {
return message;
} else {
Log.w(K9.LOG_TAG, "Could not find message for notification action.");
}
} else {
Log.w(K9.LOG_TAG, "Could not find folder for notification action.");
}
} catch (MessagingException e) {
Log.w(K9.LOG_TAG, "Could not retrieve message for reference.", e);
}
return null;
}
@Override @Override
public int startService(Intent intent, int startId) { public int startService(Intent intent, int startId) {
if (K9.DEBUG) if (K9.DEBUG)
@ -103,7 +83,7 @@ public class NotificationActionService extends CoreService {
ArrayList<Message> messages = new ArrayList<Message>(); ArrayList<Message> messages = new ArrayList<Message>();
for (MessageReference ref : refs) { for (MessageReference ref : refs) {
Message m = getMessageFromRef(account, ref); Message m = ref.restoreToLocalMessage(this);
if (m != null) { if (m != null) {
messages.add(m); messages.add(m);
} }
@ -115,7 +95,7 @@ public class NotificationActionService extends CoreService {
Log.i(K9.LOG_TAG, "NotificationActionService initiating reply"); Log.i(K9.LOG_TAG, "NotificationActionService initiating reply");
MessageReference ref = (MessageReference) intent.getParcelableExtra(EXTRA_MESSAGE); MessageReference ref = (MessageReference) intent.getParcelableExtra(EXTRA_MESSAGE);
Message message = getMessageFromRef(account, ref); Message message = ref.restoreToLocalMessage(this);
if (message != null) { if (message != null) {
Intent i = MessageCompose.getActionReplyIntent(this, account, message, false, null); Intent i = MessageCompose.getActionReplyIntent(this, account, message, false, null);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);