[geary/wip/728002-webkit2: 22/96] Update how inline email attachments are loaded for viewing.



commit 410b11d8e46847274d8ff737a4aa0eadb6be9ecb
Author: Michael James Gratton <mike vee net>
Date:   Tue Oct 11 01:31:18 2016 +1100

    Update how inline email attachments are loaded for viewing.
    
    * src/client/components/client-web-view.vala
      (ClientWebView::add_inline_resource): Renamed fro add_cid_resource, to
      make it more obvious what it is useful for and updated call sites.
      (ClientWebView::add_inline_resources): New method for adding a complete
      set of inline resources.
    
    * src/client/conversation-viewer/conversation-email.vala
      (ConversationEmail::ConversationEmail): Construct a map of inline
      resources, add them to both the primary and attached messages.
      (ConversationEmail::start_loading): Only load attachments once all web
      views have been loaded, so any inline parts that were not displayed
      inline can be displayed as attachments.

 src/client/components/client-web-view.vala         |   11 ++++-
 src/client/composer/composer-widget.vala           |    2 +-
 .../conversation-viewer/conversation-email.vala    |   44 ++++++++++++++++---
 .../conversation-viewer/conversation-message.vala  |    2 +-
 4 files changed, 48 insertions(+), 11 deletions(-)
---
diff --git a/src/client/components/client-web-view.vala b/src/client/components/client-web-view.vala
index 70230ef..e81119a 100644
--- a/src/client/components/client-web-view.vala
+++ b/src/client/components/client-web-view.vala
@@ -94,13 +94,20 @@ public class ClientWebView : WebKit.WebView {
     }
 
     /**
-     * Adds a resource that may be accessed via a cid:id url.
+     * Adds an inline resource that may be accessed via a cid:id url.
      */
-    public void add_cid_resource(string id, Geary.Memory.Buffer buf) {
+    public void add_inline_resource(string id, Geary.Memory.Buffer buf) {
         this.cid_resources[id] = buf;
     }
 
     /**
+     * Adds a set of inline resource that may be accessed via a cid:id url.
+     */
+    public void add_inline_resources(Gee.Map<string,Geary.Memory.Buffer> res) {
+        this.cid_resources.set_all(res);
+    }
+
+    /**
      * Selects all content in the web view.
      */
     public void select_all() {
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index c39ffcb..fc794af 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -1533,7 +1533,7 @@ public class ComposerWidget : Gtk.EventBox {
                         // attachment instead.
                         if (part.content_id != null) {
                             this.cid_files[part.content_id] = file;
-                            this.editor.add_cid_resource(
+                            this.editor.add_inline_resource(
                                 part.content_id,
                                 new Geary.Memory.FileBuffer(file, true)
                             );
diff --git a/src/client/conversation-viewer/conversation-email.vala 
b/src/client/conversation-viewer/conversation-email.vala
index cf75a4e..cdb0183 100644
--- a/src/client/conversation-viewer/conversation-email.vala
+++ b/src/client/conversation-viewer/conversation-email.vala
@@ -418,8 +418,23 @@ public class ConversationEmail : Gtk.Box {
             });
         insert_action_group("eml", message_actions);
 
+        // Construct CID resources from attachments
+
+        Gee.Map<string,Geary.Memory.Buffer> cid_resources =
+            new Gee.HashMap<string,Geary.Memory.Buffer>();
+        foreach (Geary.Attachment att in email.attachments) {
+            if (att.content_id != null) {
+                try {
+                    cid_resources[att.content_id] =
+                        new Geary.Memory.FileBuffer(att.file, true);
+                } catch (Error err) {
+                    debug("Could not open attachment: %s", err.message);
+                }
+            }
+        }
+
         // Construct the view for the primary message, hook into it
-        
+
         Geary.RFC822.Message message;
         try {
             message = email.get_message();
@@ -433,6 +448,7 @@ public class ConversationEmail : Gtk.Box {
             contact_store,
             email.load_remote_images().is_certain()
         );
+        this.primary_message.web_view.add_inline_resources(cid_resources);
         connect_message_view_signals(this.primary_message);
 
         this.primary_message.summary.add(this.actions);
@@ -475,6 +491,7 @@ public class ConversationEmail : Gtk.Box {
             ConversationMessage attached_message =
                 new ConversationMessage(sub_message, contact_store, false);
             connect_message_view_signals(attached_message);
+            attached_message.web_view.add_inline_resources(cid_resources);
             this.sub_messages.add(attached_message);
             this._attached_messages.add(attached_message);
         }
@@ -496,11 +513,22 @@ public class ConversationEmail : Gtk.Box {
                     GearyApplication.instance.controller.avatar_session,
                     load_cancelled
                 );
+
                 return !load_cancelled.is_cancelled();
             });
 
+        // Only load attachments once the web views have finished
+        // loading, since we want to know if any attachments marked as
+        // being inline were actually not displayed inline, and hence
+        // need to be displayed as if they were attachments.
         if (!load_cancelled.is_cancelled()) {
-            yield load_attachments(load_cancelled);
+            if (this.message_bodies_loaded) {
+                yield load_attachments(load_cancelled);
+            } else {
+                this.notify["message-bodies-loaded"].connect(() => {
+                        load_attachments.begin(load_cancelled);
+                    });
+            }
         }
     }
 
@@ -636,12 +664,13 @@ public class ConversationEmail : Gtk.Box {
     }
 
     private async void load_attachments(Cancellable load_cancelled) {
-        // Do we have any attachments to be displayed? This relies on
-        // the primary and any attached message bodies having being
-        // already loaded, so that we know which attachments have been
-        // shown inline and hence do not need to be included here.
+        // Determine if we have any attachments to be displayed. This
+        // relies on the primary and any attached message bodies
+        // having being already loaded, so that we know which
+        // attachments have been shown inline and hence do not need to
+        // be included here.
         foreach (Geary.Attachment attachment in email.attachments) {
-            if (!(attachment.content_id in inlined_content_ids)) {
+            if (!(attachment.content_id in this.inlined_content_ids)) {
                 Geary.Mime.DispositionType? disposition = null;
                 if (attachment.content_disposition != null) {
                     disposition = attachment.content_disposition.disposition_type;
@@ -661,6 +690,7 @@ public class ConversationEmail : Gtk.Box {
             }
         }
 
+        // Now we can actually show the attachments, if any
         if (!this.displayed_attachments.is_empty) {
             this.attachments_button.show();
             this.attachments_button.set_sensitive(!this.is_collapsed);
diff --git a/src/client/conversation-viewer/conversation-message.vala 
b/src/client/conversation-viewer/conversation-message.vala
index d258fc1..5a07459 100644
--- a/src/client/conversation-viewer/conversation-message.vala
+++ b/src/client/conversation-viewer/conversation-message.vala
@@ -729,7 +729,7 @@ public class ConversationMessage : Gtk.Grid {
             id = REPLACED_CID_TEMPLATE.printf(this.next_replaced_buffer_number++);
         }
 
-        this.web_view.add_cid_resource(id, buffer);
+        this.web_view.add_inline_resource(id, buffer);
 
         return "<img alt=\"%s\" class=\"%s\" src=\"%s%s\" />".printf(
             Geary.HTML.escape_markup(filename),


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