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_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); | ||||
| 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); | ||||
| 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); | ||||
| 
 | ||||
| size_t dc_channel_recipients(dc_channel_t c); | ||||
| void dc_channel_addrecipient(dc_channel_t c, dc_account_t a); | ||||
| dc_account_t dc_channel_nthrecipient(dc_channel_t c, size_t i); | ||||
| void dc_channel_add_recipient(dc_channel_t c, dc_account_t a); | ||||
| 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); | ||||
| dc_message_t dc_channel_nthmessage(dc_channel_t c, size_t i); | ||||
| void dc_channel_addmessages(dc_channel_t c, dc_message_t *m, size_t s); | ||||
| dc_message_t dc_channel_nth_message(dc_channel_t c, size_t i); | ||||
| 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 | ||||
|  | ||||
| @ -56,12 +56,30 @@ dc_account_t dc_session_me(dc_session_t s); | ||||
|  * access to the internal account cache | ||||
|  */ | ||||
| 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); | ||||
| 
 | ||||
| /**
 | ||||
|  * 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 | ||||
|  */ | ||||
|  | ||||
| @ -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; | ||||
|     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)); | ||||
| } | ||||
| 
 | ||||
| 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 (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); | ||||
|     } | ||||
| 
 | ||||
|     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; | ||||
| 
 | ||||
| cleanup: | ||||
|  | ||||
| @ -249,33 +249,42 @@ size_t dc_channel_recipients(dc_channel_t c) | ||||
|     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(i >= c->recipients->len, NULL); | ||||
|     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,); | ||||
|     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) | ||||
| { | ||||
|     return_if_true(c == NULL || c->messages == NULL, 0); | ||||
|     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(i >= c->messages->len, NULL); | ||||
|     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(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); | ||||
| } | ||||
| 
 | ||||
| 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) | ||||
| { | ||||
|     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"); | ||||
|     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)) { | ||||
|         case FRIEND_STATE_PENDING: c = 'P'; 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); | ||||
| 
 | ||||
|     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) { | ||||
|             friend = cur; | ||||
|             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); | ||||
| 
 | ||||
|     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 && | ||||
|             dc_account_friend_state(cur) == FRIEND_STATE_PENDING) { | ||||
|             friend = cur; | ||||
|  | ||||
| @ -49,7 +49,7 @@ bool ncdc_cmd_login(ncdc_mainwindow_t n, size_t ac, wchar_t **av) | ||||
|     dc_unref(current_session); | ||||
|     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; | ||||
| 
 | ||||
| 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; | ||||
|     size_t i = 0; | ||||
| 
 | ||||
|     if (is_logged_in()) { | ||||
|     if (!is_logged_in()) { | ||||
|         LOG(n, L"msg: not logged in"); | ||||
|         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
 | ||||
|      */ | ||||
|     dc_account_t f = dc_account_findfriend(current_account, target); | ||||
|     dc_account_t f = dc_session_account_fullname(current_session, target); | ||||
|     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; | ||||
|     } | ||||
| 
 | ||||
|     /* 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++) { | ||||
|         v = g_ptr_array_index(ncdc_mainwindow_views(n), i); | ||||
|         dc_channel_t chan = ncdc_textview_channel(v); | ||||
|         ncdc_textview_t view = g_ptr_array_index(ncdc_mainwindow_views(n), i); | ||||
|         dc_channel_t chan = ncdc_textview_channel(view); | ||||
| 
 | ||||
|         if (chan != NULL && | ||||
|             dc_channel_type(chan) == CHANNEL_TYPE_DM_TEXT && | ||||
|             dc_account_equal(dc_channel_nthrecipient(chan, 1), f)) { | ||||
|             c = dc_ref(chan); | ||||
|         if (dc_channel_compare(chan, c)) { | ||||
|             ncdc_mainwindow_switchview(n, i); | ||||
|             v = view; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (c == 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; | ||||
|         } | ||||
| 
 | ||||
|     if (v == NULL) { | ||||
|         v = ncdc_textview_new(); | ||||
|         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); | ||||
| 
 | ||||
|     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)); | ||||
|         if (i < (rlen-1)) { | ||||
|             fwprintf(f, L","); | ||||
| @ -201,7 +201,7 @@ ncdc_textview_render_msgs(ncdc_textview_t v, WINDOW *win, int lines, int cols) | ||||
|     atline = lines; | ||||
| 
 | ||||
|     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 const *end = s, *last = NULL; | ||||
|         size_t len = 0; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user