[geary/wip/778276-better-flag-updates: 13/19] Fire folders_contents_altered when we alter folder contents.
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/778276-better-flag-updates: 13/19] Fire folders_contents_altered when we alter folder contents.
- Date: Tue, 5 Dec 2017 04:02:22 +0000 (UTC)
commit 261dce5131ef51994a39ae4b9858ea92e8a56f20
Author: Michael James Gratton <mike vee net>
Date: Tue Nov 28 10:12:41 2017 +1100
Fire folders_contents_altered when we alter folder contents.
Ensuring f-c-a is fired means that the background sync will pick up the
changes from the operations after they happen, rather than when the next
folder refresh happens.
* src/engine/imap-engine/imap-engine-generic-account.vala
(Account::update_folders): Provide a convenience singleton version of
::update_folders to fire folders_contents_altered.
* src/engine/imap-engine/imap-engine-generic-account.vala
(RefreshFolderUnseen): Update cached status values for a folder and
fire f-c-a signal, but only for folders that have changed.
* src/engine/imap-engine/imap-engine-minimal-folder.vala
(MinimalFolder::copy_email_async): Fire f-c-a signal after the op
completes.
* src/engine/imap-engine/imap-engine-revokable-move.vala (RevokableMove),
src/engine/imap-engine/imap-engine-revokable-committed-move.vala
(RevokableCommittedMove): Notify contents have changed when a move is
revoked.
.../imap-engine/imap-engine-generic-account.vala | 34 +++++++++++--
.../imap-engine/imap-engine-minimal-folder.vala | 23 ++++++---
.../imap-engine-revokable-committed-move.vala | 3 +
.../imap-engine/imap-engine-revokable-move.vala | 52 +++++++++++++------
.../imap-engine-send-replay-operation.vala | 12 +++--
5 files changed, 90 insertions(+), 34 deletions(-)
---
diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala
b/src/engine/imap-engine/imap-engine-generic-account.vala
index ad3e44d..7635ad2 100644
--- a/src/engine/imap-engine/imap-engine-generic-account.vala
+++ b/src/engine/imap-engine/imap-engine-generic-account.vala
@@ -532,7 +532,22 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
}
/**
+ * Fires appropriate signals for a single altered folder.
+ *
+ * This is functionally equivalent to {@link update_folders}.
+ */
+ internal void update_folder(Geary.Folder folder) {
+ Gee.Collection<Geary.Folder> folders =
+ new Gee.LinkedList<Geary.Folder>();
+ folders.add(folder);
+ debug("Contents altered!");
+ notify_folders_contents_altered(folders);
+ }
+
+ /**
* Fires appropriate signals for folders have been altered.
+ *
+ * This is functionally equivalent to {@link update_folder}.
*/
internal void update_folders(Gee.Collection<Geary.Folder> folders) {
if (!folders.is_empty) {
@@ -1051,15 +1066,18 @@ internal class Geary.ImapEngine.UpdateRemoteFolders : AccountOperation {
internal class Geary.ImapEngine.RefreshFolderUnseen : AccountOperation {
- private weak Geary.Folder folder;
+ private weak MinimalFolder folder;
+ private weak GenericAccount account;
private weak Imap.Account remote;
private weak ImapDB.Account local;
- internal RefreshFolderUnseen(Geary.Folder folder,
+ internal RefreshFolderUnseen(MinimalFolder folder,
+ GenericAccount account,
Imap.Account remote,
ImapDB.Account local) {
this.folder = folder;
+ this.account = account;
this.remote = remote;
this.local = local;
}
@@ -1083,9 +1101,15 @@ internal class Geary.ImapEngine.RefreshFolderUnseen : AccountOperation {
cancellable
);
- yield local.update_folder_status_async(
- remote_folder, false, true, cancellable
- );
+ if (remote_folder.properties.have_contents_changed(
+ this.folder.local_folder.get_properties(),
+ this.folder.to_string())) {
+ yield local.update_folder_status_async(
+ remote_folder, false, true, cancellable
+ );
+
+ this.account.update_folder(this.folder);
+ }
}
}
diff --git a/src/engine/imap-engine/imap-engine-minimal-folder.vala
b/src/engine/imap-engine/imap-engine-minimal-folder.vala
index c1fbc40..b79ff83 100644
--- a/src/engine/imap-engine/imap-engine-minimal-folder.vala
+++ b/src/engine/imap-engine/imap-engine-minimal-folder.vala
@@ -1428,16 +1428,20 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
yield mark.wait_for_ready_async(cancellable);
}
-
+
public virtual async void copy_email_async(Gee.List<Geary.EmailIdentifier> to_copy,
- Geary.FolderPath destination, Cancellable? cancellable = null) throws Error {
+ Geary.FolderPath destination,
+ Cancellable? cancellable = null)
+ throws Error {
+ Geary.Folder target = yield this._account.fetch_folder_async(destination);
yield copy_email_uids_async(to_copy, destination, cancellable);
+ this._account.update_folder(target);
}
-
+
/**
* Returns the destination folder's UIDs for the copied messages.
*/
- public async Gee.Set<Imap.UID>? copy_email_uids_async(Gee.List<Geary.EmailIdentifier> to_copy,
+ protected async Gee.Set<Imap.UID>? copy_email_uids_async(Gee.List<Geary.EmailIdentifier> to_copy,
Geary.FolderPath destination, Cancellable? cancellable = null) throws Error {
check_open("copy_email_uids_async");
check_ids("copy_email_uids_async", to_copy);
@@ -1471,10 +1475,13 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
if (prepare.prepared_for_move == null || prepare.prepared_for_move.size == 0)
return null;
-
- return new RevokableMove(_account, this, destination, prepare.prepared_for_move);
+
+ Geary.Folder target = yield this._account.fetch_folder_async(destination);
+ return new RevokableMove(
+ _account, this, target, prepare.prepared_for_move
+ );
}
-
+
public void schedule_op(ReplayOperation op) throws Error {
check_open("schedule_op");
@@ -1604,7 +1611,7 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
// We queue an account operation since the folder itself is
// closed and hence does not have a connection to use for it.
RefreshFolderUnseen op = new RefreshFolderUnseen(
- this, this.remote, this.local
+ this, this._account, this.remote, this.local
);
try {
this._account.queue_operation(op);
diff --git a/src/engine/imap-engine/imap-engine-revokable-committed-move.vala
b/src/engine/imap-engine/imap-engine-revokable-committed-move.vala
index 3ac60dc..0f3f24a 100644
--- a/src/engine/imap-engine/imap-engine-revokable-committed-move.vala
+++ b/src/engine/imap-engine/imap-engine-revokable-committed-move.vala
@@ -42,6 +42,9 @@ private class Geary.ImapEngine.RevokableCommittedMove : Revokable {
}
notify_revoked();
+
+ Geary.Folder target = yield this.account.fetch_folder_async(this.destination);
+ this.account.update_folder(target);
} finally {
if (detached_destination != null) {
try {
diff --git a/src/engine/imap-engine/imap-engine-revokable-move.vala
b/src/engine/imap-engine/imap-engine-revokable-move.vala
index 594697b..a637be0 100644
--- a/src/engine/imap-engine/imap-engine-revokable-move.vala
+++ b/src/engine/imap-engine/imap-engine-revokable-move.vala
@@ -17,11 +17,11 @@ private class Geary.ImapEngine.RevokableMove : Revokable {
private const int COMMIT_TIMEOUT_SEC = 60;
private GenericAccount account;
- private ImapEngine.MinimalFolder source;
- private FolderPath destination;
+ private MinimalFolder source;
+ private Geary.Folder destination;
private Gee.Set<ImapDB.EmailIdentifier> move_ids;
- public RevokableMove(GenericAccount account, ImapEngine.MinimalFolder source, FolderPath destination,
+ public RevokableMove(GenericAccount account, MinimalFolder source, Geary.Folder destination,
Gee.Set<ImapDB.EmailIdentifier> move_ids) {
base (COMMIT_TIMEOUT_SEC);
@@ -48,7 +48,7 @@ private class Geary.ImapEngine.RevokableMove : Revokable {
source.path.to_string(), destination.to_string());
try {
- source.schedule_op(new MoveEmailCommit(source, move_ids, destination, null));
+ source.schedule_op(new MoveEmailCommit(source, move_ids, destination.path, null));
} catch (Error err) {
debug("Move from %s to %s failed: %s", source.path.to_string(), destination.to_string(),
err.message);
@@ -58,26 +58,34 @@ private class Geary.ImapEngine.RevokableMove : Revokable {
source.path.to_string(), source.get_open_state().to_string());
}
}
-
+
protected override async void internal_revoke_async(Cancellable? cancellable) throws Error {
try {
- yield source.exec_op_async(new MoveEmailRevoke(source, move_ids, cancellable),
- cancellable);
-
+ MoveEmailRevoke op = new MoveEmailRevoke(
+ source, move_ids, cancellable
+ );
+ yield source.exec_op_async(op, cancellable);
+
// valid must still be true before firing
notify_revoked();
+
+ yield op.wait_for_ready_async(cancellable);
+ this.account.update_folder(this.destination);
} finally {
set_invalid();
}
}
-
+
protected override async void internal_commit_async(Cancellable? cancellable) throws Error {
try {
- MoveEmailCommit op = new MoveEmailCommit(source, move_ids, destination, cancellable);
+ MoveEmailCommit op = new MoveEmailCommit(source, move_ids, destination.path, cancellable);
yield source.exec_op_async(op, cancellable);
-
+
// valid must still be true before firing
- notify_committed(new RevokableCommittedMove(account, source.path, destination,
op.destination_uids));
+ notify_committed(new RevokableCommittedMove(account, source.path, destination.path,
op.destination_uids));
+
+ yield op.wait_for_ready_async(cancellable);
+ this.account.update_folder(this.destination);
} finally {
set_invalid();
}
@@ -87,7 +95,7 @@ private class Geary.ImapEngine.RevokableMove : Revokable {
// look for either of the folders going away
if (unavailable != null) {
foreach (Folder folder in unavailable) {
- if (folder.path.equal_to(source.path) || folder.path.equal_to(destination)) {
+ if (folder.path.equal_to(source.path) || folder.path.equal_to(destination.path)) {
set_invalid();
break;
@@ -107,13 +115,23 @@ private class Geary.ImapEngine.RevokableMove : Revokable {
if (move_ids.size <= 0)
set_invalid();
}
-
+
private void on_source_closing(Gee.List<ReplayOperation> final_ops) {
if (!valid)
return;
-
- final_ops.add(new MoveEmailCommit(source, move_ids, destination, null));
+
+ MoveEmailCommit op = new MoveEmailCommit(
+ source, move_ids, destination.path, null
+ );
+ final_ops.add(op);
set_invalid();
+ op.wait_for_ready_async.begin(null, (obj, res) => {
+ try {
+ op.wait_for_ready_async.end(res);
+ this.account.update_folder(this.destination);
+ } catch (Error err) {
+ // Oh well
+ }
+ });
}
}
-
diff --git a/src/engine/imap-engine/imap-engine-send-replay-operation.vala
b/src/engine/imap-engine/imap-engine-send-replay-operation.vala
index 90d9d9c..d3f6bc3 100644
--- a/src/engine/imap-engine/imap-engine-send-replay-operation.vala
+++ b/src/engine/imap-engine/imap-engine-send-replay-operation.vala
@@ -4,21 +4,25 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
+
+/**
+ * A replay operation for a user-initiated operation.
+ */
private abstract class Geary.ImapEngine.SendReplayOperation : Geary.ImapEngine.ReplayOperation {
protected SendReplayOperation(string name, ReplayOperation.OnError on_remote_error = OnError.THROW) {
base (name, ReplayOperation.Scope.LOCAL_AND_REMOTE, on_remote_error);
}
-
+
protected SendReplayOperation.only_local(string name, ReplayOperation.OnError on_remote_error =
OnError.THROW) {
base (name, ReplayOperation.Scope.LOCAL_ONLY, on_remote_error);
}
-
+
protected SendReplayOperation.only_remote(string name, ReplayOperation.OnError on_remote_error =
OnError.THROW) {
base (name, ReplayOperation.Scope.REMOTE_ONLY, on_remote_error);
}
-
+
public override void notify_remote_removed_position(Imap.SequenceNumber removed) {
// we've worked very hard to keep positional addressing out of the SendReplayOperations
}
-}
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]