about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/contact.c21
-rw-r--r--src/contact.h3
-rw-r--r--src/contact_list.c38
-rw-r--r--src/contact_list.h6
-rw-r--r--src/profanity.c20
-rw-r--r--src/profanity.h5
-rw-r--r--src/ui/ui.h4
-rw-r--r--src/ui/windows.c13
-rw-r--r--src/xmpp/presence.c22
9 files changed, 76 insertions, 56 deletions
diff --git a/src/contact.c b/src/contact.c
index 45ace58f..372ccf5f 100644
--- a/src/contact.c
+++ b/src/contact.c
@@ -75,6 +75,12 @@ p_contact_add_resource(PContact contact, Resource *resource)
     g_hash_table_insert(contact->available_resources, strdup(resource->name), resource);
 }
 
+gboolean
+p_contact_remove_resource(PContact contact, const char * const resource)
+{
+    return g_hash_table_remove(contact->available_resources, resource);
+}
+
 PContact
 p_contact_new_subscription(const char * const barejid,
     const char * const subscription, gboolean pending_out)
@@ -178,20 +184,9 @@ p_contact_caps_str(const PContact contact)
 }
 
 void
-p_contact_set_presence(const PContact contact, const char * const presence)
+p_contact_set_presence(const PContact contact, Resource *resource)
 {
-    if (g_strcmp0(presence, "offline") == 0) {
-        g_hash_table_remove(contact->available_resources, "default");
-    } else {
-        resource_presence_t resource_presence = resource_presence_from_string(presence);
-        if (g_hash_table_size(contact->available_resources) == 0) {
-            Resource *resource = resource_new("default", resource_presence, NULL, 0, NULL);
-            g_hash_table_insert(contact->available_resources, strdup(resource->name), resource);
-        } else {
-            Resource *resource = g_hash_table_lookup(contact->available_resources, "default");
-                resource->presence = resource_presence;
-        }
-    }
+    g_hash_table_replace(contact->available_resources, strdup(resource->name), resource);
 }
 
 void
diff --git a/src/contact.h b/src/contact.h
index c32f3800..0b376d81 100644
--- a/src/contact.h
+++ b/src/contact.h
@@ -32,6 +32,7 @@ PContact p_contact_new(const char * const barejid, const char * const name,
 PContact p_contact_new_subscription(const char * const barejid,
     const char * const subscription, gboolean pending_out);
 void p_contact_add_resource(PContact contact, Resource *resource);
+gboolean p_contact_remove_resource(PContact contact, const char * const resource);
 void p_contact_free(PContact contact);
 const char* p_contact_barejid(PContact contact);
 const char* p_contact_name(PContact contact);
@@ -41,7 +42,7 @@ const char* p_contact_subscription(const PContact contact);
 const char* p_contact_caps_str(const PContact contact);
 GDateTime* p_contact_last_activity(const PContact contact);
 gboolean p_contact_pending_out(const PContact contact);
-void p_contact_set_presence(const PContact contact, const char * const presence);
+void p_contact_set_presence(const PContact contact, Resource *resource);
 void p_contact_set_status(const PContact contact, const char * const status);
 void p_contact_set_subscription(const PContact contact, const char * const subscription);
 void p_contact_set_caps_str(const PContact contact, const char * const caps_str);
diff --git a/src/contact_list.c b/src/contact_list.c
index 13c71f0a..3b6aab1a 100644
--- a/src/contact_list.c
+++ b/src/contact_list.c
@@ -20,6 +20,7 @@
  *
  */
 
+#include <assert.h>
 #include <string.h>
 
 #include <glib.h>
@@ -86,36 +87,35 @@ contact_list_remove(const char * const barejid)
 }
 
 gboolean
