Merge branch 'wip/76-gmail-drafts' into 'mainline'
Don't support removing an email when creating another Closes #76 See merge request GNOME/geary!279
This commit is contained in:
commit
1ea567821c
8 changed files with 107 additions and 102 deletions
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright 2016 Software Freedom Conservancy Inc.
|
||||
*
|
||||
* This software is licensed under the GNU Lesser General Public License
|
||||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
@ -30,17 +30,12 @@ public interface Geary.FolderSupport.Create : Folder {
|
|||
* time to be set when saved. Like EmailFlags, this is optional
|
||||
* if not applicable.
|
||||
*
|
||||
* If an id is passed, this will replace the existing message by
|
||||
* deleting it after the new message is created. The new
|
||||
* message's ID is returned.
|
||||
*
|
||||
* @see FolderProperties.create_never_returns_id
|
||||
*/
|
||||
public abstract async EmailIdentifier?
|
||||
create_email_async(RFC822.Message rfc822,
|
||||
EmailFlags? flags,
|
||||
DateTime? date_received,
|
||||
EmailIdentifier? id,
|
||||
GLib.Cancellable? cancellable = null)
|
||||
throws GLib.Error;
|
||||
|
||||
|
|
|
|||
|
|
@ -408,8 +408,13 @@ public class Geary.App.DraftManager : BaseObject {
|
|||
return false;
|
||||
|
||||
// make sure there's a folder to work with
|
||||
if (drafts_folder == null || drafts_folder.get_open_state() == Folder.OpenState.CLOSED) {
|
||||
fatal(new EngineError.SERVER_UNAVAILABLE("%s: premature drafts folder close", to_string()));
|
||||
if (this.drafts_folder == null ||
|
||||
this.drafts_folder.get_open_state() == CLOSED) {
|
||||
fatal(
|
||||
new EngineError.SERVER_UNAVAILABLE(
|
||||
"%s: premature drafts folder close", to_string()
|
||||
)
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -417,44 +422,48 @@ public class Geary.App.DraftManager : BaseObject {
|
|||
// at this point, only operation left is PUSH
|
||||
assert(op.op_type == OperationType.PUSH);
|
||||
|
||||
draft_state = DraftState.STORING;
|
||||
|
||||
// delete old draft for all PUSHes: best effort ... since create_email_async() will handle
|
||||
// replacement in a transactional-kinda-way, only outright delete if not using create
|
||||
if (current_draft_id != null && op.draft == null) {
|
||||
bool success = false;
|
||||
try {
|
||||
yield remove_support.remove_email_async(
|
||||
iterate<EmailIdentifier>(current_draft_id).to_array_list());
|
||||
success = true;
|
||||
} catch (Error err) {
|
||||
debug("%s: Unable to remove existing draft %s: %s", to_string(), current_draft_id.to_string(),
|
||||
err.message);
|
||||
}
|
||||
|
||||
// always clear draft id (assuming that retrying a failed remove is unnecessary), but
|
||||
// only signal the discard if it actually was removed
|
||||
current_draft_id = null;
|
||||
if (success)
|
||||
notify_discarded();
|
||||
}
|
||||
this.draft_state = DraftState.STORING;
|
||||
|
||||
// if draft supplied, save it
|
||||
if (op.draft != null) {
|
||||
try {
|
||||
current_draft_id = yield create_support.create_email_async(op.draft, op.flags,
|
||||
op.date_received, current_draft_id, null);
|
||||
EmailIdentifier? old_id = this.current_draft_id;
|
||||
this.current_draft_id =
|
||||
yield this.create_support.create_email_async(
|
||||
op.draft,
|
||||
op.flags,
|
||||
op.date_received,
|
||||
null
|
||||
);
|
||||
yield this.remove_support.remove_email_async(
|
||||
Collection.single(old_id), null
|
||||
);
|
||||
|
||||
draft_state = DraftState.STORED;
|
||||
this.draft_state = DraftState.STORED;
|
||||
notify_stored(op.draft);
|
||||
} catch (Error err) {
|
||||
draft_state = DraftState.ERROR;
|
||||
|
||||
// notify subscribers
|
||||
} catch (GLib.Error err) {
|
||||
this.draft_state = DraftState.ERROR;
|
||||
draft_failed(op.draft, err);
|
||||
}
|
||||
} else {
|
||||
draft_state = DraftState.NOT_STORED;
|
||||
this.draft_state = DraftState.NOT_STORED;
|
||||
|
||||
// Delete the old draft if present so it's not hanging
|
||||
// around
|
||||
if (this.current_draft_id != null) {
|
||||
try {
|
||||
yield this.remove_support.remove_email_async(
|
||||
Collection.single(this.current_draft_id),
|
||||
null
|
||||
);
|
||||
notify_discarded();
|
||||
} catch (GLib.Error err) {
|
||||
warning("%s: Unable to remove existing draft %s: %s",
|
||||
to_string(),
|
||||
current_draft_id.to_string(),
|
||||
err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -463,5 +472,12 @@ public class Geary.App.DraftManager : BaseObject {
|
|||
public string to_string() {
|
||||
return "%s DraftManager".printf(account.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
private async void save_draft(EmailIdentifier id) {
|
||||
|
||||
}
|
||||
|
||||
private async void remove_draft(EmailIdentifier id) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,41 @@
|
|||
/* Copyright 2016 Software Freedom Conservancy Inc.
|
||||
/*
|
||||
* Copyright 2016 Software Freedom Conservancy Inc.
|
||||
*
|
||||
* This software is licensed under the GNU Lesser General Public License
|
||||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gmail's Drafts folder supports basic operations as well as true removal of messages and creating
|
||||
* new ones (IMAP APPEND).
|
||||
* A draft folder for Gmail.
|
||||
*
|
||||
* Gmail's drafts folders supports basic operations as well as true
|
||||
* removal of messages and creating new ones (IMAP APPEND).
|
||||
*/
|
||||
private class Geary.ImapEngine.GmailDraftsFolder :
|
||||
MinimalFolder, FolderSupport.Create, FolderSupport.Remove {
|
||||
|
||||
private class Geary.ImapEngine.GmailDraftsFolder : MinimalFolder, FolderSupport.Create,
|
||||
FolderSupport.Remove {
|
||||
public GmailDraftsFolder(GmailAccount account,
|
||||
ImapDB.Folder local_folder,
|
||||
SpecialFolderType special_folder_type) {
|
||||
base (account, local_folder, special_folder_type);
|
||||
base(account, local_folder, special_folder_type);
|
||||
}
|
||||
|
||||
public new async Geary.EmailIdentifier? create_email_async(
|
||||
RFC822.Message rfc822, Geary.EmailFlags? flags, DateTime? date_received,
|
||||
Geary.EmailIdentifier? id, Cancellable? cancellable = null) throws Error {
|
||||
return yield base.create_email_async(rfc822, flags, date_received, id, cancellable);
|
||||
public new async EmailIdentifier?
|
||||
create_email_async(RFC822.Message rfc822,
|
||||
EmailFlags? flags,
|
||||
DateTime? date_received,
|
||||
GLib.Cancellable? cancellable = null)
|
||||
throws GLib.Error {
|
||||
return yield base.create_email_async(
|
||||
rfc822, flags, date_received, cancellable
|
||||
);
|
||||
}
|
||||
|
||||
public async void remove_email_async(
|
||||
Gee.Collection<Geary.EmailIdentifier> email_ids,
|
||||
GLib.Cancellable? cancellable = null)
|
||||
public async void
|
||||
remove_email_async(Gee.Collection<EmailIdentifier> email_ids,
|
||||
GLib.Cancellable? cancellable = null)
|
||||
throws GLib.Error {
|
||||
yield GmailFolder.true_remove_email_async(this, email_ids, cancellable);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,15 @@ private class Geary.ImapEngine.GmailFolder : MinimalFolder, FolderSupport.Archiv
|
|||
base (account, local_folder, special_folder_type);
|
||||
}
|
||||
|
||||
public new async Geary.EmailIdentifier? create_email_async(
|
||||
RFC822.Message rfc822, Geary.EmailFlags? flags, DateTime? date_received,
|
||||
Geary.EmailIdentifier? id, Cancellable? cancellable = null) throws Error {
|
||||
return yield base.create_email_async(rfc822, flags, date_received, id, cancellable);
|
||||
public new async EmailIdentifier?
|
||||
create_email_async(RFC822.Message rfc822,
|
||||
EmailFlags? flags,
|
||||
DateTime? date_received,
|
||||
GLib.Cancellable? cancellable = null)
|
||||
throws GLib.Error {
|
||||
return yield base.create_email_async(
|
||||
rfc822, flags, date_received, cancellable
|
||||
);
|
||||
}
|
||||
|
||||
public async Geary.Revokable?
|
||||
|
|
|
|||
|
|
@ -48,9 +48,14 @@ private class Geary.ImapEngine.GenericFolder : MinimalFolder,
|
|||
yield expunge_all_async(cancellable);
|
||||
}
|
||||
|
||||
public new async Geary.EmailIdentifier? create_email_async(RFC822.Message rfc822,
|
||||
Geary.EmailFlags? flags, DateTime? date_received, Geary.EmailIdentifier? id,
|
||||
Cancellable? cancellable = null) throws Error {
|
||||
return yield base.create_email_async(rfc822, flags, date_received, id, cancellable);
|
||||
public new async EmailIdentifier?
|
||||
create_email_async(RFC822.Message rfc822,
|
||||
EmailFlags? flags,
|
||||
DateTime? date_received,
|
||||
GLib.Cancellable? cancellable = null)
|
||||
throws GLib.Error {
|
||||
return yield base.create_email_async(
|
||||
rfc822, flags, date_received, cancellable
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1458,58 +1458,34 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
|
|||
return earliest;
|
||||
}
|
||||
|
||||
protected async Geary.EmailIdentifier? create_email_async(RFC822.Message rfc822,
|
||||
Geary.EmailFlags? flags, DateTime? date_received, Geary.EmailIdentifier? id,
|
||||
Cancellable? cancellable = null) throws Error {
|
||||
protected async EmailIdentifier?
|
||||
create_email_async(RFC822.Message rfc822,
|
||||
EmailFlags? flags,
|
||||
DateTime? date_received,
|
||||
GLib.Cancellable? cancellable = null)
|
||||
throws GLib.Error {
|
||||
check_open("create_email_async");
|
||||
if (id != null)
|
||||
check_id("create_email_async", id);
|
||||
CreateEmail op = new CreateEmail(
|
||||
this, rfc822, flags, date_received, cancellable
|
||||
);
|
||||
replay_queue.schedule(op);
|
||||
yield op.wait_for_ready_async(cancellable);
|
||||
this._account.update_folder(this);
|
||||
|
||||
Error? cancel_error = null;
|
||||
Geary.EmailIdentifier? ret = null;
|
||||
try {
|
||||
CreateEmail create = new CreateEmail(this, rfc822, flags, date_received, cancellable);
|
||||
replay_queue.schedule(create);
|
||||
yield create.wait_for_ready_async(cancellable);
|
||||
|
||||
ret = create.created_id;
|
||||
} catch (Error e) {
|
||||
if (e is IOError.CANCELLED)
|
||||
cancel_error = e;
|
||||
else
|
||||
throw e;
|
||||
}
|
||||
|
||||
Geary.FolderSupport.Remove? remove_folder = this as Geary.FolderSupport.Remove;
|
||||
|
||||
// Remove old message.
|
||||
if (id != null && remove_folder != null)
|
||||
yield remove_folder.remove_email_async(iterate<EmailIdentifier>(id).to_array_list());
|
||||
|
||||
// If the user cancelled the operation, throw the error here.
|
||||
if (cancel_error != null)
|
||||
throw cancel_error;
|
||||
|
||||
// If the caller cancelled during the remove operation, delete the newly created message to
|
||||
// safely back out.
|
||||
if (cancellable != null && cancellable.is_cancelled() && ret != null && remove_folder != null)
|
||||
yield remove_folder.remove_email_async(iterate<EmailIdentifier>(ret).to_array_list());
|
||||
|
||||
if (ret != null) {
|
||||
if (op.created_id != null) {
|
||||
// Server returned a UID for the new message. It was saved
|
||||
// locally possibly before the server notified that the
|
||||
// message exists. As such, fetch any missing parts from
|
||||
// the remote to ensure it is properly filled in.
|
||||
yield list_email_by_id_async(
|
||||
ret, 1, ALL, INCLUDING_ID, cancellable
|
||||
op.created_id, 1, ALL, INCLUDING_ID, cancellable
|
||||
);
|
||||
} else {
|
||||
// The server didn't return a UID for the new email, so do
|
||||
// a sync now to ensure it shows up immediately.
|
||||
yield synchronise_remote(cancellable);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return op.created_id;
|
||||
}
|
||||
|
||||
/** Fires a {@link marked_email_removed} signal for this folder. */
|
||||
|
|
|
|||
|
|
@ -112,7 +112,6 @@ private class Geary.Outbox.Folder :
|
|||
create_email_async(RFC822.Message rfc822,
|
||||
Geary.EmailFlags? flags,
|
||||
GLib.DateTime? date_received,
|
||||
Geary.EmailIdentifier? id = null,
|
||||
GLib.Cancellable? cancellable = null)
|
||||
throws GLib.Error {
|
||||
check_open();
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ internal class Geary.Smtp.ClientService : Geary.ClientService {
|
|||
debug("Queuing message for sending: %s", message_subject(rfc822));
|
||||
|
||||
EmailIdentifier id = yield this.outbox.create_email_async(
|
||||
rfc822, null, null, null, cancellable
|
||||
rfc822, null, null, cancellable
|
||||
);
|
||||
this.outbox_queue.send(id);
|
||||
}
|
||||
|
|
@ -330,7 +330,7 @@ internal class Geary.Smtp.ClientService : Geary.ClientService {
|
|||
try {
|
||||
yield create.open_async(NO_DELAY, cancellable);
|
||||
open = true;
|
||||
yield create.create_email_async(raw, null, null, null, cancellable);
|
||||
yield create.create_email_async(raw, null, null, cancellable);
|
||||
yield wait_for_message(create, message, cancellable);
|
||||
} finally {
|
||||
if (open) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue