/dev/tomkiewicz/new-smileys: 222e69060b4a: Remote smileys: displ...
Tomasz Wasilczyk
twasilczyk at pidgin.im
Fri Apr 4 14:30:17 EDT 2014
Changeset: 222e69060b4a3a10fa1b8f29b25d35df6409ffcd
Author: Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date: 2014-04-04 20:30 +0200
Branch: default
URL: https://hg.pidgin.im/dev/tomkiewicz/new-smileys/rev/222e69060b4a
Description:
Remote smileys: display them even on the first time
diffstat:
libpurple/conversation.c | 3 ++
libpurple/smiley-remote.c | 14 +++++++----
pidgin/gtkconv.c | 56 ++++++++++++++++++++++++++++++++++++++++++--
pidgin/themes/Template.html | 27 ++++++++++++++++++++-
4 files changed, 90 insertions(+), 10 deletions(-)
diffs (177 lines):
diff --git a/libpurple/conversation.c b/libpurple/conversation.c
--- a/libpurple/conversation.c
+++ b/libpurple/conversation.c
@@ -965,6 +965,9 @@ purple_conversation_add_remote_smiley(Pu
return NULL;
}
+ /* TODO: connect to the failed signal, to make it possible returning this smiley object again (later). Maybe just remove from the list on fail */
+ /* TODO: test it by doing failed on the first retrieval, succ on the second */
+
/* smiley was already added */
if (smiley)
return NULL;
diff --git a/libpurple/smiley-remote.c b/libpurple/smiley-remote.c
--- a/libpurple/smiley-remote.c
+++ b/libpurple/smiley-remote.c
@@ -42,18 +42,18 @@ enum
PROP_0,
PROP_LAST
};
+#endif
enum
{
- SIG_READY,
+ SIG_FAILED,
SIG_LAST
};
-#endif
static GObjectClass *parent_class;
+static guint signals[SIG_LAST];
#if 0
-static guint signals[SIG_LAST];
static GParamSpec *properties[PROP_LAST];
#endif
@@ -104,7 +104,7 @@ purple_remote_smiley_close(PurpleRemoteS
priv->contents = NULL;
g_object_set(smiley, "is-ready", TRUE, NULL);
- /* TODO: call ready signal */
+ g_signal_emit_by_name(smiley, "ready");
}
void
@@ -120,7 +120,7 @@ purple_remote_smiley_failed(PurpleRemote
return;
g_object_set(smiley, "failed", TRUE, NULL);
- /* TODO: call failed signal */
+ g_signal_emit(smiley, signals[SIG_FAILED], 0);
}
static PurpleStoredImage *
@@ -222,6 +222,10 @@ purple_remote_smiley_class_init(PurpleRe
g_object_class_install_properties(gobj_class, PROP_LAST, properties);
#endif
+
+ signals[SIG_FAILED] = g_signal_new("failed", G_OBJECT_CLASS_TYPE(klass),
+ 0, 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}
GType
diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c
--- 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, P
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
--- 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(){
More information about the Commits
mailing list