engine: When opening a folder, sanitize remote unseen.
Messages may have been marked as read while waiting in open_remote_session_locked(). Unsure we handle the diff when remote session opened. Fix #1023 Fix #364
This commit is contained in:
parent
8164b5034e
commit
418de07582
5 changed files with 54 additions and 7 deletions
|
|
@ -1060,7 +1060,7 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
|
|||
return deleted_email_ids;
|
||||
}
|
||||
|
||||
public async void mark_email_async(Gee.Collection<ImapDB.EmailIdentifier> to_mark,
|
||||
public async int mark_email_async(Gee.Collection<ImapDB.EmailIdentifier> to_mark,
|
||||
Geary.EmailFlags? flags_to_add, Geary.EmailFlags? flags_to_remove, Cancellable? cancellable)
|
||||
throws Error {
|
||||
int unread_change = 0; // Negative means messages are read, positive means unread.
|
||||
|
|
@ -1120,6 +1120,8 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
|
|||
// Signal changes so other folders can be updated.
|
||||
if (unread_status.size > 0)
|
||||
unread_updated(unread_status);
|
||||
|
||||
return unread_change;
|
||||
}
|
||||
|
||||
internal async Gee.List<Imap.UID>? get_email_uids_async(
|
||||
|
|
|
|||
|
|
@ -1373,6 +1373,15 @@ internal class Geary.ImapEngine.UpdateRemoteFolders : AccountOperation {
|
|||
// always update, openable or not; have the folder update the UID info the next time
|
||||
// it's opened
|
||||
try {
|
||||
// Some emails may have been marked as read locally while
|
||||
// updating remote folders
|
||||
if (minimal_folder.replay_queue != null &&
|
||||
minimal_folder.replay_queue.pending_unread_change() != 0) {
|
||||
remote_folder.properties.set_status_unseen(
|
||||
remote_folder.properties.unseen +
|
||||
minimal_folder.replay_queue.pending_unread_change()
|
||||
);
|
||||
}
|
||||
yield minimal_folder.local_folder.update_folder_status(
|
||||
remote_folder.properties, false, cancellable
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1112,6 +1112,13 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
|
|||
return;
|
||||
}
|
||||
|
||||
// Some emails may have been marked as read locally while
|
||||
// claiming folder session, handle the diff here.
|
||||
session.folder.properties.set_status_unseen(
|
||||
session.folder.properties.unseen +
|
||||
this.replay_queue.pending_unread_change()
|
||||
);
|
||||
|
||||
// Update the local folder's totals and UID values after
|
||||
// normalisation, so it does not mistake the remote's current
|
||||
// state with our previous state
|
||||
|
|
@ -1371,6 +1378,10 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
|
|||
replay_queue.schedule(mark);
|
||||
|
||||
yield mark.wait_for_ready_async(cancellable);
|
||||
|
||||
// Cancel any remote update, we just updated locally unread_count,
|
||||
// incoming data will have an invalid unseen value
|
||||
this.account.cancel_remote_update();
|
||||
}
|
||||
|
||||
public virtual async void
|
||||
|
|
|
|||
|
|
@ -397,6 +397,24 @@ private class Geary.ImapEngine.ReplayQueue : BaseObject, Logging.Source {
|
|||
closed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get pending unread change.
|
||||
*/
|
||||
public int pending_unread_change() {
|
||||
int unread_change = 0;
|
||||
Gee.Collection<ReplayOperation> replay_ops = traverse(
|
||||
remote_queue.get_all()
|
||||
).to_array_list();
|
||||
replay_ops.add(this.remote_op_active);
|
||||
foreach (ReplayOperation op in replay_ops) {
|
||||
if (op is ImapEngine.MarkEmail) {
|
||||
ImapEngine.MarkEmail mark_email = op as ImapEngine.MarkEmail;
|
||||
unread_change += mark_email.unread_change;
|
||||
}
|
||||
}
|
||||
return unread_change;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Logging.State to_logging_state() {
|
||||
return new Logging.State(
|
||||
|
|
@ -447,7 +465,7 @@ private class Geary.ImapEngine.ReplayQueue : BaseObject, Logging.Source {
|
|||
break;
|
||||
}
|
||||
|
||||
local_op_active = op;
|
||||
this.local_op_active = op;
|
||||
|
||||
// If this is a Close operation, shut down the queue after processing it
|
||||
if (op is CloseReplayQueue)
|
||||
|
|
@ -526,7 +544,7 @@ private class Geary.ImapEngine.ReplayQueue : BaseObject, Logging.Source {
|
|||
failed(op);
|
||||
}
|
||||
|
||||
local_op_active = null;
|
||||
this.local_op_active = null;
|
||||
}
|
||||
|
||||
debug("ReplayQueue.do_replay_local_async %s exiting", to_string());
|
||||
|
|
@ -547,7 +565,7 @@ private class Geary.ImapEngine.ReplayQueue : BaseObject, Logging.Source {
|
|||
break;
|
||||
}
|
||||
|
||||
remote_op_active = op;
|
||||
this.remote_op_active = op;
|
||||
|
||||
// ReplayClose means this queue (and the folder) are closing, so handle errors a little
|
||||
// differently
|
||||
|
|
@ -641,7 +659,7 @@ private class Geary.ImapEngine.ReplayQueue : BaseObject, Logging.Source {
|
|||
else
|
||||
failed(op);
|
||||
|
||||
remote_op_active = null;
|
||||
this.remote_op_active = null;
|
||||
}
|
||||
|
||||
debug("ReplayQueue.do_replay_remote_async %s exiting", to_string());
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ private class Geary.ImapEngine.MarkEmail : Geary.ImapEngine.SendReplayOperation
|
|||
private Gee.Map<ImapDB.EmailIdentifier, Geary.EmailFlags>? original_flags = null;
|
||||
private Cancellable? cancellable;
|
||||
|
||||
internal int unread_change { get; private set; default=0; }
|
||||
|
||||
public MarkEmail(MinimalFolder engine,
|
||||
Gee.Collection<ImapDB.EmailIdentifier> to_mark,
|
||||
EmailFlags? flags_to_add,
|
||||
|
|
@ -46,8 +48,12 @@ private class Geary.ImapEngine.MarkEmail : Geary.ImapEngine.SendReplayOperation
|
|||
if (original_flags == null || original_flags.size == 0)
|
||||
return ReplayOperation.Status.COMPLETED;
|
||||
|
||||
yield engine.local_folder.mark_email_async(original_flags.keys, flags_to_add, flags_to_remove,
|
||||
cancellable);
|
||||
this.unread_change = 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
|
||||
|
|
@ -71,6 +77,7 @@ private class Geary.ImapEngine.MarkEmail : Geary.ImapEngine.SendReplayOperation
|
|||
msg_sets, flags_to_add, flags_to_remove, cancellable
|
||||
);
|
||||
}
|
||||
this.unread_change = 0;
|
||||
}
|
||||
|
||||
public override async void backout_local_async() throws Error {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue