From 1b5156dfc53299fa1d461c681f0537701bab79b1 Mon Sep 17 00:00:00 2001 From: M66B Date: Fri, 4 Jan 2019 18:37:56 +0000 Subject: [PATCH] Store copy of message in target folder --- .../eu/faircode/email/AdapterAttachment.java | 2 +- .../java/eu/faircode/email/AdapterFolder.java | 2 +- .../eu/faircode/email/AdapterMessage.java | 28 ++++---- .../java/eu/faircode/email/DaoMessage.java | 12 ++-- .../java/eu/faircode/email/EntityMessage.java | 3 +- .../eu/faircode/email/EntityOperation.java | 64 ++++++++++++++++--- .../eu/faircode/email/FragmentCompose.java | 18 +++--- .../eu/faircode/email/FragmentMessages.java | 19 +++--- .../eu/faircode/email/FragmentOptions.java | 2 +- .../main/java/eu/faircode/email/Helper.java | 2 +- .../eu/faircode/email/ServiceSynchronize.java | 11 ++-- 11 files changed, 108 insertions(+), 55 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/AdapterAttachment.java b/app/src/main/java/eu/faircode/email/AdapterAttachment.java index 3443332f36..dba6d9d082 100644 --- a/app/src/main/java/eu/faircode/email/AdapterAttachment.java +++ b/app/src/main/java/eu/faircode/email/AdapterAttachment.java @@ -251,7 +251,7 @@ public class AdapterAttachment extends RecyclerView.Adapter messages = db.message().getMessageByThread( message.account, message.thread, threading && thread ? null : id, message.folder); for (EntityMessage threaded : messages) - EntityOperation.queue(db, threaded, EntityOperation.FLAG, flagged); + EntityOperation.queue(context, db, threaded, EntityOperation.FLAG, flagged); db.setTransactionSuccessful(); } finally { @@ -1375,7 +1377,7 @@ public class AdapterMessage extends RecyclerView.Adapter 0); @@ -1633,7 +1637,7 @@ public class AdapterMessage extends RecyclerView.Adapter getMessageByThread(long account, String thread, Long id, Long folder); - @Query("SELECT message.* FROM message" + - " JOIN folder ON folder.id = message.folder" + - " WHERE message.account = :account" + - " AND message.msgid = :msgid") + @Query("SELECT * FROM message" + + " WHERE account = :account" + + " AND msgid = :msgid") List getMessageByMsgId(long account, String msgid); + @Query("SELECT COUNT(*) FROM message" + + " WHERE folder = :folder" + + " AND msgid = :msgid") + int countMessageByMsgId(long folder, String msgid); + @Query("SELECT * FROM message" + " WHERE folder = :folder" + " AND ui_seen" + diff --git a/app/src/main/java/eu/faircode/email/EntityMessage.java b/app/src/main/java/eu/faircode/email/EntityMessage.java index e7f3fd9609..3b45511350 100644 --- a/app/src/main/java/eu/faircode/email/EntityMessage.java +++ b/app/src/main/java/eu/faircode/email/EntityMessage.java @@ -285,7 +285,7 @@ public class EntityMessage implements Serializable { //(this.identity == null ? other.identity == null : this.identity.equals(other.identity)) && //(this.replying == null ? other.replying == null : this.replying.equals(other.replying)) && //(this.forwarding == null ? other.forwarding == null : this.forwarding.equals(other.forwarding)) && - //(this.uid == null ? other.uid == null : this.uid.equals(other.uid)) && + (this.uid == null ? other.uid == null : this.uid.equals(other.uid)) && (this.msgid == null ? other.msgid == null : this.msgid.equals(other.msgid)) && // debug info //(this.references == null ? other.references == null : this.references.equals(other.references)) && //(this.deliveredto == null ? other.deliveredto == null : this.deliveredto.equals(other.deliveredto)) && @@ -305,7 +305,6 @@ public class EntityMessage implements Serializable { //(this.sent == null ? other.sent == null : this.sent.equals(other.sent)) && this.received.equals(other.received) && this.stored.equals(other.stored) && // updated after decryption - //this.stored.equals(other.stored) && //this.seen.equals(other.seen) && //this.answered.equals(other.answered) && //this.flagged.equals(other.flagged) && diff --git a/app/src/main/java/eu/faircode/email/EntityOperation.java b/app/src/main/java/eu/faircode/email/EntityOperation.java index ce89d22fb5..1b8327389e 100644 --- a/app/src/main/java/eu/faircode/email/EntityOperation.java +++ b/app/src/main/java/eu/faircode/email/EntityOperation.java @@ -19,10 +19,14 @@ package eu.faircode.email; Copyright 2018-2019 by Marcel Bokhorst (M66B) */ +import android.content.Context; + import org.json.JSONArray; import org.json.JSONException; +import java.io.IOException; import java.util.Date; +import java.util.List; import androidx.annotation.NonNull; import androidx.room.Entity; @@ -72,22 +76,22 @@ public class EntityOperation { static final String ATTACHMENT = "attachment"; static final String SYNC = "sync"; - static void queue(DB db, EntityMessage message, String name) { + static void queue(Context context, DB db, EntityMessage message, String name) { JSONArray jargs = new JSONArray(); - queue(db, message, name, jargs); + queue(context, db, message, name, jargs); } - static void queue(DB db, EntityMessage message, String name, Object value) { + static void queue(Context context, DB db, EntityMessage message, String name, Object value) { JSONArray jargs = new JSONArray(); jargs.put(value); - queue(db, message, name, jargs); + queue(context, db, message, name, jargs); } - static void queue(DB db, EntityMessage message, String name, Object value1, Object value2) { + static void queue(Context context, DB db, EntityMessage message, String name, Object value1, Object value2) { JSONArray jargs = new JSONArray(); jargs.put(value1); jargs.put(value2); - queue(db, message, name, jargs); + queue(context, db, message, name, jargs); } static void sync(DB db, long fid) { @@ -121,7 +125,7 @@ public class EntityOperation { } } - private static void queue(DB db, EntityMessage message, String name, JSONArray jargs) { + private static void queue(Context context, DB db, EntityMessage message, String name, JSONArray jargs) { try { if (SEEN.equals(name)) { for (EntityMessage similar : db.message().getMessageByMsgId(message.account, message.msgid)) { @@ -139,9 +143,53 @@ public class EntityOperation { else if (MOVE.equals(name)) { EntityFolder source = db.folder().getFolder(message.folder); - if (!EntityFolder.ARCHIVE.equals(source.type)) + EntityFolder target = db.folder().getFolder(jargs.getLong(0)); + + if (!EntityFolder.ARCHIVE.equals(source.type) || EntityFolder.TRASH.equals(target.type)) db.message().setMessageUiHide(message.id, true); + // Create copy without uid in target folder + // Message with same msgid can be in archive and source folder + if (db.message().countMessageByMsgId(target.id, message.msgid) == 0) { + long id = message.id; + long uid = message.uid; + message.id = null; + message.uid = null; + message.folder = target.id; + long newid = db.message().insertMessage(message); + message.id = id; + message.uid = uid; + message.folder = source.id; + if (message.content) + try { + Helper.copy( + EntityMessage.getFile(context, id), + EntityMessage.getFile(context, newid)); + } catch (IOException ex) { + Log.e(ex); + db.message().setMessageContent(newid, false, null); + } + + List attachments = db.attachment().getAttachments(message.id); + for (EntityAttachment attachment : attachments) { + long aid = attachment.id; + attachment.id = null; + attachment.message = newid; + attachment.progress = null; + attachment.id = db.attachment().insertAttachment(attachment); + if (attachment.available) + try { + Helper.copy( + EntityAttachment.getFile(context, aid), + EntityAttachment.getFile(context, attachment.id)); + } catch (IOException ex) { + Log.e(ex); + attachment.available = false; + db.attachment().updateAttachment(attachment); + } + } + } + } else if (DELETE.equals(name)) db.message().setMessageUiHide(message.id, true); } catch (JSONException ex) { diff --git a/app/src/main/java/eu/faircode/email/FragmentCompose.java b/app/src/main/java/eu/faircode/email/FragmentCompose.java index 1be5a77a52..7f076a2b1e 100644 --- a/app/src/main/java/eu/faircode/email/FragmentCompose.java +++ b/app/src/main/java/eu/faircode/email/FragmentCompose.java @@ -1470,14 +1470,14 @@ public class FragmentCompose extends FragmentEx { } } - EntityOperation.queue(db, result.draft, EntityOperation.ADD); + EntityOperation.queue(context, db, result.draft, EntityOperation.ADD); } else { // Existing draft result.account = db.account().getAccount(result.draft.account); if (!result.draft.content) { if (result.draft.uid == null) throw new IllegalStateException("Draft without uid"); - EntityOperation.queue(db, result.draft, EntityOperation.BODY); + EntityOperation.queue(context, db, result.draft, EntityOperation.BODY); } } @@ -1723,14 +1723,14 @@ public class FragmentCompose extends FragmentEx { draft.content = false; draft.ui_hide = true; draft.id = db.message().insertMessage(draft); - EntityOperation.queue(db, draft, EntityOperation.DELETE); + EntityOperation.queue(context, db, draft, EntityOperation.DELETE); draft.id = id; draft.account = aid; draft.folder = db.folder().getFolderByType(aid, EntityFolder.DRAFTS).id; draft.content = true; draft.ui_hide = false; - EntityOperation.queue(db, draft, EntityOperation.ADD); + EntityOperation.queue(context, db, draft, EntityOperation.ADD); } // Convert data @@ -1798,7 +1798,7 @@ public class FragmentCompose extends FragmentEx { // Execute action if (action == R.id.action_delete) { - EntityOperation.queue(db, draft, EntityOperation.DELETE); + EntityOperation.queue(context, db, draft, EntityOperation.DELETE); if (!empty) { Handler handler = new Handler(context.getMainLooper()); @@ -1810,7 +1810,7 @@ public class FragmentCompose extends FragmentEx { } } else if (action == R.id.action_save || action == R.id.menu_encrypt) { if (dirty) { - EntityOperation.queue(db, draft, EntityOperation.ADD); + EntityOperation.queue(context, db, draft, EntityOperation.ADD); Handler handler = new Handler(context.getMainLooper()); handler.post(new Runnable() { @@ -1835,7 +1835,7 @@ public class FragmentCompose extends FragmentEx { throw new IllegalArgumentException(context.getString(R.string.title_attachments_missing)); // Delete draft (cannot move to outbox) - EntityOperation.queue(db, draft, EntityOperation.DELETE); + EntityOperation.queue(context, db, draft, EntityOperation.DELETE); // Copy message to outbox draft.id = null; @@ -1854,11 +1854,11 @@ public class FragmentCompose extends FragmentEx { Helper.copy(file, EntityAttachment.getFile(context, attachment.id)); } - EntityOperation.queue(db, draft, EntityOperation.SEND); + EntityOperation.queue(context, db, draft, EntityOperation.SEND); if (draft.replying != null) { EntityMessage replying = db.message().getMessage(draft.replying); - EntityOperation.queue(db, replying, EntityOperation.ANSWERED, true); + EntityOperation.queue(context, db, replying, EntityOperation.ANSWERED, true); } Handler handler = new Handler(context.getMainLooper()); diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index 48bd386b93..ae8abd2657 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -900,7 +900,7 @@ public class FragmentMessages extends FragmentEx { List messages = db.message().getMessageByThread( message.account, message.thread, threading ? null : id, message.folder); for (EntityMessage threaded : messages) - EntityOperation.queue(db, threaded, EntityOperation.SEEN, seen); + EntityOperation.queue(context, db, threaded, EntityOperation.SEEN, seen); } } @@ -942,7 +942,7 @@ public class FragmentMessages extends FragmentEx { List messages = db.message().getMessageByThread( message.account, message.thread, threading ? null : id, message.folder); for (EntityMessage threaded : messages) - EntityOperation.queue(db, threaded, EntityOperation.FLAG, flagged); + EntityOperation.queue(context, db, threaded, EntityOperation.FLAG, flagged); } } @@ -1003,7 +1003,7 @@ public class FragmentMessages extends FragmentEx { if (threaded.uid == null && !TextUtils.isEmpty(threaded.error)) // outbox db.message().deleteMessage(threaded.id); else - EntityOperation.queue(db, threaded, EntityOperation.DELETE); + EntityOperation.queue(context, db, threaded, EntityOperation.DELETE); } } @@ -1612,7 +1612,7 @@ public class FragmentMessages extends FragmentEx { message.uid = null; db.message().updateMessage(message); Log.i("Appending sent msgid=" + message.msgid); - EntityOperation.queue(db, message, EntityOperation.ADD); // Could already exist + EntityOperation.queue(context, db, message, EntityOperation.ADD); // Could already exist } } @@ -1920,10 +1920,10 @@ public class FragmentMessages extends FragmentEx { EntityFolder folder = db.folder().getFolder(message.folder); if (!message.content) - EntityOperation.queue(db, message, EntityOperation.BODY); + EntityOperation.queue(context, db, message, EntityOperation.BODY); if (!message.ui_seen && !EntityFolder.OUTBOX.equals(folder.type)) - EntityOperation.queue(db, message, EntityOperation.SEEN, true); + EntityOperation.queue(context, db, message, EntityOperation.SEEN, true); db.setTransactionSuccessful(); } finally { @@ -1992,7 +1992,7 @@ public class FragmentMessages extends FragmentEx { if (message != null) { Log.i("Move id=" + id + " target=" + result.target.name); EntityFolder folder = db.folder().getFolderByName(message.account, result.target.name); - EntityOperation.queue(db, message, EntityOperation.MOVE, folder.id); + EntityOperation.queue(context, db, message, EntityOperation.MOVE, folder.id); } } @@ -2059,11 +2059,12 @@ public class FragmentMessages extends FragmentEx { if (snackbar.isShown()) snackbar.dismiss(); - final DB db = DB.getInstance(getContext()); + final Context context = getContext().getApplicationContext(); new Thread(new Runnable() { @Override public void run() { + DB db = DB.getInstance(context); try { db.beginTransaction(); @@ -2072,7 +2073,7 @@ public class FragmentMessages extends FragmentEx { if (message != null && message.ui_hide) { Log.i("Move id=" + id + " target=" + result.target.name); EntityFolder folder = db.folder().getFolderByName(message.account, result.target.name); - EntityOperation.queue(db, message, EntityOperation.MOVE, folder.id); + EntityOperation.queue(context, db, message, EntityOperation.MOVE, folder.id); } } diff --git a/app/src/main/java/eu/faircode/email/FragmentOptions.java b/app/src/main/java/eu/faircode/email/FragmentOptions.java index 8e38f79139..6c30bc7da6 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptions.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptions.java @@ -239,7 +239,7 @@ public class FragmentOptions extends FragmentEx implements SharedPreferences.OnS Log.e(ex); db.message().setMessageContent(message.id, false, null); if (!metered) - EntityOperation.queue(db, message, EntityOperation.BODY); + EntityOperation.queue(context, db, message, EntityOperation.BODY); } } diff --git a/app/src/main/java/eu/faircode/email/Helper.java b/app/src/main/java/eu/faircode/email/Helper.java index af814fefeb..3325611763 100644 --- a/app/src/main/java/eu/faircode/email/Helper.java +++ b/app/src/main/java/eu/faircode/email/Helper.java @@ -318,7 +318,7 @@ public class Helper { attachOperations(context, draft.id, 4); attachLogcat(context, draft.id, 5); - EntityOperation.queue(db, draft, EntityOperation.ADD); + EntityOperation.queue(context, db, draft, EntityOperation.ADD); db.setTransactionSuccessful(); } finally { diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java index 5f545f1ff8..1c019e4ff4 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java +++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java @@ -365,7 +365,7 @@ public class ServiceSynchronize extends LifecycleService { switch (parts[0]) { case "seen": - EntityOperation.queue(db, message, EntityOperation.SEEN, true); + EntityOperation.queue(ServiceSynchronize.this, db, message, EntityOperation.SEEN, true); break; case "archive": @@ -373,13 +373,13 @@ public class ServiceSynchronize extends LifecycleService { if (archive == null) archive = db.folder().getFolderByType(message.account, EntityFolder.TRASH); if (archive != null) - EntityOperation.queue(db, message, EntityOperation.MOVE, archive.id); + EntityOperation.queue(ServiceSynchronize.this, db, message, EntityOperation.MOVE, archive.id); break; case "trash": EntityFolder trash = db.folder().getFolderByType(message.account, EntityFolder.TRASH); if (trash != null) - EntityOperation.queue(db, message, EntityOperation.MOVE, trash.id); + EntityOperation.queue(ServiceSynchronize.this, db, message, EntityOperation.MOVE, trash.id); break; case "ignore": @@ -1699,9 +1699,6 @@ public class ServiceSynchronize extends LifecycleService { Folder itarget = istore.getFolder(target.name); itarget.appendMessages(new Message[]{icopy}); } - - if (EntityFolder.ARCHIVE.equals(folder.type)) - db.message().setMessageUiHide(message.id, false); } private void doDelete(EntityFolder folder, IMAPFolder ifolder, EntityMessage message, JSONArray jargs, DB db) throws MessagingException, JSONException { @@ -1816,7 +1813,7 @@ public class ServiceSynchronize extends LifecycleService { message.uid = null; db.message().updateMessage(message); Log.i("Appending sent msgid=" + message.msgid); - EntityOperation.queue(db, message, EntityOperation.ADD); // Could already exist + EntityOperation.queue(ServiceSynchronize.this, db, message, EntityOperation.ADD); // Could already exist } }