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="mark_all_as_read">Mark all as read</string>
|
||||||
|
|
||||||
<string name="loading_attachment">Loading attachment…</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>
|
</resources>
|
||||||
|
@ -61,6 +61,7 @@ import com.fsck.k9.controller.MessagingController;
|
|||||||
import com.fsck.k9.controller.MessagingListener;
|
import com.fsck.k9.controller.MessagingListener;
|
||||||
import com.fsck.k9.crypto.CryptoProvider;
|
import com.fsck.k9.crypto.CryptoProvider;
|
||||||
import com.fsck.k9.crypto.PgpData;
|
import com.fsck.k9.crypto.PgpData;
|
||||||
|
import com.fsck.k9.fragment.ProgressDialogFragment;
|
||||||
import com.fsck.k9.helper.ContactItem;
|
import com.fsck.k9.helper.ContactItem;
|
||||||
import com.fsck.k9.helper.Contacts;
|
import com.fsck.k9.helper.Contacts;
|
||||||
import com.fsck.k9.helper.HtmlConverter;
|
import com.fsck.k9.helper.HtmlConverter;
|
||||||
@ -94,7 +95,6 @@ import java.util.Collections;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -103,7 +103,9 @@ import java.util.StringTokenizer;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
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_SAVE_OR_DISCARD_DRAFT_MESSAGE = 1;
|
||||||
private static final int DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED = 2;
|
private static final int DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED = 2;
|
||||||
private static final int DIALOG_CONTINUE_WITHOUT_PUBLIC_KEY = 3;
|
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";
|
"com.fsck.k9.activity.MessageCompose.forcePlainText";
|
||||||
private static final String STATE_KEY_QUOTED_TEXT_FORMAT =
|
private static final String STATE_KEY_QUOTED_TEXT_FORMAT =
|
||||||
"com.fsck.k9.activity.MessageCompose.quotedTextFormat";
|
"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 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_ON = 1;
|
||||||
private static final int MSG_PROGRESS_OFF = 2;
|
private static final int MSG_PROGRESS_OFF = 2;
|
||||||
private static final int MSG_SKIPPED_ATTACHMENTS = 3;
|
private static final int MSG_SKIPPED_ATTACHMENTS = 3;
|
||||||
private static final int MSG_SAVED_DRAFT = 4;
|
private static final int MSG_SAVED_DRAFT = 4;
|
||||||
private static final int MSG_DISCARDED_DRAFT = 5;
|
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 ACTIVITY_REQUEST_PICK_ATTACHMENT = 1;
|
||||||
private static final int CONTACT_PICKER_TO = 4;
|
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;
|
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() {
|
private Handler mHandler = new Handler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(android.os.Message msg) {
|
public void handleMessage(android.os.Message msg) {
|
||||||
@ -354,6 +378,9 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
|||||||
getString(R.string.message_discarded_toast),
|
getString(R.string.message_discarded_toast),
|
||||||
Toast.LENGTH_LONG).show();
|
Toast.LENGTH_LONG).show();
|
||||||
break;
|
break;
|
||||||
|
case MSG_PERFORM_STALLED_ACTION:
|
||||||
|
performStalledAction();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
super.handleMessage(msg);
|
super.handleMessage(msg);
|
||||||
break;
|
break;
|
||||||
@ -1080,6 +1107,8 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
|||||||
attachments.add(attachment);
|
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.putParcelableArrayList(STATE_KEY_ATTACHMENTS, attachments);
|
||||||
outState.putBoolean(STATE_KEY_CC_SHOWN, mCcWrapper.getVisibility() == View.VISIBLE);
|
outState.putBoolean(STATE_KEY_CC_SHOWN, mCcWrapper.getVisibility() == View.VISIBLE);
|
||||||
outState.putBoolean(STATE_KEY_BCC_SHOWN, mBccWrapper.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();
|
mAttachments.removeAllViews();
|
||||||
mMaxLoaderId = 0;
|
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);
|
ArrayList<Attachment> attachments = savedInstanceState.getParcelableArrayList(STATE_KEY_ATTACHMENTS);
|
||||||
for (Attachment attachment : attachments) {
|
for (Attachment attachment : attachments) {
|
||||||
addAttachmentView(attachment);
|
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();
|
Toast.makeText(this, getString(R.string.message_compose_error_no_recipients), Toast.LENGTH_LONG).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mWaitingForAttachments != WaitingAction.NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNumAttachmentsLoading > 0) {
|
||||||
|
mWaitingForAttachments = WaitingAction.SEND;
|
||||||
|
showWaitingForAttachmentDialog();
|
||||||
|
} else {
|
||||||
|
performSend();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performSend() {
|
||||||
final CryptoProvider crypto = mAccount.getCryptoProvider();
|
final CryptoProvider crypto = mAccount.getCryptoProvider();
|
||||||
if (mEncryptCheckbox.isChecked() && !mPgpData.hasEncryptionKeys()) {
|
if (mEncryptCheckbox.isChecked() && !mPgpData.hasEncryptionKeys()) {
|
||||||
// key selection before encryption
|
// key selection before encryption
|
||||||
@ -1847,6 +1900,19 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onSave() {
|
private void onSave() {
|
||||||
|
if (mWaitingForAttachments != WaitingAction.NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNumAttachmentsLoading > 0) {
|
||||||
|
mWaitingForAttachments = WaitingAction.SAVE;
|
||||||
|
showWaitingForAttachmentDialog();
|
||||||
|
} else {
|
||||||
|
performSend();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performSave() {
|
||||||
saveIfNeeded();
|
saveIfNeeded();
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
@ -1987,6 +2053,7 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
|||||||
new LoaderManager.LoaderCallbacks<Attachment>() {
|
new LoaderManager.LoaderCallbacks<Attachment>() {
|
||||||
@Override
|
@Override
|
||||||
public Loader<Attachment> onCreateLoader(int id, Bundle args) {
|
public Loader<Attachment> onCreateLoader(int id, Bundle args) {
|
||||||
|
onFetchAttachmentStarted();
|
||||||
Attachment attachment = args.getParcelable(LOADER_ARG_ATTACHMENT);
|
Attachment attachment = args.getParcelable(LOADER_ARG_ATTACHMENT);
|
||||||
return new AttachmentInfoLoader(MessageCompose.this, attachment);
|
return new AttachmentInfoLoader(MessageCompose.this, attachment);
|
||||||
}
|
}
|
||||||
@ -2004,6 +2071,8 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
|||||||
|
|
||||||
attachment.loaderId = ++mMaxLoaderId;
|
attachment.loaderId = ++mMaxLoaderId;
|
||||||
initAttachmentContentLoader(attachment);
|
initAttachmentContentLoader(attachment);
|
||||||
|
} else {
|
||||||
|
onFetchAttachmentFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
getSupportLoaderManager().destroyLoader(loaderId);
|
getSupportLoaderManager().destroyLoader(loaderId);
|
||||||
@ -2011,6 +2080,7 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoaderReset(Loader<Attachment> loader) {
|
public void onLoaderReset(Loader<Attachment> loader) {
|
||||||
|
onFetchAttachmentFinished();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2038,14 +2108,48 @@ public class MessageCompose extends K9Activity implements OnClickListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onFetchAttachmentFinished();
|
||||||
|
|
||||||
getSupportLoaderManager().destroyLoader(loaderId);
|
getSupportLoaderManager().destroyLoader(loaderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoaderReset(Loader<Attachment> loader) {
|
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
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
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
|
@Override
|
||||||
public Dialog onCreateDialog(int id) {
|
public Dialog onCreateDialog(int id) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
|
@ -752,8 +752,8 @@ public class MessageViewFragment extends SherlockFragment implements OnClickList
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case R.id.dialog_attachment_progress: {
|
case R.id.dialog_attachment_progress: {
|
||||||
String title = getString(R.string.dialog_attachment_progress_title);
|
String message = getString(R.string.dialog_attachment_progress_title);
|
||||||
fragment = ProgressDialogFragment.newInstance(title);
|
fragment = ProgressDialogFragment.newInstance(null, message);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
@ -2,19 +2,22 @@ package com.fsck.k9.fragment;
|
|||||||
|
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import com.actionbarsherlock.app.SherlockDialogFragment;
|
import com.actionbarsherlock.app.SherlockDialogFragment;
|
||||||
|
|
||||||
|
|
||||||
public class ProgressDialogFragment extends 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();
|
ProgressDialogFragment fragment = new ProgressDialogFragment();
|
||||||
|
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putString(ARG_TITLE, title);
|
args.putString(ARG_TITLE, title);
|
||||||
|
args.putString(ARG_MESSAGE, message);
|
||||||
fragment.setArguments(args);
|
fragment.setArguments(args);
|
||||||
|
|
||||||
return fragment;
|
return fragment;
|
||||||
@ -25,11 +28,28 @@ public class ProgressDialogFragment extends SherlockDialogFragment {
|
|||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
Bundle args = getArguments();
|
Bundle args = getArguments();
|
||||||
String title = args.getString(ARG_TITLE);
|
String title = args.getString(ARG_TITLE);
|
||||||
|
String message = args.getString(ARG_MESSAGE);
|
||||||
|
|
||||||
ProgressDialog dialog = new ProgressDialog(getActivity());
|
ProgressDialog dialog = new ProgressDialog(getActivity());
|
||||||
dialog.setIndeterminate(true);
|
dialog.setIndeterminate(true);
|
||||||
dialog.setTitle(title);
|
dialog.setTitle(title);
|
||||||
|
dialog.setMessage(message);
|
||||||
|
|
||||||
return dialog;
|
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