soc.2009.telepathy: 63a09f4b: Proper support for XMPP-like scrollback ...
sttwister at soc.pidgin.im
sttwister at soc.pidgin.im
Wed Jul 15 12:56:16 EDT 2009
-----------------------------------------------------------------
Revision: 63a09f4bc6b6a86724b97316c00e40558e6fa65d
Ancestor: 230a1e3c78497ff93f3d1f181255e2a33705560f
Author: sttwister at soc.pidgin.im
Date: 2009-07-15T16:51:38
Branch: im.pidgin.soc.2009.telepathy
URL: http://d.pidgin.im/viewmtn/revision/info/63a09f4bc6b6a86724b97316c00e40558e6fa65d
Modified files:
libpurple/protocols/telepathy/telepathy_channel_text.c
libpurple/protocols/telepathy/telepathy_channel_text.h
ChangeLog:
Proper support for XMPP-like scrollback messages
-------------- next part --------------
============================================================
--- libpurple/protocols/telepathy/telepathy_channel_text.c 8165efb01127ec026e125676d5d60cb25484910e
+++ libpurple/protocols/telepathy/telepathy_channel_text.c 5538db5af85c645ad0363e69033ecae3a353be7a
@@ -113,6 +113,97 @@ static void
}
static void
+get_contacts_for_scrollback_cb (TpConnection *connection,
+ guint n_contacts,
+ TpContact * const *contacts,
+ guint n_failed,
+ const TpHandle *failed,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ telepathy_scrollback_messages *tp_messages = user_data;
+ telepathy_room_channel *tp_channel = tp_messages->channel_data;
+
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Error while getting contacts for scrollback: %s\n",
+ error->message);
+ }
+ else
+ {
+ int i;
+
+ if (n_failed > 0)
+ {
+ purple_debug_info("telepathy", "Failed to fetch %u contacts for scrollback\n",
+ n_failed);
+ }
+ /* Cache the contacts */
+ for (i = 0; i<n_contacts; ++i)
+ {
+ TpContact *contact = contacts[i];
+
+ TpHandle handle = tp_contact_get_handle(contact);
+
+ g_hash_table_insert(tp_channel->contacts, (gpointer)handle, contact);
+ }
+
+ /* We are now ready to print the messages */
+ for (i = 0; i<tp_messages->messages->len; ++i)
+ {
+ telepathy_message tp_message = g_array_index(tp_messages->messages,
+ telepathy_message, i);
+
+ chat_got_message(tp_channel,
+ tp_message.msg_id,
+ tp_message.timestamp,
+ tp_message.sender,
+ tp_message.type,
+ tp_message.flags,
+ tp_message.msg);
+
+ g_free(tp_message.msg);
+ }
+
+ /* Remove the cached contacts */
+ for (i = 0; i<n_contacts; ++i)
+ {
+ TpContact *contact = contacts[i];
+
+ TpHandle handle = tp_contact_get_handle(contact);
+
+ g_hash_table_remove(tp_channel->contacts, (gpointer)handle);
+ }
+
+ }
+
+ g_array_free(tp_messages->messages, TRUE);
+ g_array_free(tp_messages->handles, TRUE);
+
+ g_free(tp_messages);
+}
+
+static void
+chat_got_scrollback_messages (telepathy_connection *data,
+ telepathy_scrollback_messages *tp_messages)
+{
+ GArray *handles = tp_messages->handles;
+
+ const TpContactFeature features[] = {
+ TP_CONTACT_FEATURE_ALIAS,
+ };
+
+ purple_debug_info("telepathy", "Requesting %u contacts for scrollback\n", handles->len);
+
+ tp_connection_get_contacts_by_handle(data->connection,
+ handles->len, (TpHandle *)handles->data,
+ G_N_ELEMENTS (features), features,
+ get_contacts_for_scrollback_cb, tp_messages,
+ NULL, NULL);
+}
+
+static void
chat_list_pending_messages_cb (TpChannel *proxy,
const GPtrArray *out_Pending_Messages,
const GError *error,
@@ -138,6 +229,8 @@ chat_list_pending_messages_cb (TpChanne
telepathy_room_channel *tp_channel = g_hash_table_lookup(
data->room_Channels, (gpointer)handle);
+ telepathy_scrollback_messages *tp_messages;
+
if (tp_channel == NULL)
{
purple_debug_warning("telepathy", "Pending message from %s,"
@@ -145,21 +238,61 @@ chat_list_pending_messages_cb (TpChanne
return;
}
+ /* We need to check if we already know who sent the messages. In case of
+ * scrollback messages, the user that sent the message might not be in
+ * the channel when we join, so we must request a TpContact for that handle.
+ *
+ * In order to keep the chronology of the messages, we'll check the sender
+ * of all the messages, and only after that can we print all messages.
+ */
+
+
+ /* This struct will keep all the messages and the handles we need to query */
+ tp_messages = g_new(telepathy_scrollback_messages, 1);
+
+ /* This will keep the messages, including all information */
+ tp_messages->messages = g_array_new(FALSE, FALSE, sizeof(telepathy_message));
+
+ /* This will keep the handles of the contacts that we need to query */
+ tp_messages->handles = g_array_new(TRUE, FALSE, sizeof(TpHandle));
+
+ tp_messages->channel_data = tp_channel;
+
for (i = 0; i<out_Pending_Messages->len; ++i)
{
/* unpack the relevant info from (uuuuus) */
GValueArray *arr = g_ptr_array_index(out_Pending_Messages, i);
- guint msg_id = g_value_get_uint(g_value_array_get_nth(arr, 0));
- guint timestamp = g_value_get_uint(g_value_array_get_nth(arr, 1));
- guint sender = g_value_get_uint(g_value_array_get_nth(arr, 2));
- guint type = g_value_get_uint(g_value_array_get_nth(arr, 3));
- guint flags = g_value_get_uint(g_value_array_get_nth(arr, 4));
- gchar *msg = (gchar *)g_value_get_string(g_value_array_get_nth(arr, 5));
+ telepathy_message tp_message;
+ TpContact *contact;
- /* Forward the message to purple-land */
- chat_got_message(tp_channel, msg_id, timestamp, sender, type, flags, msg);
+ tp_message.msg_id = g_value_get_uint(g_value_array_get_nth(arr, 0));
+ tp_message.timestamp = g_value_get_uint(g_value_array_get_nth(arr, 1));
+ tp_message.sender = g_value_get_uint(g_value_array_get_nth(arr, 2));
+ tp_message.type = g_value_get_uint(g_value_array_get_nth(arr, 3));
+ tp_message.flags = g_value_get_uint(g_value_array_get_nth(arr, 4));
+ tp_message.msg = g_strdup(g_value_get_string(g_value_array_get_nth(arr, 5)));
+
+ /* Save the message in the array */
+ g_array_append_val(tp_messages->messages, tp_message);
+
+ /* We must check if the sender of this message has already been cached */
+ contact = g_hash_table_lookup(
+ tp_channel->contacts, (gpointer)tp_message.sender);
+
+ if (contact == NULL)
+ {
+ /* We don't know this handle, so we'll request a contact for it */
+ purple_debug_info("telepathy", "Handle %u is not known, "
+ "requesting a contact for scrollback\n",
+ tp_message.sender);
+
+ g_array_append_val(tp_messages->handles, tp_message.sender);
+ }
}
+
+ /* Fetch the needed contacts and finally print those messages */
+ chat_got_scrollback_messages(data, tp_messages);
}
}
============================================================
--- libpurple/protocols/telepathy/telepathy_channel_text.h 696d427959ccb30ad4dd15acccd53766efcaf072
+++ libpurple/protocols/telepathy/telepathy_channel_text.h 3e5b06e1e75675021a5fd2891b3146fd8b49b675
@@ -44,6 +44,26 @@ typedef struct
typedef struct
{
+ guint msg_id;
+ guint timestamp;
+ guint sender;
+ guint type;
+ guint flags;
+ gchar *msg;
+
+} telepathy_message;
+
+typedef struct
+{
+ GArray *messages;
+ GArray *handles;
+
+ telepathy_room_channel *channel_data;
+
+} telepathy_scrollback_messages;
+
+typedef struct
+{
telepathy_room_channel *tp_channel;
gchar *msg;
More information about the Commits
mailing list