1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-15 07:33:01 +01:00

Refactor groupchats

This commit is contained in:
Jfreegman 2015-07-16 17:10:04 -04:00
parent 0597152352
commit 15ef50e46c
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
7 changed files with 142 additions and 161 deletions

View File

@ -95,8 +95,6 @@ static void cmd_kickban_helper(ToxWindow *self, Tox *m, const char *nick, bool s
switch (err) { switch (err) {
case TOX_ERR_GROUP_MOD_REMOVE_PEER_OK: { case TOX_ERR_GROUP_MOD_REMOVE_PEER_OK: {
type_str = set_ban ? "banned" : "kicked";
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, RED, "You have %s %s from the group.", type_str, nick);
return; return;
} }
case TOX_ERR_GROUP_MOD_REMOVE_PEER_PERMISSIONS: { case TOX_ERR_GROUP_MOD_REMOVE_PEER_PERMISSIONS: {
@ -241,7 +239,6 @@ void cmd_mod(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
switch (err) { switch (err) {
case TOX_ERR_GROUP_MOD_SET_ROLE_OK: { case TOX_ERR_GROUP_MOD_SET_ROLE_OK: {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, BLUE, "You have promoted %s to moderator.", nick);
return; return;
} }
case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: { case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: {
@ -284,7 +281,6 @@ void cmd_unmod(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[M
switch (err) { switch (err) {
case TOX_ERR_GROUP_MOD_SET_ROLE_OK: { case TOX_ERR_GROUP_MOD_SET_ROLE_OK: {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, BLUE, "You have revoked moderator powers from %s.", nick);
return; return;
} }
case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: { case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: {
@ -444,7 +440,6 @@ void cmd_silence(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)
switch (err) { switch (err) {
case TOX_ERR_GROUP_MOD_SET_ROLE_OK: { case TOX_ERR_GROUP_MOD_SET_ROLE_OK: {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, BLUE, "You have silenced %s", nick);
return; return;
} }
case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: { case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: {
@ -483,7 +478,6 @@ void cmd_unsilence(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg
switch (err) { switch (err) {
case TOX_ERR_GROUP_MOD_SET_ROLE_OK: { case TOX_ERR_GROUP_MOD_SET_ROLE_OK: {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, BLUE, "You have unsilenced %s.", nick);
return; return;
} }
case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: { case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: {

View File

@ -124,7 +124,7 @@ static const char group_cmd_list[AC_NUM_GROUP_COMMANDS][MAX_CMDNAME_SIZE] = {
static void groupchat_set_group_name(ToxWindow *self, Tox *m, uint32_t groupnum); static void groupchat_set_group_name(ToxWindow *self, Tox *m, uint32_t groupnum);
ToxWindow new_group_chat(Tox *m, uint32_t groupnum, const char *groupname, int length); ToxWindow new_group_chat(Tox *m, uint32_t groupnum, const char *groupname, int length);
static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, uint32_t groupnum); static void groupchat_onGroupPeerlistUpdate(ToxWindow *self, Tox *m, uint32_t groupnum);
int init_groupchat_win(Tox *m, uint32_t groupnum, const char *groupname, size_t length) int init_groupchat_win(Tox *m, uint32_t groupnum, const char *groupname, size_t length)
{ {
@ -134,7 +134,7 @@ int init_groupchat_win(Tox *m, uint32_t groupnum, const char *groupname, size_t
ToxWindow self = new_group_chat(m, groupnum, groupname, length); ToxWindow self = new_group_chat(m, groupnum, groupname, length);
/* In case we're loading a saved group */ /* In case we're loading a saved group */
if (length <= 0) if (length == 0)
groupchat_set_group_name(&self, m, groupnum); groupchat_set_group_name(&self, m, groupnum);
int i; int i;
@ -143,18 +143,13 @@ int init_groupchat_win(Tox *m, uint32_t groupnum, const char *groupname, size_t
if (!groupchats[i].active) { if (!groupchats[i].active) {
groupchats[i].chatwin = add_window(m, self); groupchats[i].chatwin = add_window(m, self);
groupchats[i].active = true; groupchats[i].active = true;
groupchats[i].peer_names = malloc(sizeof(uint8_t) * TOX_MAX_NAME_LENGTH);
groupchats[i].peer_name_lengths = malloc(sizeof(uint16_t));
groupchats[i].groupnumber = groupnum; groupchats[i].groupnumber = groupnum;
if (groupchats[i].peer_names == NULL || groupchats[i].peer_name_lengths == NULL)
exit_toxic_err("failed in init_groupchat_win", FATALERR_MEMORY);
if (i == max_groupchat_index) if (i == max_groupchat_index)
++max_groupchat_index; ++max_groupchat_index;
set_active_window(groupchats[i].chatwin); set_active_window(groupchats[i].chatwin);
groupchat_onGroupNamelistChange(&self, m, groupnum); groupchat_onGroupPeerlistUpdate(&self, m, groupnum);
store_data(m, DATA_FILE); store_data(m, DATA_FILE);
return 0; return 0;
@ -182,8 +177,14 @@ static void kill_groupchat_window(ToxWindow *self)
/* Closes groupchat window and cleans up. */ /* Closes groupchat window and cleans up. */
void close_groupchat(ToxWindow *self, Tox *m, uint32_t groupnum) void close_groupchat(ToxWindow *self, Tox *m, uint32_t groupnum)
{ {
free(groupchats[groupnum].peer_names); GroupChat *chat = &groupchats[groupnum];
free(groupchats[groupnum].peer_name_lengths);
if (chat->peer_list)
free(chat->peer_list);
if (chat->name_list)
free(chat->name_list);
memset(&groupchats[groupnum], 0, sizeof(GroupChat)); memset(&groupchats[groupnum], 0, sizeof(GroupChat));
int i; int i;
@ -223,7 +224,6 @@ void set_nick_all_groups(Tox *m, const char *nick, size_t length)
switch (err) { switch (err) {
case TOX_ERR_GROUP_SELF_NAME_SET_OK: { case TOX_ERR_GROUP_SELF_NAME_SET_OK: {
line_info_add(self, timefrmt, NULL, nick, NAME_CHANGE, 0, MAGENTA, "You are now known as ");
break; break;
} }
case TOX_ERR_GROUP_SELF_NAME_SET_TAKEN: { case TOX_ERR_GROUP_SELF_NAME_SET_TAKEN: {
@ -256,14 +256,32 @@ int group_get_nick_peernumber(uint32_t groupnum, const char *nick)
uint32_t i; uint32_t i;
for (i = 0; i < groupchats[groupnum].num_peers; ++i) { for (i = 0; i < groupchats[groupnum].num_peers; ++i) {
if (strcmp(nick, (char *) &groupchats[groupnum].peer_names[i * TOX_MAX_NAME_LENGTH]) == 0) if (strcmp(nick, groupchats[groupnum].peer_list[i].name) == 0)
return i; return i;
} }
return -1; return -1;
} }
/* destroys and re-creates groupchat window with or without the peerlist */ static void group_update_name_list(uint32_t groupnum)
{
GroupChat *chat = &groupchats[groupnum];
if (chat->name_list)
free(chat->name_list);
chat->name_list = malloc(sizeof(char *) * chat->num_peers * TOX_MAX_NAME_LENGTH);
if (chat->name_list == NULL)
exit_toxic_err("failed in group_update_name_list", FATALERR_MEMORY);
uint32_t i;
for (i = 0; i < chat->num_peers; ++i)
memcpy(&chat->name_list[i * TOX_MAX_NAME_LENGTH], chat->peer_list[i].name, chat->peer_list[i].name_length + 1);
}
/* destroys and re-creates groupchat window */
void redraw_groupchat_win(ToxWindow *self) void redraw_groupchat_win(ToxWindow *self)
{ {
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
@ -320,8 +338,7 @@ static void group_onAction(ToxWindow *self, Tox *m, uint32_t groupnum, uint32_t
box_silent_notify2(self, NT_NOFOCUS, self->active_box, "* %s %s", nick, action ); box_silent_notify2(self, NT_NOFOCUS, self->active_box, "* %s %s", nick, action );
else else
box_silent_notify(self, NT_NOFOCUS, &self->active_box, self->name, "* %s %s", nick, action); box_silent_notify(self, NT_NOFOCUS, &self->active_box, self->name, "* %s %s", nick, action);
} } else {
else {
sound_notify(self, silent, NT_WNDALERT_1, NULL); sound_notify(self, silent, NT_WNDALERT_1, NULL);
} }
@ -366,8 +383,7 @@ static void groupchat_onGroupMessage(ToxWindow *self, Tox *m, uint32_t groupnum,
box_silent_notify(self, NT_NOFOCUS, &self->active_box, self->name, "%s %s", nick, msg); box_silent_notify(self, NT_NOFOCUS, &self->active_box, self->name, "%s %s", nick, msg);
nick_clr = RED; nick_clr = RED;
} } else {
else {
sound_notify(self, silent, NT_WNDALERT_1, NULL); sound_notify(self, silent, NT_WNDALERT_1, NULL);
} }
@ -485,51 +501,8 @@ static void groupchat_onGroupPassword(ToxWindow *self, Tox *m, uint32_t groupnum
} }
} }
/* Copies peer names/lengths */
static void copy_peernames(int gnum, uint8_t peerlist[][TOX_MAX_NAME_LENGTH], uint16_t lengths[], int npeers)
{
free(groupchats[gnum].peer_names);
free(groupchats[gnum].peer_name_lengths);
int N = TOX_MAX_NAME_LENGTH;
groupchats[gnum].peer_names = calloc(1, sizeof(uint8_t) * MAX(1, npeers) * N);
groupchats[gnum].peer_name_lengths = calloc(1, sizeof(uint32_t) * MAX(1, npeers));
if (groupchats[gnum].peer_names == NULL || groupchats[gnum].peer_name_lengths == NULL)
exit_toxic_err("failed in copy_peernames", FATALERR_MEMORY);
if (npeers == 0)
return;
uint16_t u_len = strlen(UNKNOWN_NAME);
int i;
for (i = 0; i < npeers; ++i) {
if (!lengths[i]) {
memcpy(&groupchats[gnum].peer_names[i * N], UNKNOWN_NAME, u_len);
groupchats[gnum].peer_names[i * N + u_len] = '\0';
groupchats[gnum].peer_name_lengths[i] = u_len;
} else {
uint16_t n_len = MIN(lengths[i], TOXIC_MAX_NAME_LENGTH - 1);
memcpy(&groupchats[gnum].peer_names[i * N], peerlist[i], n_len);
groupchats[gnum].peer_names[i * N + n_len] = '\0';
groupchats[gnum].peer_name_lengths[i] = n_len;
filter_str((char *) &groupchats[gnum].peer_names[i * N], n_len);
}
}
}
/* copies name to dest and assigns len to dest_len. dest must have room for TOX_MAX_NAME_LENGTH */
static void copy_temp_peernames(uint8_t *dest, uint16_t *dest_len, const char *name, size_t len)
{
*dest_len = (uint16_t) len;
memcpy(dest, name, *dest_len);
dest[*dest_len] = '\0';
}
/* TODO: This function could probably be cleaned up and optimized */ /* TODO: This function could probably be cleaned up and optimized */
static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, uint32_t groupnum) static void groupchat_onGroupPeerlistUpdate(ToxWindow *self, Tox *m, uint32_t groupnum)
{ {
if (self->num != groupnum) if (self->num != groupnum)
return; return;
@ -540,29 +513,42 @@ static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, uint32_t gr
if (num_peers == 0 || err != TOX_ERR_GROUP_STATE_QUERIES_OK) if (num_peers == 0 || err != TOX_ERR_GROUP_STATE_QUERIES_OK)
return; return;
uint8_t tmp_peerlist[num_peers][TOX_MAX_NAME_LENGTH]; GroupChat *chat = &groupchats[groupnum];
uint16_t tmp_peerlens[num_peers]; chat->num_peers = num_peers;
if (chat->peer_list)
free(chat->peer_list);
chat->peer_list = malloc(sizeof(struct GroupPeer) * num_peers);
if (chat->peer_list == NULL)
exit_toxic_err("failed in groupchat_onGroupPeerlistUpdate", FATALERR_MEMORY);
uint32_t i; uint32_t i;
for (i = 0; i < num_peers; ++i) { for (i = 0; i < num_peers; ++i) {
TOX_ERR_GROUP_PEER_QUERY name_err; memset(&chat->peer_list[i], 0, sizeof(struct GroupPeer));
size_t len = tox_group_peer_get_name_size(m, groupnum, i, &name_err);
if (name_err != TOX_ERR_GROUP_PEER_QUERY_OK) { TOX_ERR_GROUP_PEER_QUERY err;
copy_temp_peernames(tmp_peerlist[i], &tmp_peerlens[i], UNKNOWN_NAME, strlen(UNKNOWN_NAME)); size_t name_length = tox_group_peer_get_name_size(m, groupnum, i, &err);
} else {
char name[len];
if (tox_group_peer_get_name(m, groupnum, i, (uint8_t *) name, NULL)) if (err != TOX_ERR_GROUP_PEER_QUERY_OK)
copy_temp_peernames(tmp_peerlist[i], &tmp_peerlens[i], name, len); name_length = 0;
else else
copy_temp_peernames(tmp_peerlist[i], &tmp_peerlens[i], UNKNOWN_NAME, strlen(UNKNOWN_NAME)); name_length = MIN(name_length, TOX_MAX_NAME_LENGTH - 1);
}
if (!tox_group_peer_get_name(m, groupnum, i, (uint8_t *) chat->peer_list[i].name, NULL)) {
chat->peer_list[i].name_length = strlen(UNKNOWN_NAME);
memcpy(chat->peer_list[i].name, UNKNOWN_NAME, chat->peer_list[i].name_length);
} }
groupchats[groupnum].num_peers = num_peers; chat->peer_list[i].name[name_length] = '\0';
copy_peernames(groupnum, tmp_peerlist, tmp_peerlens, num_peers); chat->peer_list[i].name_length = name_length;
chat->peer_list[i].status = tox_group_peer_get_status(m, groupnum, i, NULL);
chat->peer_list[i].role = tox_group_peer_get_role(m, groupnum, i, NULL);
}
group_update_name_list(groupnum);
} }
static void groupchat_onGroupPeerJoin(ToxWindow *self, Tox *m, uint32_t groupnum, uint32_t peernum) static void groupchat_onGroupPeerJoin(ToxWindow *self, Tox *m, uint32_t groupnum, uint32_t peernum)
@ -707,6 +693,8 @@ static void groupchat_onGroupModeration(ToxWindow *self, Tox *m, uint32_t groupn
if (groupnum != self->num) if (groupnum != self->num)
return; return;
GroupChat *chat = &groupchats[groupnum];
char src_name[TOX_MAX_NAME_LENGTH]; char src_name[TOX_MAX_NAME_LENGTH];
char tgt_name[TOX_MAX_NAME_LENGTH]; char tgt_name[TOX_MAX_NAME_LENGTH];
@ -727,12 +715,15 @@ static void groupchat_onGroupModeration(ToxWindow *self, Tox *m, uint32_t groupn
line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 1, RED, "-!- %s has been banned by %s", tgt_name, src_name); line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 1, RED, "-!- %s has been banned by %s", tgt_name, src_name);
break; break;
case TOX_GROUP_MOD_EVENT_OBSERVER: case TOX_GROUP_MOD_EVENT_OBSERVER:
chat->peer_list[tgt_peernum].role = TOX_GROUP_ROLE_OBSERVER;
line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 1, BLUE, "-!- %s has set %s's role to observer", src_name, tgt_name); line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 1, BLUE, "-!- %s has set %s's role to observer", src_name, tgt_name);
break; break;
case TOX_GROUP_MOD_EVENT_USER: case TOX_GROUP_MOD_EVENT_USER:
chat->peer_list[tgt_peernum].role = TOX_GROUP_ROLE_USER;
line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 1, BLUE, "-!- %s has set %s's role to user", src_name, tgt_name); line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 1, BLUE, "-!- %s has set %s's role to user", src_name, tgt_name);
break; break;
case TOX_GROUP_MOD_EVENT_MODERATOR: case TOX_GROUP_MOD_EVENT_MODERATOR:
chat->peer_list[tgt_peernum].role = TOX_GROUP_ROLE_MODERATOR;
line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 1, BLUE, "-!- %s has set %s's role to moderator", src_name, tgt_name); line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 1, BLUE, "-!- %s has set %s's role to moderator", src_name, tgt_name);
break; break;
default: default:
@ -746,14 +737,32 @@ static void groupchat_onGroupNickChange(ToxWindow *self, Tox *m, uint32_t groupn
if (groupnum != self->num) if (groupnum != self->num)
return; return;
GroupChat *chat = &groupchats[groupnum];
char oldnick[TOX_MAX_NAME_LENGTH]; char oldnick[TOX_MAX_NAME_LENGTH];
get_group_nick_truncate(m, oldnick, peernum, groupnum); get_group_nick_truncate(m, oldnick, peernum, groupnum);
len = MAX(len, TOX_MAX_NAME_LENGTH - 1);
memcpy(groupchats[groupnum].peer_list[peernum].name, newnick, len);
chat->peer_list[peernum].name[len] = '\0';
chat->peer_list[peernum].name_length = len;
char timefrmt[TIME_STR_SIZE]; char timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt, sizeof(timefrmt)); get_time_str(timefrmt, sizeof(timefrmt));
line_info_add(self, timefrmt, oldnick, newnick, NAME_CHANGE, 0, MAGENTA, " is now known as "); line_info_add(self, timefrmt, oldnick, chat->peer_list[peernum].name, NAME_CHANGE, 0, MAGENTA, " is now known as ");
group_update_name_list(groupnum);
} }
static void groupchat_onGroupStatusChange(ToxWindow *self, Tox *m, uint32_t groupnum, uint32_t peernum,
TOX_USER_STATUS status)
{
if (groupnum != self->num)
return;
GroupChat *chat = &groupchats[groupnum];
chat->peer_list[peernum].status = status;
}
static void send_group_message(ToxWindow *self, Tox *m, uint32_t groupnum, const char *msg, TOX_MESSAGE_TYPE type) static void send_group_message(ToxWindow *self, Tox *m, uint32_t groupnum, const char *msg, TOX_MESSAGE_TYPE type)
{ {
@ -804,6 +813,7 @@ static void send_group_message(ToxWindow *self, Tox *m, uint32_t groupnum, const
static void send_group_prvt_message(ToxWindow *self, Tox *m, uint32_t groupnum, const char *data) static void send_group_prvt_message(ToxWindow *self, Tox *m, uint32_t groupnum, const char *data)
{ {
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
GroupChat *chat = &groupchats[groupnum];
if (data == NULL) { if (data == NULL) {
wprintw(ctx->history, "Message is empty.\n"); wprintw(ctx->history, "Message is empty.\n");
@ -815,12 +825,11 @@ static void send_group_prvt_message(ToxWindow *self, Tox *m, uint32_t groupnum,
char *nick = NULL; char *nick = NULL;
/* need to match the longest nick in case of nicks that are smaller sub-strings */ /* need to match the longest nick in case of nicks that are smaller sub-strings */
for (i = 0; i < groupchats[groupnum].num_peers; ++i) { for (i = 0; i < chat->num_peers; ++i) {
if (memcmp((char *) &groupchats[groupnum].peer_names[i * TOX_MAX_NAME_LENGTH], data, if (memcmp(chat->peer_list[i].name, data, chat->peer_list[i].name_length) == 0) {
groupchats[groupnum].peer_name_lengths[i]) == 0) { if (chat->peer_list[i].name_length > nick_len) {
if (groupchats[groupnum].peer_name_lengths[i] > nick_len) { nick_len = chat->peer_list[i].name_length;
nick_len = groupchats[groupnum].peer_name_lengths[i]; nick = chat->peer_list[i].name;
nick = (char *) &groupchats[groupnum].peer_names[i * TOX_MAX_NAME_LENGTH];
peernum = i; peernum = i;
} }
} }
@ -831,12 +840,12 @@ static void send_group_prvt_message(ToxWindow *self, Tox *m, uint32_t groupnum,
return; return;
} }
int msg_len = strlen(data) - groupchats[groupnum].peer_name_lengths[peernum] - 1; int msg_len = strlen(data) - chat->peer_list[i].name_length - 1;
if (msg_len <= 0) if (msg_len <= 0)
return; return;
const char *msg = data + groupchats[groupnum].peer_name_lengths[peernum] + 1; const char *msg = data + chat->peer_list[i].name_length + 1;
TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE err; TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE err;
if (!tox_group_send_private_message(m, groupnum, peernum, (uint8_t *) msg, msg_len, &err)) { if (!tox_group_send_private_message(m, groupnum, peernum, (uint8_t *) msg, msg_len, &err)) {
@ -853,7 +862,7 @@ static void send_group_prvt_message(ToxWindow *self, Tox *m, uint32_t groupnum,
char pm_nick[TOX_MAX_NAME_LENGTH + 2]; char pm_nick[TOX_MAX_NAME_LENGTH + 2];
strcpy(pm_nick, ">"); strcpy(pm_nick, ">");
strcpy(pm_nick + 1, nick); strcpy(pm_nick + 1, nick);
strcpy(pm_nick + 1 + groupchats[groupnum].peer_name_lengths[peernum], "<"); strcpy(pm_nick + 1 + chat->peer_list[i].name_length, "<");
char timefrmt[TIME_STR_SIZE]; char timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt, sizeof(timefrmt)); get_time_str(timefrmt, sizeof(timefrmt));
@ -865,6 +874,7 @@ static void send_group_prvt_message(ToxWindow *self, Tox *m, uint32_t groupnum,
static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
{ {
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
GroupChat *chat = &groupchats[self->num];
int x, y, y2, x2; int x, y, y2, x2;
getyx(self->window, y, x); getyx(self->window, y, x);
@ -891,12 +901,11 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
if (key == '\t') { /* TAB key: auto-completes peer name or command */ if (key == '\t') { /* TAB key: auto-completes peer name or command */
if (ctx->len > 0) { if (ctx->len > 0) {
int diff; int diff = -1;
/* TODO: make this not suck */ /* TODO: make this not suck */
if (ctx->line[0] != L'/' || wcschr(ctx->line, L' ') != NULL) { if (ctx->line[0] != L'/' || wcschr(ctx->line, L' ') != NULL) {
diff = complete_line(self, groupchats[self->num].peer_names, groupchats[self->num].num_peers, diff = complete_line(self, chat->name_list, chat->num_peers, TOX_MAX_NAME_LENGTH);
TOX_MAX_NAME_LENGTH);
} else if (wcsncmp(ctx->line, L"/avatar \"", wcslen(L"/avatar \"")) == 0) { } else if (wcsncmp(ctx->line, L"/avatar \"", wcslen(L"/avatar \"")) == 0) {
diff = dir_match(self, m, ctx->line, L"/avatar"); diff = dir_match(self, m, ctx->line, L"/avatar");
} else { } else {
@ -918,10 +927,10 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
int L = y2 - CHATBOX_HEIGHT - SDBAR_OFST; int L = y2 - CHATBOX_HEIGHT - SDBAR_OFST;
if (groupchats[self->num].side_pos < groupchats[self->num].num_peers - L) if (groupchats[self->num].side_pos < groupchats[self->num].num_peers - L)
++groupchats[self->num].side_pos; ++chat->side_pos;
} else if (key == user_settings->key_peer_list_up) { } else if (key == user_settings->key_peer_list_up) {
if (groupchats[self->num].side_pos > 0) if (groupchats[self->num].side_pos > 0)
--groupchats[self->num].side_pos; --chat->side_pos;
} else if (key == '\n') { } else if (key == '\n') {
rm_trailing_spaces_buf(ctx); rm_trailing_spaces_buf(ctx);
@ -965,6 +974,7 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m)
getmaxyx(self->window, y2, x2); getmaxyx(self->window, y2, x2);
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
GroupChat *chat = &groupchats[self->num];
pthread_mutex_lock(&Winthread.lock); pthread_mutex_lock(&Winthread.lock);
line_info_print(self); line_info_print(self);
@ -986,11 +996,9 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m)
pthread_mutex_lock(&Winthread.lock); pthread_mutex_lock(&Winthread.lock);
uint32_t num_peers = groupchats[self->num].num_peers;
wmove(ctx->sidebar, 0, 1); wmove(ctx->sidebar, 0, 1);
wattron(ctx->sidebar, A_BOLD); wattron(ctx->sidebar, A_BOLD);
wprintw(ctx->sidebar, "Peers: %d\n", num_peers); wprintw(ctx->sidebar, "Peers: %d\n", chat->num_peers);
wattroff(ctx->sidebar, A_BOLD); wattroff(ctx->sidebar, A_BOLD);
mvwaddch(ctx->sidebar, 1, 0, ACS_LTEE); mvwaddch(ctx->sidebar, 1, 0, ACS_LTEE);
@ -999,48 +1007,36 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m)
int maxlines = y2 - SDBAR_OFST - CHATBOX_HEIGHT; int maxlines = y2 - SDBAR_OFST - CHATBOX_HEIGHT;
uint32_t i; uint32_t i;
for (i = 0; i < num_peers && i < maxlines; ++i) { for (i = 0; i < chat->num_peers && i < maxlines; ++i) {
wmove(ctx->sidebar, i + 2, 1); wmove(ctx->sidebar, i + 2, 1);
int peer = i + groupchats[self->num].side_pos; int peer = i + chat->side_pos;
/* TODO: Make this not poll */ int maxlen_offset = chat->peer_list[i].role == TOX_GROUP_ROLE_USER ? 2 : 3;
TOX_ERR_GROUP_PEER_QUERY err;
TOX_USER_STATUS status = tox_group_peer_get_status(m, self->num, i, &err);
if (err != TOX_ERR_GROUP_PEER_QUERY_OK)
status = TOX_USER_STATUS_NONE;
TOX_GROUP_ROLE role = tox_group_peer_get_role(m, self->num, i, &err);
if (err != TOX_ERR_GROUP_PEER_QUERY_OK)
role = TOX_GROUP_ROLE_USER;
int maxlen_offset = role == TOX_GROUP_ROLE_USER ? 2 : 3;
/* truncate nick to fit in side panel without modifying list */ /* truncate nick to fit in side panel without modifying list */
char tmpnck[TOX_MAX_NAME_LENGTH]; char tmpnck[TOX_MAX_NAME_LENGTH];
int maxlen = SIDEBAR_WIDTH - maxlen_offset; int maxlen = SIDEBAR_WIDTH - maxlen_offset;
memcpy(tmpnck, &groupchats[self->num].peer_names[peer * TOX_MAX_NAME_LENGTH], maxlen); memcpy(tmpnck, chat->peer_list[peer].name, maxlen);
tmpnck[maxlen] = '\0'; tmpnck[maxlen] = '\0';
int namecolour = WHITE; int namecolour = WHITE;
if (status == TOX_USER_STATUS_AWAY) if (chat->peer_list[i].status == TOX_USER_STATUS_AWAY)
namecolour = YELLOW; namecolour = YELLOW;
else if (status == TOX_USER_STATUS_BUSY) else if (chat->peer_list[i].status == TOX_USER_STATUS_BUSY)
namecolour = RED; namecolour = RED;
/* Signify roles (e.g. founder, moderator) */ /* Signify roles (e.g. founder, moderator) */
const char *rolesig = ""; const char *rolesig = "";
int rolecolour = WHITE; int rolecolour = WHITE;
if (role == TOX_GROUP_ROLE_FOUNDER) { if (chat->peer_list[i].role == TOX_GROUP_ROLE_FOUNDER) {
rolesig = "&"; rolesig = "&";
rolecolour = BLUE; rolecolour = BLUE;
} else if (role == TOX_GROUP_ROLE_MODERATOR) { } else if (chat->peer_list[i].role == TOX_GROUP_ROLE_MODERATOR) {
rolesig = "+"; rolesig = "+";
rolecolour = GREEN; rolecolour = GREEN;
} else if (role == TOX_GROUP_ROLE_OBSERVER) { } else if (chat->peer_list[i].role == TOX_GROUP_ROLE_OBSERVER) {
rolesig = "-"; rolesig = "-";
rolecolour = MAGENTA; rolecolour = MAGENTA;
} }
@ -1112,7 +1108,7 @@ ToxWindow new_group_chat(Tox *m, uint32_t groupnum, const char *groupname, int l
ret.onDraw = &groupchat_onDraw; ret.onDraw = &groupchat_onDraw;
ret.onInit = &groupchat_onInit; ret.onInit = &groupchat_onInit;
ret.onGroupMessage = &groupchat_onGroupMessage; ret.onGroupMessage = &groupchat_onGroupMessage;
ret.onGroupNamelistChange = &groupchat_onGroupNamelistChange; ret.onGroupPeerlistUpdate = &groupchat_onGroupPeerlistUpdate;
ret.onGroupPrivateMessage = &groupchat_onGroupPrivateMessage; ret.onGroupPrivateMessage = &groupchat_onGroupPrivateMessage;
ret.onGroupPeerJoin = &groupchat_onGroupPeerJoin; ret.onGroupPeerJoin = &groupchat_onGroupPeerJoin;
ret.onGroupPeerExit = &groupchat_onGroupPeerExit; ret.onGroupPeerExit = &groupchat_onGroupPeerExit;
@ -1121,6 +1117,7 @@ ToxWindow new_group_chat(Tox *m, uint32_t groupnum, const char *groupname, int l
ret.onGroupPrivacyState = &groupchat_onGroupPrivacyState; ret.onGroupPrivacyState = &groupchat_onGroupPrivacyState;
ret.onGroupPassword = &groupchat_onGroupPassword; ret.onGroupPassword = &groupchat_onGroupPassword;
ret.onGroupNickChange = &groupchat_onGroupNickChange; ret.onGroupNickChange = &groupchat_onGroupNickChange;
ret.onGroupStatusChange = &groupchat_onGroupStatusChange;
ret.onGroupSelfJoin = &groupchat_onGroupSelfJoin; ret.onGroupSelfJoin = &groupchat_onGroupSelfJoin;
ret.onGroupRejected = &groupchat_onGroupRejected; ret.onGroupRejected = &groupchat_onGroupRejected;
ret.onGroupModeration = &groupchat_onGroupModeration; ret.onGroupModeration = &groupchat_onGroupModeration;

View File

@ -26,50 +26,27 @@
#include "toxic.h" #include "toxic.h"
#include "windows.h" #include "windows.h"
#ifdef AUDIO
#include "audio_call.h"
#endif
#ifdef AUDIO
#ifdef __APPLE__
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#else
#include <AL/al.h>
#include <AL/alc.h>
/* compatibility with older versions of OpenAL */
#ifndef ALC_ALL_DEVICES_SPECIFIER
#include <AL/alext.h>
#endif /* ALC_ALL_DEVICES_SPECIFIER */
#endif /* __APPLE__ */
#endif /* AUDIO */
#define SIDEBAR_WIDTH 16 #define SIDEBAR_WIDTH 16
#define SDBAR_OFST 2 /* Offset for the peer number box at the top of the statusbar */ #define SDBAR_OFST 2 /* Offset for the peer number box at the top of the statusbar */
#define MAX_GROUPCHAT_NUM MAX_WINDOWS_NUM - 2 #define MAX_GROUPCHAT_NUM MAX_WINDOWS_NUM - 2
#define GROUP_EVENT_WAIT 3 #define GROUP_EVENT_WAIT 3
#ifdef AUDIO struct GroupPeer {
struct GAudio { char name[TOX_MAX_NAME_LENGTH];
ALCdevice *dvhandle; /* Handle of device selected/opened */ size_t name_length;
ALCcontext *dvctx; TOX_USER_STATUS status;
ALuint source; TOX_GROUP_ROLE role;
ALuint buffers[OPENAL_BUFS];
}; };
#endif /* AUDIO */
typedef struct { typedef struct {
struct GroupPeer *peer_list;
char *name_list; /* List of peer names, needed for tab completion */
uint32_t num_peers;
uint32_t groupnumber; uint32_t groupnumber;
int chatwin; int chatwin;
bool active; bool active;
bool is_connected; bool is_connected;
int side_pos; /* current position of the sidebar - used for scrolling up and down */ int side_pos; /* current position of the sidebar - used for scrolling up and down */
uint32_t num_peers;
uint8_t *peer_names;
uint16_t *peer_name_lengths;
#ifdef AUDIO
struct GAudio audio;
#endif
} GroupChat; } GroupChat;
void close_groupchat(ToxWindow *self, Tox *m, uint32_t groupnum); void close_groupchat(ToxWindow *self, Tox *m, uint32_t groupnum);
@ -78,7 +55,7 @@ void set_nick_all_groups(Tox *m, const char *nick, size_t length);
void set_status_all_groups(Tox *m, uint8_t status); void set_status_all_groups(Tox *m, uint8_t status);
int group_get_nick_peernumber(uint32_t groupnum, const char *nick); int group_get_nick_peernumber(uint32_t groupnum, const char *nick);
/* destroys and re-creates groupchat window with or without the peerlist */ /* destroys and re-creates groupchat window */
void redraw_groupchat_win(ToxWindow *self); void redraw_groupchat_win(ToxWindow *self);
#endif /* #define GROUPCHAT_H */ #endif /* #define GROUPCHAT_H */

View File

@ -574,6 +574,7 @@ static void init_tox_callbacks(Tox *m)
tox_callback_group_peer_join(m, on_group_peer_join, NULL); tox_callback_group_peer_join(m, on_group_peer_join, NULL);
tox_callback_group_peer_exit(m, on_group_peer_exit, NULL); tox_callback_group_peer_exit(m, on_group_peer_exit, NULL);
tox_callback_group_peer_name(m, on_group_nick_change, NULL); tox_callback_group_peer_name(m, on_group_nick_change, NULL);
tox_callback_group_peer_status(m, on_group_status_change, NULL);
tox_callback_group_topic(m, on_group_topic_change, NULL); tox_callback_group_topic(m, on_group_topic_change, NULL);
tox_callback_group_peer_limit(m, on_group_peer_limit, NULL); tox_callback_group_peer_limit(m, on_group_peer_limit, NULL);
tox_callback_group_privacy_state(m, on_group_privacy_state, NULL); tox_callback_group_privacy_state(m, on_group_privacy_state, NULL);

View File

@ -127,6 +127,7 @@ void on_group_peer_limit(Tox *m, uint32_t groupnumber, uint32_t peer_limit, void
void on_group_privacy_state(Tox *m, uint32_t groupnumber, TOX_GROUP_PRIVACY_STATE privacy_state, void *userdata); void on_group_privacy_state(Tox *m, uint32_t groupnumber, TOX_GROUP_PRIVACY_STATE privacy_state, void *userdata);
void on_group_password(Tox *m, uint32_t groupnumber, const uint8_t *password, size_t length, void *userdata); void on_group_password(Tox *m, uint32_t groupnumber, const uint8_t *password, size_t length, void *userdata);
void on_group_nick_change(Tox *m, uint32_t groupnumber, uint32_t peernumber, const uint8_t *newname, size_t length, void *userdata); void on_group_nick_change(Tox *m, uint32_t groupnumber, uint32_t peernumber, const uint8_t *newname, size_t length, void *userdata);
void on_group_status_change(Tox *m, uint32_t groupnumber, uint32_t peernumber, TOX_USER_STATUS status, void *userdata);
void on_group_self_join(Tox *m, uint32_t groupnumber, void *userdata); void on_group_self_join(Tox *m, uint32_t groupnumber, void *userdata);
void on_group_rejected(Tox *m, uint32_t groupnumber, TOX_GROUP_JOIN_FAIL type, void *userdata); void on_group_rejected(Tox *m, uint32_t groupnumber, TOX_GROUP_JOIN_FAIL type, void *userdata);
void on_group_moderation(Tox *m, uint32_t groupnumber, uint32_t source_peernum, uint32_t target_peernum, void on_group_moderation(Tox *m, uint32_t groupnumber, uint32_t source_peernum, uint32_t target_peernum,

View File

@ -194,8 +194,18 @@ void on_group_namelistchange(Tox *m, uint32_t groupnumber, void *userdata)
size_t i; size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) { for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onGroupNamelistChange != NULL) if (windows[i].onGroupPeerlistUpdate != NULL)
windows[i].onGroupNamelistChange(&windows[i], m, groupnumber); windows[i].onGroupPeerlistUpdate(&windows[i], m, groupnumber);
}
}
void on_group_status_change(Tox *m, uint32_t groupnumber, uint32_t peernumber, TOX_USER_STATUS status, void *userdata)
{
size_t i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i].onGroupStatusChange != NULL)
windows[i].onGroupStatusChange(&windows[i], m, groupnumber, peernumber, status);
} }
} }

View File

@ -131,10 +131,11 @@ struct ToxWindow {
void(*onGroupInvite)(ToxWindow *, Tox *, int32_t, const char *, size_t); void(*onGroupInvite)(ToxWindow *, Tox *, int32_t, const char *, size_t);
void(*onGroupMessage)(ToxWindow *, Tox *, uint32_t, uint32_t, TOX_MESSAGE_TYPE, const char *, size_t); void(*onGroupMessage)(ToxWindow *, Tox *, uint32_t, uint32_t, TOX_MESSAGE_TYPE, const char *, size_t);
void(*onGroupPrivateMessage)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t); void(*onGroupPrivateMessage)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t);
void(*onGroupNamelistChange)(ToxWindow *, Tox *, uint32_t); void(*onGroupPeerlistUpdate)(ToxWindow *, Tox *, uint32_t);
void(*onGroupPeerJoin)(ToxWindow *, Tox *, uint32_t, uint32_t); void(*onGroupPeerJoin)(ToxWindow *, Tox *, uint32_t, uint32_t);
void(*onGroupPeerExit)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t); void(*onGroupPeerExit)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t);
void(*onGroupNickChange)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t); void(*onGroupNickChange)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t);
void(*onGroupStatusChange)(ToxWindow *, Tox *, uint32_t, uint32_t, TOX_USER_STATUS);
void(*onGroupTopicChange)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t); void(*onGroupTopicChange)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t);
void(*onGroupPeerLimit)(ToxWindow *, Tox *, uint32_t, uint32_t); void(*onGroupPeerLimit)(ToxWindow *, Tox *, uint32_t, uint32_t);
void(*onGroupPrivacyState)(ToxWindow *, Tox *, uint32_t, TOX_GROUP_PRIVACY_STATE); void(*onGroupPrivacyState)(ToxWindow *, Tox *, uint32_t, TOX_GROUP_PRIVACY_STATE);