[geary/wip/794700-lazy-load-conversations: 11/19] Ensure selecting a new conversation can interrupt any currrent load



commit b87eab93559b8cd384a134aa22b53d1bf11c6053
Author: Michael Gratton <mike vee net>
Date:   Fri Jan 18 15:46:38 2019 +1100

    Ensure selecting a new conversation can interrupt any currrent load
    
    Not 100% prefect, but getting better.

 .../conversation-viewer/conversation-list-box.vala | 34 +++++++++++++++-----
 .../conversation-viewer/conversation-viewer.vala   | 36 ++++++++++++++--------
 2 files changed, 51 insertions(+), 19 deletions(-)
---
diff --git a/src/client/conversation-viewer/conversation-list-box.vala 
b/src/client/conversation-viewer/conversation-list-box.vala
index c10919a5..1972f4e5 100644
--- a/src/client/conversation-viewer/conversation-list-box.vala
+++ b/src/client/conversation-viewer/conversation-list-box.vala
@@ -426,7 +426,7 @@ public class ConversationListBox : Gtk.ListBox, Geary.BaseInterface {
         base.destroy();
     }
 
-    public async void load_conversation()
+    public async void load_conversation(Geary.SearchQuery? query)
         throws GLib.Error {
         set_sort_func(null);
 
@@ -501,18 +501,25 @@ public class ConversationListBox : Gtk.ListBox, Geary.BaseInterface {
             bool added = false;
             Gtk.Adjustment listbox_adj = get_adjustment();
             foreach (Geary.Email email in uninteresting) {
+                // Give GTK a moment to process newly added rows, so
+                // when updating the adjustment below the values are
+                // valid. Priority must be low otherwise other async
+                // tasks (like cancelling loading if another
+                // conversation is selected) won't get a look in until
+                // this is done.
+                GLib.Idle.add(
+                    this.load_conversation.callback, GLib.Priority.LOW
+                );
+                yield;
+
+                // Check for cancellation after resuming in case the
+                // load was cancelled in the mean time.
                 if (this.cancellable.is_cancelled()) {
                     throw new GLib.IOError.CANCELLED(
                         "Conversation load cancelled"
                     );
                 }
 
-                // Give GTK a moment to process newly added rows, so
-                // when updating the adjustment below the values are
-                // valid
-                GLib.Idle.add(this.load_conversation.callback);
-                yield;
-
                 EmailRow row = add_email(email, false);
                 // Drafts aren't interesting?
                 if (row.view.is_draft) {
@@ -538,6 +545,19 @@ public class ConversationListBox : Gtk.ListBox, Geary.BaseInterface {
         }
 
         set_sort_func(on_sort);
+
+        if (query != null) {
+            // XXX this sucks for large conversations because it can take
+            // a long time for the load to complete and hence for
+            // matches to show up.
+            highlight_matching_email(query);
+        }
+    }
+
+    /** Cancels loading the current conversation, if still in progress */
+    public void cancel_conversation_load() {
+        this.loading_timeout.reset();
+        this.cancellable.cancel();
     }
 
     /**
diff --git a/src/client/conversation-viewer/conversation-viewer.vala 
b/src/client/conversation-viewer/conversation-viewer.vala
index e7393b39..4a542fcc 100644
--- a/src/client/conversation-viewer/conversation-viewer.vala
+++ b/src/client/conversation-viewer/conversation-viewer.vala
@@ -201,8 +201,7 @@ public class ConversationViewer : Gtk.Stack, Geary.BaseInterface {
      */
     public async void load_conversation(Geary.App.Conversation conversation,
                                         Geary.App.EmailStore email_store,
-                                        Application.AvatarStore avatar_store)
-        throws GLib.Error {
+                                        Application.AvatarStore avatar_store) {
         remove_current_list();
 
         ConversationListBox new_list = new ConversationListBox(
@@ -235,8 +234,6 @@ public class ConversationViewer : Gtk.Stack, Geary.BaseInterface {
         add_new_list(new_list);
         set_visible_child(this.conversation_page);
 
-        yield new_list.load_conversation();
-
         // Highlight matching terms from find if active, otherwise
         // from the search folder if that's where we are at
         Geary.SearchQuery? query = get_find_search_query(
@@ -249,9 +246,24 @@ public class ConversationViewer : Gtk.Stack, Geary.BaseInterface {
                 query = search_folder.search_query;
             }
         }
-        if (query != null) {
-            new_list.highlight_matching_email.begin(query);
-        }
+
+        // Launch this as a background task so that additional
+        // conversation selection events can get processed before
+        // loading this one has completed.
+        //
+        // XXX we really should be yielding until the first
+        // interesting email has been loaded, and the rest should be
+        // loaded in he background.
+        new_list.load_conversation.begin(
+            query,
+            (obj, res) => {
+                try {
+                    new_list.load_conversation.end(res);
+                } catch (GLib.Error err) {
+                    debug("Error loading conversation: %s", err.message);
+                }
+            }
+        );
     }
 
     // Add a new conversation list to the UI
@@ -272,15 +284,15 @@ public class ConversationViewer : Gtk.Stack, Geary.BaseInterface {
 
     // Remove any existing conversation list, cancelling its loading
     private void remove_current_list() {
-        // XXX GTK+ Bug 778190 workaround
-        this.conversation_scroller.destroy();
-        new_conversation_scroller();
-
-        // Notify that the current list was removed
         if (this.current_list != null) {
+            this.current_list.cancel_conversation_load();
             this.conversation_removed(this.current_list);
             this.current_list = null;
         }
+
+        // XXX GTK+ Bug 778190 workaround
+        this.conversation_scroller.destroy(); // removes the list
+        new_conversation_scroller();
     }
 
     private void new_conversation_scroller() {


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