Skip to content

Commit

Permalink
feat: Allow friend invites from group and conference windows
Browse files Browse the repository at this point in the history
Friends from the friend list can now be invited to groups and
conferences with the /invite and /cinvite commands respectively.
  • Loading branch information
JFreegman committed Dec 22, 2024
1 parent 76d6b1e commit d1887c5
Show file tree
Hide file tree
Showing 13 changed files with 207 additions and 19 deletions.
4 changes: 2 additions & 2 deletions src/chat_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ void cmd_cancelfile(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, cha
close_file_transfer(self, toxic, ft, TOX_FILE_CONTROL_CANCEL, msg, silent);
}

void cmd_conference_invite(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE])
void cmd_invite_to_conference(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE])
{
UNUSED_VAR(window);

Expand Down Expand Up @@ -275,7 +275,7 @@ void cmd_group_accept(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, c
}
}

void cmd_group_invite(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE])
void cmd_invite_to_group(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE])
{
if (toxic == NULL || self == NULL) {
return;
Expand Down
4 changes: 2 additions & 2 deletions src/chat_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@

void cmd_autoaccept_files(WINDOW *window, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_cancelfile(WINDOW *window, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_conference_invite(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_invite_to_conference(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_conference_join(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_group_accept(WINDOW *window, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_group_invite(WINDOW *window, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_invite_to_group(WINDOW *window, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_game_join(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_savefile(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_sendfile(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
Expand Down
16 changes: 16 additions & 0 deletions src/conference.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "autocomplete.h"
#include "conference.h"
#include "execute.h"
#include "friendlist.h"
#include "help.h"
#include "input.h"
#include "line_info.h"
Expand Down Expand Up @@ -67,6 +68,7 @@ static const char *const conference_cmd_list[] = {
#endif
"/avatar",
"/chatid",
"/cinvite",
"/clear",
"/close",
"/color",
Expand Down Expand Up @@ -662,6 +664,7 @@ static void set_peer_audio_position(Tox *tox, uint32_t conferencenum, uint32_t p
const float angle = asinf(peer_posn - (float)(num_posns - 1) / 2);
set_source_position(peer->audio_out_idx, sinf(angle), cosf(angle), 0);
}

#endif // AUDIO


Expand Down Expand Up @@ -965,6 +968,18 @@ static bool conference_onKey(ToxWindow *self, Toxic *toxic, wint_t key, bool ltr
}
} else if (wcsncmp(ctx->line, L"/avatar ", wcslen(L"/avatar ")) == 0) {
diff = dir_match(self, toxic, ctx->line, L"/avatar");
} else if (wcsncmp(ctx->line, L"/cinvite ", wcslen(L"/cinvite ")) == 0) {
size_t num_friends = friendlist_get_count();
char **friend_names = (char **) malloc_ptr_array(num_friends, TOX_MAX_NAME_LENGTH);

if (friend_names == NULL) {
fprintf(stderr, "Failed to allocate memory for friends list\n");
num_friends = 0;
}

friendlist_get_names(friend_names, num_friends, TOX_MAX_NAME_LENGTH);
diff = complete_line(self, toxic, (const char *const *) friend_names, num_friends);
free_ptr_array((void **) friend_names);
}

#ifdef PYTHON
Expand Down Expand Up @@ -1602,4 +1617,5 @@ float conference_get_VAD_threshold(uint32_t conferencenum)

return device_get_VAD_threshold(chat->audio_in_idx);
}

#endif // AUDIO
46 changes: 46 additions & 0 deletions src/conference_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <string.h>

#include "conference.h"
#include "friendlist.h"
#include "line_info.h"
#include "log.h"
#include "misc_tools.h"
Expand Down Expand Up @@ -51,6 +52,50 @@ void cmd_conference_chatid(WINDOW *window, ToxWindow *self, Toxic *toxic, int ar
line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, "%s", id_string);
}

void cmd_conference_invite(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE])
{
UNUSED_VAR(window);

if (toxic == NULL || self == NULL) {
return;
}

Tox *tox = toxic->tox;
const Client_Config *c_config = toxic->c_config;

if (argc != 1) {
line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, "Friend name required.");
return;
}

const char *nick = argv[1];
const int64_t friend_number = get_friend_number(nick);

if (friend_number == -1) {
line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0,
"Friend '%s' not found (names are case-sensitive)", nick);
return;
}

if (friend_number == -2) {
line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0,
"There are multiple friends in your friend list with this name. To invite this friend, navigate to their chat window and try again");
return;
}

const long int conferencenum = self->num;

Tox_Err_Conference_Invite err;

if (!tox_conference_invite(tox, (uint32_t)friend_number, conferencenum, &err)) {
line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0,
"Failed to invite contact to conference (error %d)", err);
return;
}

line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, "Invited %s to the conference", nick);
}

void cmd_conference_set_title(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE])
{
UNUSED_VAR(window);
Expand Down Expand Up @@ -248,4 +293,5 @@ void cmd_conference_push_to_talk(WINDOW *window, ToxWindow *self, Toxic *toxic,

print_err(self, c_config, enable ? "Push-To-Talk is enabled. Push F2 to activate" : "Push-To-Talk is disabled");
}

#endif /* AUDIO */
1 change: 1 addition & 0 deletions src/conference_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "windows.h"

void cmd_conference_chatid(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_conference_invite(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_conference_set_title(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_enable_audio(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_conference_mute(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
Expand Down
10 changes: 7 additions & 3 deletions src/execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ static struct cmd_func global_commands[] = {
static struct cmd_func chat_commands[] = {
{ "/autoaccept", cmd_autoaccept_files },
{ "/cancel", cmd_cancelfile },
{ "/cinvite", cmd_conference_invite },
{ "/cinvite", cmd_invite_to_conference },
{ "/cjoin", cmd_conference_join },
{ "/gaccept", cmd_group_accept },
{ "/invite", cmd_group_invite },
{ "/invite", cmd_invite_to_group },
#ifdef GAMES
{ "/play", cmd_game_join },
#endif
Expand All @@ -99,6 +99,7 @@ static struct cmd_func chat_commands[] = {

static struct cmd_func conference_commands[] = {
{ "/chatid", cmd_conference_chatid },
{ "/cinvite", cmd_conference_invite },
{ "/title", cmd_conference_set_title },

#ifdef AUDIO
Expand All @@ -112,8 +113,9 @@ static struct cmd_func conference_commands[] = {

static struct cmd_func groupchat_commands[] = {
{ "/chatid", cmd_chatid },
{ "/disconnect", cmd_disconnect },
{ "/disconnect", cmd_disconnect },
{ "/ignore", cmd_ignore },
{ "/invite", cmd_group_invite },
{ "/kick", cmd_kick },
{ "/list", cmd_list },
{ "/locktopic", cmd_set_topic_lock },
Expand All @@ -137,9 +139,11 @@ static struct cmd_func groupchat_commands[] = {
static const char special_commands[][MAX_CMDNAME_SIZE] = {
"/add",
"/avatar",
"/cinvite",
"/gaccept",
"/group",
"/ignore",
"/invite",
"/kick",
"/mod",
"/nick",
Expand Down
38 changes: 38 additions & 0 deletions src/friendlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -1424,6 +1424,24 @@ void disable_friend_window(uint32_t f_num)
Friends.list[f_num].window_id = -1;
}

size_t friendlist_get_count(void)
{
return Friends.num_friends;
}

void friendlist_get_names(char **names, size_t max_names, size_t max_name_size)
{
if (Friends.num_friends == 0) {
return;
}

const size_t bytes_to_copy = MIN(sizeof(Friends.list[0].name), max_name_size);

for (size_t i = 0; i < max_names && i < Friends.num_friends; ++i) {
snprintf(names[i], bytes_to_copy, "%s", Friends.list[i].name);
}
}

#ifdef AUDIO
static void friendlist_onAV(ToxWindow *self, Toxic *toxic, uint32_t friend_number, int state)
{
Expand Down Expand Up @@ -1455,6 +1473,7 @@ static void friendlist_onAV(ToxWindow *self, Toxic *toxic, uint32_t friend_numbe
set_active_window_by_id(toxic->windows, window_id);
}
}

#endif /* AUDIO */

/* Returns a friend's status */
Expand All @@ -1477,6 +1496,25 @@ Tox_Connection get_friend_connection_status(uint32_t friendnumber)
return Friends.list[friendnumber].connection_status;
}

int64_t get_friend_number(const char *name)
{
int64_t num = -1;
size_t count = 0;

for (size_t i = 0; i < Friends.max_idx; ++i) {
if (memcmp(name, Friends.list[i].name, Friends.list[i].namelength) == 0) {
num = Friends.list[i].num;
++count;
}
}

if (count > 1) {
return -2;
}

return num;
}

/*
* Returns true if friend associated with `public_key` is in the block list.
*
Expand Down
20 changes: 20 additions & 0 deletions src/friendlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,19 @@ void friendlist_onFriendAdded(ToxWindow *self, Toxic *toxic, uint32_t num, bool
Tox_User_Status get_friend_status(uint32_t friendnumber);
Tox_Connection get_friend_connection_status(uint32_t friendnumber);

/*
* Returns the number of friends in the friend list.
*/
size_t friendlist_get_count(void);

/*
* Copies names from the friends list into the `names` array.
*
* @max_length The maximum number of names to copy.
* @max_name_length The maximum number of bytes to copy per name.
*/
void friendlist_get_names(char **names, size_t max_names, size_t max_name_size);

/*
* Loads the list of blocked peers from `path`.
*
Expand Down Expand Up @@ -162,6 +175,13 @@ bool friend_get_auto_accept_files(uint32_t friendnumber);
*/
uint16_t get_friend_name(char *buf, size_t buf_size, uint32_t friendnumber);

/*
* Returns the friend number associated with `nick`.
* Returns -1 if `nick` does not designate a friend in the friend list.
* Returns -2 if `nick` matches more than one friend in the friend list.
*/
int64_t get_friend_number(const char *nick);

/*
* Puts a friend's public key in `pk`, which must have room for at least
* TOX_PUBLIC_KEY_SIZE bytes.
Expand Down
2 changes: 2 additions & 0 deletions src/global_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ void cmd_avatar(WINDOW *window, ToxWindow *, Toxic *, int argc, char (*argv)[MAX
void cmd_clear(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_color(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_conference(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_conference_invite_global(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_connect(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_decline(WINDOW *window, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_groupchat(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_group_invite_global(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_join(WINDOW *window, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_log(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_myid(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
Expand Down
51 changes: 47 additions & 4 deletions src/groupchat_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@
#include <string.h>
#include <stdlib.h>

#include "toxic.h"
#include "windows.h"
#include "friendlist.h"
#include "groupchats.h"
#include "line_info.h"
#include "misc_tools.h"
#include "log.h"
#include "groupchats.h"
#include "misc_tools.h"
#include "toxic.h"
#include "windows.h"

extern GroupChat groupchats[MAX_GROUPCHAT_NUM];

Expand Down Expand Up @@ -168,6 +169,48 @@ void cmd_ignore(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*
group_toggle_peer_ignore(self->num, peer_id, true);
}

void cmd_group_invite(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE])
{
if (toxic == NULL || self == NULL) {
return;
}

Tox *tox = toxic->tox;
const Client_Config *c_config = toxic->c_config;

if (argc != 1) {
line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, "Friend name required.");
return;
}

const char *nick = argv[1];
const int64_t friend_number = get_friend_number(nick);

if (friend_number == -1) {
line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0,
"Friend '%s' not found (names are case-sensitive)", nick);
return;
}

if (friend_number == -2) {
line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0,
"There are multiple friends in your friend list with this name. To invite this friend, navigate to their chat window and try again");
return;
}

const int groupnumber = self->num;

Tox_Err_Group_Invite_Friend err;

if (!tox_group_invite_friend(tox, groupnumber, (uint32_t)friend_number, &err)) {
line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to invite contact to group (error %d).",
err);
return;
}

line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, "Invited %s to the group", nick);
}

void cmd_kick(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE])
{
UNUSED_VAR(window);
Expand Down
1 change: 1 addition & 0 deletions src/groupchat_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

void cmd_chatid(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_disconnect(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_group_invite(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_group_nick(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_ignore(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_kick(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]);
Expand Down
Loading

0 comments on commit d1887c5

Please sign in to comment.