1
0
mirror of https://github.com/Tha14/toxic.git synced 2025-06-27 01:16:45 +02:00

Compare commits

...

13 Commits

Author SHA1 Message Date
d3c4008b59 fix: add ca-certificates support for termux in run_toxic.sh 2023-11-15 11:07:40 +02:00
30d01127e7 Remove invalid groupchat commands
These commands only work in audio conferences
2023-10-05 13:37:54 -04:00
85ab7592c9 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.
2023-10-03 20:33:37 -04:00
6cdd01da25 Fix syntax error in static build script 2023-09-03 08:16:42 -04:00
69e4ed452d tell compiler that exit_toxic funcs don't return 2023-08-26 08:05:43 -04:00
4c77e80a7f Fix ID lookup error messages
We now properly distinguish between ID lookups and domain name lookups
and print the appropriate error message for each given case
2023-08-09 10:39:27 -04:00
ff669be8d1 detach group names from global name
Group names are now set on a per-group basis and are not affected
by the global /nick command.
2023-04-04 16:16:57 -04:00
5d757e1230 Update help dialog height to fit the new commands
Made the "global" and "chat" help pages fit properly in the dialog again.
I also made the logic for deciding height for the chat page consistent with the other pages.
2023-03-04 17:07:15 -05:00
70ab422acc Update static build script 2023-03-04 10:11:37 -05:00
2a052edb9e Bump version to 0.12.0 & Update man pages
We no longer use libera as they were found to be spying on their
users' private conversations, so we've replaced it with a
public tox group via the new groupchat implementation
2023-03-04 09:52:15 -05:00
efbfa2c95c Remove toxme.io from nameservers list as it no longer exists 2023-01-11 13:16:13 -05:00
3f3e848b6f Show connection status in groupchat peerlist 2023-01-05 12:33:04 -05:00
8d125d5e6b Change conference invite, accept, Add NGC join, invite, accept 2023-01-05 19:12:00 +02:00
18 changed files with 347 additions and 104 deletions

View File

@ -55,9 +55,9 @@ author = 'Jakob Kreuze'
# built documents.
#
# The short X.Y version.
version = '0.11.3'
version = '0.12.0'
# The full version, including alpha/beta/rc tags.
release = '0.11.3'
release = '0.12.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -1,5 +1,5 @@
# Version
TOXIC_VERSION = 0.11.3
TOXIC_VERSION = 0.12.0
REV = $(shell git rev-list HEAD --count 2>/dev/null || echo -n "error")
ifneq (, $(findstring error, $(REV)))
VERSION = $(TOXIC_VERSION)

View File

@ -1,13 +1,13 @@
'\" t
.\" Title: toxic
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
.\" Date: 2021-05-24
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
.\" Date: 2021-12-05
.\" Manual: Toxic Manual
.\" Source: toxic __VERSION__
.\" Language: English
.\"
.TH "TOXIC" "1" "2021\-05\-24" "toxic __VERSION__" "Toxic Manual"
.TH "TOXIC" "1" "2021\-12\-05" "toxic __VERSION__" "Toxic Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@ -156,14 +156,14 @@ Configuration example\&.
\-Screen flickering sometimes occurs on certain terminals\&.
.sp
\-Resizing the terminal window when a game window is open will break things\&.
.SH "LINKS"
.sp
Project page: https://github\&.com/JFreegman/toxic
.sp
Tox development group public key: 360497DA684BCE2A500C1AF9B3A5CE949BBB9F6FB1F91589806FB04CA039E313
.SH "AUTHORS"
.sp
JFreegman <JFreegman@gmail\&.com>
.SH "SEE ALSO"
.sp
\fBtoxic\&.conf\fR(5)
.SH "LINKS"
.sp
Project page: https://github\&.com/JFreegman/toxic
.sp
IRC channel: irc\&.libera\&.chat#tox

View File

