diff --git a/src/engine/imap-db/imap-db-folder.vala b/src/engine/imap-db/imap-db-folder.vala index 46550808..8c14fa0f 100644 --- a/src/engine/imap-db/imap-db-folder.vala +++ b/src/engine/imap-db/imap-db-folder.vala @@ -1122,6 +1122,18 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics { unread_updated(unread_status); } + internal async Gee.List? get_email_uids_async( + Gee.Collection ids, Cancellable? cancellable) throws Error { + Gee.List uids = null; + yield db.exec_transaction_async(Db.TransactionType.RO, (cx, cancellable) => { + uids = do_get_email_uids(cx, ids, cancellable); + + return Db.TransactionOutcome.SUCCESS; + }, cancellable); + + return uids; + } + internal async Gee.Map? get_email_flags_async( Gee.Collection ids, Cancellable? cancellable) throws Error { Gee.Map? map = null; @@ -1882,6 +1894,21 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics { return builder.str; } + private Gee.List? do_get_email_uids(Db.Connection cx, + Gee.Collection ids, Cancellable? cancellable) throws Error { + Gee.List? locs = do_get_locations_for_ids(cx, ids, ListFlags.NONE, + cancellable); + if (locs == null) + return null; + + Gee.List uids = new Gee.ArrayList(); + foreach (LocationIdentifier location in locs) { + uids.insert(0, location.uid); + } + + return (uids.size > 0) ? uids : null; + } + private Gee.Map? do_get_email_flags(Db.Connection cx, Gee.Collection ids, Cancellable? cancellable) throws Error { Gee.List? locs = do_get_locations_for_ids(cx, ids, ListFlags.NONE, diff --git a/src/engine/imap-engine/replay-ops/imap-engine-mark-email.vala b/src/engine/imap-engine/replay-ops/imap-engine-mark-email.vala index b48e8edb..e8017761 100644 --- a/src/engine/imap-engine/replay-ops/imap-engine-mark-email.vala +++ b/src/engine/imap-engine/replay-ops/imap-engine-mark-email.vala @@ -7,6 +7,7 @@ private class Geary.ImapEngine.MarkEmail : Geary.ImapEngine.SendReplayOperation { private MinimalFolder engine; private Gee.List to_mark = new Gee.ArrayList(); + private Gee.List to_mark_uids = new Gee.ArrayList(); private Geary.EmailFlags? flags_to_add; private Geary.EmailFlags? flags_to_remove; private Gee.Map? original_flags = null; @@ -48,6 +49,10 @@ private class Geary.ImapEngine.MarkEmail : Geary.ImapEngine.SendReplayOperation yield engine.local_folder.mark_email_async(original_flags.keys, flags_to_add, flags_to_remove, cancellable); + // We can't rely on email identifier for remote replay + // An email identifier id can match multiple uids + to_mark_uids = yield engine.local_folder.get_email_uids_async(to_mark, cancellable); + // Notify using flags from DB. Gee.Map? map = yield engine.local_folder.get_email_flags_async( original_flags.keys, cancellable); @@ -60,9 +65,8 @@ private class Geary.ImapEngine.MarkEmail : Geary.ImapEngine.SendReplayOperation public override async void replay_remote_async(Imap.FolderSession remote) throws GLib.Error { // potentially empty due to writebehind operation - if (original_flags.size > 0) { - Gee.List msg_sets = Imap.MessageSet.uid_sparse( - ImapDB.EmailIdentifier.to_uids(original_flags.keys)); + if (to_mark_uids.size > 0) { + Gee.List msg_sets = Imap.MessageSet.uid_sparse(to_mark_uids); yield remote.mark_email_async( msg_sets, flags_to_add, flags_to_remove, cancellable );