/soc/2015/jgeboski/facebook: d8e50d403e82: facebook: display ima...

James Geboski jgeboski at gmail.com
Wed Aug 19 21:50:24 EDT 2015


Changeset: d8e50d403e82a68c63ca23779f384e1c7cedda1d
Author:	 James Geboski <jgeboski at gmail.com>
Date:	 2015-08-19 21:50 -0400
Branch:	 facebook
URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/d8e50d403e82

Description:

facebook: display images in-line

diffstat:

 libpurple/protocols/facebook/api.c      |   6 ++
 libpurple/protocols/facebook/api.h      |   6 ++-
 libpurple/protocols/facebook/data.c     |  11 +++++
 libpurple/protocols/facebook/data.h     |  10 ++++
 libpurple/protocols/facebook/facebook.c |  69 ++++++++++++++++++++++++++++++--
 5 files changed, 96 insertions(+), 6 deletions(-)

diffs (207 lines):

diff --git a/libpurple/protocols/facebook/api.c b/libpurple/protocols/facebook/api.c
--- a/libpurple/protocols/facebook/api.c
+++ b/libpurple/protocols/facebook/api.c
@@ -1236,8 +1236,11 @@ fb_api_message_parse_attach(FbApi *api, 
 		url = fb_json_values_next_str(values, NULL);
 
 		if ((str != NULL) && g_str_has_prefix(str, "image/")) {
+			msg->flags |= FB_API_MESSAGE_FLAG_IMAGE;
 			msg->text = g_strdup(url);
 			mptr = fb_api_message_dup(msg, FALSE);
+
+			msg->flags &= ~FB_API_MESSAGE_FLAG_IMAGE;
 			msgs = g_slist_prepend(msgs, mptr);
 			continue;
 		}
@@ -2080,8 +2083,11 @@ fb_api_cb_unread_parse_attach(FbApi *api
 		url = fb_json_values_next_str(values, NULL);
 
 		if ((str != NULL) && g_str_has_prefix(str, "image/")) {
+			msg->flags |= FB_API_MESSAGE_FLAG_IMAGE;
 			msg->text = g_strdup(url);
 			mptr = fb_api_message_dup(msg, FALSE);
+
+			msg->flags &= ~FB_API_MESSAGE_FLAG_IMAGE;
 			msgs = g_slist_prepend(msgs, mptr);
 			continue;
 		}
diff --git a/libpurple/protocols/facebook/api.h b/libpurple/protocols/facebook/api.h
--- a/libpurple/protocols/facebook/api.h
+++ b/libpurple/protocols/facebook/api.h
@@ -265,13 +265,17 @@ typedef enum
 
 /**
  * FbApiMessageFlags:
+ * @FB_API_MESSAGE_FLAG_DONE: The text has been processed.
+ * @FB_API_MESSAGE_FLAG_IMAGE: The text is a URL to an image.
  * @FB_API_MESSAGE_FLAG_SELF: The text is from the #FbApi user.
  *
  * The #FbApiMessage flags.
  */
 typedef enum
 {
-	FB_API_MESSAGE_FLAG_SELF = 1 << 0
+	FB_API_MESSAGE_FLAG_DONE = 1 << 0,
+	FB_API_MESSAGE_FLAG_IMAGE = 1 << 1,
+	FB_API_MESSAGE_FLAG_SELF = 1 << 2
 } FbApiMessageFlags;
 
 /**
diff --git a/libpurple/protocols/facebook/data.c b/libpurple/protocols/facebook/data.c
--- a/libpurple/protocols/facebook/data.c
+++ b/libpurple/protocols/facebook/data.c
@@ -382,6 +382,17 @@ fb_data_add_message(FbData *fata, FbApiM
 	g_queue_push_tail(priv->msgs, msg);
 }
 
+void
+fb_data_remove_message(FbData *fata, FbApiMessage *msg)
+{
+	FbDataPrivate *priv;
+
+	g_return_if_fail(FB_IS_DATA(fata));
+	priv = fata->priv;
+
+	g_queue_remove(priv->msgs, msg);
+}
+
 GSList *
 fb_data_take_messages(FbData *fata, FbId uid)
 {
diff --git a/libpurple/protocols/facebook/data.h b/libpurple/protocols/facebook/data.h
--- a/libpurple/protocols/facebook/data.h
+++ b/libpurple/protocols/facebook/data.h
@@ -278,6 +278,16 @@ void
 fb_data_add_message(FbData *fata, FbApiMessage *msg);
 
 /**
+ * fb_data_remove_message:
+ * @fata: The #FbData.
+ * @msg: The #FbApiMessage.
+ *
+ * Removes an #FbApiMessage from the #FbData.
+ */
+void
+fb_data_remove_message(FbData *fata, FbApiMessage *msg);
+
+/**
  * fb_data_take_messages:
  * @fata: The #FbData.
  * @uid: The user #FbId.
diff --git a/libpurple/protocols/facebook/facebook.c b/libpurple/protocols/facebook/facebook.c
--- a/libpurple/protocols/facebook/facebook.c
+++ b/libpurple/protocols/facebook/facebook.c
@@ -33,6 +33,8 @@
 #include "conversations.h"
 #include "conversationtypes.h"
 #include "glibcompat.h"
+#include "image.h"
+#include "image-store.h"
 #include "message.h"
 #include "notify.h"
 #include "plugins.h"
@@ -405,8 +407,49 @@ fb_cb_api_events(FbApi *api, GSList *eve
 }
 
 static void
+fb_cb_image(FbDataImage *img, GError *error)
+{
+	const gchar *url;
+	FbApi *api;
+	FbApiMessage *msg;
+	FbData *fata;
+	gsize size;
+	GSList *msgs = NULL;
+	guint id;
+	guint8 *image;
+	PurpleImage *pimg;
+
+	fata = fb_data_image_get_fata(img);
+	msg = fb_data_image_get_data(img);
+	fb_data_remove_message(fata, msg);
+
+	if (G_UNLIKELY(error != NULL)) {
+		url = fb_data_image_get_url(img);
+		fb_util_debug_warning("Failed to retrieve image %s: %s",
+		                      url, error->message);
+		return;
+	}
+
+	api = fb_data_get_api(fata);
+	image = fb_data_image_dup_image(img, &size);
+	pimg = purple_image_new_from_data(image, size);
+	id = purple_image_store_add_weak(pimg);
+
+	g_free(msg->text);
+	msg->text = g_strdup_printf("<img src=\""
+	                            PURPLE_IMAGE_STORE_PROTOCOL
+	                            "%u\">", id);
+	msg->flags |= FB_API_MESSAGE_FLAG_DONE;
+
+	msgs = g_slist_prepend(msgs, msg);
+	fb_cb_api_messages(api, msgs, fata);
+	g_slist_free_full(msgs, (GDestroyNotify) fb_api_message_free);
+}
+
+static void
 fb_cb_api_messages(FbApi *api, GSList *msgs, gpointer data)
 {
+	const gchar *text;
 	FbApiMessage *msg;
 	FbData *fata = data;
 	gboolean mark;
@@ -429,12 +472,10 @@ fb_cb_api_messages(FbApi *api, GSList *m
 
 	for (l = msgs; l != NULL; l = l->next) {
 		msg = l->data;
-		html = purple_markup_escape_text(msg->text, -1);
 		FB_ID_TO_STR(msg->uid, uid);
 
 		if (purple_blist_find_buddy(acct, uid) == NULL) {
-			msg = fb_api_message_dup(msg, FALSE);
-			msg->text = html;
+			msg = fb_api_message_dup(msg, TRUE);
 			fb_data_add_message(fata, msg);
 			fb_api_contact(api, msg->uid);
 			continue;
@@ -443,12 +484,30 @@ fb_cb_api_messages(FbApi *api, GSList *m
 		self = (msg->flags & FB_API_MESSAGE_FLAG_SELF) != 0;
 		flags = self ? PURPLE_MESSAGE_SEND : PURPLE_MESSAGE_RECV;
 
+		if (msg->flags & FB_API_MESSAGE_FLAG_IMAGE) {
+			if (!(msg->flags & FB_API_MESSAGE_FLAG_DONE)) {
+				msg = fb_api_message_dup(msg, TRUE);
+				fb_data_image_add(fata, msg->text,
+				                  fb_cb_image, msg);
+				fb_data_add_message(fata, msg);
+				fb_data_image_queue(fata);
+				continue;
+			}
+
+			flags |= PURPLE_MESSAGE_IMAGES;
+			text = msg->text;
+			html = NULL;
+		} else {
+			html = purple_markup_escape_text(msg->text, -1);
+			text = html;
+		}
+
 		if (msg->tid == 0) {
 			if (mark && !self) {
 				fb_data_set_unread(fata, msg->uid, TRUE);
 			}
 
-			fb_util_serv_got_im(gc, uid, html, flags, time(NULL));
+			fb_util_serv_got_im(gc, uid, text, flags, time(NULL));
 			g_free(html);
 			continue;
 		}
@@ -473,7 +532,7 @@ fb_cb_api_messages(FbApi *api, GSList *m
 			fb_data_set_unread(fata, msg->tid, TRUE);
 		}
 
-		fb_util_serv_got_chat_in(gc, id, uid, html, flags, time(NULL));
+		fb_util_serv_got_chat_in(gc, id, uid, text, flags, time(NULL));
 		g_free(html);
 	}
 }



More information about the Commits mailing list