mirror of
				https://github.com/Tha14/toxic.git
				synced 2025-10-31 03:06:51 +01:00 
			
		
		
		
	Fix group ignore functionality
Ignoring a peer now persists if they leave/disconnect and rejoin the group. In addition, ignore status is now displayed in the peer list sidebar as a red # symbol.
This commit is contained in:
		| @@ -141,6 +141,8 @@ void cmd_ignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ | ||||
|     } | ||||
|  | ||||
|     line_info_add(self, true, NULL, NULL, SYS_MSG, 1, BLUE, "-!- Ignoring %s", nick); | ||||
|  | ||||
|     group_toggle_peer_ignore(self->num, peer_id, true); | ||||
| } | ||||
|  | ||||
| void cmd_kick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) | ||||
| @@ -842,6 +844,8 @@ void cmd_unignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv | ||||
|     } | ||||
|  | ||||
|     line_info_add(self, true, NULL, NULL, SYS_MSG, 1, BLUE, "-!- You are no longer ignoring %s", nick); | ||||
|  | ||||
|     group_toggle_peer_ignore(self->num, peer_id, false); | ||||
| } | ||||
|  | ||||
| void cmd_whois(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) | ||||
|   | ||||
							
								
								
									
										146
									
								
								src/groupchats.c
									
									
									
									
									
								
							
							
						
						
									
										146
									
								
								src/groupchats.c
									
									
									
									
									
								
							| @@ -138,6 +138,7 @@ static void groupchat_onGroupStatusChange(ToxWindow *self, Tox *m, uint32_t grou | ||||
|         TOX_USER_STATUS status); | ||||
| static void groupchat_onGroupSelfNickChange(ToxWindow *self, Tox *m, uint32_t groupnumber, const char *old_nick, | ||||
|         size_t old_length, const char *new_nick, size_t length); | ||||
| static void ignore_list_cleanup(GroupChat *chat); | ||||
|  | ||||
| /* | ||||
|  * Return a GroupChat pointer associated with groupnumber. | ||||
| @@ -240,6 +241,8 @@ static void close_groupchat(ToxWindow *self, Tox *m, uint32_t groupnumber) | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     ignore_list_cleanup(chat); | ||||
|  | ||||
|     realloc_peer_list(groupnumber, 0); | ||||
|  | ||||
|     free_ptr_array((void **) chat->name_list); | ||||
| @@ -661,6 +664,131 @@ int get_peer_index(uint32_t groupnumber, uint32_t peer_id) | ||||
|     return -1; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Return true if `key` is in the ignored list. | ||||
|  */ | ||||
| static bool peer_is_ignored(const GroupChat *chat, const uint8_t *key) | ||||
| { | ||||
|     for (uint16_t i = 0; i < chat->num_ignored; ++i) { | ||||
|         if (memcmp(chat->ignored_list[i], key, TOX_GROUP_PEER_PUBLIC_KEY_SIZE) == 0) { | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| static bool ignore_list_add_key(GroupChat *chat, const uint8_t *key) | ||||
| { | ||||
|     uint8_t **tmp_list = (uint8_t **)realloc(chat->ignored_list, (chat->num_ignored + 1) * sizeof(uint8_t *)); | ||||
|  | ||||
|     if (tmp_list == NULL) { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     chat->ignored_list = tmp_list; | ||||
|  | ||||
|     tmp_list[chat->num_ignored] = (uint8_t *)malloc(sizeof(uint8_t) * TOX_GROUP_PEER_PUBLIC_KEY_SIZE); | ||||
|  | ||||
|     if (tmp_list[chat->num_ignored] == NULL) { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     memcpy(tmp_list[chat->num_ignored], key, TOX_GROUP_PEER_PUBLIC_KEY_SIZE); | ||||
|     ++chat->num_ignored; | ||||
|  | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| static void ignore_list_cleanup(GroupChat *chat) | ||||
| { | ||||
|     for (uint16_t i = 0; i < chat->num_ignored; ++i) { | ||||
|         if (chat->ignored_list[i] != NULL) { | ||||
|             free(chat->ignored_list[i]); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     free(chat->ignored_list); | ||||
|     chat->ignored_list = NULL; | ||||
|     chat->num_ignored = 0; | ||||
| } | ||||
|  | ||||
| static bool ignore_list_rm_key(GroupChat *chat, const uint8_t *key) | ||||
| { | ||||
|     if (chat->num_ignored == 0) { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     int32_t idx = -1; | ||||
|  | ||||
|     for (uint16_t i = 0; i < chat->num_ignored; ++i) { | ||||
|         if (memcmp(chat->ignored_list[i], key, TOX_GROUP_PEER_PUBLIC_KEY_SIZE) == 0) { | ||||
|             idx = i; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (idx == -1) { | ||||
|         fprintf(stderr, "Key not found in ignore list\n"); | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     if ((chat->num_ignored - 1) == 0) { | ||||
|         ignore_list_cleanup(chat); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     --chat->num_ignored; | ||||
|  | ||||
|     if (idx != chat->num_ignored) { | ||||
|         memcpy(chat->ignored_list[idx], chat->ignored_list[chat->num_ignored], TOX_GROUP_PEER_PUBLIC_KEY_SIZE); | ||||
|     } | ||||
|  | ||||
|     free(chat->ignored_list[chat->num_ignored]); | ||||
|  | ||||
|     uint8_t **tmp_list = realloc(chat->ignored_list, chat->num_ignored * sizeof(uint8_t *)); | ||||
|  | ||||
|     if (tmp_list == NULL) { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     chat->ignored_list = tmp_list; | ||||
|  | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| void group_toggle_peer_ignore(uint32_t groupnumber, int peer_id, bool ignore) | ||||
| { | ||||
|     int peer_index = get_peer_index(groupnumber, peer_id); | ||||
|  | ||||
|     if (peer_index < 0) { | ||||
|         fprintf(stderr, "Failed to find peer index (group_toggle_peer_ignore())\n"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     GroupChat *chat = get_groupchat(groupnumber); | ||||
|  | ||||
|     if (!chat) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     GroupPeer *peer = &chat->peer_list[peer_index]; | ||||
|  | ||||
|     peer->is_ignored = ignore; | ||||
|  | ||||
|     bool ret; | ||||
|  | ||||
|     if (ignore) { | ||||
|         ret = ignore_list_add_key(chat, peer->public_key); | ||||
|     } else { | ||||
|         ret = ignore_list_rm_key(chat, peer->public_key); | ||||
|     } | ||||
|  | ||||
|     if (!ret) { | ||||
|         fprintf(stderr, "Client failed to modify ignore list\n"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void group_update_name_list(uint32_t groupnumber) | ||||
| { | ||||
|     GroupChat *chat = get_groupchat(groupnumber); | ||||
| @@ -1028,6 +1156,11 @@ static void groupchat_onGroupPeerJoin(ToxWindow *self, Tox *m, uint32_t groupnum | ||||
|         peer->role = tox_group_peer_get_role(m, groupnumber, peer_id, NULL); | ||||
|         peer->last_active = get_unix_time(); | ||||
|         tox_group_peer_get_public_key(m, groupnumber, peer_id, (uint8_t *)peer->public_key, NULL); | ||||
|         peer->is_ignored = peer_is_ignored(chat, peer->public_key); | ||||
|  | ||||
|         if (peer->is_ignored) { | ||||
|             tox_group_set_ignore(m, groupnumber, peer_id, true, NULL); | ||||
|         } | ||||
|  | ||||
|         if (i == chat->max_idx) { | ||||
|             ++chat->max_idx; | ||||
| @@ -1750,7 +1883,12 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m) | ||||
|  | ||||
|             wmove(ctx->sidebar, offset + 2, 1); | ||||
|  | ||||
|             const int maxlen_offset = chat->peer_list[i].role == TOX_GROUP_ROLE_USER ? 2 : 3; | ||||
|             const bool is_ignored = chat->peer_list[i].is_ignored; | ||||
|             uint16_t maxlen_offset = chat->peer_list[i].role == TOX_GROUP_ROLE_USER ? 2 : 3; | ||||
|  | ||||
|             if (is_ignored) { | ||||
|                 ++maxlen_offset; | ||||
|             } | ||||
|  | ||||
|             /* truncate nick to fit in side panel without modifying list */ | ||||
|             char tmpnck[TOX_MAX_NAME_LENGTH]; | ||||
| @@ -1785,6 +1923,12 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m) | ||||
|  | ||||
|             pthread_mutex_unlock(&Winthread.lock); | ||||
|  | ||||
|             if (is_ignored) { | ||||
|                 wattron(ctx->sidebar, COLOR_PAIR(RED) | A_BOLD); | ||||
|                 wprintw(ctx->sidebar, "#"); | ||||
|                 wattroff(ctx->sidebar, COLOR_PAIR(RED) | A_BOLD); | ||||
|             } | ||||
|  | ||||
|             wattron(ctx->sidebar, COLOR_PAIR(rolecolour) | A_BOLD); | ||||
|             wprintw(ctx->sidebar, "%s", rolesig); | ||||
|             wattroff(ctx->sidebar, COLOR_PAIR(rolecolour) | A_BOLD); | ||||
|   | ||||
| @@ -47,6 +47,7 @@ typedef struct GroupPeer { | ||||
|     uint8_t          public_key[TOX_GROUP_PEER_PUBLIC_KEY_SIZE]; | ||||
|     TOX_USER_STATUS  status; | ||||
|     Tox_Group_Role   role; | ||||
|     bool             is_ignored; | ||||
|     uint64_t         last_active; | ||||
| } GroupPeer; | ||||
|  | ||||
| @@ -56,6 +57,9 @@ typedef struct { | ||||
|     uint32_t   num_peers;     /* Number of peers in the chat/name_list array */ | ||||
|     uint32_t   max_idx;       /* Maximum peer list index - 1 */ | ||||
|  | ||||
|     uint8_t    **ignored_list; /* List of keys of peers that we're ignoring */ | ||||
|     uint16_t   num_ignored; | ||||
|  | ||||
|     char       group_name[TOX_GROUP_MAX_GROUP_NAME_LENGTH + 1]; | ||||
|     size_t     group_name_length; | ||||
|     uint32_t   groupnumber; | ||||
| @@ -108,4 +112,9 @@ void redraw_groupchat_win(ToxWindow *self); | ||||
|  */ | ||||
| GroupChat *get_groupchat(uint32_t groupnumber); | ||||
|  | ||||
| /** | ||||
|  * Toggles the ignore status of the peer associated with `peer_id`. | ||||
|  */ | ||||
| void group_toggle_peer_ignore(uint32_t groupnumber, int peer_id, bool ignore); | ||||
|  | ||||
| #endif /* #define GROUPCHATS_H */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user