about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2012-10-28 23:27:56 +0000
committerJames Booth <boothj5@gmail.com>2012-10-28 23:27:56 +0000
commit34238ad6a49917847bbf51f8a02d898f74a0aa2d (patch)
tree2037d8eac780dfac4e0b07ab67e0ececa3a581e5
parentbc5d8418ad20386b1a270527dce24b7a4b7119ff (diff)
downloadprofani-tty-34238ad6a49917847bbf51f8a02d898f74a0aa2d.tar.gz
Handle presence after roster request
-rw-r--r--src/contact_list.c105
-rw-r--r--src/contact_list.h3
-rw-r--r--src/profanity.c22
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 <string.h>
 
+#include <glib.h>
+
 #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