Merge branch 'mjog/790-email-flag-interleaving' into 'mainline'

Fix email flag interleaving

Closes #790

See merge request GNOME/geary!669
This commit is contained in:
Michael Gratton 2021-02-28 04:30:22 +00:00
commit d37847682d
2 changed files with 57 additions and 22 deletions

View file

@ -661,7 +661,7 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject {
all_uid = false;
cmds.add(
new StoreCommand(msg_set, flags, StoreCommand.Option.ADD_FLAGS, cancellable)
new StoreCommand(msg_set, ADD_FLAGS, SILENT, flags, cancellable)
);
}
@ -698,7 +698,11 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject {
if (msg_flags_add.size > 0) {
cmds.add(
new StoreCommand(
msg_set, msg_flags_add, ADD_FLAGS, cancellable
msg_set,
ADD_FLAGS,
SILENT,
msg_flags_add,
cancellable
)
);
}
@ -706,7 +710,11 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject {
if (msg_flags_remove.size > 0) {
cmds.add(
new StoreCommand(
msg_set, msg_flags_remove, REMOVE_FLAGS, cancellable
msg_set,
REMOVE_FLAGS,
SILENT,
msg_flags_remove,
cancellable
)
);
}

View file

@ -6,6 +6,8 @@
*/
/**
* The IMAP `STORE` and `UID STORE` commands.
*
* See [[http://tools.ietf.org/html/rfc3501#section-6.4.6]]
*
* @see FetchCommand
@ -13,37 +15,62 @@
*/
public class Geary.Imap.StoreCommand : Command {
public const string NAME = "store";
public const string UID_NAME = "uid store";
public const string NAME = "STORE";
public const string UID_NAME = "UID STORE";
/**
* Options indicating functionality of the {@link StoreCommand}.
*
* Note that {@link ADD_FLAGS} and {@link REMOVE_FLAGS} are mutally exclusive. REMOVE_FLAGS
* actually does not set a bit, meaning that removing is the default operation and, if both
* add and remove are set, an add occurs.
*/
[Flags]
public enum Option {
REMOVE_FLAGS = 0,
/** Defines how the given flags are used to update message's flags. */
public enum Mode {
/** Sets the given flags as the complete set for the message's. */
SET_FLAGS,
/** Adds the given flags to the message's existing flags. */
ADD_FLAGS,
/** Removes the given flags from the message's existing flags. */
REMOVE_FLAGS,
}
/** Specifies optional functionality for the command. */
[Flags]
public enum Options {
/** No options should be used. */
NONE,
/** Prevent the server from sending an untagged FETCH in response. */
SILENT
}
public StoreCommand(MessageSet message_set,
Mode mode,
Options options,
Gee.List<MessageFlag> flag_list,
Option options,
GLib.Cancellable? should_send) {
base(message_set.is_uid ? UID_NAME : NAME, null, should_send);
bool add_flag = (options & Option.ADD_FLAGS) != 0;
bool silent = (options & Option.SILENT) != 0;
this.args.add(message_set.to_parameter());
this.args.add(new AtomParameter("%sflags%s".printf(add_flag ? "+" : "-", silent ? ".silent" : "")));
ListParameter list = new ListParameter();
foreach(MessageFlag flag in flag_list) {
var command = new GLib.StringBuilder();
switch (mode) {
case ADD_FLAGS:
command.append_c('+');
break;
case REMOVE_FLAGS:
command.append_c('-');
break;
case SET_FLAGS:
// noop
break;
}
command.append("FLAGS");
if (Options.SILENT in options) {
command.append(".SILENT");
}
this.args.add(new AtomParameter(command.str));
var list = new ListParameter();
foreach (var flag in flag_list) {
list.add(new AtomParameter(flag.value));
}