diff options
author | James Booth <boothj5@gmail.com> | 2013-02-14 23:24:00 +0000 |
---|---|---|
committer | James Booth <boothj5@gmail.com> | 2013-02-14 23:24:00 +0000 |
commit | 6794fb8101e9947be44644ce7c525f264f16a11a (patch) | |
tree | 24360b504b120b52d4f4e3c57ac2a28246faa237 | |
parent | e33ccb07a4c0803119b6b6f293a527f294b6dd48 (diff) | |
download | profani-tty-6794fb8101e9947be44644ce7c525f264f16a11a.tar.gz |
Dealing with mulitple contact resources, work in progress
-rw-r--r-- | src/command/command.c | 31 | ||||
-rw-r--r-- | src/contact.c | 109 | ||||
-rw-r--r-- | src/contact.h | 3 | ||||
-rw-r--r-- | src/muc.c | 6 |
4 files changed, 112 insertions, 37 deletions
diff --git a/src/command/command.c b/src/command/command.c index ae3d51d6..73c8b07a 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -1539,9 +1539,7 @@ _cmd_who(gchar **args, struct cmd_help_t help) while (list != NULL) { PContact contact = list->data; - const char * const contact_presence = (p_contact_presence(contact)); - if ((strcmp(contact_presence, "online") == 0) - || (strcmp(contact_presence, "chat") == 0)) { + if (p_contact_is_available(contact)) { filtered = g_list_append(filtered, contact); } list = g_list_next(list); @@ -1555,11 +1553,7 @@ _cmd_who(gchar **args, struct cmd_help_t help) while (list != NULL) { PContact contact = list->data; - const char * const contact_presence = (p_contact_presence(contact)); - if ((strcmp(contact_presence, "offline") == 0) - || (strcmp(contact_presence, "away") == 0) - || (strcmp(contact_presence, "dnd") == 0) - || (strcmp(contact_presence, "xa") == 0)) { + if (!p_contact_is_available(contact)) { filtered = g_list_append(filtered, contact); } list = g_list_next(list); @@ -1573,12 +1567,7 @@ _cmd_who(gchar **args, struct cmd_help_t help) while (list != NULL) { PContact contact = list->data; - const char * const contact_presence = (p_contact_presence(contact)); - if ((strcmp(contact_presence, "online") == 0) - || (strcmp(contact_presence, "away") == 0) - || (strcmp(contact_presence, "dnd") == 0) - || (strcmp(contact_presence, "xa") == 0) - || (strcmp(contact_presence, "chat") == 0)) { + if (p_contact_has_available_resource(contact)) { filtered = g_list_append(filtered, contact); } list = g_list_next(list); @@ -1586,6 +1575,20 @@ _cmd_who(gchar **args, struct cmd_help_t help) win_show_room_roster(room, filtered, "online"); + // online, show all status that indicate online + } else if (strcmp("offline", presence) == 0) { + GList *filtered = NULL; + + while (list != NULL) { + PContact contact = list->data; + if (!p_contact_has_available_resource(contact)) { + filtered = g_list_append(filtered, contact); + } + list = g_list_next(list); + } + + win_show_room_roster(room, filtered, "offline"); + // show specific status } else { GList *filtered = NULL; 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) { diff --git a/src/contact.h b/src/contact.h index 0b376d81..91bc1024 100644 --- a/src/contact.h +++ b/src/contact.h @@ -37,7 +37,7 @@ void p_contact_free(PContact contact); const char* p_contact_barejid(PContact contact); const char* p_contact_name(PContact contact); const char* p_contact_presence(PContact contact); -const char* p_contact_status(PContact contact); +const char* p_contact_status(PContact contact, const char * const resource); 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); @@ -48,5 +48,6 @@ void p_contact_set_subscription(const PContact contact, const char * const subsc void p_contact_set_caps_str(const PContact contact, const char * const caps_str); void p_contact_set_pending_out(const PContact contact, gboolean pending_out); void p_contact_set_last_activity(const PContact contact, GDateTime *last_activity); +gboolean p_contact_is_available(const PContact contact); #endif diff --git a/src/muc.c b/src/muc.c index a59ac96b..778b2ce3 100644 --- a/src/muc.c +++ b/src/muc.c @@ -217,13 +217,13 @@ muc_add_to_roster(const char * const room, const char * const nick, updated = TRUE; autocomplete_add(chat_room->nick_ac, strdup(nick)); } else if ((g_strcmp0(p_contact_presence(old), show) != 0) || - (g_strcmp0(p_contact_status(old), status) != 0)) { + (g_strcmp0(p_contact_status(old, nick), status) != 0)) { updated = TRUE; } PContact contact = p_contact_new(nick, NULL, NULL, FALSE); resource_presence_t resource_presence = resource_presence_from_string(show); - Resource *resource = resource_new("default", resource_presence, status, 0, caps_str); - p_contact_add_resource(contact, resource); + Resource *resource = resource_new(nick, resource_presence, status, 0, caps_str); + p_contact_set_presence(contact, resource); g_hash_table_replace(chat_room->roster, strdup(nick), contact); } |