mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-30 13:12:25 -05:00
Don't stop the activity before attachments have been fetched
Display a progress dialog when the user tries to send the message or save a draft and the attachments haven't been fetched completely.
This commit is contained in:
parent
62aa1b87d0
commit
677d6c923d
@ -1149,4 +1149,7 @@ Please submit bug reports, contribute new features and ask questions at
|
||||
<string name="mark_all_as_read">Mark all as read</string>
|
||||
|
||||
<string name="loading_attachment">Loading attachment…</string>
|
||||
<string name="fetching_attachment_dialog_title_send">Sending message</string>
|
||||
<string name="fetching_attachment_dialog_title_save">Saving draft</string>
|
||||
<string name="fetching_attachment_dialog_message">Fetching attachment…</string>
|
||||
</resources>
|
||||
|
@ -61,6 +61,7 @@ import com.fsck.k9.controller.MessagingController;
|
||||
import com.fsck.k9.controller.MessagingListener;
|
||||
import com.fsck.k9.crypto.CryptoProvider;
|
||||
import com.fsck.k9.crypto.PgpData;
|
||||
import com.fsck.k9.fragment.ProgressDialogFragment;
|
||||
import com.fsck.k9.helper.ContactItem;
|
||||
import com.fsck.k9.helper.Contacts;
|
||||
import com.fsck.k9.helper.HtmlConverter;
|
||||
@ -94,7 +95,6 @@ import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@ -103,7 +103,9 @@ import java.util.StringTokenizer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class MessageCompose extends K9Activity implements OnClickListener {
|
||||
public class MessageCompose extends K9Activity implements OnClickListener,
|
||||
ProgressDialogFragment.CancelListener {
|
||||
|
||||
private static final int DIALOG_SAVE_OR_DISCARD_DRAFT_MESSAGE = 1;
|
||||
private static final int DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED = 2;
|
||||
private static final int DIALOG_CONTINUE_WITHOUT_PUBLIC_KEY = 3;
|
||||
@ -147,14 +149,19 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
||||
"com.fsck.k9.activity.MessageCompose.forcePlainText";
|
||||
private static final String STATE_KEY_QUOTED_TEXT_FORMAT =
|
||||
"com.fsck.k9.activity.MessageCompose.quotedTextFormat";
|
||||
private static final String STATE_KEY_NUM_ATTACHMENTS_LOADING = "numAttachmentsLoading";
|
||||
private static final String STATE_KEY_WAITING_FOR_ATTACHMENTS = "waitingForAttachments";
|
||||
|
||||
private static final String LOADER_ARG_ATTACHMENT = "attachment";
|
||||
|
||||
private static final String FRAGMENT_WAITING_FOR_ATTACHMENT = "waitingForAttachment";
|
||||
|
||||
private static final int MSG_PROGRESS_ON = 1;
|
||||
private static final int MSG_PROGRESS_OFF = 2;
|
||||
private static final int MSG_SKIPPED_ATTACHMENTS = 3;
|
||||
private static final int MSG_SAVED_DRAFT = 4;
|
||||
private static final int MSG_DISCARDED_DRAFT = 5;
|
||||
private static final int MSG_PERFORM_STALLED_ACTION = 6;
|
||||
|
||||
private static final int ACTIVITY_REQUEST_PICK_ATTACHMENT = 1;
|
||||
private static final int CONTACT_PICKER_TO = 4;
|
||||
@ -326,6 +333,23 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
||||
*/
|
||||
private long mDraftId = INVALID_DRAFT_ID;
|
||||
|
||||
/**
|
||||
* Number of attachments currently being fetched.
|
||||
*/
|
||||
private int mNumAttachmentsLoading = 0;
|
||||
|
||||
private enum WaitingAction {
|
||||
NONE,
|
||||
SEND,
|
||||
SAVE
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies what action to perform once attachments have been fetched.
|
||||
*/
|
||||
private WaitingAction mWaitingForAttachments = WaitingAction.NONE;
|
||||
|
||||
|
||||
private Handler mHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(android.os.Message msg) {
|
||||
@ -354,6 +378,9 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
||||
getString(R.string.message_discarded_toast),
|
||||
Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case MSG_PERFORM_STALLED_ACTION:
|
||||
performStalledAction();
|
||||
break;
|
||||
default:
|
||||
super.handleMessage(msg);
|
||||
break;
|
||||
@ -1080,6 +1107,8 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
||||
attachments.add(attachment);
|
||||
}
|
||||
|
||||
outState.putInt(STATE_KEY_NUM_ATTACHMENTS_LOADING, mNumAttachmentsLoading);
|
||||
outState.putString(STATE_KEY_WAITING_FOR_ATTACHMENTS, mWaitingForAttachments.name());
|
||||
outState.putParcelableArrayList(STATE_KEY_ATTACHMENTS, attachments);
|
||||
outState.putBoolean(STATE_KEY_CC_SHOWN, mCcWrapper.getVisibility() == View.VISIBLE);
|
||||
outState.putBoolean(STATE_KEY_BCC_SHOWN, mBccWrapper.getVisibility() == View.VISIBLE);
|
||||
@ -1105,6 +1134,16 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
||||
mAttachments.removeAllViews();
|
||||
mMaxLoaderId = 0;
|
||||
|
||||
mNumAttachmentsLoading = savedInstanceState.getInt(STATE_KEY_NUM_ATTACHMENTS_LOADING);
|
||||
mWaitingForAttachments = WaitingAction.NONE;
|
||||
try {
|
||||
String waitingFor = savedInstanceState.getString(STATE_KEY_WAITING_FOR_ATTACHMENTS);
|
||||
mWaitingForAttachments = WaitingAction.valueOf(waitingFor);
|
||||
} catch (Exception e) {
|
||||
Log.w(K9.LOG_TAG, "Couldn't read value \" + STATE_KEY_WAITING_FOR_ATTACHMENTS +" +
|
||||
"\" from saved instance state", e);
|
||||
}
|
||||
|
||||
ArrayList<Attachment> attachments = savedInstanceState.getParcelableArrayList(STATE_KEY_ATTACHMENTS);
|
||||
for (Attachment attachment : attachments) {
|
||||
addAttachmentView(attachment);
|
||||
@ -1784,6 +1823,20 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
||||
Toast.makeText(this, getString(R.string.message_compose_error_no_recipients), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mWaitingForAttachments != WaitingAction.NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mNumAttachmentsLoading > 0) {
|
||||
mWaitingForAttachments = WaitingAction.SEND;
|
||||
showWaitingForAttachmentDialog();
|
||||
} else {
|
||||
performSend();
|
||||
}
|
||||
}
|
||||
|
||||
private void performSend() {
|
||||
final CryptoProvider crypto = mAccount.getCryptoProvider();
|
||||
if (mEncryptCheckbox.isChecked() && !mPgpData.hasEncryptionKeys()) {
|
||||
// key selection before encryption
|
||||
@ -1847,6 +1900,19 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
||||
}
|
||||
|
||||
private void onSave() {
|
||||
if (mWaitingForAttachments != WaitingAction.NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mNumAttachmentsLoading > 0) {
|
||||
mWaitingForAttachments = WaitingAction.SAVE;
|
||||
showWaitingForAttachmentDialog();
|
||||
} else {
|
||||
performSend();
|
||||
}
|
||||
}
|
||||
|
||||
private void performSave() {
|
||||
saveIfNeeded();
|
||||
finish();
|
||||
}
|
||||
@ -1987,6 +2053,7 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
||||
new LoaderManager.LoaderCallbacks<Attachment>() {
|
||||
@Override
|
||||
public Loader<Attachment> onCreateLoader(int id, Bundle args) {
|
||||
onFetchAttachmentStarted();
|
||||
Attachment attachment = args.getParcelable(LOADER_ARG_ATTACHMENT);
|
||||
return new AttachmentInfoLoader(MessageCompose.this, attachment);
|
||||
}
|
||||
@ -2004,6 +2071,8 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
||||
|
||||
attachment.loaderId = ++mMaxLoaderId;
|
||||
initAttachmentContentLoader(attachment);
|
||||
} else {
|
||||
onFetchAttachmentFinished();
|
||||
}
|
||||
|
||||
getSupportLoaderManager().destroyLoader(loaderId);
|
||||
@ -2011,6 +2080,7 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Attachment> loader) {
|
||||
onFetchAttachmentFinished();
|
||||
}
|
||||
};
|
||||
|
||||
@ -2038,14 +2108,48 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
||||
}
|
||||
}
|
||||
|
||||
onFetchAttachmentFinished();
|
||||
|
||||
getSupportLoaderManager().destroyLoader(loaderId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Attachment> loader) {
|
||||
onFetchAttachmentFinished();
|
||||
}
|
||||
};
|
||||
|
||||
private void onFetchAttachmentStarted() {
|
||||
mNumAttachmentsLoading += 1;
|
||||
}
|
||||
|
||||
private void onFetchAttachmentFinished() {
|
||||
// We're not allowed to perform fragment transactions when called from onLoadFinished().
|
||||
// So we use the Handler to call performStalledAction().
|
||||
mHandler.sendEmptyMessage(MSG_PERFORM_STALLED_ACTION);
|
||||
}
|
||||
|
||||
private void performStalledAction() {
|
||||
mNumAttachmentsLoading -= 1;
|
||||
|
||||
WaitingAction waitingFor = mWaitingForAttachments;
|
||||
mWaitingForAttachments = WaitingAction.NONE;
|
||||
|
||||
if (waitingFor != WaitingAction.NONE) {
|
||||
dismissWaitingForAttachmentDialog();
|
||||
}
|
||||
|
||||
switch (waitingFor) {
|
||||
case SEND: {
|
||||
performSend();
|
||||
break;
|
||||
}
|
||||
case SAVE: {
|
||||
performSave();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
@ -2380,6 +2484,45 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
||||
}
|
||||
}
|
||||
|
||||
private void showWaitingForAttachmentDialog() {
|
||||
String title;
|
||||
|
||||
switch (mWaitingForAttachments) {
|
||||
case SEND: {
|
||||
title = getString(R.string.fetching_attachment_dialog_title_send);
|
||||
break;
|
||||
}
|
||||
case SAVE: {
|
||||
title = getString(R.string.fetching_attachment_dialog_title_save);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ProgressDialogFragment fragment = ProgressDialogFragment.newInstance(title,
|
||||
getString(R.string.fetching_attachment_dialog_message));
|
||||
fragment.show(getSupportFragmentManager(), FRAGMENT_WAITING_FOR_ATTACHMENT);
|
||||
}
|
||||
|
||||
public void onCancel(ProgressDialogFragment fragment) {
|
||||
attachmentProgressDialogCancelled();
|
||||
}
|
||||
|
||||
void attachmentProgressDialogCancelled() {
|
||||
mWaitingForAttachments = WaitingAction.NONE;
|
||||
}
|
||||
|
||||
private void dismissWaitingForAttachmentDialog() {
|
||||
ProgressDialogFragment fragment = (ProgressDialogFragment)
|
||||
getSupportFragmentManager().findFragmentByTag(FRAGMENT_WAITING_FOR_ATTACHMENT);
|
||||
|
||||
if (fragment != null) {
|
||||
fragment.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(int id) {
|
||||
switch (id) {
|
||||
|
@ -752,8 +752,8 @@ public class MessageViewFragment extends SherlockFragment implements OnClickList
|
||||
break;
|
||||
}
|
||||
case R.id.dialog_attachment_progress: {
|
||||
String title = getString(R.string.dialog_attachment_progress_title);
|
||||
fragment = ProgressDialogFragment.newInstance(title);
|
||||
String message = getString(R.string.dialog_attachment_progress_title);
|
||||
fragment = ProgressDialogFragment.newInstance(null, message);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
@ -2,19 +2,22 @@ package com.fsck.k9.fragment;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockDialogFragment;
|
||||
|
||||
|
||||
public class ProgressDialogFragment extends SherlockDialogFragment {
|
||||
private static final String ARG_TITLE = "title";
|
||||
protected static final String ARG_TITLE = "title";
|
||||
protected static final String ARG_MESSAGE = "message";
|
||||
|
||||
public static ProgressDialogFragment newInstance(String title) {
|
||||
public static ProgressDialogFragment newInstance(String title, String message) {
|
||||
ProgressDialogFragment fragment = new ProgressDialogFragment();
|
||||
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ARG_TITLE, title);
|
||||
args.putString(ARG_MESSAGE, message);
|
||||
fragment.setArguments(args);
|
||||
|
||||
return fragment;
|
||||
@ -25,11 +28,28 @@ public class ProgressDialogFragment extends SherlockDialogFragment {
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
Bundle args = getArguments();
|
||||
String title = args.getString(ARG_TITLE);
|
||||
String message = args.getString(ARG_MESSAGE);
|
||||
|
||||
ProgressDialog dialog = new ProgressDialog(getActivity());
|
||||
dialog.setIndeterminate(true);
|
||||
dialog.setTitle(title);
|
||||
dialog.setMessage(message);
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
CancelListener listener = (CancelListener) getActivity();
|
||||
if (listener != null && listener instanceof CancelListener) {
|
||||
listener.onCancel(this);
|
||||
}
|
||||
|
||||
super.onCancel(dialog);
|
||||
}
|
||||
|
||||
|
||||
public interface CancelListener {
|
||||
void onCancel(ProgressDialogFragment fragment);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user