diff --git a/FAQ.md b/FAQ.md index 6877e6f7c4..43df03e7ea 100644 --- a/FAQ.md +++ b/FAQ.md @@ -200,6 +200,7 @@ The low priority status bar notification shows the number of pending operations, * *body*: download message text * *attachment*: download attachment * *sync*: synchronize local and remote messages +* *wait*: wait for message synchronization Operations are processed only when there is a connection to the email server or when manually synchronizing. See also [this FAQ](#user-content-faq16). diff --git a/app/src/main/java/eu/faircode/email/Core.java b/app/src/main/java/eu/faircode/email/Core.java index 624abee01b..fdd11d4119 100644 --- a/app/src/main/java/eu/faircode/email/Core.java +++ b/app/src/main/java/eu/faircode/email/Core.java @@ -142,7 +142,8 @@ class Core { !(EntityOperation.ADD.equals(op.name) || EntityOperation.DELETE.equals(op.name) || EntityOperation.SEND.equals(op.name) || - EntityOperation.SYNC.equals(op.name))) + EntityOperation.SYNC.equals(op.name) || + EntityOperation.WAIT.equals(op.name))) throw new IllegalArgumentException(op.name + " without uid " + op.args); // Operations should use database transaction when needed @@ -200,6 +201,9 @@ class Core { onSynchronizeMessages(context, jargs, account, folder, (IMAPFolder) ifolder, state); break; + case EntityOperation.WAIT: + return; + default: throw new IllegalArgumentException("Unknown operation=" + op.name); } @@ -1286,6 +1290,10 @@ class Core { db.message().updateMessage(message); else if (BuildConfig.DEBUG) Log.i(folder.name + " unchanged uid=" + uid); + + int wait = db.operation().deleteOperationWait(message.id); + if (wait > 0) + Log.i(folder.name + " deleted wait id=" + message.id); } if (!folder.isOutgoing() && !EntityFolder.ARCHIVE.equals(folder.type)) { diff --git a/app/src/main/java/eu/faircode/email/DaoOperation.java b/app/src/main/java/eu/faircode/email/DaoOperation.java index 6d5d081940..e61160ccae 100644 --- a/app/src/main/java/eu/faircode/email/DaoOperation.java +++ b/app/src/main/java/eu/faircode/email/DaoOperation.java @@ -94,6 +94,11 @@ public interface DaoOperation { @Insert long insertOperation(EntityOperation operation); + @Query("DELETE FROM operation" + + " WHERE message = :message" + + " AND name = '" + EntityOperation.WAIT + "'") + int deleteOperationWait(long message); + @Query("DELETE FROM operation WHERE id = :id") void deleteOperation(long id); } diff --git a/app/src/main/java/eu/faircode/email/EntityOperation.java b/app/src/main/java/eu/faircode/email/EntityOperation.java index d260c7c3fe..dd0713e6f4 100644 --- a/app/src/main/java/eu/faircode/email/EntityOperation.java +++ b/app/src/main/java/eu/faircode/email/EntityOperation.java @@ -81,6 +81,7 @@ public class EntityOperation { static final String BODY = "body"; static final String ATTACHMENT = "attachment"; static final String SYNC = "sync"; + static final String WAIT = "wait"; static void queue(Context context, DB db, EntityMessage message, String name, Object... values) { JSONArray jargs = new JSONArray(); @@ -149,6 +150,8 @@ public class EntityOperation { message.ui_seen = true; } newid = db.message().insertMessage(message); + message.id = newid; + queue(context, db, message, WAIT); message.id = id; message.account = source.account; message.folder = source.id; diff --git a/app/src/main/java/eu/faircode/email/ServiceSend.java b/app/src/main/java/eu/faircode/email/ServiceSend.java index a197d20701..aa3d56d819 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSend.java +++ b/app/src/main/java/eu/faircode/email/ServiceSend.java @@ -338,6 +338,12 @@ public class ServiceSend extends LifecycleService { } else db.message().setMessageUiHide(message.id, true); + if (message.inreplyto != null) { + List replieds = db.message().getMessageByMsgId(message.account, message.inreplyto); + for (EntityMessage replied : replieds) + EntityOperation.queue(this, db, replied, EntityOperation.ANSWERED, true); + } + db.setTransactionSuccessful(); } finally { db.endTransaction(); @@ -346,12 +352,6 @@ public class ServiceSend extends LifecycleService { if (refFile.exists()) refFile.delete(); - if (message.inreplyto != null) { - List replieds = db.message().getMessageByMsgId(message.account, message.inreplyto); - for (EntityMessage replied : replieds) - EntityOperation.queue(this, db, replied, EntityOperation.ANSWERED, true); - } - db.identity().setIdentityConnected(ident.id, new Date().getTime()); db.identity().setIdentityError(ident.id, null); diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java index 88db295930..f7a2567bf7 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java +++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java @@ -585,6 +585,7 @@ public class ServiceSynchronize extends LifecycleService { // Observe operations Handler handler = new Handler(getMainLooper()) { + private List waiting = new ArrayList<>(); private List handling = new ArrayList<>(); private LiveData> liveOperations; @@ -612,13 +613,23 @@ public class ServiceSynchronize extends LifecycleService { @Override public void onChanged(final List operations) { boolean process = false; - List current = new ArrayList<>(); + List ops = new ArrayList<>(); + List waits = new ArrayList<>(); for (EntityOperation op : operations) { + if (EntityOperation.WAIT.equals(op.name)) + waits.add(op.id); if (!handling.contains(op.id)) process = true; - current.add(op.id); + ops.add(op.id); } - handling = current; + for (long wait : waits) + if (!waiting.contains(wait)) { + Log.i(folder.name + " not waiting anymore"); + process = true; + break; + } + waiting = waits; + handling = ops; if (handling.size() > 0 && process) { Log.i(folder.name + " operations=" + operations.size());