From 34238ad6a49917847bbf51f8a02d898f74a0aa2d Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 28 Oct 2012 23:27:56 +0000 Subject: Handle presence after roster request --- src/contact_list.c | 105 +++++++++++++++++++++++++++++++++++++++++------------ src/contact_list.h | 3 +- src/profanity.c | 22 +++++++---- 3 files changed, 97 insertions(+), 33 deletions(-) diff --git a/src/contact_list.c b/src/contact_list.c index 81611818..427d0722 100644 --- a/src/contact_list.c +++ b/src/contact_list.c @@ -22,24 +22,29 @@ #include +#include + #include "contact.h" #include "prof_autocomplete.h" static PAutocomplete ac; +static GHashTable *contacts; + +static gboolean _key_equals(void *key1, void *key2); void contact_list_init(void) { - ac = p_obj_autocomplete_new((PStrFunc)p_contact_jid, - (PCopyFunc)p_contact_copy, - (PEqualDeepFunc)p_contacts_equal_deep, - (GDestroyNotify)p_contact_free); + ac = p_autocomplete_new(); + contacts = g_hash_table_new_full(g_str_hash, (GEqualFunc)_key_equals, g_free, + (GDestroyNotify)p_contact_free); } void contact_list_clear(void) { p_autocomplete_clear(ac); + g_hash_table_remove_all(contacts); } void @@ -48,25 +53,80 @@ contact_list_reset_search_attempts(void) p_autocomplete_reset(ac); } -gboolean -contact_list_remove(const char * const name) -{ - return p_autocomplete_remove(ac, name); -} - -gboolean +void contact_list_add(const char * const jid, const char * const name, const char * const presence, const char * const status, const char * const subscription) { - return p_autocomplete_add(ac, p_contact_new(jid, name, presence, status, - subscription)); + PContact contact = g_hash_table_lookup(contacts, jid); + + // contact not yet in list + if (contact == NULL) { + contact = p_contact_new(jid, name, presence, status, subscription); + g_hash_table_insert(contacts, strdup(jid), contact); + + // contact already exists, update non NULL arguments + } else { + char *new_name = NULL; + if (name != NULL) { + new_name = strdup(name); + } else { + if (p_contact_name(contact) != NULL) { + new_name = strdup(p_contact_name(contact)); + } + } + + char *new_presence = NULL; + if (presence != NULL) { + new_presence = strdup(presence); + } else { + if (p_contact_presence(contact) != NULL) { + new_presence = strdup(p_contact_presence(contact)); + } + } + + char *new_status = NULL; + if (status != NULL) { + new_status = strdup(status); + } else { + if (p_contact_status(contact) != NULL) { + new_status = strdup(p_contact_status(contact)); + } + } + + char *new_subscription = NULL; + if (subscription != NULL) { + new_subscription = strdup(subscription); + } else { + if (p_contact_subscription(contact) != NULL) { + new_subscription = strdup(p_contact_subscription(contact)); + } + } + + PContact new_contact = p_contact_new(jid, new_name, new_presence, + new_status, new_subscription); + + g_hash_table_replace(contacts, strdup(jid), new_contact); + } + + p_autocomplete_add(ac, strdup(jid)); } GSList * get_contact_list(void) { - return p_autocomplete_get_list(ac); + GSList *result = NULL; + GHashTableIter iter; + gpointer key; + gpointer value; + + g_hash_table_iter_init(&iter, contacts); + while (g_hash_table_iter_next(&iter, &key, &value)) { + result = g_slist_append(result, value); + } + + // resturn all contact structs + return result; } char * @@ -78,15 +138,14 @@ contact_list_find_contact(char *search_str) PContact contact_list_get_contact(const char const *jid) { - GSList *contacts = get_contact_list(); + return g_hash_table_lookup(contacts, jid); +} - while (contacts != NULL) { - PContact contact = contacts->data; - if (strcmp(p_contact_name(contact), jid) == 0) { - return contact; - } - contacts = g_slist_next(contacts); - } +static +gboolean _key_equals(void *key1, void *key2) +{ + gchar *str1 = (gchar *) key1; + gchar *str2 = (gchar *) key2; - return NULL; + return (g_strcmp0(str1, str2) == 0); } diff --git a/src/contact_list.h b/src/contact_list.h index e76a2ec9..ac9ab6cd 100644 --- a/src/contact_list.h +++ b/src/contact_list.h @@ -30,10 +30,9 @@ void contact_list_init(void); void contact_list_clear(void); void contact_list_reset_search_attempts(void); -gboolean contact_list_add(const char * const jid, const char * const name, +void contact_list_add(const char * const jid, const char * const name, const char * const presence, const char * const status, const char * const subscription); -gboolean contact_list_remove(const char * const name); GSList * get_contact_list(void); char * contact_list_find_contact(char *search_str); PContact contact_list_get_contact(const char const *jid); diff --git a/src/profanity.c b/src/profanity.c index 2953c4ba..dd6aae6e 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -165,21 +165,27 @@ prof_handle_failed_login(void) void prof_handle_contact_online(char *contact, char *show, char *status) { - gboolean result = contact_list_add(contact, NULL, show, status, NULL); - if (result) { - win_contact_online(contact, show, status); + contact_list_add(contact, NULL, show, status, NULL); + PContact result = contact_list_get_contact(contact); + if (p_contact_subscription(result) != NULL) { + if (strcmp(p_contact_subscription(result), "none") != 0) { + win_contact_online(contact, show, status); + win_page_off(); + } } - win_page_off(); } void prof_handle_contact_offline(char *contact, char *show, char *status) { - gboolean result = contact_list_add(contact, NULL, "offline", status, NULL); - if (result) { - win_contact_offline(contact, show, status); + contact_list_add(contact, NULL, "offline", status, NULL); + PContact result = contact_list_get_contact(contact); + if (p_contact_subscription(result) != NULL) { + if (strcmp(p_contact_subscription(result), "none") != 0) { + win_contact_offline(contact, show, status); + win_page_off(); + } } - win_page_off(); } static void -- cgit 1.4.1-2-gfad0