diff --git a/src/client/application/application-controller.vala b/src/client/application/application-controller.vala index e6c5dfe4..1339a034 100644 --- a/src/client/application/application-controller.vala +++ b/src/client/application/application-controller.vala @@ -2002,6 +2002,8 @@ private class Application.MarkEmailCommand : TrivialCommand, EmailCommand { public override async void execute(GLib.Cancellable? cancellable) throws GLib.Error { + this.location.account.cancel_remote_update(); + yield this.store.mark_email_async( this.email, this.to_add, this.to_remove, cancellable ); diff --git a/src/engine/api/geary-account.vala b/src/engine/api/geary-account.vala index 787fcbad..4811f105 100644 --- a/src/engine/api/geary-account.vala +++ b/src/engine/api/geary-account.vala @@ -309,6 +309,11 @@ public abstract class Geary.Account : BaseObject, Logging.Source { */ public abstract bool is_open(); + /** + * Cancel any running/pending remote update for this {@link Account}. + */ + public abstract void cancel_remote_update(); + /** * Rebuild the local data stores for this {@link Account}. * diff --git a/src/engine/imap-engine/imap-engine-account-processor.vala b/src/engine/imap-engine/imap-engine-account-processor.vala index 0e5cc2f0..1fc08f9d 100644 --- a/src/engine/imap-engine/imap-engine-account-processor.vala +++ b/src/engine/imap-engine/imap-engine-account-processor.vala @@ -78,6 +78,26 @@ internal class Geary.ImapEngine.AccountProcessor : this.queue.revoke(op); } + // Revokes all operations with the given type; returns true if at least one + // operation with the given type was found + public bool dequeue_by_type(GLib.Type type) { + bool found = false; + if (this.current_op != null && + this.current_op.get_type() == type && + this.op_cancellable != null) { + this.op_cancellable.cancel(); + this.op_cancellable = null; + found = true; + } + this.queue.revoke_matching((op) => { + if (op.get_type() == type) { + found = true; + } + return op.get_type() == type; + }); + return found; + } + public void stop() { this.is_running = false; if (this.op_cancellable != null) { diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala b/src/engine/imap-engine/imap-engine-generic-account.vala index a459274b..2db97164 100644 --- a/src/engine/imap-engine/imap-engine-generic-account.vala +++ b/src/engine/imap-engine/imap-engine-generic-account.vala @@ -229,6 +229,15 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account { return open; } + /** {@inheritDoc} */ + public override void cancel_remote_update() { + // Cancel and update again + if (this.processor.dequeue_by_type(typeof(UpdateRemoteFolders))) { + debug("Cancelled a remote update! Updating again...\n"); + update_remote_folders(false); + } + } + public override async void rebuild_async(GLib.Cancellable? cancellable = null) throws GLib.Error { if (this.open) { diff --git a/test/mock/mock-account.vala b/test/mock/mock-account.vala index f617f969..ceee35ef 100644 --- a/test/mock/mock-account.vala +++ b/test/mock/mock-account.vala @@ -58,6 +58,13 @@ public class Mock.Account : Geary.Account, } } + public override void cancel_remote_update() { + try { + void_call("cancel_remote_update", {}); + } catch (GLib.Error err) { + } + } + public override async void rebuild_async(GLib.Cancellable? cancellable = null) throws GLib.Error { void_call("rebuild_async", { cancellable });