about summary refs log tree commit diff stats
path: root/src/contact.c
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2013-02-14 23:24:00 +0000
committerJames Booth <boothj5@gmail.com>2013-02-14 23:24:00 +0000
commit6794fb8101e9947be44644ce7c525f264f16a11a (patch)
tree24360b504b120b52d4f4e3c57ac2a28246faa237 /src/contact.c
parente33ccb07a4c0803119b6b6f293a527f294b6dd48 (diff)
downloadprofani-tty-6794fb8101e9947be44644ce7c525f264f16a11a.tar.gz
Dealing with mulitple contact resources, work in progress
Diffstat (limited to 'src/contact.c')
-rw-r--r--src/contact.c109
1 files changed, 90 insertions, 19 deletions
diff --git a/src/contact.c b/src/contact.c
index 372ccf5f..ece79ca9 100644
--- a/src/contact.c
+++ b/src/contact.c
@@ -66,15 +66,6 @@ p_contact_new(const char * const barejid, const char * const name,
     return contact;
 }
 
-void
-p_contact_add_resource(PContact contact, Resource *resource)
-{
-    assert(contact != NULL);
-    assert(resource != NULL);
-
-    g_hash_table_insert(contact->available_resources, strdup(resource->name), resource);
-}
-
 gboolean
 p_contact_remove_resource(PContact contact, const char * const resource)
 {
@@ -132,26 +123,78 @@ p_contact_name(const PContact contact)
     return contact->name;
 }
 
+static resource_presence_t
+_highest_presence(resource_presence_t first, resource_presence_t second)
+{
+    if (first == RESOURCE_CHAT) {
+        return first;
+    } else if (second == RESOURCE_CHAT) {
+        return second;
+    } else if (first == RESOURCE_ONLINE) {
+        return first;
+    } else if (second == RESOURCE_ONLINE) {
+        return second;
+    } else if (first == RESOURCE_AWAY) {
+        return first;
+    } else if (second == RESOURCE_AWAY) {
+        return second;
+    } else if (first == RESOURCE_XA) {
+        return first;
+    } else if (second == RESOURCE_XA) {
+        return second;
+    } else {
+        return first;
+    }
+}
+
 const char *
 p_contact_presence(const PContact contact)
 {
+    assert(contact != NULL);
+
+    // no available resources, offline
     if (g_hash_table_size(contact->available_resources) == 0) {
         return "offline";
-    } else {
-        Resource *resource = g_hash_table_lookup(contact->available_resources, "default");
-        return string_from_resource_presence(resource->presence);
     }
+
+    // find resource with highest priority, if more than one,
+    // use highest availability, in the following order:
+    //      chat
+    //      online
+    //      away
+    //      xa
+    //      dnd
+    GList *resources = g_hash_table_get_values(contact->available_resources);
+    Resource *resource = resources->data;
+    int highest_priority = resource->priority;
+    resource_presence_t presence = resource->presence;
+    resources = g_list_next(resources);
+    while (resources != NULL) {
+        resource = resources->data;
+
+        // priority is same as current highest, choose presence
+        if (resource->priority == highest_priority) {
+            presence = _highest_presence(presence, resource->presence);
+
+        // priority higher than current highest, set new presence
+        } else if (resource->priority > highest_priority) {
+            highest_priority = resource->priority;
+            presence = resource->presence;
+        }
+
+        resources = g_list_next(resources);
+    }
+
+    return string_from_resource_presence(presence);
 }
 
 const char *
-p_contact_status(const PContact contact)
+p_contact_status(const PContact contact, const char * const resource)
 {
-    if (g_hash_table_size(contact->available_resources) == 0) {
-        return NULL;
-    } else {
-        Resource *resource = g_hash_table_lookup(contact->available_resources, "default");
-        return resource->status;
-    }
+    assert(contact != NULL);
+    assert(resource != NULL);
+    Resource *resourcep = g_hash_table_lookup(contact->available_resources, "default");
+    return resourcep->status;
 }
 
 const char *
@@ -183,6 +226,34 @@ p_contact_caps_str(const PContact contact)
     }
 }
 
+gboolean
+p_contact_is_available(const PContact contact)
+{
+    // no available resources, unavailable
+    if (g_hash_table_size(contact->available_resources) == 0) {
+        return FALSE;
+    }
+
+    // if any resource is CHAT or ONLINE, available
+    GList *resources = g_hash_table_get_values(contact->available_resources);
+    while (resources != NULL) {
+        Resource *resource = resources->data;
+        resource_presence_t presence = resource->presence;
+        if ((presence == RESOURCE_ONLINE) || (presence == RESOURCE_CHAT)) {
+            return TRUE;
+        }
+        resources = g_list_next(resources);
+    }
+
+    return FALSE;
+}
+
+gboolean
+p_contact_has_available_resource(const PContact contact)
+{
+    return (g_hash_table_size(contact->available_resources) > 0);
+}
+
 void
 p_contact_set_presence(const PContact contact, Resource *resource)
 {