@ -93,6 +93,12 @@ behaviour.
-Resizing the terminal window when a game window is open will break things.
LINKS
-----
Project page: <https://github.com/JFreegman/toxic>
Tox development group public key: 360497DA684BCE2A500C1AF9B3A5CE949BBB9F6FB1F91589806FB04CA039E313
AUTHORS
-------
JFreegman <JFreegman@gmail.com>
@ -100,9 +106,3 @@ JFreegman <JFreegman@gmail.com>
SEE ALSO
--------
*toxic.conf*(5)
LINKS
-----
Project page: <https://github.com/JFreegman/toxic>
IRC channel: irc.libera.chat#tox

View File

@ -1,13 +1,13 @@
'\" t
.\" Title: toxic.conf
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
.\" Date: 2020-11-12
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
.\" Date: 2022-06-27
.\" Manual: Toxic Manual
.\" Source: toxic __VERSION__
.\" Language: English
.\"
.TH "TOXIC\&.CONF" "5" "2020\-11\-12" "toxic __VERSION__" "Toxic Manual"
.TH "TOXIC\&.CONF" "5" "2022\-06\-27" "toxic __VERSION__" "Toxic Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@ -417,14 +417,14 @@ __DATADIR__/toxic\&.conf\&.example
.RS 4
Configuration example\&.
.RE
.SH "SEE ALSO"
.sp
\fBtoxic\fR(1)
.SH "RESOURCES"
.sp
Project page: https://github\&.com/JFreegman/toxic
.sp
IRC channel: irc\&.libera\&.chat#tox
Tox development group public key: 360497DA684BCE2A500C1AF9B3A5CE949BBB9F6FB1F91589806FB04CA039E313
.SH "AUTHORS"
.sp
JFreegman <JFreegman@gmail\&.com>
.SH "SEE ALSO"
.sp
\fBtoxic\fR(1)

View File

@ -263,19 +263,19 @@ FILES
{datadir}/toxic.conf.example::
Configuration example.
RESOURCES
---------
Project page: <https://github.com/JFreegman/toxic>
Tox development group public key: 360497DA684BCE2A500C1AF9B3A5CE949BBB9F6FB1F91589806FB04CA039E313
AUTHORS
-------
JFreegman <JFreegman@gmail.com>
SEE ALSO
--------
*toxic*(1)
RESOURCES
---------
Project page: <https://github.com/JFreegman/toxic>
IRC channel: irc.libera.chat#tox
AUTHORS
-------
JFreegman <JFreegman@gmail.com>

View File

@ -1 +0,0 @@
toxme.io 1A39E7A5D5FA9CF155C751570A32E625698A60A55F6D88028F949F66144F4F25

View File

