diff options
-rw-r--r-- | matrix-room.c | 285 | ||||
-rw-r--r-- | matrix-roommembers.c | 263 | ||||
-rw-r--r-- | matrix-roommembers.h | 92 | ||||
-rw-r--r-- | matrix-sync.c | 5 |
4 files changed, 392 insertions, 253 deletions
diff --git a/matrix-room.c b/matrix-room.c index 96ba838..2d15942 100644 --- a/matrix-room.c +++ b/matrix-room.c @@ -63,6 +63,10 @@ static MatrixConnectionData *_get_connection_data_from_conversation( /* MatrixRoomMemberTable * - see below */ #define PURPLE_CONV_MEMBER_TABLE "member_table" +/* PURPLE_CONV_FLAG_* */ +#define PURPLE_CONV_FLAGS "flags" +#define PURPLE_CONV_FLAG_NEEDS_NAME_UPDATE 0x1 + /** * Get the member table for a room @@ -84,6 +88,20 @@ static MatrixRoomStateEventTable *matrix_room_get_state_table( } +static guint _get_flags(PurpleConversation *conv) +{ + return GPOINTER_TO_UINT(purple_conversation_get_data(conv, + PURPLE_CONV_FLAGS)); +} + + +static void _set_flags(PurpleConversation *conv, guint flags) +{ + purple_conversation_set_data(conv, PURPLE_CONV_FLAGS, + GUINT_TO_POINTER(flags)); +} + + /****************************************************************************** * * room state handling @@ -91,8 +109,7 @@ static MatrixRoomStateEventTable *matrix_room_get_state_table( /** - * Update the name of the room in the buddy list (which in turn will update it - * in the chat window) + * Update the name of the room in the buddy list and the chat window * * @param conv: conversation info */ @@ -100,17 +117,38 @@ static void _update_room_alias(PurpleConversation *conv) { gchar *room_name; MatrixConnectionData *conn = _get_connection_data_from_conversation(conv); - PurpleChat *chat = purple_blist_find_chat(conv->account, conv->name); + PurpleChat *chat; + guint flags; + + room_name = _get_room_name(conn, conv); + /* update the buddy list entry */ + chat = purple_blist_find_chat(conv->account, conv->name); /* we know there should be a buddy list entry for this room */ g_assert(chat != NULL); - - room_name = _get_room_name(conn, conv); purple_blist_alias_chat(chat, room_name); + + /* explicitly update the conversation title. This will tend to happen + * anyway, but possibly not until the conversation tab is next activated. + */ + if (strcmp(room_name, purple_conversation_get_title(conv))) + purple_conversation_set_title(conv, room_name); + g_free(room_name); + + flags = _get_flags(conv); + flags &= ~PURPLE_CONV_FLAG_NEEDS_NAME_UPDATE; + _set_flags(conv, flags); } +static void _schedule_name_update(PurpleConversation *conv) +{ + guint flags = _get_flags(conv); + flags |= PURPLE_CONV_FLAG_NEEDS_NAME_UPDATE; + _set_flags(conv, flags); +} + /** * Called when there is a change to the member list. Tells the MemberTable * about it. @@ -142,10 +180,16 @@ static void _on_state_update(const gchar *event_type, if(strcmp(event_type, "m.room.member") == 0) { _on_member_change(conv, state_key, new_state); + /* we schedule a room name update here regardless of whether we end up + * changing any members, because even changes to invited members can + * affect the room name. + */ + _schedule_name_update(conv); } else if(strcmp(event_type, "m.room.alias") == 0 || + strcmp(event_type, "m.room.canonical_alias") == 0 || strcmp(event_type, "m.room.room_name") == 0) { - _update_room_alias(conv); + _schedule_name_update(conv); } } @@ -158,6 +202,12 @@ void matrix_room_handle_state_event(struct _PurpleConversation *conv, } +static gint _compare_member_user_id(const MatrixRoomMember *m, + const gchar *user_id) +{ + return g_strcmp0(matrix_roommember_get_user_id(m), user_id); +} + /** * figure out the best name for a room based on its members list * @@ -175,7 +225,8 @@ static gchar *_get_room_name_from_members(MatrixConnectionData *conn, members = matrix_roommembers_get_active_members(member_table, TRUE); /* remove ourselves from the list */ - tmp = g_list_find_custom(members, conn->user_id, (GCompareFunc)strcmp); + tmp = g_list_find_custom(members, conn->user_id, + (GCompareFunc)_compare_member_user_id); if(tmp != NULL) { members = g_list_delete_link(members, tmp); } @@ -185,16 +236,15 @@ static gchar *_get_room_name_from_members(MatrixConnectionData *conn, return NULL; } - member1 = matrix_roommembers_get_displayname_for_member( - member_table, members->data); + member1 = matrix_roommember_get_displayname(members->data); if(members->next == NULL) { /* one other person */ res = g_strdup(member1); } else if(members->next->next == NULL) { /* two other people */ - const gchar *member2 = matrix_roommembers_get_displayname_for_member( - member_table, members->next->data); + const gchar *member2 = matrix_roommember_get_displayname( + members->next->data); res = g_strdup_printf(_("%s and %s"), member1, member2); } else { int nmembers = g_list_length(members); @@ -396,6 +446,7 @@ void matrix_room_handle_timeline_event(PurpleConversation *conv, const gchar *room_id, *msg_body; PurpleMessageFlags flags; const gchar *sender_display_name; + MatrixRoomMember *sender = NULL; room_id = conv->name; @@ -440,14 +491,14 @@ void matrix_room_handle_timeline_event(PurpleConversation *conv, return; } - if(sender_id == NULL) { - sender_display_name = "<unknown>"; + if(sender_id != NULL) { + MatrixRoomMemberTable *table = matrix_room_get_member_table(conv); + sender = matrix_roommembers_lookup_member(table, sender_id); + } + if (sender != NULL) { + sender_display_name = matrix_roommember_get_displayname(sender); } else { - MatrixRoomMemberTable *member_table = - matrix_room_get_member_table(conv); - - sender_display_name = matrix_roommembers_get_displayname_for_member( - member_table, sender_id); + sender_display_name = "<unknown>"; } flags = PURPLE_MESSAGE_RECV; @@ -527,56 +578,181 @@ void matrix_room_leave_chat(PurpleConversation *conv) } -static void _update_user_list(PurpleConversation *conv, +/* ***************************************************************************** + * + * Tracking of member additions/removals. + * + * We don't tell libpurple about new arrivals immediately, because that is + * inefficient and takes ages on a big room like Matrix HQ. Instead, the + * MatrixRoomMemberTable builds up a list of changes, and we then go through + * those changes after processing all of the state changes in a /sync. + * + * This introduces a complexity in that we need to track what we've told purple + * the displayname of the user is (for instance, member1 leaves a channel, + * meaning that there is no longer a clash of displaynames, so member2 + * can be renamed: we need to know what we previously told libpurple member2 was + * called). We do this by setting the member's opaque data to the name we gave + * to libpurple. + */ + + +static void _on_member_deleted(MatrixRoomMember *member) +{ + gchar *displayname = matrix_roommember_get_opaque_data(member); + g_free(displayname); + matrix_roommember_set_opaque_data(member, NULL, NULL); +} + + +/** + * Tell libpurple about newly-arrived members + */ +static void _handle_new_members(PurpleConversation *conv, gboolean announce_arrivals) { PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); MatrixRoomMemberTable *table = matrix_room_get_member_table(conv); - GList *names = NULL, *flags = NULL, *oldnames = NULL; - gboolean updated = FALSE; + GList *names = NULL, *flags = NULL; + GSList *members; + + members = matrix_roommembers_get_new_members(table); + while(members != NULL) { + MatrixRoomMember *member = members->data; + const gchar *displayname; + GSList *tmp; + + displayname = matrix_roommember_get_opaque_data(member); + g_assert(displayname == NULL); + + displayname = matrix_roommember_get_displayname(member); + matrix_roommember_set_opaque_data(member, g_strdup(displayname), + _on_member_deleted); + + names = g_list_prepend(names, (gpointer)displayname); + flags = g_list_prepend(flags, GINT_TO_POINTER(0)); + + tmp = members; + members = members->next; + g_slist_free_1(tmp); + } - matrix_roommembers_get_new_members(table, &names, &flags); if(names) { purple_conv_chat_add_users(chat, names, NULL, flags, announce_arrivals); g_list_free(names); g_list_free(flags); - names = NULL; - flags = NULL; - updated = TRUE; } +} - matrix_roommembers_get_renamed_members(table, &oldnames, &names); - if(names) { - GList *name1 = names, *oldname1 = oldnames; - while(name1 && oldname1) { - purple_conv_chat_rename_user(chat, oldname1->data, name1->data); - name1 = g_list_next(name1); - oldname1 = g_list_next(oldname1); - } - g_list_free_full(oldnames, (GDestroyNotify)g_free); - g_list_free(names); - names = NULL; - oldnames = NULL; - updated = TRUE; + +/** + * Tell libpurple about renamed members + */ +void _handle_renamed_members(PurpleConversation *conv) +{ + PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); + MatrixRoomMemberTable *table = matrix_room_get_member_table(conv); + GSList *members; + + members = matrix_roommembers_get_renamed_members(table); + while(members != NULL) { + MatrixRoomMember *member = members->data; + gchar *current_displayname; + const gchar *new_displayname; + GSList *tmp; + + current_displayname = matrix_roommember_get_opaque_data(member); + g_assert(current_displayname != NULL); + + new_displayname = matrix_roommember_get_displayname(member); + + purple_conv_chat_rename_user(chat, current_displayname, + new_displayname); + + matrix_roommember_set_opaque_data(member, g_strdup(new_displayname), + _on_member_deleted); + g_free(current_displayname); + + tmp = members; + members = members->next; + g_slist_free_1(tmp); } +} - matrix_roommembers_get_left_members(table, &names); - if(names) { - purple_conv_chat_remove_users(chat, names, NULL); - g_list_free_full(names, (GDestroyNotify)g_free); - names = NULL; - updated = TRUE; + +/** + * Tell libpurple about departed members + */ +void _handle_left_members(PurpleConversation *conv) +{ + PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); + MatrixRoomMemberTable *table = matrix_room_get_member_table(conv); + GSList *members; + + members = matrix_roommembers_get_left_members(table); + while(members != NULL) { + MatrixRoomMember *member = members->data; + gchar *current_displayname; + GSList *tmp; + + current_displayname = matrix_roommember_get_opaque_data(member); + g_assert(current_displayname != NULL); + purple_conv_chat_remove_user(chat, current_displayname, NULL); + + g_free(current_displayname); + matrix_roommember_set_opaque_data(member, NULL, NULL); + + tmp = members; + members = members->next; + g_slist_free_1(tmp); } +} - if(updated) - _update_room_alias(conv); + +static void _update_user_list(PurpleConversation *conv, + gboolean announce_arrivals) +{ + _handle_new_members(conv, announce_arrivals); + _handle_renamed_members(conv); + _handle_left_members(conv); } + +/** + * Get the userid of a member of a room, given their displayname + * + * @returns a string, which will be freed by the caller, or null if not known + */ +gchar *matrix_room_displayname_to_userid(struct _PurpleConversation *conv, + const gchar *who) +{ + /* TODO: make this more efficient */ + MatrixRoomMemberTable *table = matrix_room_get_member_table(conv); + GList *members; + + members = matrix_roommembers_get_active_members(table, TRUE); + + while(members != NULL) { + MatrixRoomMember *member = members->data; + const gchar *displayname = matrix_roommember_get_opaque_data(member); + if(g_strcmp0(displayname, who) == 0) { + g_list_free(members); + return g_strdup(matrix_roommember_get_user_id(member)); + } + } + + g_list_free(members); + return NULL; +} + +/* ************************************************************************** */ + void matrix_room_complete_state_update(PurpleConversation *conv, gboolean announce_arrivals) { _update_user_list(conv, announce_arrivals); + if(_get_flags(conv) & PURPLE_CONV_FLAG_NEEDS_NAME_UPDATE) + _update_room_alias(conv); } @@ -585,9 +761,13 @@ static const gchar *_get_my_display_name(PurpleConversation *conv) MatrixConnectionData *conn = _get_connection_data_from_conversation(conv); MatrixRoomMemberTable *member_table = matrix_room_get_member_table(conv); + MatrixRoomMember *me; - return matrix_roommembers_get_displayname_for_member( - member_table, conn->user_id); + me = matrix_roommembers_lookup_member(member_table, conn->user_id); + if(me == NULL) + return NULL; + else + return matrix_roommember_get_displayname(me); } /** @@ -608,12 +788,3 @@ void matrix_room_send_message(PurpleConversation *conv, const gchar *message) purple_conv_chat_write(chat, _get_my_display_name(conv), message, PURPLE_MESSAGE_SEND, g_get_real_time()/1000/1000); } - - -gchar *matrix_room_displayname_to_userid(struct _PurpleConversation *conv, - const gchar *who) -{ - MatrixRoomMemberTable *member_table = - matrix_room_get_member_table(conv); - return matrix_roommembers_displayname_to_userid(member_table, who); -} diff --git a/matrix-roommembers.c b/matrix-roommembers.c index 2f68ea0..1f4ed4e 100644 --- a/matrix-roommembers.c +++ b/matrix-roommembers.c @@ -35,32 +35,24 @@ */ typedef struct _MatrixRoomMember { - gchar *userid; - - /* the displayname we gave to purple */ - gchar *current_displayname; + gchar *user_id; /* the current room membership */ int membership; - /* the displayname from the state table */ + /* the displayname from the state table (this is a pointer to the actual + * string in the state table, so should not be freed here) */ const gchar *state_displayname; -} MatrixRoomMember; + /* data attached to this member (matrix-room.c uses it to track the + * name we told libpurple this member had) + */ + gpointer opaque_data; -/** - * calculate the displayname for the given member - * - * @returns a string, which should be freed - */ -static gchar *_calculate_displayname_for_member(const MatrixRoomMember *member) -{ - if(member->state_displayname != NULL) { - return g_strdup(member->state_displayname); - } else { - return g_strdup(member->userid); - } -} + /* callback to delete the opaque_data. Called with a pointer to the member. + */ + DestroyMemberNotify on_delete; +} MatrixRoomMember; static int _parse_membership(const gchar *membership) @@ -80,21 +72,69 @@ static int _parse_membership(const gchar *membership) static MatrixRoomMember *_new_member(const gchar *userid) { MatrixRoomMember *mem = g_new0(MatrixRoomMember, 1); - mem->userid = g_strdup(userid); + mem->user_id = g_strdup(userid); return mem; } static void _free_member(MatrixRoomMember *member) { g_assert(member != NULL); - g_free(member->userid); - member->userid = NULL; - g_free(member->current_displayname); - member->current_displayname = NULL; + if(member->on_delete) + member->on_delete(member); + g_free(member->user_id); + member->user_id = NULL; g_free(member); } +/** + * Get the user_id for the given member + * + * @returns a string, which should *not* be freed + */ +const gchar *matrix_roommember_get_user_id(const MatrixRoomMember *member) +{ + return member->user_id; +} + +/** + * Get the displayname for the given member + * + * @returns a string, which should *not* be freed + */ +const gchar *matrix_roommember_get_displayname(const MatrixRoomMember *member) +{ + if(member->state_displayname != NULL) { + /* TODO: if there is more than one member with this displayname, we + * should return a deduplicated name + */ + return member->state_displayname; + } else { + return member->user_id; + } +} + + +/** + * Get the opaque data associated with the given member + */ +gpointer matrix_roommember_get_opaque_data(const MatrixRoomMember *member) +{ + return member->opaque_data; +} + + +/** + * Set the opaque data associated with the given member + */ +void matrix_roommember_set_opaque_data(MatrixRoomMember *member, + gpointer data, DestroyMemberNotify on_delete) +{ + member->opaque_data = data; + member->on_delete = on_delete; +} + + /****************************************************************************** * * member table @@ -125,120 +165,10 @@ void matrix_roommembers_free_table(MatrixRoomMemberTable *table) } -static MatrixRoomMember *_lookup_member(MatrixRoomMemberTable *table, - const gchar *userid) -{ - return g_hash_table_lookup(table->hash_table, userid); -} - - -#if 0 -static void _on_member_changed_displayname(PurpleConversation *conv, - const gchar *member_user_id, MatrixRoomMember *member) -{ - PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); - gchar *old_displayname, *new_displayname; - - old_displayname = member->current_displayname; - g_assert(old_displayname != NULL); - new_displayname = _calculate_displayname_for_member(member_user_id, member); - - purple_conv_chat_rename_user(chat, old_displayname, new_displayname); - g_free(old_displayname); - member->current_displayname = new_displayname; -} - - -static void _on_member_left(PurpleConversation *conv, - const gchar *member_user_id, MatrixRoomMember *member) +MatrixRoomMember *matrix_roommembers_lookup_member(MatrixRoomMemberTable *table, + const gchar *member_user_id) { - PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); - gchar *old_displayname; - - old_displayname = member->current_displayname; - g_assert(old_displayname != NULL); - purple_conv_chat_remove_user(chat, old_displayname, NULL); - g_free(old_displayname); - member->current_displayname = NULL; -} -#endif - - -const gchar *matrix_roommembers_get_displayname_for_member( - MatrixRoomMemberTable *table, const gchar *user_id) -{ - MatrixRoomMember *member = _lookup_member(table, user_id); - gchar *displayname; - - if(member == NULL) - return user_id; - - displayname = member -> current_displayname; - - if (displayname != NULL) - return displayname; - - displayname = _calculate_displayname_for_member(member); - member -> current_displayname = displayname; - return displayname; -} - - -void matrix_roommembers_get_new_members(MatrixRoomMemberTable *table, - GList **display_names, GList **flags) -{ - while(table->new_members != NULL) { - MatrixRoomMember *member = table->new_members->data; - gchar *displayname; - GSList *tmp; - - g_assert(member->current_displayname == NULL); - displayname = _calculate_displayname_for_member(member); - - *display_names = g_list_prepend(*display_names, displayname); - *flags = g_list_prepend(*flags, GINT_TO_POINTER(0)); - - tmp = table->new_members; - table->new_members = tmp->next; - g_slist_free_1(tmp); - } -} - -void matrix_roommembers_get_renamed_members(MatrixRoomMemberTable *table, - GList **old_names, GList **new_names) -{ - while(table->renamed_members != NULL) { - MatrixRoomMember *member = table->renamed_members->data; - gchar *displayname; - GSList *tmp; - - g_assert(member->current_displayname != NULL); - displayname = _calculate_displayname_for_member(member); - *old_names = g_list_prepend(*old_names, member->current_displayname); - *new_names = g_list_prepend(*new_names, displayname); - member->current_displayname = displayname; - - tmp = table->renamed_members; - table->renamed_members = tmp->next; - g_slist_free_1(tmp); - } -} - -void matrix_roommembers_get_left_members(MatrixRoomMemberTable *table, - GList **names) -{ - while(table->left_members != NULL) { - MatrixRoomMember *member = table->left_members->data; - GSList *tmp; - - g_assert(member->current_displayname != NULL); - *names = g_list_prepend(*names, member->current_displayname); - member->current_displayname = NULL; - - tmp = table->left_members; - table->left_members = tmp->next; - g_slist_free_1(tmp); - } + return g_hash_table_lookup(table->hash_table, member_user_id); } @@ -258,7 +188,7 @@ void matrix_roommembers_update_member(MatrixRoomMemberTable *table, new_membership_val = _parse_membership(new_membership); - member = _lookup_member(table, member_user_id); + member = matrix_roommembers_lookup_member(table, member_user_id); if(member != NULL) { old_displayname = member -> state_displayname; @@ -280,17 +210,20 @@ void matrix_roommembers_update_member(MatrixRoomMemberTable *table, if(new_membership_val == MATRIX_ROOM_MEMBERSHIP_JOIN) { if(old_membership_val != MATRIX_ROOM_MEMBERSHIP_JOIN) { - /* new user in this room */ + purple_debug_info("matrixprpl", "%s (%s) joins\n", + member_user_id, new_displayname); table->new_members = g_slist_append( table->new_members, member); } else if(g_strcmp0(old_displayname, new_displayname) != 0) { - /* user has changed name */ + purple_debug_info("matrixprpl", "%s (%s) changed name (was %s)\n", + member_user_id, new_displayname, old_displayname); table->renamed_members = g_slist_append( table->renamed_members, member); } } else { if(old_membership_val == MATRIX_ROOM_MEMBERSHIP_JOIN) { - /* user has left this room */ + purple_debug_info("matrixprpl", "%s (%s) leaves\n", + member_user_id, old_displayname); table->left_members = g_slist_append( table->left_members, member); } @@ -299,7 +232,7 @@ void matrix_roommembers_update_member(MatrixRoomMemberTable *table, /** - * Returns a list of user ids. Free the list, but not the string pointers. + * Returns a list of MatrixRoomMember *s. Free the list, but not the pointers. */ GList *matrix_roommembers_get_active_members( MatrixRoomMemberTable *member_table, gboolean include_invited) @@ -310,38 +243,40 @@ GList *matrix_roommembers_get_active_members( g_hash_table_iter_init (&iter, member_table->hash_table); while (g_hash_table_iter_next (&iter, &key, &value)) { - const gchar *user_id = key; MatrixRoomMember *member = value; if(member->membership == MATRIX_ROOM_MEMBERSHIP_JOIN || (include_invited && member->membership == MATRIX_ROOM_MEMBERSHIP_INVITE)) { - members = g_list_prepend(members, (gpointer)user_id); + members = g_list_prepend(members, value); } } return members; } -/** - * Get the userid of a member of a room, given their displayname - * - * @returns a string, which will be freed by the caller, or null if not known - */ -gchar *matrix_roommembers_displayname_to_userid( - MatrixRoomMemberTable *table, const gchar *who) +GSList *matrix_roommembers_get_new_members(MatrixRoomMemberTable *table) { - /* TODO: make this more efficient */ - GHashTableIter iter; - gpointer key, value; - g_hash_table_iter_init (&iter, table->hash_table); - while (g_hash_table_iter_next (&iter, &key, &value)) { - const gchar *user_id = key; - MatrixRoomMember *member = value; - if(member->current_displayname != NULL - && strcmp(who, member->current_displayname) == 0) { - return g_strdup(user_id); - } - } - return NULL; + GSList *members = table->new_members; + table->new_members = NULL; + return members; +} + + +GSList *matrix_roommembers_get_renamed_members(MatrixRoomMemberTable *table) +{ + GSList *members = table->renamed_members; + table->renamed_members = NULL; + return members; + +} + + +GSList *matrix_roommembers_get_left_members(MatrixRoomMemberTable *table) +{ + GSList *members = table->left_members; + table->left_members = NULL; + return members; + } + diff --git a/matrix-roommembers.h b/matrix-roommembers.h index b447034..b5e03a2 100644 --- a/matrix-roommembers.h +++ b/matrix-roommembers.h @@ -30,6 +30,54 @@ #define MATRIX_ROOM_MEMBERSHIP_INVITE 2 #define MATRIX_ROOM_MEMBERSHIP_LEAVE 3 + + +/* **************************************************************************** + * + * Handling of individual members + */ + +typedef struct _MatrixRoomMember MatrixRoomMember; + +/** + * Get the user_id for the given member + * + * @returns a string, which should *not* be freed + */ +const gchar *matrix_roommember_get_user_id(const MatrixRoomMember *member); + +/** + * Get the displayname for the given member + * + * @returns a string, which should *not* be freed + */ +const gchar *matrix_roommember_get_displayname(const MatrixRoomMember *member); + + +/** + * Get the opaque data associated with the given member + */ +gpointer matrix_roommember_get_opaque_data(const MatrixRoomMember *member); + + +typedef void (*DestroyMemberNotify)(MatrixRoomMember *member); +/** + * Set the opaque data associated with the given member + * + * @param on_delete: a callback which will be called when the RoomMember is + * deleted (usually when its parent MatrixRoomMemberTable is deleted). It is + * passed a pointer to the MatrixRoomMember. + */ +void matrix_roommember_set_opaque_data(MatrixRoomMember *member, + gpointer data, DestroyMemberNotify on_delete); + + + +/* **************************************************************************** + * + * Member table + */ + typedef struct _MatrixRoomMemberTable MatrixRoomMemberTable; struct _JsonObject; @@ -56,18 +104,17 @@ void matrix_roommembers_update_member(MatrixRoomMemberTable *table, /** - * Get the displayname for the given userid + * Look up a room member given the userid * - * @returns a string, which should *not* be freed + * @returns MatrixRoomMember *, or NULL if unknown */ -const gchar *matrix_roommembers_get_displayname_for_member( - MatrixRoomMemberTable *table, const gchar *user_id); - +MatrixRoomMember *matrix_roommembers_lookup_member(MatrixRoomMemberTable *table, + const gchar *member_user_id); /** * Get a list of the members who have joined this room. * - * Returns a list of user ids. Free the list, but not the string pointers. + * Returns a list of MatrixRoomMember *s. Free the list, but not the pointers. */ GList *matrix_roommembers_get_active_members( MatrixRoomMemberTable *member_table, gboolean include_invited); @@ -76,45 +123,30 @@ GList *matrix_roommembers_get_active_members( /** * Get a list of the new members since the last time this function was called. * - * @param display_names returns the list of display names. Do not free the - * pointers. - * @param flags returns a corresponding list of zeros + * @returns a list of MatrixRoomMember *s. Free the list when you are done with + * it. */ -void matrix_roommembers_get_new_members(MatrixRoomMemberTable *table, - GList **display_names, GList **flags); +GSList *matrix_roommembers_get_new_members(MatrixRoomMemberTable *table); /** * Get a list of the members who have been renamed since the last time this * function was called. * - * @param old_names returns the list of old display names. These are no - * longer required, so should be freed - * @param new_names returns the list of new display names. Do *not* free these - * pointers. + * @returns a list of MatrixRoomMember *s. Free the list when you are done with + * it. */ -void matrix_roommembers_get_renamed_members(MatrixRoomMemberTable *table, - GList **old_names, GList **new_names); +GSList *matrix_roommembers_get_renamed_members(MatrixRoomMemberTable *table); /** * Get a list of the members who have left the channel since the last time this * function was called. * - * @param new_names returns the list of display names. These are no - * longer required, so should be freed - */ -void matrix_roommembers_get_left_members(MatrixRoomMemberTable *table, - GList **names); - - -/** - * Get the userid of a member of a room, given their displayname - * - * @returns a string, which will be freed by the caller, or null if not known + * @returns a list of MatrixRoomMember *s. Free the list when you are done with + * it. */ -gchar *matrix_roommembers_displayname_to_userid( - MatrixRoomMemberTable *table, const gchar *who); +GSList *matrix_roommembers_get_left_members(MatrixRoomMemberTable *table); #endif /* MATRIX_ROOMMEMBERS_H_ */ diff --git a/matrix-sync.c b/matrix-sync.c index 599df70..37ecf47 100644 --- a/matrix-sync.c +++ b/matrix-sync.c @@ -117,6 +117,8 @@ static PurpleChat *_ensure_blist_entry(PurpleAccount *acct, purple_blist_node_set_bool(&chat->node, "gtk-persistent", TRUE); purple_blist_add_chat(chat, group, NULL); + purple_debug_info("matrixprpl", "added buddy list entry for room %s\n", + room_id); return chat; } @@ -133,8 +135,7 @@ static void matrix_sync_room(const gchar *room_id, PurpleConversation *conv; gboolean initial_sync = FALSE; - /* ensure we have an entry in the buddy list for this room. - * TODO: We should only do this if the user is actually *in* the room. */ + /* ensure we have an entry in the buddy list for this room. */ _ensure_blist_entry(pc->account, room_id); conv = purple_find_conversation_with_account( |