-contact_list_update_contact(const char * const barejid, const char * const presence,
-    const char * const status, GDateTime *last_activity, const char * const caps_str)
+contact_list_update_presence(const char * const barejid, Resource *resource,
+    GDateTime *last_activity)
 {
-    gboolean presence_changed = FALSE;
-    PContact contact = g_hash_table_lookup(contacts, barejid);
+    assert(barejid != NULL);
+    assert(resource != NULL);
 
+    PContact contact = g_hash_table_lookup(contacts, barejid);
     if (contact == NULL) {
         return FALSE;
     }
-
-    if (g_strcmp0(p_contact_presence(contact), presence) != 0) {
-        p_contact_set_presence(contact, presence);
-        presence_changed = TRUE;
-    }
-
-    if (g_strcmp0(p_contact_status(contact), status) != 0) {
-        p_contact_set_status(contact, status);
-        presence_changed = TRUE;
-    }
-
+    
     if (!_datetimes_equal(p_contact_last_activity(contact), last_activity)) {
         p_contact_set_last_activity(contact, last_activity);
-        presence_changed = TRUE;
     }
+    p_contact_set_presence(contact, resource);
 
-    if (g_strcmp0(p_contact_caps_str(contact), caps_str) != 0) {
-        p_contact_set_caps_str(contact, caps_str);
+    return TRUE;
+}    
+
+gboolean
+contact_list_contact_offline(const char * const barejid,
+    const char * const resource, const char * const status)
+{
+    PContact contact = g_hash_table_lookup(contacts, barejid);
+    if (contact == NULL) {
+        return FALSE;
     }
 
-    return presence_changed;
+    return p_contact_remove_resource(contact, resource);
 }
 
 void
diff --git a/src/contact_list.h b/src/contact_list.h
index 37511e67..581d6f66 100644
--- a/src/contact_list.h
+++ b/src/contact_list.h
@@ -34,13 +34,15 @@ void contact_list_reset_search_attempts(void);
 void contact_list_remove(const char * const barejid);
 gboolean contact_list_add(const char * const barejid, const char * const name,
     const char * const subscription, gboolean pending_out);
-gboolean contact_list_update_contact(const char * const barejid, const char * const presence,
-    const char * const status, GDateTime *last_activity, const char * const caps_str);
+gboolean contact_list_update_presence(const char * const barejid,
+    Resource *resource, GDateTime *last_activity);
 void contact_list_update_subscription(const char * const barejid,
     const char * const subscription, gboolean pending_out);
 gboolean contact_list_has_pending_subscriptions(void);
 GSList * get_contact_list(void);
 char * contact_list_find_contact(char *search_str);
 PContact contact_list_get_contact(const char const *barejid);
+gboolean contact_list_contact_offline(const char * const barejid,
+    const char * const resource, const char * const status);
 
 #endif
diff --git a/src/profanity.c b/src/profanity.c
index 0ba0fb15..d294a266 100644
--- a/src/profanity.c
+++ b/src/profanity.c
@@ -41,6 +41,7 @@
 #include "contact_list.h"
 #include "log.h"
 #include "muc.h"
+#include "resource.h"
 #include "ui/ui.h"
 #include "xmpp/xmpp.h"
 
@@ -316,16 +317,17 @@ prof_handle_leave_room(const char * const room)
 }
 
 void
