[geary/mjog/493-undo-send: 2/6] Implement undoing discarded composers



commit 28a4484a32eb9d8ccf8da9325a0b9a8bea3d2681
Author: Michael Gratton <mike vee net>
Date:   Tue Nov 12 14:34:50 2019 +1100

    Implement undoing discarded composers
    
    Add Application::discard_composed_email method and DiscardComposerEmail
    command, execute the latter when the former is called. Update
    Composer.Widget::discard_and_exit_async to call this as needed instead
    of manually disposing of the widget.

 src/client/application/application-controller.vala | 74 ++++++++++++++++++++++
 src/client/composer/composer-widget.vala           | 12 +++-
 2 files changed, 85 insertions(+), 1 deletion(-)
---
diff --git a/src/client/application/application-controller.vala 
b/src/client/application/application-controller.vala
index eea14079..45b01187 100644
--- a/src/client/application/application-controller.vala
+++ b/src/client/application/application-controller.vala
@@ -464,6 +464,23 @@ public class Application.Controller : Geary.BaseObject {
         }
     }
 
+    /** Queues a composer to be discarded. */
+    public async void discard_composed_email(Composer.Widget composer) {
+        AccountContext? context = this.accounts.get(
+            composer.account.information
+        );
+        if (context != null) {
+            try {
+                yield context.commands.execute(
+                    new DiscardComposerCommand(this, 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());
@@ -2720,3 +2737,60 @@ private class Application.SendComposerCommand : ComposerCommand {
     }
 
 }
+
+
+private class Application.DiscardComposerCommand : ComposerCommand {
+
+
+    private const int DESTROY_TIMEOUT_SEC = 30 * 60;
+
+    public override bool can_redo {
+        get { return false; }
+    }
+
+    private Controller controller;
+
+    private Geary.TimeoutManager destroy_timer;
+
+
+    public DiscardComposerCommand(Controller controller,
+                                  Composer.Widget composer) {
+        base(composer);
+        this.controller = controller;
+
+        this.destroy_timer = new Geary.TimeoutManager.seconds(
+            DESTROY_TIMEOUT_SEC,
+            on_destroy_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 discarded"
+        ).printf(Util.Email.to_short_recipient_display(email));
+        this.destroy_timer.start();
+    }
+
+    public override async void undo(GLib.Cancellable? cancellable)
+        throws GLib.Error {
+        if (this.composer != null) {
+            this.destroy_timer.reset();
+            this.composer.set_enabled(true);
+            this.controller.show_composer(this.composer, null);
+            clear_composer();
+        } else {
+            this.undone_label = _(
+                "Composer could not be restored"
+            );
+        }
+    }
+
+    private void on_destroy_timeout() {
+        close_composer();
+    }
+
+}
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index f184eb02..b4397bcd 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -1641,8 +1641,18 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
                 );
             }
         }
+
+        if (!is_blank) {
+            // Pass on to the controller so the discarded email can be
+            // re-opened on undo
+            if (this.container != null) {
+                this.container.close();
+            }
+            yield this.application.controller.discard_composed_email(this);
+        } else {
+            // The composer is blank, so drop the mic and walk away
+            yield close();
         }
-        yield close();
     }
 
     private void update_attachments_view() {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]