diff --git a/libdc/include/dc/account.h b/libdc/include/dc/account.h index 4c3ddf7..97471df 100644 --- a/libdc/include/dc/account.h +++ b/libdc/include/dc/account.h @@ -67,6 +67,9 @@ char const *dc_account_discriminator(dc_account_t a); char const *dc_account_fullname(dc_account_t a); +char const *dc_account_status(dc_account_t a); +void dc_account_set_status(dc_account_t a, char const *s); + void dc_account_set_token(dc_account_t a, char const *token); char const *dc_account_token(dc_account_t a); bool dc_account_has_token(dc_account_t a); diff --git a/libdc/src/account.c b/libdc/src/account.c index 90ba296..b4cbbb5 100644 --- a/libdc/src/account.c +++ b/libdc/src/account.c @@ -26,6 +26,9 @@ struct dc_account_ /* full username username#discriminator */ char *full; + /* online/offline status + */ + char *status; /* authentication token */ @@ -50,6 +53,7 @@ static void dc_account_free(dc_account_t ptr) free(ptr->discriminator); free(ptr->full); free(ptr->token); + free(ptr->status); if (ptr->friends != NULL) { g_ptr_array_unref(ptr->friends); @@ -149,9 +153,9 @@ dc_account_t dc_account_from_relationship(json_t *j) goto error; } - val = json_object_get(j, "type"); - if (val != NULL && json_is_integer(val)) { - dc_account_set_friend_state(user, json_integer_value(val)); + val = json_object_get(j, "status"); + if (val != NULL && json_is_string(val)) { + dc_account_set_status(user, json_string_value(val)); } return user; @@ -313,6 +317,19 @@ char const *dc_account_fullname(dc_account_t a) return a->full; } +char const *dc_account_status(dc_account_t a) +{ + return_if_true(a == NULL, NULL); + return a->status; +} + +void dc_account_set_status(dc_account_t a, char const *s) +{ + return_if_true(a == NULL || s == NULL,); + free(a->status); + a->status = strdup(s); +} + bool dc_account_equal(dc_account_t a, dc_account_t b) { return_if_true(a == NULL && b == NULL, true); diff --git a/libdc/src/internal.h b/libdc/src/internal.h index 8ce5ca2..620a290 100644 --- a/libdc/src/internal.h +++ b/libdc/src/internal.h @@ -29,6 +29,7 @@ #define return_if_true(v,r) do { if (v) return r; } while(0) #define goto_if_true(v,l) do { if (v) goto l; } while(0) +#define continue_if_true(v) if (v) continue #define TOKEN(l) (dc_account_token(l)) diff --git a/libdc/src/session.c b/libdc/src/session.c index 12a4084..75a2552 100644 --- a/libdc/src/session.c +++ b/libdc/src/session.c @@ -75,6 +75,7 @@ static void dc_session_handle_ready(dc_session_t s, dc_event_t e) json_t *r = dc_event_payload(e); json_t *user = NULL; json_t *relationships = NULL; + json_t *presences = NULL; size_t idx = 0; json_t *c = NULL; json_t *channels = NULL; @@ -104,6 +105,28 @@ static void dc_session_handle_ready(dc_session_t s, dc_event_t e) } } + /* check presences + */ + presences = json_object_get(r, "presences"); + if (presences != NULL && json_is_array(presences)) { + json_array_foreach(presences, idx, c) { + json_t *user = NULL, *id = NULL, *status = NULL; + dc_account_t acc = NULL; + + user = json_object_get(c, "user"); + continue_if_true(user == NULL || !json_is_object(user)); + id = json_object_get(user, "id"); + continue_if_true(id == NULL || !json_is_string(id)); + status = json_object_get(c, "status"); + continue_if_true(s == NULL || !json_is_string(status)); + + acc = g_hash_table_lookup(s->accounts, json_string_value(id)); + continue_if_true(acc == NULL); + + dc_account_set_status(acc, json_string_value(status)); + } + } + /* load channels */ channels = json_object_get(r, "private_channels"); @@ -114,6 +137,9 @@ static void dc_session_handle_ready(dc_session_t s, dc_event_t e) continue; } + /* TODO: dedup recipients + */ + dc_session_add_channel(s, chan); } } diff --git a/ncdc/src/friends.c b/ncdc/src/friends.c index 4a7df11..b1a2e24 100644 --- a/ncdc/src/friends.c +++ b/ncdc/src/friends.c @@ -12,11 +12,19 @@ ncdc_cmd_friends_list(ncdc_mainwindow_t n, size_t ac, LOG(n, L"/FRIENDS list"); for (i = 0; i < dc_account_friends_size(current_account); i++) { dc_account_t acc = dc_account_nth_friend(current_account, i); + char const *status = dc_account_status(acc); + + if (status == NULL) { + status = "offline"; + } + switch (dc_account_friend_state(acc)) { + case FRIEND_STATE_FRIEND: c = 'F'; break; case FRIEND_STATE_PENDING: c = 'P'; break; default: c = ' '; break; } - LOG(n, L" %c %s", c, dc_account_fullname(acc)); + + LOG(n, L" [%c] [%-7s] %s", c, status, dc_account_fullname(acc)); } LOG(n, L"End of /FRIENDS list");