1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-30 13:12:25 -05:00

Local messages

This commit is contained in:
Jan Berkel 2014-12-12 13:04:59 +00:00
parent 708fb57c04
commit 0024f39bc6
10 changed files with 82 additions and 92 deletions

View File

@ -442,7 +442,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
*/ */
public static Intent getActionReplyIntent( public static Intent getActionReplyIntent(
Context context, Context context,
Message message, LocalMessage message,
boolean replyAll, boolean replyAll,
String messageBody) { String messageBody) {
Intent i = new Intent(context, MessageCompose.class); Intent i = new Intent(context, MessageCompose.class);
@ -467,7 +467,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
*/ */
public static void actionReply( public static void actionReply(
Context context, Context context,
Message message, LocalMessage message,
boolean replyAll, boolean replyAll,
String messageBody) { String messageBody) {
context.startActivity(getActionReplyIntent(context, message, replyAll, messageBody)); context.startActivity(getActionReplyIntent(context, message, replyAll, messageBody));
@ -481,7 +481,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
*/ */
public static void actionForward( public static void actionForward(
Context context, Context context,
Message message, LocalMessage message,
String messageBody) { String messageBody) {
Intent i = new Intent(context, MessageCompose.class); Intent i = new Intent(context, MessageCompose.class);
i.putExtra(EXTRA_MESSAGE_BODY, messageBody); i.putExtra(EXTRA_MESSAGE_BODY, messageBody);

View File

@ -42,8 +42,8 @@ import com.fsck.k9.fragment.MessageListFragment;
import com.fsck.k9.fragment.MessageListFragment.MessageListFragmentListener; import com.fsck.k9.fragment.MessageListFragment.MessageListFragmentListener;
import com.fsck.k9.fragment.MessageViewFragment; import com.fsck.k9.fragment.MessageViewFragment;
import com.fsck.k9.fragment.MessageViewFragment.MessageViewFragmentListener; import com.fsck.k9.fragment.MessageViewFragment.MessageViewFragmentListener;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.store.StorageManager; import com.fsck.k9.mail.store.StorageManager;
import com.fsck.k9.mail.store.local.LocalMessage;
import com.fsck.k9.search.LocalSearch; import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.search.SearchAccount; import com.fsck.k9.search.SearchAccount;
import com.fsck.k9.search.SearchSpecification; import com.fsck.k9.search.SearchSpecification;
@ -1193,22 +1193,22 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
} }
@Override @Override
public void onResendMessage(Message message) { public void onResendMessage(LocalMessage message) {
MessageCompose.actionEditDraft(this, message.makeMessageReference()); MessageCompose.actionEditDraft(this, message.makeMessageReference());
} }
@Override @Override
public void onForward(Message message) { public void onForward(LocalMessage message) {
MessageCompose.actionForward(this, message, null); MessageCompose.actionForward(this, message, null);
} }
@Override @Override
public void onReply(Message message) { public void onReply(LocalMessage message) {
MessageCompose.actionReply(this, message, false, null); MessageCompose.actionReply(this, message, false, null);
} }
@Override @Override
public void onReplyAll(Message message) { public void onReplyAll(LocalMessage message) {
MessageCompose.actionReply(this, message, true, null); MessageCompose.actionReply(this, message, true, null);
} }
@ -1399,17 +1399,17 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
} }
@Override @Override
public void onReply(Message message, PgpData pgpData) { public void onReply(LocalMessage message, PgpData pgpData) {
MessageCompose.actionReply(this, message, false, pgpData.getDecryptedData()); MessageCompose.actionReply(this, message, false, pgpData.getDecryptedData());
} }
@Override @Override
public void onReplyAll(Message message, PgpData pgpData) { public void onReplyAll(LocalMessage message, PgpData pgpData) {
MessageCompose.actionReply(this, message, true, pgpData.getDecryptedData()); MessageCompose.actionReply(this, message, true, pgpData.getDecryptedData());
} }
@Override @Override
public void onForward(Message mMessage, PgpData mPgpData) { public void onForward(LocalMessage mMessage, PgpData mPgpData) {
MessageCompose.actionForward(this, mMessage, mPgpData.getDecryptedData()); MessageCompose.actionForward(this, mMessage, mPgpData.getDecryptedData());
} }

View File

@ -214,7 +214,7 @@ public class MessagingController implements Runnable {
* Don't modify this list directly, but use {@link addMessage} and * Don't modify this list directly, but use {@link addMessage} and
* {@link removeMatchingMessage} instead. * {@link removeMatchingMessage} instead.
*/ */
LinkedList<Message> messages; LinkedList<LocalMessage> messages;
/** /**
* List of references for messages that the user is still to be notified of, * List of references for messages that the user is still to be notified of,
* but which don't fit into the inbox style anymore. It's sorted from newest * but which don't fit into the inbox style anymore. It's sorted from newest
@ -238,7 +238,7 @@ public class MessagingController implements Runnable {
public NotificationData(int unread) { public NotificationData(int unread) {
unreadBeforeNotification = unread; unreadBeforeNotification = unread;
droppedMessages = new LinkedList<MessageReference>(); droppedMessages = new LinkedList<MessageReference>();
messages = new LinkedList<Message>(); messages = new LinkedList<LocalMessage>();
} }
/** /**
@ -249,9 +249,9 @@ public class MessagingController implements Runnable {
* *
* @param m The new message to add. * @param m The new message to add.
*/ */
public void addMessage(Message m) { public void addMessage(LocalMessage m) {
while (messages.size() >= MAX_MESSAGES) { while (messages.size() >= MAX_MESSAGES) {
Message dropped = messages.removeLast(); LocalMessage dropped = messages.removeLast();
droppedMessages.addFirst(dropped.makeMessageReference()); droppedMessages.addFirst(dropped.makeMessageReference());
} }
messages.addFirst(m); messages.addFirst(m);
@ -272,10 +272,10 @@ public class MessagingController implements Runnable {
} }
} }
for (Message message : messages) { for (LocalMessage message : messages) {
if (message.makeMessageReference().equals(ref)) { if (message.makeMessageReference().equals(ref)) {
if (messages.remove(message) && !droppedMessages.isEmpty()) { if (messages.remove(message) && !droppedMessages.isEmpty()) {
Message restoredMessage = droppedMessages.getFirst().restoreToLocalMessage(context); LocalMessage restoredMessage = droppedMessages.getFirst().restoreToLocalMessage(context);
if (restoredMessage != null) { if (restoredMessage != null) {
messages.addLast(restoredMessage); messages.addLast(restoredMessage);
droppedMessages.removeFirst(); droppedMessages.removeFirst();
@ -293,7 +293,7 @@ public class MessagingController implements Runnable {
* List. * List.
*/ */
public void supplyAllMessageRefs(List<MessageReference> refs) { public void supplyAllMessageRefs(List<MessageReference> refs) {
for (Message m : messages) { for (LocalMessage m : messages) {
refs.add(m.makeMessageReference()); refs.add(m.makeMessageReference());
} }
refs.addAll(droppedMessages); refs.addAll(droppedMessages);
@ -1621,7 +1621,7 @@ public class MessagingController implements Runnable {
} }
// Store the updated message locally // Store the updated message locally
final Message localMessage = localFolder.storeSmallMessage(message, new Runnable() { final LocalMessage localMessage = localFolder.storeSmallMessage(message, new Runnable() {
@Override @Override
public void run() { public void run() {
progress.incrementAndGet(); progress.incrementAndGet();
@ -1769,7 +1769,7 @@ public class MessagingController implements Runnable {
// Update the listener with what we've found // Update the listener with what we've found
progress.incrementAndGet(); progress.incrementAndGet();
// TODO do we need to re-fetch this here? // TODO do we need to re-fetch this here?
Message localMessage = localFolder.getMessage(message.getUid()); LocalMessage localMessage = localFolder.getMessage(message.getUid());
// Increment the number of "new messages" if the newly downloaded message is // Increment the number of "new messages" if the newly downloaded message is
// not marked as read. // not marked as read.
@ -4781,8 +4781,7 @@ public class MessagingController implements Runnable {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
} }
private Message findNewestMessageForNotificationLocked(Context context, private LocalMessage findNewestMessageForNotificationLocked(Context context, NotificationData data) {
Account account, NotificationData data) {
if (!data.messages.isEmpty()) { if (!data.messages.isEmpty()) {
return data.messages.getFirst(); return data.messages.getFirst();
} }
@ -4798,7 +4797,7 @@ public class MessagingController implements Runnable {
* Creates a notification of a newly received message. * Creates a notification of a newly received message.
*/ */
private void notifyAccount(Context context, Account account, private void notifyAccount(Context context, Account account,
Message message, int previousUnreadMessageCount) { LocalMessage message, int previousUnreadMessageCount) {
final NotificationData data = getNotificationData(account, previousUnreadMessageCount); final NotificationData data = getNotificationData(account, previousUnreadMessageCount);
synchronized (data) { synchronized (data) {
notifyAccountWithDataLocked(context, account, message, data); notifyAccountWithDataLocked(context, account, message, data);
@ -4809,12 +4808,12 @@ public class MessagingController implements Runnable {
private static final int NUM_SENDERS_IN_LOCK_SCREEN_NOTIFICATION = 5; private static final int NUM_SENDERS_IN_LOCK_SCREEN_NOTIFICATION = 5;
private void notifyAccountWithDataLocked(Context context, Account account, private void notifyAccountWithDataLocked(Context context, Account account,
Message message, NotificationData data) { LocalMessage message, NotificationData data) {
boolean updateSilently = false; boolean updateSilently = false;
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(context, account, data); message = findNewestMessageForNotificationLocked(context, data);
updateSilently = true; updateSilently = true;
if (message == null) { if (message == null) {
// seemingly both the message list as well as the overflow list is empty; // seemingly both the message list as well as the overflow list is empty;
@ -5110,7 +5109,7 @@ public class MessagingController implements Runnable {
int unreadCount, int unreadCount,
CharSequence accountDescription, CharSequence accountDescription,
CharSequence formattedSender, CharSequence formattedSender,
List<Message> messages) { List<? extends Message> messages) {
if (!platformSupportsLockScreenNotifications()) { if (!platformSupportsLockScreenNotifications()) {
return; return;
} }

View File

@ -1190,19 +1190,19 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
} }
} }
public void onReply(Message message) { public void onReply(LocalMessage message) {
mFragmentListener.onReply(message); mFragmentListener.onReply(message);
} }
public void onReplyAll(Message message) { public void onReplyAll(LocalMessage message) {
mFragmentListener.onReplyAll(message); mFragmentListener.onReplyAll(message);
} }
public void onForward(Message message) { public void onForward(LocalMessage message) {
mFragmentListener.onForward(message); mFragmentListener.onForward(message);
} }
public void onResendMessage(Message message) { public void onResendMessage(LocalMessage message) {
mFragmentListener.onResendMessage(message); mFragmentListener.onResendMessage(message);
} }
@ -1510,23 +1510,19 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
break; break;
} }
case R.id.reply: { case R.id.reply: {
Message message = getMessageAtPosition(adapterPosition); onReply(getMessageAtPosition(adapterPosition));
onReply(message);
break; break;
} }
case R.id.reply_all: { case R.id.reply_all: {
Message message = getMessageAtPosition(adapterPosition); onReplyAll(getMessageAtPosition(adapterPosition));
onReplyAll(message);
break; break;
} }
case R.id.forward: { case R.id.forward: {
Message message = getMessageAtPosition(adapterPosition); onForward(getMessageAtPosition(adapterPosition));
onForward(message);
break; break;
} }
case R.id.send_again: { case R.id.send_again: {
Message message = getMessageAtPosition(adapterPosition); onResendMessage(getMessageAtPosition(adapterPosition));
onResendMessage(message);
mSelectedCount = 0; mSelectedCount = 0;
break; break;
} }
@ -3113,10 +3109,10 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
void setMessageListProgress(int level); void setMessageListProgress(int level);
void showThread(Account account, String folderName, long rootId); void showThread(Account account, String folderName, long rootId);
void showMoreFromSameSender(String senderAddress); void showMoreFromSameSender(String senderAddress);
void onResendMessage(Message message); void onResendMessage(LocalMessage message);
void onForward(Message message); void onForward(LocalMessage message);
void onReply(Message message); void onReply(LocalMessage message);
void onReplyAll(Message message); void onReplyAll(LocalMessage message);
void openMessage(MessageReference messageReference); void openMessage(MessageReference messageReference);
void setMessageListTitle(String title); void setMessageListTitle(String title);
void setMessageListSubTitle(String subTitle); void setMessageListSubTitle(String subTitle);

View File

@ -846,10 +846,10 @@ public class MessageViewFragment extends Fragment implements OnClickListener,
} }
public interface MessageViewFragmentListener { public interface MessageViewFragmentListener {
public void onForward(Message mMessage, PgpData mPgpData); public void onForward(LocalMessage mMessage, PgpData mPgpData);
public void disableDeleteAction(); public void disableDeleteAction();
public void onReplyAll(Message mMessage, PgpData mPgpData); public void onReplyAll(LocalMessage mMessage, PgpData mPgpData);
public void onReply(Message mMessage, PgpData mPgpData); public void onReply(LocalMessage mMessage, PgpData mPgpData);
public void displayMessageSubject(String title); public void displayMessageSubject(String title);
public void setProgress(boolean b); public void setProgress(boolean b);
public void showNextMessageOrReturn(); public void showNextMessageOrReturn();

View File

@ -2,26 +2,20 @@
package com.fsck.k9.mail; package com.fsck.k9.mail;
import java.io.IOException; import java.io.IOException;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import android.util.Log; import android.util.Log;
import com.fsck.k9.K9; import com.fsck.k9.K9;
import com.fsck.k9.activity.MessageReference;
import com.fsck.k9.mail.filter.CountingOutputStream; import com.fsck.k9.mail.filter.CountingOutputStream;
import com.fsck.k9.mail.filter.EOLConvertingOutputStream; import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
import com.fsck.k9.mail.store.UnavailableStorageException; import com.fsck.k9.mail.store.UnavailableStorageException;
public abstract class Message implements Part, CompositeBody { public abstract class Message implements Part, CompositeBody {
protected MessageReference mReference;
public enum RecipientType { public enum RecipientType {
TO, CC, BCC, TO, CC, BCC,
} }
@ -73,7 +67,6 @@ public abstract class Message implements Part, CompositeBody {
} }
public void setUid(String uid) { public void setUid(String uid) {
this.mReference = null;
this.mUid = uid; this.mUid = uid;
} }
@ -251,15 +244,6 @@ public abstract class Message implements Part, CompositeBody {
public abstract void setCharset(String charset) throws MessagingException; public abstract void setCharset(String charset) throws MessagingException;
public MessageReference makeMessageReference() {
if (mReference == null) {
mReference = new MessageReference();
mReference.folderName = getFolder().getName();
mReference.uid = mUid;
}
return mReference;
}
public long calculateSize() { public long calculateSize() {
try { try {
@ -279,14 +263,12 @@ public abstract class Message implements Part, CompositeBody {
/** /**
* Copy the contents of this object into another {@code Message} object. * Copy the contents of this object into another {@code Message} object.
* *
* @param destination * @param destination The {@code Message} object to receive the contents of this instance.
* The {@code Message} object to receive the contents of this instance.
*/ */
protected void copy(Message destination) { protected void copy(Message destination) {
destination.mUid = mUid; destination.mUid = mUid;
destination.mInternalDate = mInternalDate; destination.mInternalDate = mInternalDate;
destination.mFolder = mFolder; destination.mFolder = mFolder;
destination.mReference = mReference;
// mFlags contents can change during the object lifetime, so copy the Set // mFlags contents can change during the object lifetime, so copy the Set
destination.mFlags = EnumSet.copyOf(mFlags); destination.mFlags = EnumSet.copyOf(mFlags);

View File

@ -608,28 +608,27 @@ public class MimeMessage extends Message {
/** /**
* Copy the contents of this object into another {@code MimeMessage} object. * Copy the contents of this object into another {@code MimeMessage} object.
* *
* @param message * @param destination The {@code MimeMessage} object to receive the contents of this instance.
* The {@code MimeMessage} object to receive the contents of this instance.
*/ */
protected void copy(MimeMessage message) { protected void copy(MimeMessage destination) {
super.copy(message); super.copy(destination);
message.mHeader = mHeader.clone(); destination.mHeader = mHeader.clone();
message.mBody = mBody; destination.mBody = mBody;
message.mMessageId = mMessageId; destination.mMessageId = mMessageId;
message.mSentDate = mSentDate; destination.mSentDate = mSentDate;
message.mDateFormat = mDateFormat; destination.mDateFormat = mDateFormat;
message.mSize = mSize; destination.mSize = mSize;
// These arrays are not supposed to be modified, so it's okay to reuse the references // These arrays are not supposed to be modified, so it's okay to reuse the references
message.mFrom = mFrom; destination.mFrom = mFrom;
message.mTo = mTo; destination.mTo = mTo;
message.mCc = mCc; destination.mCc = mCc;
message.mBcc = mBcc; destination.mBcc = mBcc;
message.mReplyTo = mReplyTo; destination.mReplyTo = mReplyTo;
message.mReferences = mReferences; destination.mReferences = mReferences;
message.mInReplyTo = mInReplyTo; destination.mInReplyTo = mInReplyTo;
} }
@Override @Override

View File

@ -1138,14 +1138,14 @@ public class LocalFolder extends Folder<LocalMessage> implements Serializable {
* @return The local version of the message. Never <code>null</code>. * @return The local version of the message. Never <code>null</code>.
* @throws MessagingException * @throws MessagingException
*/ */
public Message storeSmallMessage(final Message message, final Runnable runnable) throws MessagingException { public LocalMessage storeSmallMessage(final Message message, final Runnable runnable) throws MessagingException {
return this.localStore.database.execute(true, new DbCallback<Message>() { return this.localStore.database.execute(true, new DbCallback<LocalMessage>() {
@Override @Override
public Message doDbWork(final SQLiteDatabase db) throws WrappedException, UnavailableStorageException { public LocalMessage doDbWork(final SQLiteDatabase db) throws WrappedException, UnavailableStorageException {
try { try {
appendMessages(Collections.singletonList(message)); appendMessages(Collections.singletonList(message));
final String uid = message.getUid(); final String uid = message.getUid();
final Message result = getMessage(uid); final LocalMessage result = getMessage(uid);
runnable.run(); runnable.run();
// Set a flag indicating this message has now be fully downloaded // Set a flag indicating this message has now be fully downloaded
result.setFlag(Flag.X_DOWNLOADED_FULL, true); result.setFlag(Flag.X_DOWNLOADED_FULL, true);

View File

@ -27,7 +27,7 @@ import com.fsck.k9.mail.store.local.LockableDatabase.DbCallback;
import com.fsck.k9.mail.store.local.LockableDatabase.WrappedException; import com.fsck.k9.mail.store.local.LockableDatabase.WrappedException;
public class LocalMessage extends MimeMessage { public class LocalMessage extends MimeMessage {
protected MessageReference mReference;
private final LocalStore localStore; private final LocalStore localStore;
private long mId; private long mId;
@ -52,8 +52,7 @@ public class LocalMessage extends MimeMessage {
this.mFolder = folder; this.mFolder = folder;
} }
void populateFromGetMessageCursor(Cursor cursor) void populateFromGetMessageCursor(Cursor cursor) throws MessagingException {
throws MessagingException {
final String subject = cursor.getString(0); final String subject = cursor.getString(0);
this.setSubject(subject == null ? "" : subject); this.setSubject(subject == null ? "" : subject);
@ -191,6 +190,12 @@ public class LocalMessage extends MimeMessage {
mMessageDirty = true; mMessageDirty = true;
} }
@Override
public void setUid(String uid) {
super.setUid(uid);
this.mReference = null;
}
@Override @Override
public boolean hasAttachments() { public boolean hasAttachments() {
return (mAttachmentCount > 0); return (mAttachmentCount > 0);
@ -564,15 +569,24 @@ public class LocalMessage extends MimeMessage {
return localStore.getAccount(); return localStore.getAccount();
} }
@Override
public MessageReference makeMessageReference() { public MessageReference makeMessageReference() {
if (mReference == null) { if (mReference == null) {
mReference = super.makeMessageReference(); mReference = new MessageReference();
mReference.folderName = getFolder().getName();
mReference.uid = mUid;
mReference.accountUuid = getFolder().getUuid(); mReference.accountUuid = getFolder().getUuid();
} }
return mReference; return mReference;
} }
@Override
protected void copy(MimeMessage destination) {
super.copy(destination);
if (destination instanceof LocalMessage) {
((LocalMessage)destination).mReference = mReference;
}
}
@Override @Override
public LocalFolder getFolder() { public LocalFolder getFolder() {
return (LocalFolder) super.getFolder(); return (LocalFolder) super.getFolder();

View File

@ -103,8 +103,8 @@ public class NotificationActionService extends CoreService {
if (K9.DEBUG) if (K9.DEBUG)
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 = intent.getParcelableExtra(EXTRA_MESSAGE);
Message message = ref.restoreToLocalMessage(this); LocalMessage message = ref.restoreToLocalMessage(this);
if (message != null) { if (message != null) {
Intent i = MessageCompose.getActionReplyIntent(this, message, false, null); Intent i = MessageCompose.getActionReplyIntent(this, message, false, null);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);