mirror of
https://github.com/moparisthebest/k-9
synced 2025-02-17 07:30:16 -05:00
Download missing parts before viewing or saving
This commit is contained in:
parent
585d9cbe7f
commit
9363c5b276
@ -3144,40 +3144,8 @@ public class MessagingController implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to load the attachment specified by part from the given account and message.
|
||||
* @param account
|
||||
* @param message
|
||||
* @param part
|
||||
* @param listener
|
||||
*/
|
||||
public void loadAttachment(
|
||||
final Account account,
|
||||
final Message message,
|
||||
final Part part,
|
||||
final Object tag,
|
||||
final MessagingListener listener) {
|
||||
/*
|
||||
* Check if the attachment has already been downloaded. If it has there's no reason to
|
||||
* download it, so we just tell the listener that it's ready to go.
|
||||
*/
|
||||
|
||||
if (part.getBody() != null) {
|
||||
for (MessagingListener l : getListeners(listener)) {
|
||||
l.loadAttachmentStarted(account, message, part, tag, false);
|
||||
}
|
||||
|
||||
for (MessagingListener l : getListeners(listener)) {
|
||||
l.loadAttachmentFinished(account, message, part, tag);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (MessagingListener l : getListeners(listener)) {
|
||||
l.loadAttachmentStarted(account, message, part, tag, true);
|
||||
}
|
||||
public void loadAttachment(final Account account, final LocalMessage message, final Part part,
|
||||
final MessagingListener listener) {
|
||||
|
||||
put("loadAttachment", listener, new Runnable() {
|
||||
@Override
|
||||
@ -3185,32 +3153,29 @@ public class MessagingController implements Runnable {
|
||||
Folder remoteFolder = null;
|
||||
LocalFolder localFolder = null;
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
String folderName = message.getFolder().getName();
|
||||
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
localFolder = localStore.getFolder(folderName);
|
||||
|
||||
List<Part> attachments = MessageExtractor.collectAttachments(message);
|
||||
for (Part attachment : attachments) {
|
||||
attachment.setBody(null);
|
||||
}
|
||||
Store remoteStore = account.getRemoteStore();
|
||||
localFolder = localStore.getFolder(message.getFolder().getName());
|
||||
remoteFolder = remoteStore.getFolder(message.getFolder().getName());
|
||||
remoteFolder = remoteStore.getFolder(folderName);
|
||||
remoteFolder.open(Folder.OPEN_MODE_RW);
|
||||
|
||||
//FIXME: This is an ugly hack that won't be needed once the Message objects have been united.
|
||||
Message remoteMessage = remoteFolder.getMessage(message.getUid());
|
||||
MimeMessageHelper.setBody(remoteMessage, message.getBody());
|
||||
remoteFolder.fetchPart(remoteMessage, part, null);
|
||||
|
||||
localFolder.addPartToMessage((LocalMessage) message, part);
|
||||
localFolder.addPartToMessage(message, part);
|
||||
|
||||
for (MessagingListener l : getListeners(listener)) {
|
||||
l.loadAttachmentFinished(account, message, part, tag);
|
||||
l.loadAttachmentFinished(account, message, part);
|
||||
}
|
||||
} catch (MessagingException me) {
|
||||
if (K9.DEBUG)
|
||||
Log.v(K9.LOG_TAG, "Exception loading attachment", me);
|
||||
|
||||
for (MessagingListener l : getListeners(listener)) {
|
||||
l.loadAttachmentFailed(account, message, part, tag, me.getMessage());
|
||||
l.loadAttachmentFailed(account, message, part, me.getMessage());
|
||||
}
|
||||
notifyUserIfCertificateProblem(context, me, account, true);
|
||||
addErrorMessage(account, null, me);
|
||||
|
@ -133,13 +133,9 @@ public class MessagingListener {
|
||||
public void setPushActive(Account account, String folderName, boolean enabled) {}
|
||||
|
||||
|
||||
public void loadAttachmentStarted(Account account, Message message, Part part, Object tag,
|
||||
boolean requiresDownload) {}
|
||||
public void loadAttachmentFinished(Account account, Message message, Part part) {}
|
||||
|
||||
public void loadAttachmentFinished(Account account, Message message, Part part, Object tag) {}
|
||||
|
||||
public void loadAttachmentFailed(Account account, Message message, Part part, Object tag,
|
||||
String reason) {}
|
||||
public void loadAttachmentFailed(Account account, Message message, Part part, String reason) {}
|
||||
|
||||
|
||||
|
||||
|
@ -7,15 +7,17 @@ import com.fsck.k9.mail.internet.MimeBodyPart;
|
||||
|
||||
public class LocalBodyPart extends MimeBodyPart implements LocalPart {
|
||||
private final String accountUuid;
|
||||
private final LocalMessage message;
|
||||
private final long messagePartId;
|
||||
private final String displayName;
|
||||
private final long size;
|
||||
private final boolean firstClassAttachment;
|
||||
|
||||
public LocalBodyPart(String accountUuid, long messagePartId, String displayName, long size,
|
||||
public LocalBodyPart(String accountUuid, LocalMessage message, long messagePartId, String displayName, long size,
|
||||
boolean firstClassAttachment) throws MessagingException {
|
||||
super();
|
||||
this.accountUuid = accountUuid;
|
||||
this.message = message;
|
||||
this.messagePartId = messagePartId;
|
||||
this.displayName = displayName;
|
||||
this.size = size;
|
||||
@ -46,4 +48,9 @@ public class LocalBodyPart extends MimeBodyPart implements LocalPart {
|
||||
public boolean isFirstClassAttachment() {
|
||||
return firstClassAttachment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalMessage getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
@ -689,7 +689,8 @@ public class LocalFolder extends Folder<LocalMessage> implements Serializable {
|
||||
|
||||
String parentMimeType = parentPart.getMimeType();
|
||||
if (parentMimeType.startsWith("multipart/")) {
|
||||
BodyPart bodyPart = new LocalBodyPart(getAccountUuid(), id, displayName, size, firstClassAttachment);
|
||||
BodyPart bodyPart = new LocalBodyPart(getAccountUuid(), message, id, displayName, size,
|
||||
firstClassAttachment);
|
||||
((Multipart) parentPart.getBody()).addBodyPart(bodyPart);
|
||||
part = bodyPart;
|
||||
} else if (parentMimeType.startsWith("message/")) {
|
||||
|
@ -7,4 +7,5 @@ public interface LocalPart {
|
||||
String getDisplayName();
|
||||
long getSize();
|
||||
boolean isFirstClassAttachment();
|
||||
LocalMessage getMessage();
|
||||
}
|
||||
|
@ -19,29 +19,44 @@ import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.R;
|
||||
import com.fsck.k9.cache.TemporaryAttachmentStore;
|
||||
import com.fsck.k9.controller.MessagingController;
|
||||
import com.fsck.k9.controller.MessagingListener;
|
||||
import com.fsck.k9.helper.FileHelper;
|
||||
import com.fsck.k9.helper.MediaScannerNotifier;
|
||||
import com.fsck.k9.mail.Message;
|
||||
import com.fsck.k9.mail.Part;
|
||||
import com.fsck.k9.mail.internet.MimeUtility;
|
||||
import com.fsck.k9.mailstore.AttachmentViewInfo;
|
||||
import com.fsck.k9.mailstore.LocalMessage;
|
||||
import com.fsck.k9.mailstore.LocalPart;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
|
||||
public class AttachmentController {
|
||||
private final Context context;
|
||||
private final SingleMessageView messageView;
|
||||
private final MessagingController controller;
|
||||
private final MessageViewFragment messageViewFragment;
|
||||
private final AttachmentViewInfo attachment;
|
||||
|
||||
AttachmentController(SingleMessageView messageView, AttachmentViewInfo attachment) {
|
||||
this.context = messageView.getContext();
|
||||
this.messageView = messageView;
|
||||
AttachmentController(MessagingController controller, MessageViewFragment messageViewFragment,
|
||||
AttachmentViewInfo attachment) {
|
||||
this.context = messageViewFragment.getContext();
|
||||
this.controller = controller;
|
||||
this.messageViewFragment = messageViewFragment;
|
||||
this.attachment = attachment;
|
||||
}
|
||||
|
||||
public void viewAttachment() {
|
||||
new ViewAttachmentAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
if (needsDownloading()) {
|
||||
downloadAndViewAttachment((LocalPart) attachment.part);
|
||||
} else {
|
||||
viewLocalAttachment();
|
||||
}
|
||||
}
|
||||
|
||||
public void saveAttachment() {
|
||||
@ -52,6 +67,60 @@ public class AttachmentController {
|
||||
saveAttachmentTo(new File(directory));
|
||||
}
|
||||
|
||||
private boolean needsDownloading() {
|
||||
return isPartMissing() && isLocalPart();
|
||||
}
|
||||
|
||||
private boolean isPartMissing() {
|
||||
return attachment.part.getBody() == null;
|
||||
}
|
||||
|
||||
private boolean isLocalPart() {
|
||||
return attachment.part instanceof LocalPart;
|
||||
}
|
||||
|
||||
private void downloadAndViewAttachment(LocalPart localPart) {
|
||||
downloadAttachment(localPart, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
viewLocalAttachment();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void downloadAndSaveAttachmentTo(LocalPart localPart, final File directory) {
|
||||
downloadAttachment(localPart, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
saveAttachmentTo(directory);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void downloadAttachment(LocalPart localPart, final Runnable attachmentDownloadedCallback) {
|
||||
String accountUuid = localPart.getAccountUuid();
|
||||
Account account = Preferences.getPreferences(context).getAccount(accountUuid);
|
||||
LocalMessage message = localPart.getMessage();
|
||||
|
||||
messageViewFragment.showAttachmentLoadingDialog();
|
||||
controller.loadAttachment(account, message, attachment.part, new MessagingListener() {
|
||||
@Override
|
||||
public void loadAttachmentFinished(Account account, Message message, Part part) {
|
||||
messageViewFragment.hideAttachmentLoadingDialogOnMainThread();
|
||||
messageViewFragment.runOnMainThread(attachmentDownloadedCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadAttachmentFailed(Account account, Message message, Part part, String reason) {
|
||||
messageViewFragment.hideAttachmentLoadingDialogOnMainThread();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void viewLocalAttachment() {
|
||||
new ViewAttachmentAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void saveAttachmentTo(File directory) {
|
||||
boolean isExternalStorageMounted = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
|
||||
if (!isExternalStorageMounted) {
|
||||
@ -60,6 +129,14 @@ public class AttachmentController {
|
||||
return;
|
||||
}
|
||||
|
||||
if (needsDownloading()) {
|
||||
downloadAndSaveAttachmentTo((LocalPart) attachment.part, directory);
|
||||
} else {
|
||||
saveLocalAttachmentTo(directory);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveLocalAttachmentTo(File directory) {
|
||||
//FIXME: write file in background thread
|
||||
try {
|
||||
File file = saveAttachmentWithUniqueFileName(directory);
|
||||
@ -187,7 +264,7 @@ public class AttachmentController {
|
||||
}
|
||||
|
||||
private void addUiIntentFlags(Intent intent) {
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
||||
}
|
||||
|
||||
private int getResolvedIntentActivitiesCount(Intent intent) {
|
||||
@ -243,7 +320,7 @@ public class AttachmentController {
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
messageView.disableAttachmentViewButton(attachment);
|
||||
messageViewFragment.disableAttachmentButtons(attachment);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -254,7 +331,7 @@ public class AttachmentController {
|
||||
@Override
|
||||
protected void onPostExecute(Intent intent) {
|
||||
viewAttachment(intent);
|
||||
messageView.enableAttachmentViewButton(attachment);
|
||||
messageViewFragment.enableAttachmentButtons(attachment);
|
||||
}
|
||||
|
||||
private void viewAttachment(Intent intent) {
|
||||
|
@ -43,12 +43,14 @@ public class AttachmentView extends FrameLayout implements OnClickListener, OnLo
|
||||
return attachment;
|
||||
}
|
||||
|
||||
public void enableViewButton() {
|
||||
public void enableButtons() {
|
||||
viewButton.setEnabled(true);
|
||||
downloadButton.setEnabled(true);
|
||||
}
|
||||
|
||||
public void disableViewButton() {
|
||||
public void disableButtons() {
|
||||
viewButton.setEnabled(false);
|
||||
downloadButton.setEnabled(false);
|
||||
}
|
||||
|
||||
public void setAttachment(AttachmentViewInfo attachment) throws MessagingException {
|
||||
|
@ -663,6 +663,37 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
|
||||
}
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
public void disableAttachmentButtons(AttachmentViewInfo attachment) {
|
||||
mMessageView.disableAttachmentButtons(attachment);
|
||||
}
|
||||
|
||||
public void enableAttachmentButtons(AttachmentViewInfo attachment) {
|
||||
mMessageView.enableAttachmentButtons(attachment);
|
||||
}
|
||||
|
||||
public void runOnMainThread(Runnable runnable) {
|
||||
handler.post(runnable);
|
||||
}
|
||||
|
||||
public void showAttachmentLoadingDialog() {
|
||||
mMessageView.disableAttachmentButtons();
|
||||
showDialog(R.id.dialog_attachment_progress);
|
||||
}
|
||||
|
||||
public void hideAttachmentLoadingDialogOnMainThread() {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
removeDialog(R.id.dialog_attachment_progress);
|
||||
mMessageView.enableAttachmentButtons();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public interface MessageViewFragmentListener {
|
||||
public void onForward(LocalMessage mMessage, PgpData mPgpData);
|
||||
public void disableDeleteAction();
|
||||
@ -760,7 +791,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
|
||||
}
|
||||
|
||||
private AttachmentController getAttachmentController(AttachmentViewInfo attachment) {
|
||||
return new AttachmentController(mMessageView, attachment);
|
||||
return new AttachmentController(mController, this, attachment);
|
||||
}
|
||||
|
||||
private class DownloadMessageListener extends MessagingListener {
|
||||
|
@ -500,6 +500,18 @@ public class SingleMessageView extends LinearLayout implements OnClickListener,
|
||||
}
|
||||
}
|
||||
|
||||
public void enableAttachmentButtons() {
|
||||
for (AttachmentView attachmentView : attachments.values()) {
|
||||
attachmentView.enableButtons();
|
||||
}
|
||||
}
|
||||
|
||||
public void disableAttachmentButtons() {
|
||||
for (AttachmentView attachmentView : attachments.values()) {
|
||||
attachmentView.disableButtons();
|
||||
}
|
||||
}
|
||||
|
||||
public void showAllHeaders() {
|
||||
mHeaderContainer.onShowAdditionalHeaders();
|
||||
}
|
||||
@ -701,12 +713,12 @@ public class SingleMessageView extends LinearLayout implements OnClickListener,
|
||||
}
|
||||
}
|
||||
|
||||
public void enableAttachmentViewButton(AttachmentViewInfo attachment) {
|
||||
getAttachmentView(attachment).enableViewButton();
|
||||
public void enableAttachmentButtons(AttachmentViewInfo attachment) {
|
||||
getAttachmentView(attachment).enableButtons();
|
||||
}
|
||||
|
||||
public void disableAttachmentViewButton(AttachmentViewInfo attachment) {
|
||||
getAttachmentView(attachment).disableViewButton();
|
||||
public void disableAttachmentButtons(AttachmentViewInfo attachment) {
|
||||
getAttachmentView(attachment).disableButtons();
|
||||
}
|
||||
|
||||
private AttachmentView getAttachmentView(AttachmentViewInfo attachment) {
|
||||
|
Loading…
Reference in New Issue
Block a user