[geary/mjog/493-undo-send: 19/25] Implement undo-on-send
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/mjog/493-undo-send: 19/25] Implement undo-on-send
- Date: Tue, 12 Nov 2019 21:49:27 +0000 (UTC)
commit d337d0aa5c10b10a6597ec67c1fd939834962f03
Author: Michael Gratton <mike vee net>
Date: Tue Nov 12 12:34:50 2019 +1100
Implement undo-on-send
Implement new Application.Controller::send_email method and SendEmail
application command, execute the new command when the method is called.
Call the new method from Composer.Widget when sending the command.
Closes #493
src/client/application/application-controller.vala | 100 ++++++++++++++++++++-
src/client/composer/composer-widget.vala | 7 +-
2 files changed, 100 insertions(+), 7 deletions(-)
---
diff --git a/src/client/application/application-controller.vala
b/src/client/application/application-controller.vala
index 7470adec..aab69fdb 100644
--- a/src/client/application/application-controller.vala
+++ b/src/client/application/application-controller.vala
@@ -447,6 +447,23 @@ public class Application.Controller : Geary.BaseObject {
this.pending_mailtos.clear();
}
+ /** Queues the email in a composer for delivery. */
+ public async void send_email(Composer.Widget composer) {
+ AccountContext? context = this.accounts.get(
+ composer.account.information
+ );
+ if (context != null) {
+ try {
+ yield context.commands.execute(
+ new SendComposerCommand(this.application, context, composer),
+ context.cancellable
+ );
+ } catch (GLib.Error err) {
+ report_problem(new Geary.ProblemReport(err));
+ }
+ }
+ }
+
/** Displays a problem report when an error has been encountered. */
public void report_problem(Geary.ProblemReport report) {
debug("Problem reported: %s", report.to_string());
@@ -1656,12 +1673,12 @@ public class Application.Controller : Geary.BaseObject {
}
}
- // Translators: The label for an in-app notification. The
- // string substitution is a list of recipients of the email.
private void on_sent(Geary.Smtp.ClientService service,
Geary.RFC822.Message sent) {
+ /// Translators: The label for an in-app notification. The
+ /// string substitution is a list of recipients of the email.
string message = _(
- "Successfully sent mail to %s."
+ "Email sent to %s"
).printf(Util.Email.to_short_recipient_display(sent));
Components.InAppNotification notification =
new Components.InAppNotification(message);
@@ -2605,3 +2622,80 @@ private class Application.EmptyFolderCommand : Command {
}
}
+
+
+private class Application.SendComposerCommand : Command {
+
+
+ public override bool can_undo {
+ get { return this.application.config.undo_send_delay > 0; }
+ }
+
+ public override bool can_redo {
+ get { return false; }
+ }
+
+ private GearyApplication application;
+ private Controller.AccountContext context;
+ private Composer.Widget? composer;
+ private Geary.Smtp.ClientService smtp;
+ private Geary.TimeoutManager commit_timer;
+ private Geary.EmailIdentifier? saved = null;
+
+
+ public SendComposerCommand(GearyApplication application,
+ Controller.AccountContext context,
+ Composer.Widget composer) {
+ this.application = application;
+ this.context = context;
+ this.composer = composer;
+ this.smtp = (Geary.Smtp.ClientService) context.account.outgoing;
+
+ int send_delay = this.application.config.undo_send_delay;
+ this.commit_timer = new Geary.TimeoutManager.seconds(
+ send_delay > 0 ? send_delay : 0,
+ on_commit_timeout
+ );
+ }
+
+ public override async void execute(GLib.Cancellable? cancellable)
+ throws GLib.Error {
+ Geary.ComposedEmail email = yield this.composer.get_composed_email();
+ /// Translators: The label for an in-app notification. The
+ /// string substitution is a list of recipients of the email.
+ this.executed_label = _(
+ "Email to %s queued for delivery"
+ ).printf(Util.Email.to_short_recipient_display(email));
+
+ if (this.can_undo) {
+ this.saved = yield this.smtp.save_email(email, cancellable);
+ this.commit_timer.start();
+ } else {
+ yield this.smtp.send_email(email, cancellable);
+ }
+ }
+
+ public override async void undo(GLib.Cancellable? cancellable)
+ throws GLib.Error {
+ this.commit_timer.reset();
+ yield this.smtp.outbox.remove_email_async(
+ Geary.Collection.single(this.saved),
+ cancellable
+ );
+ this.composer.set_enabled(true);
+ this.application.controller.show_composer(this.composer, null);
+ this.composer = null;
+ this.saved = null;
+ }
+
+ private void on_commit_timeout() {
+ this.smtp.queue_email(this.saved);
+ // Calling close then immediately erasing the reference looks
+ // sketchy, but works since Controller still maintains a
+ // reference to the composer until it destroys itself.
+ this.composer.close.begin();
+ this.composer = null;
+ this.saved = null;
+ }
+
+}
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index aff254fa..d038c45f 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -1435,10 +1435,10 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
}
// Sends the current message.
- private void on_send(SimpleAction action, Variant? param) {
+ private void on_send() {
this.should_send.begin((obj, res) => {
if (this.should_send.end(res)) {
- on_send_async.begin();
+ this.on_send_async.begin();
}
});
}
@@ -1450,8 +1450,7 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
// Perform send.
try {
yield this.editor.clean_content();
- yield ((Geary.Smtp.ClientService) this.account.outgoing)
- .send_email(yield get_composed_email(), null);
+ yield this.application.controller.send_email(this);
} catch (Error e) {
GLib.message("Error sending email: %s", e.message);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]