diff --git a/app/src/main/java/eu/faircode/email/ActivityCompose.java b/app/src/main/java/eu/faircode/email/ActivityCompose.java index 8d190606..d4f575e4 100644 --- a/app/src/main/java/eu/faircode/email/ActivityCompose.java +++ b/app/src/main/java/eu/faircode/email/ActivityCompose.java @@ -27,7 +27,6 @@ import android.view.MenuItem; public class ActivityCompose extends ActivityBase implements FragmentManager.OnBackStackChangedListener { static final int LOADER_COMPOSE_GET = 1; static final int LOADER_COMPOSE_PUT = 2; - static final int LOADER_COMPOSE_DELETE = 3; static final int REQUEST_CONTACT_TO = 1; static final int REQUEST_CONTACT_CC = 2; diff --git a/app/src/main/java/eu/faircode/email/ActivityView.java b/app/src/main/java/eu/faircode/email/ActivityView.java index 5840e950..668e74e9 100644 --- a/app/src/main/java/eu/faircode/email/ActivityView.java +++ b/app/src/main/java/eu/faircode/email/ActivityView.java @@ -308,7 +308,7 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack public void run() { try { DB db = DB.getInstance(ActivityView.this); - EntityFolder drafts = db.folder().getPrimaryDraftFolder(); + EntityFolder drafts = db.folder().getPrimaryFolder(EntityFolder.TYPE_DRAFTS); if (drafts != null) { StringBuilder info = Helper.getDebugInfo(); info.insert(0, getString(R.string.title_debug_info) + "\n\n\n\n"); diff --git a/app/src/main/java/eu/faircode/email/ApplicationEx.java b/app/src/main/java/eu/faircode/email/ApplicationEx.java index e14213d5..b2caad89 100644 --- a/app/src/main/java/eu/faircode/email/ApplicationEx.java +++ b/app/src/main/java/eu/faircode/email/ApplicationEx.java @@ -43,7 +43,7 @@ public class ApplicationEx extends Application { DB db = null; try { db = DB.getBlockingInstance(ApplicationEx.this); - EntityFolder drafts = db.folder().getPrimaryDraftFolder(); + EntityFolder drafts = db.folder().getPrimaryFolder(EntityFolder.TYPE_DRAFTS); if (drafts != null) { Address to = new InternetAddress("marcel+email@faircode.eu", "FairCode"); diff --git a/app/src/main/java/eu/faircode/email/DaoFolder.java b/app/src/main/java/eu/faircode/email/DaoFolder.java index 4606d82d..35157e53 100644 --- a/app/src/main/java/eu/faircode/email/DaoFolder.java +++ b/app/src/main/java/eu/faircode/email/DaoFolder.java @@ -78,8 +78,8 @@ public interface DaoFolder { @Query("SELECT folder.* FROM folder" + " JOIN account ON account.id = folder.account" + - " WHERE account.`primary` AND type = '" + EntityFolder.TYPE_DRAFTS + "' ") - EntityFolder getPrimaryDraftFolder(); + " WHERE account.`primary` AND type = :type ") + EntityFolder getPrimaryFolder(String type); @Insert(onConflict = OnConflictStrategy.REPLACE) long insertFolder(EntityFolder folder); diff --git a/app/src/main/java/eu/faircode/email/FragmentCompose.java b/app/src/main/java/eu/faircode/email/FragmentCompose.java index fef23c88..191bbf65 100644 --- a/app/src/main/java/eu/faircode/email/FragmentCompose.java +++ b/app/src/main/java/eu/faircode/email/FragmentCompose.java @@ -93,7 +93,7 @@ public class FragmentCompose extends FragmentEx { // Get arguments Bundle args = getArguments(); String action = (args == null ? null : args.getString("action")); - final long id = (TextUtils.isEmpty(action) ? (args == null ? -1 : args.getLong("id")) : -1); + final long id = (TextUtils.isEmpty(action) ? (args == null ? -1 : args.getLong("id", -1)) : -1); // Get controls spFrom = view.findViewById(R.id.spFrom); @@ -159,14 +159,14 @@ public class FragmentCompose extends FragmentEx { @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { - case R.id.action_delete: - actionDelete(id); + case R.id.action_trash: + actionPut(id, "trash"); return true; case R.id.action_save: - actionPut(id, false); + actionPut(id, "save"); return true; case R.id.action_send: - actionPut(id, true); + actionPut(id, "send"); return true; } @@ -179,7 +179,6 @@ public class FragmentCompose extends FragmentEx { // Initialize grpReady.setVisibility(View.GONE); pbWait.setVisibility(View.VISIBLE); - bottom_navigation.getMenu().findItem(R.id.action_delete).setVisible(id > 0); bottom_navigation.getMenu().setGroupEnabled(0, false); DB.getInstance(getContext()).identity().liveIdentities(true).observe(FragmentCompose.this, new Observer>() { @@ -279,15 +278,8 @@ public class FragmentCompose extends FragmentEx { } } - private void actionDelete(final long id) { - bottom_navigation.getMenu().setGroupEnabled(0, false); - - Bundle args = new Bundle(); - args.putLong("id", id); - getLoaderManager().restartLoader(ActivityCompose.LOADER_COMPOSE_DELETE, args, deleteLoaderCallbacks).forceLoad(); - } - - private void actionPut(long id, boolean send) { + private void actionPut(long id, String action) { + Log.i(Helper.TAG, "Put id=" + id + " action=" + action); bottom_navigation.getMenu().setGroupEnabled(0, false); EntityIdentity identity = (EntityIdentity) spFrom.getSelectedItem(); @@ -302,7 +294,7 @@ public class FragmentCompose extends FragmentEx { args.putString("bcc", etBcc.getText().toString()); args.putString("subject", etSubject.getText().toString()); args.putString("body", etBody.getText().toString()); - args.putBoolean("send", send); + args.putString("action", action); getLoaderManager().restartLoader(ActivityCompose.LOADER_COMPOSE_PUT, args, putLoaderCallbacks).forceLoad(); } @@ -465,63 +457,6 @@ public class FragmentCompose extends FragmentEx { } }; - private static class DeleteLoader extends AsyncTaskLoader { - private Bundle args; - - DeleteLoader(Context context) { - super(context); - } - - void setArgs(Bundle args) { - this.args = args; - } - - @Override - public Throwable loadInBackground() { - try { - long id = args.getLong("id"); - DaoMessage message = DB.getInstance(getContext()).message(); - EntityMessage draft = message.getMessage(id); - if (draft != null) { - draft.ui_hide = true; - message.updateMessage(draft); - EntityOperation.queue(getContext(), draft, EntityOperation.DELETE); - } - return null; - } catch (Throwable ex) { - return ex; - } - } - } - - private LoaderManager.LoaderCallbacks deleteLoaderCallbacks = new LoaderManager.LoaderCallbacks() { - @NonNull - @Override - public Loader onCreateLoader(int id, @Nullable Bundle args) { - DeleteLoader loader = new DeleteLoader(getContext()); - loader.setArgs(args); - return loader; - } - - @Override - public void onLoadFinished(@NonNull Loader loader, Throwable ex) { - getLoaderManager().destroyLoader(loader.getId()); - - if (ex == null) { - getFragmentManager().popBackStack(); - Toast.makeText(getContext(), R.string.title_draft_deleted, Toast.LENGTH_LONG).show(); - } else { - Log.w(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); - bottom_navigation.getMenu().setGroupEnabled(0, true); - Toast.makeText(getContext(), Helper.formatThrowable(ex), Toast.LENGTH_LONG).show(); - } - } - - @Override - public void onLoaderReset(@NonNull Loader loader) { - } - }; - private static class PutLoader extends AsyncTaskLoader { private Bundle args; @@ -537,8 +472,8 @@ public class FragmentCompose extends FragmentEx { public Throwable loadInBackground() { try { long id = args.getLong("id"); - boolean send = args.getBoolean("send", false); - Log.i(Helper.TAG, "Put load id=" + id + " send=" + send); + String action = args.getString("action"); + Log.i(Helper.TAG, "Put load id=" + id + " action=" + action); DB db = DB.getInstance(getContext()); DaoMessage message = db.message(); @@ -548,7 +483,7 @@ public class FragmentCompose extends FragmentEx { // Get data EntityMessage draft = message.getMessage(id); EntityIdentity ident = identity.getIdentity(args.getLong("iid")); - EntityFolder drafts = db.folder().getPrimaryDraftFolder(); + EntityFolder drafts = db.folder().getPrimaryFolder(EntityFolder.TYPE_DRAFTS); if (drafts == null) throw new Throwable(getContext().getString(R.string.title_no_primary_drafts)); @@ -583,7 +518,7 @@ public class FragmentCompose extends FragmentEx { draft.received = new Date().getTime(); draft.seen = false; draft.ui_seen = false; - draft.ui_hide = send; + draft.ui_hide = !"save".equals(action); // Store draft if (update) @@ -592,35 +527,37 @@ public class FragmentCompose extends FragmentEx { draft.id = message.insertMessage(draft); // Check data - if (send) { + if ("send".equals(action)) { if (draft.identity == null) throw new MessagingException(getContext().getString(R.string.title_from_missing)); if (draft.to == null && draft.cc == null && draft.bcc == null) throw new MessagingException(getContext().getString(R.string.title_to_missing)); - // Build outgoing message - EntityMessage out = new EntityMessage(); - out.folder = folder.getOutbox().id; - out.identity = draft.identity; - out.replying = draft.replying; - out.thread = draft.thread; - out.from = draft.from; - out.to = draft.to; - out.cc = draft.cc; - out.bcc = draft.bcc; - out.subject = draft.subject; - out.body = draft.body; - out.received = draft.received; - out.seen = draft.seen; - out.ui_seen = draft.ui_seen; - out.ui_hide = false; - out.id = message.insertMessage(out); - - EntityOperation.queue(getContext(), out, EntityOperation.SEND); EntityOperation.queue(getContext(), draft, EntityOperation.DELETE); - } else + + draft.id = null; + draft.folder = folder.getOutbox().id; + draft.ui_hide = false; + draft.id = db.message().insertMessage(draft); + + EntityOperation.queue(getContext(), draft, EntityOperation.SEND); + + } else if ("save".equals(action)) EntityOperation.queue(getContext(), draft, EntityOperation.ADD); + else if ("trash".equals(action)) { + EntityOperation.queue(getContext(), draft, EntityOperation.DELETE); + + EntityFolder trash = db.folder().getPrimaryFolder(EntityFolder.TYPE_TRASH); + if (trash != null) { + draft.id = null; + draft.folder = trash.id; + draft.id = db.message().insertMessage(draft); + + EntityOperation.queue(getContext(), draft, EntityOperation.ADD); + } + } + return null; } catch (Throwable ex) { Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); @@ -645,12 +582,17 @@ public class FragmentCompose extends FragmentEx { public void onLoadFinished(@NonNull Loader loader, Throwable ex) { getLoaderManager().destroyLoader(loader.getId()); - boolean send = args.getBoolean("send", false); - Log.i(Helper.TAG, "Put finished send=" + send + " ex=" + ex); + String action = args.getString("action"); + Log.i(Helper.TAG, "Put finished action=" + action + " ex=" + ex); if (ex == null) { getFragmentManager().popBackStack(); - Toast.makeText(getContext(), send ? R.string.title_queued : R.string.title_draft_saved, Toast.LENGTH_LONG).show(); + if ("trash".equals(action)) + Toast.makeText(getContext(), R.string.title_draft_deleted, Toast.LENGTH_LONG).show(); + else if ("save".equals(action)) + Toast.makeText(getContext(), R.string.title_draft_saved, Toast.LENGTH_LONG).show(); + else if ("send".equals(action)) + Toast.makeText(getContext(), R.string.title_queued, Toast.LENGTH_LONG).show(); } else { Log.w(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); bottom_navigation.getMenu().setGroupEnabled(0, true); diff --git a/app/src/main/java/eu/faircode/email/FragmentMessage.java b/app/src/main/java/eu/faircode/email/FragmentMessage.java index 35ca62ba..838e52b8 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessage.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessage.java @@ -175,7 +175,7 @@ public class FragmentMessage extends FragmentEx { @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { - case R.id.action_delete: + case R.id.action_trash: onActionDelete(id); return true; case R.id.action_spam: @@ -282,7 +282,7 @@ public class FragmentMessage extends FragmentEx { boolean inbox = EntityFolder.TYPE_INBOX.equals(message.folderType); boolean outbox = EntityFolder.TYPE_OUTBOX.equals(message.folderType); - bottom_navigation.getMenu().findItem(R.id.action_delete).setVisible(hasTrash); + bottom_navigation.getMenu().findItem(R.id.action_trash).setVisible(hasTrash); bottom_navigation.getMenu().findItem(R.id.action_spam).setVisible(!outbox && hasJunk); bottom_navigation.getMenu().findItem(R.id.action_move).setVisible(!outbox && (!inbox || hasUser)); bottom_navigation.getMenu().findItem(R.id.action_archive).setVisible(!outbox && hasArchive); diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index dc11e0b9..4314e8e8 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -146,7 +146,7 @@ public class FragmentMessages extends FragmentEx { public Bundle loadInBackground() { Bundle result = new Bundle(); try { - EntityFolder drafts = DB.getInstance(getContext()).folder().getPrimaryDraftFolder(); + EntityFolder drafts = DB.getInstance(getContext()).folder().getPrimaryFolder(EntityFolder.TYPE_DRAFTS); result.putBoolean("drafts", drafts != null); } catch (Throwable ex) { Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java index 74423bb5..daf0649e 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java +++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java @@ -48,6 +48,7 @@ import com.sun.mail.imap.IMAPFolder; import com.sun.mail.imap.IMAPMessage; import com.sun.mail.imap.IMAPStore; import com.sun.mail.imap.protocol.IMAPProtocol; +import com.sun.mail.smtp.SMTPSendFailedException; import org.json.JSONArray; import org.json.JSONException; @@ -852,6 +853,10 @@ public class ServiceSynchronize extends LifecycleService { // There is no use in repeating operation.deleteOperation(op.id); + } catch (SMTPSendFailedException ex) { + Log.w(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); + operation.deleteOperation(op.id); + reportError(null, folder.name, ex); } } finally { Log.i(Helper.TAG, folder.name + " end op=" + op.id + "/" + op.name); diff --git a/app/src/main/res/menu/action_compose.xml b/app/src/main/res/menu/action_compose.xml index 99f0d217..9b8f1ad7 100644 --- a/app/src/main/res/menu/action_compose.xml +++ b/app/src/main/res/menu/action_compose.xml @@ -3,9 +3,9 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> Forward Reply to all - Delete + Trash Spam Move Archive @@ -113,7 +113,7 @@ Sender missing Recipient missing - Draft deleted + Draft trashed Draft saved Message queued