[geary/wip/765516-gtk-widget-conversation-viewer: 46/207] Reenable and update code for inline message image display.
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/765516-gtk-widget-conversation-viewer: 46/207] Reenable and update code for inline message image display.
- Date: Tue, 4 Oct 2016 00:00:17 +0000 (UTC)
commit 22e67655ac97de522e9eed8dff8679d447b317c8
Author: Michael James Gratton <mike vee net>
Date: Wed Apr 13 00:08:14 2016 +1000
Reenable and update code for inline message image display.
Use a GtkInfoBar to display to the user the message and related buttons
instead of the message-inline HTML approach. Still needs some additional
work to save per-message loading and displaying images from same sender
in convo when "Always Show" is chosen.
* src/client/conversation-viewer/conversation-message.vala: Reenable
remote image related code, remove HTML-based UI management code.
* src/client/components/main-window.vala (MainWindow::set_styling):
Add some theme CSS to style the remote images infobar.
* ui/conversation-message.ui: Add the remote images infobar.
.../conversation-viewer/conversation-message.vala | 204 +++++++++-----------
ui/conversation-message.ui | 99 ++++++++++
ui/geary.css | 4 +
3 files changed, 198 insertions(+), 109 deletions(-)
---
diff --git a/src/client/conversation-viewer/conversation-message.vala
b/src/client/conversation-viewer/conversation-message.vala
index d58cfec..dc1c827 100644
--- a/src/client/conversation-viewer/conversation-message.vala
+++ b/src/client/conversation-viewer/conversation-message.vala
@@ -102,6 +102,9 @@ public class ConversationMessage : Gtk.Box {
[GtkChild]
private Gtk.Label bad_link_label;
+ [GtkChild]
+ private Gtk.InfoBar remote_images_infobar;
+
// The folder containing the message
private Geary.Folder containing_folder = null; // XXX weak??
@@ -440,32 +443,21 @@ public class ConversationMessage : Gtk.Box {
});
web_view.load_string(body_text, "text/html", "UTF8", "");
- // XXX The following will probably need to happen after the
- // message has been loaded.
-
- // if (remote_images) {
- // Geary.Contact contact = containing_folder.account.get_contact_store().get_by_rfc822(
- // email.get_primary_originator());
- // bool always_load = contact != null && contact.always_load_remote_images();
+ if (remote_images) {
+ Geary.Contact contact = containing_folder.account.get_contact_store().get_by_rfc822(
+ email.get_primary_originator());
+ bool always_load = contact != null && contact.always_load_remote_images();
- // if (always_load || email.load_remote_images().is_certain()) {
- // show_images_email(div_message, false);
- // } else {
- // WebKit.DOM.HTMLElement remote_images_bar =
- // Util.DOM.select(div_message, ".remote_images");
- // try {
- // ((WebKit.DOM.Element) remote_images_bar).get_class_list().add("show");
- // remote_images_bar.set_inner_html("""%s %s
- // <input type="button" value="%s" class="show_images" />
- // <input type="button" value="%s" class="show_from" />""".printf(
- // remote_images_bar.get_inner_html(),
- // _("This message contains remote images."), _("Show Images"),
- // _("Always Show From Sender")));
- // } catch (Error error) {
- // warning("Error showing remote images bar: %s", error.message);
- // }
- // }
- // }
+ if (always_load || email.load_remote_images().is_certain()) {
+ web_view.notify["load-status"].connect((source, param) => {
+ if (web_view.load_status == WebKit.LoadStatus.FINISHED) {
+ show_images(false);
+ }
+ });
+ } else {
+ remote_images_infobar.show();
+ }
+ }
}
// This delegate is called from within Geary.RFC822.Message.get_body while assembling the plain
@@ -642,90 +634,6 @@ public class ConversationMessage : Gtk.Box {
// get_viewer().mark_read();
// }
- // private void on_show_images() {
- // show_images(true);
- // }
-
- // private void on_show_images_from() {
- // Geary.ContactStore contact_store =
- // containing_folder.account.get_contact_store();
- // Geary.Contact? contact = contact_store.get_by_rfc822(email.get_primary_originator());
- // if (contact == null) {
- // debug("Couldn't find contact for %s", email.from.to_string());
- // return;
- // }
-
- // Geary.ContactFlags flags = new Geary.ContactFlags();
- // flags.add(Geary.ContactFlags.ALWAYS_LOAD_REMOTE_IMAGES);
- // Gee.ArrayList<Geary.Contact> contact_list = new Gee.ArrayList<Geary.Contact>();
- // contact_list.add(contact);
- // contact_store.mark_contacts_async.begin(contact_list, flags, null);
-
- // WebKit.DOM.Document document = web_view.get_dom_document();
- // try {
- // WebKit.DOM.NodeList nodes = document.query_selector_all(".email");
- // for (ulong i = 0; i < nodes.length; i ++) {
- // WebKit.DOM.Element? email_element = nodes.item(i) as WebKit.DOM.Element;
- // if (email_element != null) {
- // string? address = null;
- // WebKit.DOM.Element? address_el = email_element.query_selector(".address_value");
- // if (address_el != null) {
- // address = ((WebKit.DOM.HTMLElement) address_el).get_inner_text();
- // } else {
- // address_el = email_element.query_selector(".address_name");
- // if (address_el != null)
- // address = ((WebKit.DOM.HTMLElement) address_el).get_inner_text();
- // }
- // if (address != null && address.normalize().casefold() == contact.normalized_email)
- // show_images(false);
- // }
- // }
- // } catch (Error error) {
- // debug("Error showing images: %s", error.message);
- // }
- // }
-
- // private void show_images(bool remember) {
- // WebKit.DOM.Element email_element = get_email_element();
- // try {
- // WebKit.DOM.NodeList body_nodes = email_element.query_selector_all(".body");
- // for (ulong j = 0; j < body_nodes.length; j++) {
- // WebKit.DOM.Element? body = body_nodes.item(j) as WebKit.DOM.Element;
- // if (body == null)
- // continue;
-
- // WebKit.DOM.NodeList nodes = body.query_selector_all("img");
- // for (ulong i = 0; i < nodes.length; i++) {
- // WebKit.DOM.Element? element = nodes.item(i) as WebKit.DOM.Element;
- // if (element == null || !element.has_attribute("src"))
- // continue;
-
- // string src = element.get_attribute("src");
- // if (!web_view.is_always_loaded(src)) {
- // // Workaround a WebKitGTK+ 2.4.10 crash. See Bug 763933
- // element.remove_attribute("src");
- // element.set_attribute("src", web_view.allow_prefix + src);
- // }
- // }
- // }
-
- // WebKit.DOM.Element? remote_images = email_element.query_selector(".remote_images");
- // if (remote_images != null)
- // remote_images.get_class_list().remove("show");
- // } catch (Error error) {
- // warning("Error showing images: %s", error.message);
- // }
-
- // if (remember) {
- // // only add flag to load remote images if not already present
- // if (email != null && !email.load_remote_images().is_certain()) {
- // Geary.EmailFlags flags = new Geary.EmailFlags();
- // flags.add(Geary.EmailFlags.LOAD_REMOTE_IMAGES);
- //
get_viewer().mark_messages(Geary.iterate<Geary.EmailIdentifier>(email.id).to_array_list(), flags, null);
- // }
- // }
- // }
-
// private void on_attachment_clicked(string attachment_id) {
// Geary.Attachment? attachment = null;
// try {
@@ -1039,6 +947,66 @@ public class ConversationMessage : Gtk.Box {
}
}
+ private void show_images(bool remember) {
+ try {
+ WebKit.DOM.Element body = Util.DOM.select(
+ web_view.get_dom_document(), "body"
+ );
+ if (body == null) {
+ warning("Could not find message body");
+ } else {
+ WebKit.DOM.NodeList nodes = body.get_elements_by_tag_name("img");
+ for (ulong i = 0; i < nodes.length; i++) {
+ WebKit.DOM.Element? element = nodes.item(i) as WebKit.DOM.Element;
+ if (element == null || !element.has_attribute("src"))
+ continue;
+
+ string src = element.get_attribute("src");
+ if (!web_view.is_always_loaded(src)) {
+ // Workaround a WebKitGTK+ 2.4.10 crash. See Bug 763933
+ element.remove_attribute("src");
+ element.set_attribute("src", web_view.allow_prefix + src);
+ }
+ }
+ }
+ } catch (Error error) {
+ warning("Error showing images: %s", error.message);
+ }
+
+ if (remember) {
+ // only add flag to load remote images if not already present
+ if (email != null && !email.load_remote_images().is_certain()) {
+ Geary.EmailFlags flags = new Geary.EmailFlags();
+ flags.add(Geary.EmailFlags.LOAD_REMOTE_IMAGES);
+ // XXX reenable this
+ //get_viewer().mark_messages(Geary.iterate<Geary.EmailIdentifier>(email.id).to_array_list(),
flags, null);
+ }
+ }
+ }
+
+ private void always_show_images() {
+ Geary.ContactStore contact_store =
+ containing_folder.account.get_contact_store();
+ Geary.Contact? contact = contact_store.get_by_rfc822(
+ email.get_primary_originator()
+ );
+ if (contact == null) {
+ debug("Couldn't find contact for %s", email.from.to_string());
+ return;
+ }
+
+ Geary.ContactFlags flags = new Geary.ContactFlags();
+ flags.add(Geary.ContactFlags.ALWAYS_LOAD_REMOTE_IMAGES);
+ Gee.ArrayList<Geary.Contact> contact_list = new Gee.ArrayList<Geary.Contact>();
+ contact_list.add(contact);
+ contact_store.mark_contacts_async.begin(contact_list, flags, null);
+
+ show_images(false);
+
+ // XXX notify something to go load images for the rest of the
+ // messages in he current convo for this sender
+ }
+
// private bool should_show_attachment(Geary.Attachment attachment) {
// // if displayed inline, don't include in attachment list
// if (attachment.content_id in inlined_content_ids)
@@ -1293,6 +1261,24 @@ public class ConversationMessage : Gtk.Box {
body_box.set_tooltip_text(hover_url);
body_box.trigger_tooltip_query();
}
+
+
+ [GtkCallback]
+ private void on_remote_images_response(Gtk.InfoBar info_bar,
+ int response_id) {
+ switch (response_id) {
+ case 1:
+ show_images(true);
+ break;
+ case 2:
+ always_show_images();
+ break;
+ default:
+ break; // pass
+ }
+
+ remote_images_infobar.hide();
+ }
// private void on_copy_text() {
// web_view.copy_clipboard();
diff --git a/ui/conversation-message.ui b/ui/conversation-message.ui
index 4aff05c..dcde9ae 100644
--- a/ui/conversation-message.ui
+++ b/ui/conversation-message.ui
@@ -412,6 +412,105 @@
<property name="position">0</property>
</packing>
</child>
+ <child>
+ <object class="GtkInfoBar" id="remote_images_infobar">
+ <property name="app_paintable">True</property>
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="message_type">warning</property>
+ <property name="show_close_button">True</property>
+ <signal name="response" handler="on_remote_images_response" swapped="no"/>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="button1">
+ <property name="label" translatable="yes">Show Images</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button2">
+ <property name="label" translatable="yes">Always Show From Sender</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="non_homogeneous">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child internal-child="content_area">
+ <object class="GtkBox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Remote images not shown</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Only show remote images from senders you
trust.</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <action-widgets>
+ <action-widget response="1">button1</action-widget>
+ <action-widget response="2">button2</action-widget>
+ </action-widgets>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
</object>
</child>
</object>
diff --git a/ui/geary.css b/ui/geary.css
index 5d85843..bd24813 100644
--- a/ui/geary.css
+++ b/ui/geary.css
@@ -82,6 +82,10 @@ row.geary-folder-popover-list-row > label {
#ConversationMessage separator {
margin: 12px 0;
}
+#ConversationMessage infobar {
+ border-radius: 2px;
+ margin-bottom: 12px;
+}
#composer_embed headerbar {
border-radius: 0px;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]