@ -136,10 +136,10 @@ mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
# The git hash of the c-toxcore version we're using
TOXCORE_VERSION="0a277b52ea22fe297a8487ac05a0c507a74c6480"
TOXCORE_VERSION="172f279dc0647a538b30e62c96bab8bb1b0c8960"
# The sha256sum of the c-toxcore tarball for TOXCORE_VERSION
TOXCORE_HASH="a63f3d8c9ee8bf51dd40fd0035914a73b4214e8d314c06f38a366c79c20278fb"
TOXCORE_HASH="9884d4ad9b80917e22495c2ebe7a76c509fb98c61031824562883225e66684ae"
TOXCORE_FILENAME="c-toxcore-$TOXCORE_VERSION.tar.gz"
@ -157,7 +157,7 @@ CMP_FILENAME="cmp-$CMP_VERSION.tar.gz"
wget --timeout=10 -O "$CMP_FILENAME" "https://github.com/TokTok/cmp/archive/$CMP_VERSION.tar.gz"
tar -o -xf "$CMP_FILENAME"
mv cmp\-*/* "cmp/"
mv cmp-*/* 'cmp/'
cd ..
cmake -B_build -H. \
@ -180,8 +180,8 @@ cmake --build _build --target install
# location with SSL_CERT_FILE env variable.
cd "$BUILD_DIR"
CURL_VERSION="7.81.0"
CURL_HASH="ac8e1087711084548d788ef18b9b732c8de887457b81f616fc681d1044b32f98"
CURL_VERSION="7.88.1"
CURL_HASH="cdb38b72e36bc5d33d5b8810f8018ece1baa29a8f215b4495e495ded82bbf3c7"
CURL_FILENAME="curl-$CURL_VERSION.tar.gz"
wget --timeout=10 -O "$CURL_FILENAME" "https://curl.haxx.se/download/$CURL_FILENAME"
@ -277,6 +277,7 @@ echo '#!/usr/bin/env sh
DEBIAN_SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
RHEL_SSL_CERT_FILE=/etc/pki/tls/certs/ca-bundle.crt
OPENSUSE_CERT_FILE=/etc/ssl/ca-bundle.pem
TERMUX_CERT_FILE=/data/data/com.termux/files/usr/etc/tls/cert.pem
if [ ! -f "$SSL_CERT_FILE" ] ; then
if [ -f "$DEBIAN_SSL_CERT_FILE" ] ; then
@ -285,6 +286,8 @@ if [ ! -f "$SSL_CERT_FILE" ] ; then
SSL_CERT_FILE="$RHEL_SSL_CERT_FILE"
elif [ -f "$OPENSUSE_CERT_FILE" ] ; then
SSL_CERT_FILE="$OPENSUSE_CERT_FILE"
elif [ -f "$TERMUX_CERT_FILE" ] ; then
SSL_CERT_FILE="$TERMUX_CERT_FILE"
fi
fi

View File

@ -130,6 +130,7 @@ static struct cmd_func groupchat_commands[] = {
{ "/list", cmd_list },
{ "/locktopic", cmd_set_topic_lock },
{ "/mod", cmd_mod },
{ "/nick", cmd_group_nick },
{ "/passwd", cmd_set_passwd },
{ "/peerlimit", cmd_set_peerlimit },
{ "/privacy", cmd_set_privacy },
@ -141,10 +142,6 @@ static struct cmd_func groupchat_commands[] = {
{ "/unsilence", cmd_unsilence },
{ "/voice", cmd_set_voice },
{ "/whois", cmd_whois },
#ifdef AUDIO
{ "/mute", cmd_mute },
{ "/sense", cmd_sense },
#endif /* AUDIO */
{ NULL, NULL },
};

View File

@ -173,10 +173,16 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
char id_bin[TOX_ADDRESS_SIZE] = {0};
const bool is_tox_id = (char_find(0, id, '@') == arg_length) && (arg_length >= TOX_ADDRESS_SIZE * 2);
const bool is_domain = char_find(0, id, '@') != arg_length;
const bool valid_id_size = arg_length >= TOX_ADDRESS_SIZE * 2; // arg_length may include invite message
if (!is_tox_id) {
name_lookup(self, m, id_bin, id, msg);
if (is_domain) {
if (!name_lookup(self, m, id_bin, id, msg)) {
return;
}
} else if (!valid_id_size) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid Tox ID.");
return;
}
char xx[3];
@ -777,7 +783,6 @@ void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
tox_self_set_name(m, (uint8_t *) nick, len, NULL);
prompt_update_nick(prompt, nick);
set_nick_all_groups(m, nick, len);
store_data(m, DATA_FILE);
}

View File

@ -76,6 +76,32 @@ void cmd_disconnect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar
}
}
void cmd_group_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
UNUSED_VAR(window);
if (argc < 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Input required.");
return;
}
char nick[MAX_STR_SIZE];
snprintf(nick, sizeof(nick), "%s", argv[1]);
size_t len = strlen(nick);
if (!valid_nick(nick)) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid name.");
return;
}
len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1);
nick[len] = '\0';
set_nick_this_group(self, m, nick, len);
store_data(m, DATA_FILE);
}
void cmd_ignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
if (argc < 1) {
@ -115,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])
@ -816,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])

