diff --git a/app/src/main/java/eu/faircode/email/Core.java b/app/src/main/java/eu/faircode/email/Core.java index e281197d9c..31d331fc4b 100644 --- a/app/src/main/java/eu/faircode/email/Core.java +++ b/app/src/main/java/eu/faircode/email/Core.java @@ -1289,22 +1289,20 @@ class Core { } } - // Delete not synchronized messages without uid - db.message().deleteOrphans(folder.id); - // Add local sent messages to remote sent folder if (EntityFolder.SENT.equals(folder.type)) { - List orphans = db.message().getSentOrphans(folder.account); - Log.i(folder.name + " sent orphans=" + orphans.size() + " account=" + folder.account); + List orphans = db.message().getOrphans(folder.id); + Log.i(folder.name + " sent orphans=" + orphans.size()); for (EntityMessage orphan : orphans) { - Log.i(folder.name + " adding orphan id=" + orphan.id + " sent=" + new Date(orphan.sent)); - orphan.folder = folder.id; - orphan.ui_hide = 0L; - db.message().updateMessage(orphan); - EntityOperation.queue(context, orphan, EntityOperation.ADD); + Log.i(folder.name + " adding orphan id=" + orphan.id); + if (orphan.content) + EntityOperation.queue(context, orphan, EntityOperation.ADD); } } + // Delete not synchronized messages without uid + db.message().deleteOrphans(folder.id); + int count = ifolder.getMessageCount(); db.folder().setFolderTotal(folder.id, count < 0 ? null : count); @@ -1418,8 +1416,7 @@ class Core { " folder=" + dfolder.type + ":" + dup.folder + "/" + folder.type + ":" + folder.id + " msgid=" + dup.msgid + " thread=" + dup.thread); - if (dup.folder.equals(folder.id) || - (EntityFolder.OUTBOX.equals(dfolder.type) && EntityFolder.SENT.equals(folder.type))) { + if (dup.folder.equals(folder.id)) { String thread = helper.getThreadId(context, account.id, uid); Log.i(folder.name + " found as id=" + dup.id + " uid=" + dup.uid + "/" + uid + @@ -1427,15 +1424,13 @@ class Core { if (dup.uid == null) { Log.i(folder.name + " set uid=" + uid); - dup.folder = folder.id; // outbox to sent dup.uid = uid; - dup.msgid = msgid; dup.thread = thread; if (dup.size == null) dup.size = helper.getSize(); - if (EntityFolder.OUTBOX.equals(dfolder.type)) { + if (EntityFolder.SENT.equals(folder.type)) { dup.received = helper.getReceived(); dup.sent = helper.getSent(); } diff --git a/app/src/main/java/eu/faircode/email/DaoMessage.java b/app/src/main/java/eu/faircode/email/DaoMessage.java index 4ec4043df2..91b0164e8a 100644 --- a/app/src/main/java/eu/faircode/email/DaoMessage.java +++ b/app/src/main/java/eu/faircode/email/DaoMessage.java @@ -312,12 +312,14 @@ public interface DaoMessage { " AND NOT uid IS NULL") List getUids(long folder, Long received); - @Query("SELECT message.* FROM message" + - " JOIN folder on folder.id = message.folder" + - " WHERE message.account = :account" + - " AND folder.type = '" + EntityFolder.OUTBOX + "'" + - " AND sent IS NOT NULL") - List getSentOrphans(long account); + @Query("SELECT * FROM message" + + " WHERE folder = :folder" + + " AND uid IS NULL" + + " AND NOT EXISTS" + + " (SELECT * FROM operation" + + " WHERE operation.message = message.id" + + " AND operation.name = '" + EntityOperation.ADD + "')") + List getOrphans(long folder); @Query("SELECT * FROM message WHERE NOT ui_snoozed IS NULL") List getSnoozed(); @@ -343,15 +345,6 @@ public interface DaoMessage { @Update int updateMessage(EntityMessage message); - @Query("UPDATE message SET folder = :folder WHERE id = :id") - int setMessageFolder(long id, long folder); - - @Query("UPDATE message SET identity = :identity WHERE id = :id") - int setMessageIdentity(long id, Long identity); - - @Query("UPDATE message SET `from` = :from WHERE id = :id") - int setMessageFrom(long id, String from); - @Query("UPDATE message SET uid = :uid WHERE id = :id") int setMessageUid(long id, Long uid); @@ -397,12 +390,6 @@ public interface DaoMessage { @Query("UPDATE message SET received = :sent, sent = :sent WHERE id = :id") int setMessageSent(long id, Long sent); - @Query("UPDATE message SET receipt_request = :receipt_request WHERE id = :id") - int setMessageReceiptRequested(long id, Boolean receipt_request); - - @Query("UPDATE message SET avatar = :avatar WHERE id = :id") - int setMessageAvatar(long id, String avatar); - @Query("UPDATE message SET error = :error WHERE id = :id") int setMessageError(long id, String error); diff --git a/app/src/main/java/eu/faircode/email/ServiceSend.java b/app/src/main/java/eu/faircode/email/ServiceSend.java index f142d1919a..5bbc589ca3 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSend.java +++ b/app/src/main/java/eu/faircode/email/ServiceSend.java @@ -351,6 +351,43 @@ public class ServiceSend extends ServiceBase { imessage.addHeader("Disposition-Notification-To", ident.replyto == null ? ident.email : ident.replyto); } + // Prepare sent message + Long sid = null; + EntityFolder sent = db.folder().getFolderByType(message.account, EntityFolder.SENT); + if (sent != null) { + Log.i(sent.name + " Preparing sent message"); + + long id = message.id; + + MessageHelper helper = new MessageHelper(imessage); + + message.id = null; + message.folder = sent.id; + message.identity = null; + message.receipt_request = helper.getReceiptRequested(); + message.from = helper.getFrom(); + message.bcc = helper.getBcc(); + message.reply = helper.getReply(); + message.received = new Date().getTime(); + message.seen = true; + message.ui_seen = true; + message.ui_hide = Long.MAX_VALUE; + message.error = null; + message.id = db.message().insertMessage(message); + + MessageHelper.MessageParts parts = helper.getMessageParts(); + String body = parts.getHtml(this); + Helper.writeText(message.getFile(this), body); + db.message().setMessageContent(message.id, + true, + parts.isPlainOnly(), + HtmlHelper.getPreview(body), + parts.getWarnings(message.warning)); + + sid = message.id; + message.id = id; + } + // Create transport try (MailService iservice = new MailService( this, ident.getProtocol(), ident.realm, ident.insecure, debug)) { @@ -372,27 +409,11 @@ public class ServiceSend extends ServiceBase { try { db.beginTransaction(); - db.message().setMessageIdentity(message.id, null); - db.message().setMessageFrom(message.id, DB.Converters.encodeAddresses(imessage.getFrom())); // extra - db.message().setMessageSent(message.id, time); - db.message().setMessageReceiptRequested(message.id, ident.delivery_receipt || ident.read_receipt); - db.message().setMessageSeen(message.id, true); - db.message().setMessageUiSeen(message.id, true); - db.message().setMessageError(message.id, null); - if (!BuildConfig.DEBUG && !debug) - db.message().setMessageUiHide(message.id, new Date().getTime()); + db.message().deleteMessage(message.id); - EntityFolder sent = db.folder().getFolderByType(message.account, EntityFolder.SENT); - if (sent != null) { - // Give server time to store message into the sent folder - try { - Thread.sleep(AFTER_SEND_DELAY); - } catch (InterruptedException ex) { - Log.w(ex); - } - - // Check for sent orphans - EntityOperation.sync(this, sent.id, false); + if (sid != null) { + db.message().setMessageSent(sid, time); + db.message().setMessageUiHide(sid, 0L); } if (message.inreplyto != null) { @@ -406,25 +427,29 @@ public class ServiceSend extends ServiceBase { db.endTransaction(); } - // Update message with signature / referenced text for sent orphans - MessageHelper helper = new MessageHelper(imessage); - MessageHelper.MessageParts parts = helper.getMessageParts(); - String body = parts.getHtml(this); - Helper.writeText(message.getFile(this), body); - db.message().setMessageContent(message.id, - true, - parts.isPlainOnly(), - HtmlHelper.getPreview(body), - parts.getWarnings(message.warning)); - + // Reset identity db.identity().setIdentityConnected(ident.id, new Date().getTime()); db.identity().setIdentityError(ident.id, null); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); nm.cancel("send:" + message.identity, 1); + + // Check for sent orphans + if (sent != null) { + // Give server time to store message into the sent folder + try { + Thread.sleep(AFTER_SEND_DELAY); + } catch (InterruptedException ex) { + Log.w(ex); + } + EntityOperation.sync(this, sent.id, false); + } } catch (MessagingException ex) { Log.e(ex); + if (sid != null) + db.message().deleteMessage(sid); + db.identity().setIdentityError(ident.id, Helper.formatThrowable(ex)); if (ex instanceof AuthenticationFailedException ||