diff --git a/app/src/main/java/eu/faircode/email/AdapterAnswer.java b/app/src/main/java/eu/faircode/email/AdapterAnswer.java index 8091b17294..6770f1b9f0 100644 --- a/app/src/main/java/eu/faircode/email/AdapterAnswer.java +++ b/app/src/main/java/eu/faircode/email/AdapterAnswer.java @@ -49,7 +49,7 @@ public class AdapterAnswer extends RecyclerView.Adapter all = new ArrayList<>(); private List filtered = new ArrayList<>(); - private EntityAccount primary = null; + private boolean primary = false; public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { private View itemView; @@ -92,7 +92,7 @@ public class AdapterAnswer extends RecyclerView.Adapter() { + new SimpleTask() { @Override - protected EntityAccount onExecute(Context context, Bundle args) { - return DB.getInstance(context).account().getPrimaryAccount(); + protected EntityFolder onExecute(Context context, Bundle args) { + return DB.getInstance(context).folder().getPrimaryDrafts(); } @Override - protected void onExecuted(Bundle args, EntityAccount account) { - primary = account; + protected void onExecuted(Bundle args, EntityFolder drafts) { + primary = (drafts != null); } @Override diff --git a/app/src/main/java/eu/faircode/email/DaoFolder.java b/app/src/main/java/eu/faircode/email/DaoFolder.java index 40eb4036c7..70c6d4f268 100644 --- a/app/src/main/java/eu/faircode/email/DaoFolder.java +++ b/app/src/main/java/eu/faircode/email/DaoFolder.java @@ -91,12 +91,6 @@ public interface DaoFolder { " WHERE `primary` AND type = '" + EntityFolder.ARCHIVE + "'") LiveData livePrimaryArchive(); - @Query("SELECT folder.* FROM folder" + - " JOIN account ON account.id = folder.account" + - " WHERE folder.type = '" + EntityFolder.DRAFTS + "'" + - " AND (account.id = :account OR (:account IS NULL AND account.`primary`))") - LiveData liveDrafts(Long account); - @Query("SELECT folder.*, account.name AS accountName, account.color AS accountColor, account.pop as accountPop, account.state AS accountState" + ", COUNT(message.id) AS messages" + ", SUM(CASE WHEN message.content = 1 THEN 1 ELSE 0 END) AS content" + diff --git a/app/src/main/java/eu/faircode/email/DaoIdentity.java b/app/src/main/java/eu/faircode/email/DaoIdentity.java index d181db1bf0..89662c47ff 100644 --- a/app/src/main/java/eu/faircode/email/DaoIdentity.java +++ b/app/src/main/java/eu/faircode/email/DaoIdentity.java @@ -37,8 +37,18 @@ public interface DaoIdentity { @Query("SELECT identity.*, account.name AS accountName FROM identity" + " JOIN account ON account.id = identity.account" + " JOIN folder ON folder.account = identity.account AND folder.type = '" + EntityFolder.DRAFTS + "'" + - " WHERE identity.synchronize AND account.synchronize") - List getComposableIdentities(); + " WHERE :account IS NULL OR identity.account = :account" + + " AND identity.synchronize" + + " AND account.synchronize") + List getComposableIdentities(Long account); + + @Query("SELECT identity.*, account.name AS accountName FROM identity" + + " JOIN account ON account.id = identity.account" + + " JOIN folder ON folder.account = identity.account AND folder.type = '" + EntityFolder.DRAFTS + "'" + + " WHERE :account IS NULL OR identity.account = :account" + + " AND identity.synchronize" + + " AND account.synchronize") + LiveData> liveComposableIdentities(Long account); @Query("SELECT * FROM identity WHERE account = :account") List getIdentities(long account); diff --git a/app/src/main/java/eu/faircode/email/FragmentCompose.java b/app/src/main/java/eu/faircode/email/FragmentCompose.java index d7d2491fd8..0d26a80eb3 100644 --- a/app/src/main/java/eu/faircode/email/FragmentCompose.java +++ b/app/src/main/java/eu/faircode/email/FragmentCompose.java @@ -1463,9 +1463,9 @@ public class FragmentCompose extends FragmentBase { return attachment; } - private SimpleTask draftLoader = new SimpleTask() { + private SimpleTask draftLoader = new SimpleTask() { @Override - protected DraftAccount onExecute(Context context, Bundle args) throws IOException { + protected EntityMessage onExecute(Context context, Bundle args) throws IOException { String action = args.getString("action"); long id = args.getLong("id", -1); long reference = args.getLong("reference", -1); @@ -1473,31 +1473,33 @@ public class FragmentCompose extends FragmentBase { Log.i("Load draft action=" + action + " id=" + id + " reference=" + reference); - DraftAccount result = new DraftAccount(); + EntityMessage draft; DB db = DB.getInstance(context); try { db.beginTransaction(); - result.draft = db.message().getMessage(id); - if (result.draft == null || result.draft.ui_hide) { + draft = db.message().getMessage(id); + if (draft == null || draft.ui_hide) { // New draft if ("edit".equals(action)) - throw new IllegalStateException("Draft not found hide=" + (result.draft != null)); + throw new IllegalStateException("Draft not found hide=" + (draft != null)); - List identities = db.identity().getComposableIdentities(); + List identities = db.identity().getComposableIdentities(null); + EntityFolder drafts; EntityMessage ref = db.message().getMessage(reference); if (ref == null) { long aid = args.getLong("account", -1); - if (aid < 0) { - result.account = db.account().getPrimaryAccount(); - if (result.account == null) - throw new IllegalArgumentException(context.getString(R.string.title_no_primary_drafts)); - } else - result.account = db.account().getAccount(aid); + drafts = (aid < 0 + ? db.folder().getPrimaryDrafts() + : db.folder().getFolderByType(aid, EntityFolder.DRAFTS)); + if (drafts == null) + throw new IllegalArgumentException(context.getString(R.string.title_no_primary_drafts)); } else { - result.account = db.account().getAccount(ref.account); + drafts = db.folder().getFolderByType(ref.account, EntityFolder.DRAFTS); + if (drafts == null) + throw new IllegalArgumentException(context.getString(R.string.title_no_primary_drafts)); // Reply to recipient, not to known self if (ref.reply != null && ref.reply.length > 0) { @@ -1536,45 +1538,38 @@ public class FragmentCompose extends FragmentBase { } } - EntityFolder drafts; - drafts = db.folder().getFolderByType(result.account.id, EntityFolder.DRAFTS); - if (drafts == null) - drafts = db.folder().getPrimaryDrafts(); - if (drafts == null) - throw new IllegalArgumentException(context.getString(R.string.title_no_primary_drafts)); - String body = ""; - result.draft = new EntityMessage(); - result.draft.account = result.account.id; - result.draft.folder = drafts.id; - result.draft.msgid = EntityMessage.generateMessageId(); + draft = new EntityMessage(); + draft.account = drafts.account; + draft.folder = drafts.id; + draft.msgid = EntityMessage.generateMessageId(); if (ref == null) { - result.draft.thread = result.draft.msgid; + draft.thread = draft.msgid; try { String to = args.getString("to"); - result.draft.to = (TextUtils.isEmpty(to) ? null : InternetAddress.parse(to)); + draft.to = (TextUtils.isEmpty(to) ? null : InternetAddress.parse(to)); } catch (AddressException ex) { Log.w(ex); } try { String cc = args.getString("cc"); - result.draft.cc = (TextUtils.isEmpty(cc) ? null : InternetAddress.parse(cc)); + draft.cc = (TextUtils.isEmpty(cc) ? null : InternetAddress.parse(cc)); } catch (AddressException ex) { Log.w(ex); } try { String bcc = args.getString("bcc"); - result.draft.bcc = (TextUtils.isEmpty(bcc) ? null : InternetAddress.parse(bcc)); + draft.bcc = (TextUtils.isEmpty(bcc) ? null : InternetAddress.parse(bcc)); } catch (AddressException ex) { Log.w(ex); } - result.draft.subject = args.getString("subject", ""); + draft.subject = args.getString("subject", ""); body = args.getString("body", ""); body = body.replaceAll("\\r?\\n", "
"); @@ -1582,11 +1577,11 @@ public class FragmentCompose extends FragmentBase { body = EntityAnswer.getAnswerText(db, answer, null) + body; } else { if ("reply".equals(action) || "reply_all".equals(action)) { - result.draft.references = (ref.references == null ? "" : ref.references + " ") + ref.msgid; - result.draft.inreplyto = ref.msgid; - result.draft.thread = ref.thread; - result.draft.to = (ref.reply == null || ref.reply.length == 0 ? ref.from : ref.reply); - result.draft.from = ref.to; + draft.references = (ref.references == null ? "" : ref.references + " ") + ref.msgid; + draft.inreplyto = ref.msgid; + draft.thread = ref.thread; + draft.to = (ref.reply == null || ref.reply.length == 0 ? ref.from : ref.reply); + draft.from = ref.to; if ("reply_all".equals(action)) { List
addresses = new ArrayList<>(); @@ -1602,23 +1597,23 @@ public class FragmentCompose extends FragmentBase { addresses.remove(address); } } - result.draft.cc = addresses.toArray(new Address[0]); + draft.cc = addresses.toArray(new Address[0]); } } else if ("forward".equals(action)) { - result.draft.thread = result.draft.msgid; // new thread - result.draft.from = ref.to; + draft.thread = draft.msgid; // new thread + draft.from = ref.to; } if ("reply".equals(action) || "reply_all".equals(action)) - result.draft.subject = context.getString(R.string.title_subject_reply, + draft.subject = context.getString(R.string.title_subject_reply, ref.subject == null ? "" : ref.subject); else if ("forward".equals(action)) - result.draft.subject = context.getString(R.string.title_subject_forward, + draft.subject = context.getString(R.string.title_subject_forward, ref.subject == null ? "" : ref.subject); if (answer > 0 && ("reply".equals(action) || "reply_all".equals(action))) - body = EntityAnswer.getAnswerText(db, answer, result.draft.to) + body; + body = EntityAnswer.getAnswerText(db, answer, draft.to) + body; } // Select identity matching from address @@ -1630,15 +1625,15 @@ public class FragmentCompose extends FragmentBase { do { String from = null; if (iindex >= 0) - from = Helper.canonicalAddress(((InternetAddress) result.draft.from[iindex]).getAddress()); + from = Helper.canonicalAddress(((InternetAddress) draft.from[iindex]).getAddress()); for (EntityIdentity identity : identities) { String email = Helper.canonicalAddress(identity.email); if (email.equals(from)) { - result.draft.identity = identity.id; - result.draft.from = new InternetAddress[]{new InternetAddress(identity.email, identity.name)}; + draft.identity = identity.id; + draft.from = new InternetAddress[]{new InternetAddress(identity.email, identity.name)}; break; } - if (identity.account.equals(result.draft.account)) { + if (identity.account.equals(draft.account)) { icount++; if (identity.primary) primary = identity; @@ -1646,31 +1641,31 @@ public class FragmentCompose extends FragmentBase { first = identity; } } - if (result.draft.identity != null) + if (draft.identity != null) break; iindex++; - } while (iindex < (result.draft.from == null ? -1 : result.draft.from.length)); + } while (iindex < (draft.from == null ? -1 : draft.from.length)); // Select identity - if (result.draft.identity == null) { + if (draft.identity == null) { if (primary != null) { - result.draft.identity = primary.id; - result.draft.from = new InternetAddress[]{new InternetAddress(primary.email, primary.name)}; + draft.identity = primary.id; + draft.from = new InternetAddress[]{new InternetAddress(primary.email, primary.name)}; } else if (first != null && icount == 1) { - result.draft.identity = first.id; - result.draft.from = new InternetAddress[]{new InternetAddress(first.email, first.name)}; + draft.identity = first.id; + draft.from = new InternetAddress[]{new InternetAddress(first.email, first.name)}; } } - result.draft.sender = MessageHelper.getSortKey(result.draft.from); + draft.sender = MessageHelper.getSortKey(draft.from); - result.draft.received = new Date().getTime(); + draft.received = new Date().getTime(); - result.draft.id = db.message().insertMessage(result.draft); - Helper.writeText(EntityMessage.getFile(context, result.draft.id), body); + draft.id = db.message().insertMessage(draft); + Helper.writeText(EntityMessage.getFile(context, draft.id), body); - db.message().setMessageContent(result.draft.id, true, HtmlHelper.getPreview(body)); + db.message().setMessageContent(draft.id, true, HtmlHelper.getPreview(body)); // Write reference text if (ref != null && ref.content) { @@ -1678,14 +1673,14 @@ public class FragmentCompose extends FragmentBase { Html.escapeHtml(new Date(ref.received).toString()), Html.escapeHtml(MessageHelper.formatAddresses(ref.from)), Helper.readText(EntityMessage.getFile(context, ref.id))); - Helper.writeText(EntityMessage.getRefFile(context, result.draft.id), refBody); + Helper.writeText(EntityMessage.getRefFile(context, draft.id), refBody); } if ("new".equals(action)) { ArrayList uris = args.getParcelableArrayList("attachments"); if (uris != null) for (Uri uri : uris) - addAttachment(context, result.draft.id, uri, false); + addAttachment(context, draft.id, uri, false); } else { int sequence = 0; List attachments = db.attachment().getAttachments(ref.id); @@ -1694,7 +1689,7 @@ public class FragmentCompose extends FragmentBase { ("forward".equals(action) || attachment.isInline())) { long orig = attachment.id; attachment.id = null; - attachment.message = result.draft.id; + attachment.message = draft.id; attachment.sequence = ++sequence; attachment.id = db.attachment().insertAttachment(attachment); @@ -1704,21 +1699,18 @@ public class FragmentCompose extends FragmentBase { } } - EntityOperation.queue(context, db, result.draft, EntityOperation.ADD); + EntityOperation.queue(context, db, draft, EntityOperation.ADD); } else { - // Existing draft - result.account = db.account().getAccount(result.draft.account); - - if (!result.draft.content) { - if (result.draft.uid == null) + if (!draft.content) { + if (draft.uid == null) throw new IllegalStateException("Draft without uid"); - EntityOperation.queue(context, db, result.draft, EntityOperation.BODY); + EntityOperation.queue(context, db, draft, EntityOperation.BODY); } - List attachments = db.attachment().getAttachments(result.draft.id); + List attachments = db.attachment().getAttachments(draft.id); for (EntityAttachment attachment : attachments) if (!attachment.available) - EntityOperation.queue(context, db, result.draft, EntityOperation.ATTACHMENT, attachment.sequence); + EntityOperation.queue(context, db, draft, EntityOperation.ATTACHMENT, attachment.sequence); } db.setTransactionSuccessful(); @@ -1726,21 +1718,21 @@ public class FragmentCompose extends FragmentBase { db.endTransaction(); } - return result; + return draft; } @Override - protected void onExecuted(Bundle args, final DraftAccount result) { - working = result.draft.id; + protected void onExecuted(Bundle args, final EntityMessage draft) { + working = draft.id; final String action = getArguments().getString("action"); - Log.i("Loaded draft id=" + result.draft.id + " action=" + action); + Log.i("Loaded draft id=" + draft.id + " action=" + action); - etExtra.setText(result.draft.extra); - etTo.setText(MessageHelper.formatAddressesCompose(result.draft.to)); - etCc.setText(MessageHelper.formatAddressesCompose(result.draft.cc)); - etBcc.setText(MessageHelper.formatAddressesCompose(result.draft.bcc)); - etSubject.setText(result.draft.subject); + etExtra.setText(draft.extra); + etTo.setText(MessageHelper.formatAddressesCompose(draft.to)); + etCc.setText(MessageHelper.formatAddressesCompose(draft.cc)); + etBcc.setText(MessageHelper.formatAddressesCompose(draft.bcc)); + etSubject.setText(draft.subject); long reference = args.getLong("reference", -1); etTo.setTag(reference < 0 ? "" : etTo.getText().toString()); @@ -1758,7 +1750,7 @@ public class FragmentCompose extends FragmentBase { @Override protected List onExecute(Context context, Bundle args) { DB db = DB.getInstance(context); - List identities = db.identity().getComposableIdentities(); + List identities = db.identity().getComposableIdentities(null); if (identities == null) identities = new ArrayList<>(); @@ -1789,9 +1781,9 @@ public class FragmentCompose extends FragmentBase { spIdentity.setAdapter(adapter); // Select identity - if (result.draft.identity != null) + if (draft.identity != null) for (int pos = 0; pos < identities.size(); pos++) { - if (identities.get(pos).id.equals(result.draft.identity)) { + if (identities.get(pos).id.equals(draft.identity)) { spIdentity.setSelection(pos); break; } @@ -1806,7 +1798,7 @@ public class FragmentCompose extends FragmentBase { DB db = DB.getInstance(getContext()); - db.attachment().liveAttachments(result.draft.id).observe(getViewLifecycleOwner(), + db.attachment().liveAttachments(draft.id).observe(getViewLifecycleOwner(), new Observer>() { private int last_available = 0; @@ -1838,11 +1830,11 @@ public class FragmentCompose extends FragmentBase { rvAttachment.setTag(downloading); checkInternet(); - checkDraft(result.draft.id); + checkDraft(draft.id); } }); - db.message().liveMessage(result.draft.id).observe(getViewLifecycleOwner(), new Observer() { + db.message().liveMessage(draft.id).observe(getViewLifecycleOwner(), new Observer() { @Override public void onChanged(EntityMessage draft) { // Draft was deleted @@ -2451,11 +2443,6 @@ public class FragmentCompose extends FragmentBase { } }; - private class DraftAccount { - EntityMessage draft; - EntityAccount account; - } - public class IdentityAdapter extends ArrayAdapter { private Context context; private List identities; diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index f106ac946e..e495013a24 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -329,11 +329,9 @@ public class FragmentMessages extends FragmentBase { fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - EntityFolder drafts = (EntityFolder) fab.getTag(); - startActivity(new Intent(getContext(), ActivityCompose.class) .putExtra("action", "new") - .putExtra("account", drafts.account) + .putExtra("account", account) ); } }); @@ -341,13 +339,35 @@ public class FragmentMessages extends FragmentBase { fab.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { - EntityFolder drafts = (EntityFolder) fab.getTag(); + Bundle args = new Bundle(); + args.putLong("account", account); - LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext()); - lbm.sendBroadcast( - new Intent(ActivityView.ACTION_VIEW_MESSAGES) - .putExtra("account", drafts.account) - .putExtra("folder", drafts.id)); + new SimpleTask() { + @Override + protected EntityFolder onExecute(Context context, Bundle args) { + long account = args.getLong("account"); + + DB db = DB.getInstance(context); + if (account < 0) + return db.folder().getPrimaryDrafts(); + else + return db.folder().getFolderByType(account, EntityFolder.DRAFTS); + } + + @Override + protected void onExecuted(Bundle args, EntityFolder drafts) { + LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext()); + lbm.sendBroadcast( + new Intent(ActivityView.ACTION_VIEW_MESSAGES) + .putExtra("account", drafts.account) + .putExtra("folder", drafts.id)); + } + + @Override + protected void onException(Bundle args, Throwable ex) { + Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex); + } + }.execute(FragmentMessages.this, args, "messages:drafts"); return true; } @@ -1556,17 +1576,16 @@ public class FragmentMessages extends FragmentBase { fabMore.hide(); if (viewType != AdapterMessage.ViewType.THREAD) { - db.folder().liveDrafts(account < 0 ? null : account).observe(getViewLifecycleOwner(), new Observer() { - @Override - public void onChanged(EntityFolder drafts) { - if (drafts == null) - fab.hide(); - else { - fab.setTag(drafts); - fab.show(); - } - } - }); + db.identity().liveComposableIdentities(account < 0 ? null : account).observe(getViewLifecycleOwner(), + new Observer>() { + @Override + public void onChanged(List identities) { + if (identities == null || identities.size() == 0) + fab.hide(); + else + fab.show(); + } + }); } }