summaryrefslogtreecommitdiff
path: root/pidgin
diff options
context:
space:
mode:
authorTomasz Wasilczyk <twasilczyk@pidgin.im>2014-04-04 20:30:07 +0200
committerTomasz Wasilczyk <twasilczyk@pidgin.im>2014-04-04 20:30:07 +0200
commita88104999c911c7530ebdcfc1e1d70009f3fa0c6 (patch)
tree56f832e28cd407a9af4a5c77a7c0d8acca270cd6 /pidgin
parenta0e662e12dafca38bb51d83f7d41846656892c46 (diff)
downloadpidgin-a88104999c911c7530ebdcfc1e1d70009f3fa0c6.tar.gz
Remote smileys: display them even on the first time
Diffstat (limited to 'pidgin')
-rw-r--r--pidgin/gtkconv.c56
-rw-r--r--pidgin/themes/Template.html27
2 files changed, 78 insertions, 5 deletions
diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c
index 81b641c251..fe4e88c7b6 100644
--- a/pidgin/gtkconv.c
+++ b/pidgin/gtkconv.c
@@ -6582,6 +6582,53 @@ replace_message_tokens(
return g_string_free(str, FALSE);
}
+static gulong
+pidgin_smiley_get_unique_id(PurpleSmiley *smiley)
+{
+ static gulong max_id = 0;
+ gulong id;
+ g_return_val_if_fail(smiley != NULL, 0);
+
+ id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(smiley),
+ "pidgin-conv-smiley-unique-id"));
+ if (id != 0)
+ return id;
+
+ id = ++max_id;
+
+ g_object_set_data(G_OBJECT(smiley), "pidgin-conv-smiley-unique-id",
+ GINT_TO_POINTER(id));
+
+ return id;
+}
+
+static void
+pidgin_conv_remote_smiley_got(PurpleSmiley *smiley, gpointer _conv)
+{
+ PurpleConversation *conv = _conv;
+ PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
+ PurpleStoredImage *img;
+ gulong smiley_id;
+ int image_id;
+ gchar *js;
+
+ if (!gtkconv)
+ return;
+
+ img = purple_smiley_get_image(smiley);
+ smiley_id = pidgin_smiley_get_unique_id(smiley);
+ image_id = purple_imgstore_add_with_id(img);
+
+ purple_debug_info("gtkconv", "Smiley '%s' (%ld) is ready for display",
+ purple_smiley_get_shortcut(smiley), smiley_id);
+
+ js = g_strdup_printf("emoticonIsReady(%ld, '"
+ PURPLE_STORED_IMAGE_PROTOCOL "%d')", smiley_id, image_id);
+ pidgin_webview_safe_execute_script(
+ PIDGIN_WEBVIEW(gtkconv->webview), js);
+ g_free(js);
+}
+
static void
pidgin_conv_write_smiley(GString *out, PurpleSmiley *smiley,
PurpleConversation *conv, gpointer _proto_name)
@@ -6606,9 +6653,12 @@ pidgin_conv_write_smiley(GString *out, PurpleSmiley *smiley,
PURPLE_STORED_IMAGE_PROTOCOL "%d\" />",
escaped_shortcut, escaped_shortcut, imgid);
} else {
- g_string_append_printf(out,
- "<span class=\"emoticon pending\">%s</span>",
- escaped_shortcut);
+ g_string_append_printf(out, "<span class=\"emoticon pending "
+ "emoticon-id-%ld\">%s</span>",
+ pidgin_smiley_get_unique_id(smiley), escaped_shortcut);
+ g_signal_connect_object(smiley, "ready",
+ G_CALLBACK(pidgin_conv_remote_smiley_got), conv, 0);
+
/* TODO: watch for "is-ready" state changes
* (it's not possible without conv handle here) */
/* XXX: avoid race condition between is-ready
diff --git a/pidgin/themes/Template.html b/pidgin/themes/Template.html
index bb9d180011..7562d6c609 100644
--- a/pidgin/themes/Template.html
+++ b/pidgin/themes/Template.html
@@ -236,8 +236,31 @@
//If true is passed, view will be scrolled down
function alignChat(shouldScroll) {
- if (shouldScroll)
- scrollToBottom();
+ if (!shouldScroll)
+ return;
+
+ scrollToBottom();
+ /* wait for images to load and scroll again */
+ setTimeout(scrollToBottom, 10);
+ }
+
+ function emoticonIsReady(emoticonId, url) {
+ var shouldScroll = nearBottom();
+ var emoticons;
+
+ emoticons = document.getElementsByClassName('emoticon-id-' + emoticonId);
+ for (var i = 0; i < emoticons.length; i++) {
+ var node = emoticons[i];
+ var img = document.createElement('img');
+ var alt = node.textContent.trim();
+ img.setAttribute('src', url);
+ img.setAttribute('alt', alt);
+ img.setAttribute('title', alt);
+ img.className = 'emoticon';
+ node.parentNode.replaceChild(img, node);
+ }
+
+ alignChat(shouldScroll);
}
window.onresize = function windowDidResize(){