revamp handling of channels
This commit is contained in:
parent
596969bbae
commit
6d7c7e641f
@ -79,9 +79,9 @@ bool dc_account_equal(dc_account_t a, dc_account_t b);
|
|||||||
*/
|
*/
|
||||||
void dc_account_set_friends(dc_account_t a, dc_account_t *ptr, size_t len);
|
void dc_account_set_friends(dc_account_t a, dc_account_t *ptr, size_t len);
|
||||||
void dc_account_add_friend(dc_account_t a, dc_account_t friend);
|
void dc_account_add_friend(dc_account_t a, dc_account_t friend);
|
||||||
dc_account_t dc_account_nthfriend(dc_account_t a, size_t i);
|
dc_account_t dc_account_nth_friend(dc_account_t a, size_t i);
|
||||||
size_t dc_account_friends_size(dc_account_t a);
|
size_t dc_account_friends_size(dc_account_t a);
|
||||||
dc_account_t dc_account_findfriend(dc_account_t a, char const *fullname);
|
dc_account_t dc_account_find_friend(dc_account_t a, char const *fullname);
|
||||||
|
|
||||||
int dc_account_friend_state(dc_account_t a);
|
int dc_account_friend_state(dc_account_t a);
|
||||||
void dc_account_set_friend_state(dc_account_t a, int state);
|
void dc_account_set_friend_state(dc_account_t a, int state);
|
||||||
|
@ -56,11 +56,14 @@ dc_channel_type_t dc_channel_type(dc_channel_t c);
|
|||||||
void dc_channel_set_type(dc_channel_t c, dc_channel_type_t t);
|
void dc_channel_set_type(dc_channel_t c, dc_channel_type_t t);
|
||||||
|
|
||||||
size_t dc_channel_recipients(dc_channel_t c);
|
size_t dc_channel_recipients(dc_channel_t c);
|
||||||
void dc_channel_addrecipient(dc_channel_t c, dc_account_t a);
|
void dc_channel_add_recipient(dc_channel_t c, dc_account_t a);
|
||||||
dc_account_t dc_channel_nthrecipient(dc_channel_t c, size_t i);
|
dc_account_t dc_channel_nth_recipient(dc_channel_t c, size_t i);
|
||||||
|
bool dc_channel_has_recipient(dc_channel_t c, dc_account_t a);
|
||||||
|
|
||||||
size_t dc_channel_messages(dc_channel_t c);
|
size_t dc_channel_messages(dc_channel_t c);
|
||||||
dc_message_t dc_channel_nthmessage(dc_channel_t c, size_t i);
|
dc_message_t dc_channel_nth_message(dc_channel_t c, size_t i);
|
||||||
void dc_channel_addmessages(dc_channel_t c, dc_message_t *m, size_t s);
|
void dc_channel_add_messages(dc_channel_t c, dc_message_t *m, size_t s);
|
||||||
|
|
||||||
|
bool dc_channel_compare(dc_channel_t a, dc_channel_t b);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -56,12 +56,30 @@ dc_account_t dc_session_me(dc_session_t s);
|
|||||||
* access to the internal account cache
|
* access to the internal account cache
|
||||||
*/
|
*/
|
||||||
void dc_session_add_account(dc_session_t s, dc_account_t u);
|
void dc_session_add_account(dc_session_t s, dc_account_t u);
|
||||||
|
dc_account_t dc_session_account_fullname(dc_session_t s, char const *f);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* access to the internal channel cache
|
* Adds a new channel to the internal cache.
|
||||||
*/
|
*/
|
||||||
void dc_session_add_channel(dc_session_t s, dc_channel_t u);
|
void dc_session_add_channel(dc_session_t s, dc_channel_t u);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new channel, or returns an existing channel if a channel with
|
||||||
|
* these recipients already exists.
|
||||||
|
* Warning: You must dc_ref() the return object if you need it beyond the
|
||||||
|
* life-span of the session.
|
||||||
|
*/
|
||||||
|
dc_channel_t dc_session_make_channel(dc_session_t s, dc_account_t *r,
|
||||||
|
size_t n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a channel object by that match the given recipients.
|
||||||
|
* Warning: You must dc_ref() the return object if you need it beyond the
|
||||||
|
* life-span of the session.
|
||||||
|
*/
|
||||||
|
dc_channel_t dc_session_channel_recipients(dc_session_t s,
|
||||||
|
dc_account_t *r, size_t sz);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* comparision functions for sorting, and finding
|
* comparision functions for sorting, and finding
|
||||||
*/
|
*/
|
||||||
|
@ -331,7 +331,7 @@ void dc_account_set_friends(dc_account_t a, dc_account_t *friends, size_t len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dc_account_t dc_account_findfriend(dc_account_t a, char const *fullname)
|
dc_account_t dc_account_find_friend(dc_account_t a, char const *fullname)
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
return_if_true(a == NULL || fullname == NULL, NULL);
|
return_if_true(a == NULL || fullname == NULL, NULL);
|
||||||
@ -352,7 +352,7 @@ void dc_account_add_friend(dc_account_t a, dc_account_t friend)
|
|||||||
g_ptr_array_add(a->friends, dc_ref(friend));
|
g_ptr_array_add(a->friends, dc_ref(friend));
|
||||||
}
|
}
|
||||||
|
|
||||||
dc_account_t dc_account_nthfriend(dc_account_t a, size_t i)
|
dc_account_t dc_account_nth_friend(dc_account_t a, size_t i)
|
||||||
{
|
{
|
||||||
return_if_true(a == NULL || a->friends == NULL, NULL);
|
return_if_true(a == NULL || a->friends == NULL, NULL);
|
||||||
return (dc_account_t)g_ptr_array_index(a->friends, i);
|
return (dc_account_t)g_ptr_array_index(a->friends, i);
|
||||||
|
@ -27,7 +27,7 @@ bool dc_api_get_messages(dc_api_t api, dc_account_t login, dc_channel_t c)
|
|||||||
g_ptr_array_add(msgs, m);
|
g_ptr_array_add(msgs, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
dc_channel_addmessages(c, (dc_message_t*)msgs->pdata, msgs->len);
|
dc_channel_add_messages(c, (dc_message_t*)msgs->pdata, msgs->len);
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
@ -249,33 +249,42 @@ size_t dc_channel_recipients(dc_channel_t c)
|
|||||||
return c->recipients->len;
|
return c->recipients->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc_account_t dc_channel_nthrecipient(dc_channel_t c, size_t i)
|
dc_account_t dc_channel_nth_recipient(dc_channel_t c, size_t i)
|
||||||
{
|
{
|
||||||
return_if_true(c == NULL || c->recipients == NULL, NULL);
|
return_if_true(c == NULL || c->recipients == NULL, NULL);
|
||||||
return_if_true(i >= c->recipients->len, NULL);
|
return_if_true(i >= c->recipients->len, NULL);
|
||||||
return g_ptr_array_index(c->recipients, i);
|
return g_ptr_array_index(c->recipients, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dc_channel_addrecipient(dc_channel_t c, dc_account_t a)
|
void dc_channel_add_recipient(dc_channel_t c, dc_account_t a)
|
||||||
{
|
{
|
||||||
return_if_true(c == NULL || a == NULL,);
|
return_if_true(c == NULL || a == NULL,);
|
||||||
g_ptr_array_add(c->recipients, dc_ref(a));
|
g_ptr_array_add(c->recipients, dc_ref(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool dc_channel_has_recipient(dc_channel_t c, dc_account_t a)
|
||||||
|
{
|
||||||
|
return_if_true(c == NULL || a == NULL, false);
|
||||||
|
return g_ptr_array_find_with_equal_func(
|
||||||
|
c->recipients, a, (GEqualFunc)dc_account_equal, NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t dc_channel_messages(dc_channel_t c)
|
size_t dc_channel_messages(dc_channel_t c)
|
||||||
{
|
{
|
||||||
return_if_true(c == NULL || c->messages == NULL, 0);
|
return_if_true(c == NULL || c->messages == NULL, 0);
|
||||||
return c->messages->len;
|
return c->messages->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc_message_t dc_channel_nthmessage(dc_channel_t c, size_t i)
|
dc_message_t dc_channel_nth_message(dc_channel_t c, size_t i)
|
||||||
{
|
{
|
||||||
return_if_true(c == NULL || c->messages == NULL, NULL);
|
return_if_true(c == NULL || c->messages == NULL, NULL);
|
||||||
return_if_true(i >= c->messages->len, NULL);
|
return_if_true(i >= c->messages->len, NULL);
|
||||||
return g_ptr_array_index(c->messages, i);
|
return g_ptr_array_index(c->messages, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dc_channel_addmessages(dc_channel_t c, dc_message_t *m, size_t s)
|
void dc_channel_add_messages(dc_channel_t c, dc_message_t *m, size_t s)
|
||||||
{
|
{
|
||||||
return_if_true(c == NULL || c->messages == NULL,);
|
return_if_true(c == NULL || c->messages == NULL,);
|
||||||
return_if_true(m == NULL || s == 0,);
|
return_if_true(m == NULL || s == 0,);
|
||||||
@ -288,3 +297,10 @@ void dc_channel_addmessages(dc_channel_t c, dc_message_t *m, size_t s)
|
|||||||
|
|
||||||
g_ptr_array_sort(c->messages, (GCompareFunc)dc_message_compare);
|
g_ptr_array_sort(c->messages, (GCompareFunc)dc_message_compare);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool dc_channel_compare(dc_channel_t a, dc_channel_t b)
|
||||||
|
{
|
||||||
|
return_if_true(a == NULL || b == NULL, false);
|
||||||
|
return_if_true(a->id == NULL || b->id == NULL, false);
|
||||||
|
return (strcmp(a->id, b->id) == 0);
|
||||||
|
}
|
||||||
|
@ -235,6 +235,25 @@ void dc_session_add_account(dc_session_t s, dc_account_t u)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dc_account_t dc_session_account_fullname(dc_session_t s, char const *f)
|
||||||
|
{
|
||||||
|
return_if_true(s == NULL || f == NULL, NULL);
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key, value;
|
||||||
|
|
||||||
|
/* TODO: hash table with fullname
|
||||||
|
*/
|
||||||
|
g_hash_table_iter_init(&iter, s->accounts);
|
||||||
|
while (g_hash_table_iter_next(&iter, &key, &value)) {
|
||||||
|
dc_account_t a = (dc_account_t)value;
|
||||||
|
if (strcmp(dc_account_fullname(a), f) == 0) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void dc_session_add_channel(dc_session_t s, dc_channel_t u)
|
void dc_session_add_channel(dc_session_t s, dc_channel_t u)
|
||||||
{
|
{
|
||||||
return_if_true(s == NULL || u == NULL,);
|
return_if_true(s == NULL || u == NULL,);
|
||||||
@ -248,3 +267,63 @@ void dc_session_add_channel(dc_session_t s, dc_channel_t u)
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dc_channel_t dc_session_make_channel(dc_session_t s, dc_account_t *r,
|
||||||
|
size_t n)
|
||||||
|
{
|
||||||
|
dc_channel_t c = NULL;
|
||||||
|
|
||||||
|
/* check if we have the channel already with those recipients
|
||||||
|
*/
|
||||||
|
c = dc_session_channel_recipients(s, r, n);
|
||||||
|
return_if_true(c != NULL, c);
|
||||||
|
|
||||||
|
/* no? create new one
|
||||||
|
*/
|
||||||
|
if (!dc_api_create_channel(s->api, s->login, r, n, &c)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return_if_true(c == NULL, NULL);
|
||||||
|
dc_session_add_channel(s, c);
|
||||||
|
|
||||||
|
/* unref once to match the proper ref count after dc_session_add_channel()
|
||||||
|
* BUG: if dc_session_add_channel() fails this is bad
|
||||||
|
*/
|
||||||
|
dc_unref(c);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
dc_channel_t dc_session_channel_recipients(dc_session_t s,
|
||||||
|
dc_account_t *r, size_t sz)
|
||||||
|
{
|
||||||
|
return_if_true(s == NULL || r == NULL || sz == 0, NULL);
|
||||||
|
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key, value;
|
||||||
|
size_t i = 0, j = 0;
|
||||||
|
|
||||||
|
g_hash_table_iter_init(&iter, s->channels);
|
||||||
|
while (g_hash_table_iter_next(&iter, &key, &value)) {
|
||||||
|
dc_channel_t chan = (dc_channel_t)value;
|
||||||
|
bool found = true;
|
||||||
|
|
||||||
|
if (dc_channel_recipients(chan) != sz) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < sz; i++) {
|
||||||
|
if (!dc_channel_has_recipient(chan, r[j])) {
|
||||||
|
found = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
return chan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@ -10,7 +10,7 @@ ncdc_cmd_friends_list(ncdc_mainwindow_t n, size_t ac, wchar_t **av)
|
|||||||
|
|
||||||
LOG(n, L"/FRIENDS list");
|
LOG(n, L"/FRIENDS list");
|
||||||
for (i = 0; i < dc_account_friends_size(current_account); i++) {
|
for (i = 0; i < dc_account_friends_size(current_account); i++) {
|
||||||
dc_account_t acc = dc_account_nthfriend(current_account, i);
|
dc_account_t acc = dc_account_nth_friend(current_account, i);
|
||||||
switch (dc_account_friend_state(acc)) {
|
switch (dc_account_friend_state(acc)) {
|
||||||
case FRIEND_STATE_PENDING: c = 'P'; break;
|
case FRIEND_STATE_PENDING: c = 'P'; break;
|
||||||
default: c = ' '; break;
|
default: c = ' '; break;
|
||||||
@ -76,7 +76,7 @@ ncdc_cmd_friends_remove(ncdc_mainwindow_t n, size_t ac, wchar_t **av)
|
|||||||
return_if_true(name == NULL, false);
|
return_if_true(name == NULL, false);
|
||||||
|
|
||||||
for (i = 0; i < dc_account_friends_size(current_account); i++) {
|
for (i = 0; i < dc_account_friends_size(current_account); i++) {
|
||||||
dc_account_t cur = dc_account_nthfriend(current_account, i);
|
dc_account_t cur = dc_account_nth_friend(current_account, i);
|
||||||
if (strcmp(dc_account_fullname(cur), name) == 0) {
|
if (strcmp(dc_account_fullname(cur), name) == 0) {
|
||||||
friend = cur;
|
friend = cur;
|
||||||
break;
|
break;
|
||||||
@ -120,7 +120,7 @@ ncdc_cmd_friends_accept(ncdc_mainwindow_t n, size_t ac, wchar_t **av)
|
|||||||
return_if_true(name == NULL, false);
|
return_if_true(name == NULL, false);
|
||||||
|
|
||||||
for (i = 0; i < dc_account_friends_size(current_account); i++) {
|
for (i = 0; i < dc_account_friends_size(current_account); i++) {
|
||||||
dc_account_t cur = dc_account_nthfriend(current_account, i);
|
dc_account_t cur = dc_account_nth_friend(current_account, i);
|
||||||
if (strcmp(dc_account_fullname(cur), name) == 0 &&
|
if (strcmp(dc_account_fullname(cur), name) == 0 &&
|
||||||
dc_account_friend_state(cur) == FRIEND_STATE_PENDING) {
|
dc_account_friend_state(cur) == FRIEND_STATE_PENDING) {
|
||||||
friend = cur;
|
friend = cur;
|
||||||
|
@ -49,7 +49,7 @@ bool ncdc_cmd_login(ncdc_mainwindow_t n, size_t ac, wchar_t **av)
|
|||||||
dc_unref(current_session);
|
dc_unref(current_session);
|
||||||
current_session = dc_ref(s);
|
current_session = dc_ref(s);
|
||||||
|
|
||||||
LOG(n, L"login: %ls: authentication successful", av[1]);
|
LOG(n, L"login: %ls: authentication successful, waiting for data...", av[1]);
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
@ -15,7 +15,7 @@ bool ncdc_cmd_msg(ncdc_mainwindow_t n, size_t ac, wchar_t **av)
|
|||||||
dc_account_t current_account = NULL;
|
dc_account_t current_account = NULL;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
if (is_logged_in()) {
|
if (!is_logged_in()) {
|
||||||
LOG(n, L"msg: not logged in");
|
LOG(n, L"msg: not logged in");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -27,40 +27,33 @@ bool ncdc_cmd_msg(ncdc_mainwindow_t n, size_t ac, wchar_t **av)
|
|||||||
|
|
||||||
/* find out if the target is a friend we can contact
|
/* find out if the target is a friend we can contact
|
||||||
*/
|
*/
|
||||||
dc_account_t f = dc_account_findfriend(current_account, target);
|
dc_account_t f = dc_session_account_fullname(current_session, target);
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
LOG(n, L"msg: no such friend found: \"%s\"", target);
|
LOG(n, L"msg: no such account found: \"%s\"", target);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = dc_session_make_channel(current_session, &f, 1);
|
||||||
|
if (c == NULL) {
|
||||||
|
LOG(n, L"msg: failed to create channel for these recipients");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* see if we have a channel already, that services that user
|
/* see if we have a channel already, that services that user
|
||||||
|
* if so we set v to something non-NIL and it should be good
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < ncdc_mainwindow_views(n)->len; i++) {
|
for (i = 0; i < ncdc_mainwindow_views(n)->len; i++) {
|
||||||
v = g_ptr_array_index(ncdc_mainwindow_views(n), i);
|
ncdc_textview_t view = g_ptr_array_index(ncdc_mainwindow_views(n), i);
|
||||||
dc_channel_t chan = ncdc_textview_channel(v);
|
dc_channel_t chan = ncdc_textview_channel(view);
|
||||||
|
|
||||||
if (chan != NULL &&
|
if (dc_channel_compare(chan, c)) {
|
||||||
dc_channel_type(chan) == CHANNEL_TYPE_DM_TEXT &&
|
|
||||||
dc_account_equal(dc_channel_nthrecipient(chan, 1), f)) {
|
|
||||||
c = dc_ref(chan);
|
|
||||||
ncdc_mainwindow_switchview(n, i);
|
ncdc_mainwindow_switchview(n, i);
|
||||||
|
v = view;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == NULL) {
|
if (v == NULL) {
|
||||||
/* no? create a new window and switch to it
|
|
||||||
*/
|
|
||||||
if (!dc_api_create_channel(api, current_account, &f, 1, &c)) {
|
|
||||||
LOG(n, L"msg: failed to create channel");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dc_api_get_messages(api, current_account, c)) {
|
|
||||||
LOG(n, L"msg: failed to fetch messages in channel");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
v = ncdc_textview_new();
|
v = ncdc_textview_new();
|
||||||
goto_if_true(v == NULL, cleanup);
|
goto_if_true(v == NULL, cleanup);
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ static void ncdc_textview_maketitle(ncdc_textview_t v)
|
|||||||
size_t rlen = dc_channel_recipients(v->channel);
|
size_t rlen = dc_channel_recipients(v->channel);
|
||||||
|
|
||||||
for (i = 0; i < rlen; i++) {
|
for (i = 0; i < rlen; i++) {
|
||||||
dc_account_t r = dc_channel_nthrecipient(v->channel, i);
|
dc_account_t r = dc_channel_nth_recipient(v->channel, i);
|
||||||
fwprintf(f, L"%s", dc_account_fullname(r));
|
fwprintf(f, L"%s", dc_account_fullname(r));
|
||||||
if (i < (rlen-1)) {
|
if (i < (rlen-1)) {
|
||||||
fwprintf(f, L",");
|
fwprintf(f, L",");
|
||||||
@ -201,7 +201,7 @@ ncdc_textview_render_msgs(ncdc_textview_t v, WINDOW *win, int lines, int cols)
|
|||||||
atline = lines;
|
atline = lines;
|
||||||
|
|
||||||
for (i = msgs-1; i >= 0; i--) {
|
for (i = msgs-1; i >= 0; i--) {
|
||||||
dc_message_t m = dc_channel_nthmessage(v->channel, i);
|
dc_message_t m = dc_channel_nth_message(v->channel, i);
|
||||||
wchar_t *s = ncdc_textview_format(m);
|
wchar_t *s = ncdc_textview_format(m);
|
||||||
wchar_t const *end = s, *last = NULL;
|
wchar_t const *end = s, *last = NULL;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user