From 6d5b0bc5b6ee45b6f31ba53d98c6a6c77e5ce2cd Mon Sep 17 00:00:00 2001
From: Michael Gratton <mike@vee.net>
Date: Sun, 25 Oct 2020 18:57:47 +1100
Subject: [PATCH 114/124] Composer.Widget: Rework draft manager management

Since the draft manager will now block until a remote for the draft
folder has been obtained, it now must be ensured that all calls to
opening the manager are backgrounded so that the UI isn't blocked
when offline.
---
 src/client/composer/composer-widget.vala | 76 ++++++++++++++++--------
 1 file changed, 50 insertions(+), 26 deletions(-)

diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index fe29011d..61e3a84c 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -971,7 +971,21 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
         this.header.set_sensitive(enabled);
 
         if (enabled) {
-            this.open_draft_manager.begin(this.saved_id, null);
+            var current_account = this.sender_context.account;
+            this.open_draft_manager.begin(
+                this.saved_id,
+                (obj, res) => {
+                    try {
+                        this.open_draft_manager.end(res);
+                    } catch (GLib.Error error) {
+                        this.application.report_problem(
+                            new Geary.AccountProblemReport(
+                                current_account.information, error
+                            )
+                        );
+                    }
+                }
+            );
         } else {
             if (this.container != null) {
                 this.container.close();
@@ -984,7 +998,7 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
     public async void set_save_to_override(Geary.Folder? save_to)
         throws GLib.Error {
         this.save_to = save_to;
-        yield reopen_draft_manager();
+        this.reopen_draft_manager.begin();
     }
 
     /**
@@ -1423,11 +1437,21 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
             is_body_complete
         );
 
-        try {
-            yield open_draft_manager(this.saved_id);
-        } catch (Error e) {
-            debug("Could not open draft manager: %s", e.message);
-        }
+        var current_account = this.sender_context.account;
+        this.open_draft_manager.begin(
+            this.saved_id,
+            (obj, res) => {
+                try {
+                    this.open_draft_manager.end(res);
+                } catch (GLib.Error error) {
+                    this.application.report_problem(
+                        new Geary.AccountProblemReport(
+                            current_account.information, error
+                        )
+                    );
+                }
+            }
+        );
     }
 
     private async bool should_send() {
@@ -1501,6 +1525,11 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
 
     /**
      * Creates and opens the composer's draft manager.
+     *
+     * Note that since the draft manager may block until a remote
+     * connection is open, this method may likewise do so. Hence this
+     * method typically needs to be called from the main loop as a
+     * background async task using the `begin` async call form.
      */
     private async void open_draft_manager(Geary.EmailIdentifier? editing_draft_id)
         throws GLib.Error {
@@ -1572,13 +1601,21 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
     /**
      * Closes current draft manager, if any, then opens a new one.
      */
-    private async void reopen_draft_manager()
-        throws GLib.Error {
+    private async void reopen_draft_manager() {
         // Discard the draft, if any, since it may be on a different
         // account
-        yield close_draft_manager(DISCARD);
-        yield open_draft_manager(null);
-        yield save_draft();
+        var current_account = this.sender_context.account;
+        try {
+            yield close_draft_manager(DISCARD);
+            yield open_draft_manager(null);
+            yield save_draft();
+        } catch (GLib.Error error) {
+            this.application.report_problem(
+                new Geary.AccountProblemReport(
+                    current_account.information, error
+                )
+            );
+        }
     }
 
     private async void close_draft_manager(DraftPolicy draft_policy)
@@ -2254,20 +2291,7 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
                 this.update_signature.begin(null);
                 load_entry_completions();
 
-                var current_account = this.sender_context.account;
-                this.reopen_draft_manager.begin(
-                    (obj, res) => {
-                        try {
-                            this.reopen_draft_manager.end(res);
-                        } catch (GLib.Error error) {
-                            this.application.report_problem(
-                                new Geary.AccountProblemReport(
-                                    current_account.information, error
-                                )
-                            );
-                        }
-                    }
-                );
+                this.reopen_draft_manager.begin();
             }
         }
     }
-- 
2.29.2