View File

@ -28,6 +28,7 @@
void cmd_chatid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_disconnect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_group_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_ignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_kick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_list(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);

View File

@ -117,12 +117,6 @@ static const char *group_cmd_list[] = {
"/voice",
"/whisper",
"/whois",
#ifdef AUDIO
"/lsdev",
"/sdev",
"/mute",
"/sense",
#endif /* AUDIO */
};
GroupChat groupchats[MAX_GROUPCHAT_NUM];
@ -138,6 +132,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 +235,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);
@ -363,40 +360,75 @@ int init_groupchat_win(Tox *m, uint32_t groupnumber, const char *groupname, size
return -1;
}
void set_nick_all_groups(Tox *m, const char *new_nick, size_t length)
void set_nick_this_group(ToxWindow *self, Tox *m, const char *new_nick, size_t length)
{
for (int i = 0; i < max_groupchat_index; ++i) {
if (groupchats[i].active) {
ToxWindow *self = get_window_ptr(groupchats[i].chatwin);
if (self == NULL) {
return;
}
if (!self) {
continue;
char old_nick[TOX_MAX_NAME_LENGTH + 1];
size_t old_length = get_group_self_nick_truncate(m, old_nick, self->num);
Tox_Err_Group_Self_Name_Set err;
tox_group_self_set_name(m, self->num, (uint8_t *) new_nick, length, &err);
GroupChat *chat = get_groupchat(self->num);
if (chat == NULL) {
line_info_add(self, false, NULL, 0, SYS_MSG, 0, RED, "-!- Failed to set nick: invalid groupnumber");
return;
}
switch (err) {
case TOX_ERR_GROUP_SELF_NAME_SET_OK: {
groupchat_onGroupSelfNickChange(self, m, self->num, old_nick, old_length, new_nick, length);
break;
}
default: {
if (chat->time_connected > 0) {
line_info_add(self, false, NULL, 0, SYS_MSG, 0, RED, "-!- Failed to set nick (error %d).", err);
}
char old_nick[TOX_MAX_NAME_LENGTH + 1];
size_t old_length = get_group_self_nick_truncate(m, old_nick, self->num);
Tox_Err_Group_Self_Name_Set err;
tox_group_self_set_name(m, groupchats[i].groupnumber, (uint8_t *) new_nick, length, &err);
switch (err) {
case TOX_ERR_GROUP_SELF_NAME_SET_OK: {
groupchat_onGroupSelfNickChange(self, m, self->num, old_nick, old_length, new_nick, length);
break;
}
default: {
if (groupchats[i].time_connected > 0) {
line_info_add(self, false, NULL, 0, SYS_MSG, 0, RED, "-!- Failed to set nick (error %d).", err);
}
break;
}
}
break;
}
}
}
/* void set_nick_all_groups(Tox *m, const char *new_nick, size_t length) */
/* { */
/* for (int i = 0; i < max_groupchat_index; ++i) { */
/* if (groupchats[i].active) { */
/* ToxWindow *self = get_window_ptr(groupchats[i].chatwin); */
/* if (!self) { */
/* continue; */
/* } */
/* char old_nick[TOX_MAX_NAME_LENGTH + 1]; */
/* size_t old_length = get_group_self_nick_truncate(m, old_nick, self->num); */
/* Tox_Err_Group_Self_Name_Set err; */
/* tox_group_self_set_name(m, groupchats[i].groupnumber, (uint8_t *) new_nick, length, &err); */
/* switch (err) { */
/* case TOX_ERR_GROUP_SELF_NAME_SET_OK: { */
/* groupchat_onGroupSelfNickChange(self, m, self->num, old_nick, old_length, new_nick, length); */
/* break; */
/* } */
/* default: { */
/* if (groupchats[i].time_connected > 0) { */
/* line_info_add(self, false, NULL, 0, SYS_MSG, 0, RED, "-!- Failed to set nick (error %d).", err); */
/* } */
/* break; */
/* } */
/* } */
/* } */
/* } */
/* } */
void set_status_all_groups(Tox *m, uint8_t status)
{
for (int i = 0; i < max_groupchat_index; ++i) {
@ -626,6 +658,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);
@ -992,7 +1149,12 @@ static void groupchat_onGroupPeerJoin(ToxWindow *self, Tox *m, uint32_t groupnum
peer->status = tox_group_peer_get_status(m, groupnumber, peer_id, NULL);
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);
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;
@ -1679,7 +1841,15 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m)
wattron(ctx->sidebar, A_BOLD);
pthread_mutex_lock(&Winthread.lock);
wprintw(ctx->sidebar, "Peers: %d\n", chat->num_peers);
if (chat->num_peers > 1) {
wprintw(ctx->sidebar, "Peers: %d\n", chat->num_peers);
} else if (tox_group_is_connected(m, self->num, NULL)) {
wprintw(ctx->sidebar, "Connecting...\n");
} else {
wprintw(ctx->sidebar, "Disconnected\n");
}
pthread_mutex_unlock(&Winthread.lock);
wattroff(ctx->sidebar, A_BOLD);
@ -1707,7 +1877,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];
@ -1742,6 +1917,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);

View File

@ -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;
@ -68,7 +72,7 @@ typedef struct {
void exit_groupchat(ToxWindow *self, Tox *m, uint32_t groupnumber, const char *partmessage, size_t length);
int init_groupchat_win(Tox *m, uint32_t groupnumber, const char *groupname, size_t length, Group_Join_Type join_type);
void set_nick_all_groups(Tox *m, const char *new_nick, size_t length);
void set_nick_this_group(ToxWindow *self, Tox *m, const char *new_nick, size_t length);
void set_status_all_groups(Tox *m, uint8_t status);
int get_peer_index(uint32_t groupnumber, uint32_t peer_id);
void groupchat_onGroupPeerExit(ToxWindow *self, Tox *m, uint32_t groupnumber, uint32_t peer_id,
@ -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 */

View File

@ -183,11 +183,12 @@ static void help_draw_global(ToxWindow *self)
wprintw(win, " /requests : List pending friend requests\n");
wprintw(win, " /status <type> : Set status (Online, Busy, Away)\n");
wprintw(win, " /note <msg> : Set a personal note\n");
wprintw(win, " /nick <nick> : Set your nickname\n");
wprintw(win, " /nick <name> : Set your global name (doesn't affect groups)\n");
wprintw(win, " /nospam <value> : Change part of your Tox ID to stop spam\n");
wprintw(win, " /log <on> or <off> : Enable/disable logging\n");
wprintw(win, " /myid : Print your Tox ID\n");
wprintw(win, " /group <name> : Create a new group chat\n");
wprintw(win, " /join <chatid> : Join a groupchat using a Chat ID\n");
#ifdef GAMES
wprintw(win, " /game : Play a game\n");
#endif /* GAMES */
@ -245,8 +246,10 @@ static void help_draw_chat(ToxWindow *self)
wprintw(win, "Chat Commands:\n");
wattroff(win, A_BOLD | COLOR_PAIR(RED));
wprintw(win, " /invite <n> : Invite contact to a conference \n");
wprintw(win, " /join : Join a pending conference\n");
wprintw(win, " /cinvite <n> : Invite contact to a conference \n");
wprintw(win, " /cjoin : Join a pending conference\n");
wprintw(win, " /invite <n> : Invite contact to a groupchat \n");
wprintw(win, " /gaccept <password> : Accept a pending groupchat invite\n");
wprintw(win, " /sendfile <path> : Send a file\n");
wprintw(win, " /savefile <id> : Receive a file\n");
wprintw(win, " /cancel <type> <id> : Cancel file transfer where type: in|out\n");
@ -304,6 +307,7 @@ static void help_draw_groupchats(ToxWindow *self)
wprintw(win, " /list : Print a list of peers currently in the group\n");
wprintw(win, " /locktopic : Set the topic lock: on | off\n");
wprintw(win, " /mod <name> : Promote a peer to moderator\n");
wprintw(win, " /nick <name> : Set your name for this group only\n");
wprintw(win, " /passwd <s> : Set a password needed to join the group\n");
wprintw(win, " /peerlimit <n> : Set the maximum number of peers that can join\n");
wprintw(win, " /privacy <state> : Set the privacy state: private | public\n");
@ -430,18 +434,21 @@ void help_onKey(ToxWindow *self, wint_t key)
break;
case L'c':
height = 12;
#ifdef VIDEO
help_init_window(self, 26, 80);
height += 15;
#elif AUDIO
help_init_window(self, 21, 80);
#else
help_init_window(self, 11, 80);
height += 5;
#endif
#ifdef GAMES
height += 1;
#endif
help_init_window(self, height, 80);
self->help->type = HELP_CHAT;
break;
case L'g':
height = 22;
height = 24;
#ifdef VIDEO
height += 8;
#elif AUDIO
@ -490,7 +497,7 @@ void help_onKey(ToxWindow *self, wint_t key)
break;
case L'r':
help_init_window(self, 26, 80);
help_init_window(self, 27, 80);
self->help->type = HELP_GROUP;
break;
}

View File

@ -362,16 +362,20 @@ on_exit:
return 0;
}
void name_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *message)
/* Attempts to do a tox name lookup.
*
* Returns true on success.
*/
bool name_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *message)
{
if (t_data.disabled) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "name lookups are disabled.");
return;
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "nameservers list is empty or does not exist.");
return false;
}
if (t_data.busy) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Please wait for previous name lookup to finish.");
return;
return false;
}
snprintf(t_data.id_bin, sizeof(t_data.id_bin), "%s", id_bin);
@ -384,22 +388,24 @@ void name_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr,
if (pthread_attr_init(&lookup_thread.attr) != 0) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, "Error: lookup thread attr failed to init");
clear_thread_data();
return;
return false;
}
if (pthread_attr_setdetachstate(&lookup_thread.attr, PTHREAD_CREATE_DETACHED) != 0) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, "Error: lookup thread attr failed to set");
pthread_attr_destroy(&lookup_thread.attr);
clear_thread_data();
return;
return false;
}
if (pthread_create(&lookup_thread.tid, &lookup_thread.attr, lookup_thread_func, NULL) != 0) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, "Error: lookup thread failed to init");
pthread_attr_destroy(&lookup_thread.attr);
clear_thread_data();
return;
return false;
}
return true;
}
/* Initializes http based name lookups. Note: This function must be called only once before additional

View File

@ -23,14 +23,19 @@
#ifndef NAME_LOOKUP
#define NAME_LOOKUP
/* Initializes http based name lookups. Note: This function must be called only once before additional
* threads are spawned.
/* Initializes http based name lookups.
*
* Note: This function must be called only once before additional threads are spawned.
*
* Returns 0 on success.
* Returns -1 on failure.
*/
int name_lookup_init(int curl_init_status);
int name_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *message);
/* Attempts to do a tox name lookup.
*
* Returns true on success.
*/
bool name_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *message);
#endif /* NAME_LOOKUP */

View File

@ -114,8 +114,8 @@ void flag_interface_refresh(void);
/* Sets ncurses refresh rate. Lower values make it refresh more often. */
void set_window_refresh_rate(size_t refresh_rate);
void exit_toxic_success(Tox *m);
void exit_toxic_err(const char *errmsg, int errcode);
void exit_toxic_success(Tox *m) __attribute__((__noreturn__));
void exit_toxic_err(const char *errmsg, int errcode) __attribute__((__noreturn__));
int store_data(Tox *m, const char *path);