From 54e591fea34c1168a48457d25a500ce9f506a13b Mon Sep 17 00:00:00 2001 From: James Booth Date: Wed, 7 Nov 2012 22:24:50 +0000 Subject: [PATCH] jabber: wait until full room roster received before showing --- src/jabber.c | 24 +++++++++++++++++++----- src/profanity.c | 11 ++++++++--- src/profanity.h | 4 +--- src/room_chat.c | 28 ++++++++++++++++++++++++++++ src/room_chat.h | 2 ++ 5 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/jabber.c b/src/jabber.c index 2df1bf41..60fe2e3d 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -655,13 +655,27 @@ _presence_handler(xmpp_conn_t * const conn, char *from = xmpp_stanza_get_attribute(stanza, "from"); + // handle chat room presence if (room_is_active(from)) { - char **tokens = g_strsplit(from, "/", 0); - char *room_jid = tokens[0]; - char *nick = tokens[1]; - if (strcmp(room_get_nick_for_room(room_jid), nick) != 0) { - prof_handle_chat_room_member(room_jid, nick); + char *room = NULL; + char *nick = NULL; + + if (!room_parse_room_jid(from, &room, &nick)) { + log_error("Could not parse room jid: %s", room); + g_free(room); + g_free(nick); + + return 1; } + + // handle self presence (means room roster has been sent) + if (strcmp(room_get_nick_for_room(room), nick) == 0) { + prof_handle_room_roster_complete(room); + } else { + room_add_to_roster(room, nick); + } + + // handle regular presence } else { char *short_from = strtok(from, "/"); char *type = xmpp_stanza_get_attribute(stanza, "type"); diff --git a/src/profanity.c b/src/profanity.c index 0e0c1fcd..21d3847b 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -35,6 +35,7 @@ #include "log.h" #include "preferences.h" #include "profanity.h" +#include "room_chat.h" #include "jabber.h" #include "ui.h" @@ -186,10 +187,14 @@ prof_handle_room_message(const char * const room_jid, const char * const nick, } void -prof_handle_chat_room_member(const char * const room_jid, - const char * const nick) +prof_handle_room_roster_complete(const char * const room) { - win_show_chat_room_member(room_jid, nick); + GSList *roster = room_get_roster(room); + + while (roster != NULL) { + win_show_chat_room_member(room, roster->data); + roster = g_slist_next(roster); + } } void diff --git a/src/profanity.h b/src/profanity.h index e8bd19c0..d7bbd37c 100644 --- a/src/profanity.h +++ b/src/profanity.h @@ -39,8 +39,6 @@ void prof_handle_room_history(const char * const room_jid, const char * const nick, GTimeVal tv_stamp, const char * const message); void prof_handle_room_message(const char * const room_jid, const char * const nick, const char * const message); -void -prof_handle_chat_room_member(const char * const room_jid, - const char * const nick); +void prof_handle_room_roster_complete(const char * const room); #endif diff --git a/src/room_chat.c b/src/room_chat.c index dd8ae91a..6b560bbf 100644 --- a/src/room_chat.c +++ b/src/room_chat.c @@ -28,6 +28,7 @@ typedef struct _muc_room_t { char *jid; char *nick; + GSList *roster; } muc_room; GHashTable *rooms = NULL; @@ -45,6 +46,7 @@ room_join(const char * const jid, const char * const nick) muc_room *new_room = malloc(sizeof(muc_room)); new_room->jid = strdup(jid); new_room->nick = strdup(nick); + new_room->roster = NULL; g_hash_table_insert(rooms, strdup(jid), new_room); } @@ -107,6 +109,28 @@ room_parse_room_jid(const char * const room_jid, char **room, char **nick) } } +void +room_add_to_roster(const char * const jid, const char * const nick) +{ + muc_room *room = g_hash_table_lookup(rooms, jid); + + if (room != NULL) { + room->roster = g_slist_append(room->roster, strdup(nick)); + } +} + +GSList * +room_get_roster(const char * const jid) +{ + muc_room *room = g_hash_table_lookup(rooms, jid); + + if (room != NULL) { + return room->roster; + } else { + return NULL; + } +} + static void _room_free(muc_room *room) { @@ -119,6 +143,10 @@ _room_free(muc_room *room) g_free(room->nick); room->nick = NULL; } + if (room->roster != NULL) { + g_slist_free_full(room->roster, g_free); + room->roster = NULL; + } g_free(room); } room = NULL; diff --git a/src/room_chat.h b/src/room_chat.h index 41f93c62..58e309a1 100644 --- a/src/room_chat.h +++ b/src/room_chat.h @@ -28,3 +28,5 @@ gboolean room_is_active(const char * const jid); char * room_get_nick_for_room(const char * const jid); gboolean room_parse_room_jid(const char * const room_jid, char **room, char **nick); +void room_add_to_roster(const char * const jid, const char * const nick); +GSList * room_get_roster(const char * const jid);