-prof_handle_contact_online(char *contact, char *show, char *status,
-    GDateTime *last_activity, char *caps_str)
+prof_handle_contact_online(char *contact, Resource *resource,
+    GDateTime *last_activity)
 {
-    gboolean presence_changed = contact_list_update_contact(contact, show, status, last_activity, caps_str);
+    gboolean updated = contact_list_update_presence(contact, resource, last_activity);
 
-    if (presence_changed) {
+    if (updated) {
         PContact result = contact_list_get_contact(contact);
         if (p_contact_subscription(result) != NULL) {
             if (strcmp(p_contact_subscription(result), "none") != 0) {
-                ui_contact_online(contact, show, status, last_activity);
+                const char *show = string_from_resource_presence(resource->presence);
+                ui_contact_online(contact, resource->name, show, resource->status, last_activity);
                 win_current_page_off();
             }
         }
@@ -333,15 +335,15 @@ prof_handle_contact_online(char *contact, char *show, char *status,
 }
 
 void
-prof_handle_contact_offline(char *contact, char *show, char *status)
+prof_handle_contact_offline(char *contact, char *resource, char *status)
 {
-    gboolean presence_changed = contact_list_update_contact(contact, "offline", status, NULL, NULL);
+    gboolean updated = contact_list_contact_offline(contact, resource, status);
 
-    if (presence_changed) {
+    if (updated) {
         PContact result = contact_list_get_contact(contact);
         if (p_contact_subscription(result) != NULL) {
             if (strcmp(p_contact_subscription(result), "none") != 0) {
-                ui_contact_offline(contact, show, status);
+                ui_contact_offline(contact, "offline", status);
                 win_current_page_off();
             }
         }
diff --git a/src/profanity.h b/src/profanity.h
index 8cbec501..366188e1 100644
--- a/src/profanity.h
+++ b/src/profanity.h
@@ -23,6 +23,7 @@
 #ifndef PROFANITY_H
 #define PROFANITY_H
 
+#include "resource.h"
 #include "xmpp/xmpp.h"
 
 void prof_run(const int disable_tls, char *log_level);
@@ -33,8 +34,8 @@ void prof_handle_lost_connection(void);
 void prof_handle_disconnect(const char * const jid);
 void prof_handle_failed_login(void);
 void prof_handle_typing(char *from);
-void prof_handle_contact_online(char *contact, char *show, char *status,
-    GDateTime *last_activity, char *caps_str);
+void prof_handle_contact_online(char *contact, Resource *resource,
+    GDateTime *last_activity);
 void prof_handle_contact_offline(char *contact, char *show, char *status);
 void prof_handle_incoming_message(char *from, char *message, gboolean priv);
 void prof_handle_delayed_message(char *from, char *message, GTimeVal tv_stamp,
diff --git a/src/ui/ui.h b/src/ui/ui.h
index 6686acb7..80139cc1 100644
--- a/src/ui/ui.h
+++ b/src/ui/ui.h
@@ -70,8 +70,8 @@ void ui_show_typing(const char * const from);
 void ui_idle(void);
 void ui_show_incoming_msg(const char * const from, const char * const message,
     GTimeVal *tv_stamp, gboolean priv);
-void ui_contact_online(const char * const from, const char * const show,
-    const char * const status, GDateTime *last_activity);
+void ui_contact_online(const char * const barejid, const char * const resource,
+    const char * const show, const char * const status, GDateTime *last_activity);
 void ui_contact_offline(const char * const from, const char * const show,
     const char * const status);
 void ui_disconnected(void);
diff --git a/src/ui/windows.c b/src/ui/windows.c
index d764755b..2b269223 100644
--- a/src/ui/windows.c
+++ b/src/ui/windows.c
@@ -453,19 +453,22 @@ ui_show_incoming_msg(const char * const from, const char * const message,
 }
 
 void
-ui_contact_online(const char * const from, const char * const show,
-    const char * const status, GDateTime *last_activity)
+ui_contact_online(const char * const barejid, const char * const resource,
+    const char * const show, const char * const status, GDateTime *last_activity)
 {
-    _show_status_string(console->win, from, show, status, last_activity, "++",
+    Jid *jid = jid_create_from_bare_and_resource(barejid, resource);
+    _show_status_string(console->win, jid->fulljid, show, status, last_activity, "++",
         "online");
 
-    int win_index = _find_prof_win_index(from);
+    int win_index = _find_prof_win_index(barejid);
     if (win_index != NUM_WINS) {
         WINDOW *win = windows[win_index]->win;
-        _show_status_string(win, from, show, status, last_activity, "++",
+        _show_status_string(win, jid->fulljid, show, status, last_activity, "++",
             "online");
     }
 
+    jid_destroy(jid);
+
     if (win_index == current_index)
         dirty = TRUE;
 }
diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c
index aaca0e00..5773e349 100644
--- a/src/xmpp/presence.c
+++ b/src/xmpp/presence.c
@@ -342,7 +342,7 @@ _unavailable_handler(xmpp_conn_t * const conn,
         status_str = NULL;
 
     if (strcmp(my_jid->barejid, from_jid->barejid) !=0) {
-        prof_handle_contact_offline(from_jid->barejid, "offline", status_str);
+        prof_handle_contact_offline(from_jid->barejid, "default", status_str);
     }
 
     jid_destroy(my_jid);
@@ -406,9 +406,25 @@ _available_handler(xmpp_conn_t * const conn,
     else
         status_str = NULL;
 
+    // get priority
+    int priority = 0;
+    xmpp_stanza_t *priority_stanza =
+        xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_PRIORITY);
+
+    if (priority_stanza != NULL) {
+        char *priority_str = xmpp_stanza_get_text(priority_stanza);
+        if (priority_str != NULL) {
+            priority = atoi(priority_str);
+        }
+    }
+
+    // if not self presence (TODO allow self presence from other resources?)
     if (strcmp(my_jid->barejid, from_jid->barejid) !=0) {
-        prof_handle_contact_online(from_jid->barejid, show_str, status_str,
-            last_activity, caps_key);
+        // create the resource
+        resource_presence_t presence = resource_presence_from_string(show_str);
+        Resource *resource = resource_new("default", presence,
+            status_str, priority, caps_key);
+        prof_handle_contact_online(from_jid->barejid, resource, last_activity);
     }
 
     jid_destroy(my_jid);