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

implement group private messaging

This commit is contained in:
Jfreegman 2015-03-22 00:56:14 -04:00
parent 88d6d907d8
commit 05c05868c6
10 changed files with 129 additions and 35 deletions

View File

@ -2,12 +2,12 @@
.\" Title: toxic.conf .\" Title: toxic.conf
.\" Author: [see the "AUTHORS" section] .\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/> .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
.\" Date: 2015-02-19 .\" Date: 2015-02-26
.\" Manual: Toxic Manual .\" Manual: Toxic Manual
.\" Source: toxic __VERSION__ .\" Source: toxic __VERSION__
.\" Language: English .\" Language: English
.\" .\"
.TH "TOXIC\&.CONF" "5" "2015\-02\-19" "toxic __VERSION__" "Toxic Manual" .TH "TOXIC\&.CONF" "5" "2015\-02\-26" "toxic __VERSION__" "Toxic Manual"
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
.\" * Define some portability stuff .\" * Define some portability stuff
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
@ -138,6 +138,11 @@ Indicator for alert messages\&.
Indicator for normal messages\&. Indicator for normal messages\&.
.RE .RE
.PP .PP
\fBline_special\fR
.RS 4
Indicator for special messages\&.
.RE
.PP
\fBmplex_away\fR \fBmplex_away\fR
.RS 4 .RS 4
Set user status when attaching and detaching from GNU screen or tmux\&. true or false Set user status when attaching and detaching from GNU screen or tmux\&. true or false

View File

@ -88,6 +88,9 @@ OPTIONS
*line_normal*;; *line_normal*;;
Indicator for normal messages. Indicator for normal messages.
*line_special*;;
Indicator for special messages.
*mplex_away*;; *mplex_away*;;
Set user status when attaching and detaching from GNU screen or tmux. Set user status when attaching and detaching from GNU screen or tmux.
true or false true or false

View File

@ -44,6 +44,9 @@ ui = {
// Indicator for normal messages. // Indicator for normal messages.
line_normal="---"; line_normal="---";
// Indicator for special messages (currently only used for private group messages)
line_special=">>>";
// true to change status based on screen/tmux attach/detach, false to disable // true to change status based on screen/tmux attach/detach, false to disable
mplex_away=true; mplex_away=true;

View File

@ -94,8 +94,8 @@ static struct cmd_func group_commands[] = {
{ NULL, NULL }, { NULL, NULL },
}; };
#define SPECIAL_COMMANDS 9 #define NUM_SPECIAL_COMMANDS 9
static const char special_commands[SPECIAL_COMMANDS][MAX_CMDNAME_SIZE] = { static const char special_commands[NUM_SPECIAL_COMMANDS][MAX_CMDNAME_SIZE] = {
"/ban", "/ban",
"/deop", "/deop",
"/group", "/group",
@ -117,7 +117,7 @@ static bool is_special_command(const char *input)
int i; int i;
for (i = 0; i < SPECIAL_COMMANDS; ++i) { for (i = 0; i < NUM_SPECIAL_COMMANDS; ++i) {
if (strncmp(input, special_commands[i], s) == 0) if (strncmp(input, special_commands[i], s) == 0)
return true; return true;
} }
@ -127,7 +127,9 @@ static bool is_special_command(const char *input)
/* Parses commands in the special_commands array which take exactly one argument that may contain spaces. /* Parses commands in the special_commands array which take exactly one argument that may contain spaces.
* Unlike parse_command, this function does not split the input string at spaces. * Unlike parse_command, this function does not split the input string at spaces.
* Returns number of arguments on success, returns -1 on failure *
* Returns number of arguments on success
* Returns -1 on failure
*/ */
static int parse_special_command(WINDOW *w, ToxWindow *self, const char *input, char (*args)[MAX_STR_SIZE]) static int parse_special_command(WINDOW *w, ToxWindow *self, const char *input, char (*args)[MAX_STR_SIZE])
{ {
@ -146,7 +148,9 @@ static int parse_special_command(WINDOW *w, ToxWindow *self, const char *input,
} }
/* Parses input command and puts args (split by spaces) into args array. /* Parses input command and puts args (split by spaces) into args array.
* Returns number of arguments on success, -1 on failure. *
* Returns number of arguments on success
* Returns -1 on failure.
*/ */
static int parse_command(WINDOW *w, ToxWindow *self, const char *input, char (*args)[MAX_STR_SIZE]) static int parse_command(WINDOW *w, ToxWindow *self, const char *input, char (*args)[MAX_STR_SIZE])
{ {
@ -194,7 +198,11 @@ static int parse_command(WINDOW *w, ToxWindow *self, const char *input, char (*a
return num_args; return num_args;
} }
/* Matches command to respective function. Returns 0 on match, 1 on no match */ /* Matches command to respective function.
*
* Returns 0 on match,
* Returns -1 on no match
*/
static int do_command(WINDOW *w, ToxWindow *self, Tox *m, int num_args, struct cmd_func *commands, static int do_command(WINDOW *w, ToxWindow *self, Tox *m, int num_args, struct cmd_func *commands,
char (*args)[MAX_STR_SIZE]) char (*args)[MAX_STR_SIZE])
{ {
@ -207,7 +215,7 @@ static int do_command(WINDOW *w, ToxWindow *self, Tox *m, int num_args, struct c
} }
} }
return 1; return -1;
} }
void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode) void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode)

View File

@ -70,9 +70,9 @@ extern struct user_settings *user_settings;
extern struct Winthread Winthread; extern struct Winthread Winthread;
#ifdef AUDIO #ifdef AUDIO
#define AC_NUM_GROUP_COMMANDS 27 #define AC_NUM_GROUP_COMMANDS 28
#else #else
#define AC_NUM_GROUP_COMMANDS 23 #define AC_NUM_GROUP_COMMANDS 24
#endif /* AUDIO */ #endif /* AUDIO */
/* groupchat command names used for tab completion. */ /* groupchat command names used for tab completion. */
@ -100,6 +100,7 @@ static const char group_cmd_list[AC_NUM_GROUP_COMMANDS][MAX_CMDNAME_SIZE] = {
{ "/status" }, { "/status" },
{ "/topic" }, { "/topic" },
{ "/unignore" }, { "/unignore" },
{ "/whisper" },
#ifdef AUDIO #ifdef AUDIO
@ -345,7 +346,7 @@ static void groupchat_onGroupAction(ToxWindow *self, Tox *m, int groupnum, int p
} }
static void groupchat_onGroupPrivateMessage(ToxWindow *self, Tox *m, int groupnum, uint32_t peernum, static void groupchat_onGroupPrivateMessage(ToxWindow *self, Tox *m, int groupnum, uint32_t peernum,
const char *action, uint16_t len) const char *msg, uint16_t len)
{ {
if (self->num != groupnum) if (self->num != groupnum)
return; return;
@ -358,8 +359,8 @@ static void groupchat_onGroupPrivateMessage(ToxWindow *self, Tox *m, int groupnu
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, nick, NULL, IN_MSG, 0, RED, "%s", action); line_info_add(self, timefrmt, nick, NULL, IN_PRVT_MSG, 0, MAGENTA, "%s", msg);
write_to_log(action, nick, ctx->log, false); write_to_log(msg, nick, ctx->log, false);
sound_notify(self, silent, NT_WNDALERT_1, NULL); sound_notify(self, silent, NT_WNDALERT_1, NULL);
} }
@ -627,9 +628,13 @@ static void send_group_message(ToxWindow *self, Tox *m, int groupnum, const char
{ {
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
if (msg == NULL) {
wprintw(ctx->history, "Invalid syntax.\n");
return;
}
if (tox_group_message_send(m, self->num, (uint8_t *) msg, strlen(msg)) == -1) { if (tox_group_message_send(m, self->num, (uint8_t *) msg, strlen(msg)) == -1) {
const char *errmsg = " * Failed to send message."; line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Failed to send message");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "%s", errmsg);
return; return;
} }
@ -644,7 +649,7 @@ static void send_group_message(ToxWindow *self, Tox *m, int groupnum, const char
write_to_log(msg, selfname, ctx->log, false); write_to_log(msg, selfname, ctx->log, false);
} }
static void send_group_action(ToxWindow *self, Tox *m, int groupnum, char *action) static void send_group_action(ToxWindow *self, Tox *m, int groupnum, const char *action)
{ {
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
@ -654,8 +659,7 @@ static void send_group_action(ToxWindow *self, Tox *m, int groupnum, char *actio
} }
if (tox_group_action_send(m, groupnum, (uint8_t *) action, strlen(action)) == -1) { if (tox_group_action_send(m, groupnum, (uint8_t *) action, strlen(action)) == -1) {
const char *errmsg = " * Failed to send action."; line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Failed to send action");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "%s", errmsg);
return; return;
} }
@ -670,6 +674,54 @@ static void send_group_action(ToxWindow *self, Tox *m, int groupnum, char *actio
write_to_log(action, selfname, ctx->log, true); write_to_log(action, selfname, ctx->log, true);
} }
static void send_group_prvt_message(ToxWindow *self, Tox *m, int groupnum, const char *data)
{
ChatContext *ctx = self->chatwin;
if (data == NULL) {
wprintw(ctx->history, "Invalid syntax.\n");
return;
}
size_t i;
int peernum = -1, len = 0;
const char *msg = NULL;
for (i = 0; i < groupchats[groupnum].num_peers; ++i) {
if (memcmp((char *) &groupchats[groupnum].peer_names[i * TOX_MAX_NAME_LENGTH], data,
groupchats[groupnum].peer_name_lengths[i]) == 0) {
len = strlen(data) - groupchats[groupnum].peer_name_lengths[i] - 1;
if (len <= 0)
return;
msg = data + groupchats[groupnum].peer_name_lengths[i] + 1;
peernum = i;
break;
}
}
if (peernum == -1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid peer name");
return;
}
if (tox_group_private_message_send(m, groupnum, peernum, (uint8_t *) msg, len) == -1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Failed to send private message");
return;
}
char selfname[TOX_MAX_NAME_LENGTH];
uint16_t slen = tox_group_get_self_name(m, groupnum, (uint8_t *) selfname);
selfname[slen] = '\0';
char timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt, sizeof(timefrmt));
line_info_add(self, timefrmt, selfname, NULL, OUT_PRVT_MSG, 0, 0, "%s", msg);
write_to_log(msg, selfname, ctx->log, false);
}
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;
@ -742,7 +794,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
add_line_to_hist(ctx); add_line_to_hist(ctx);
if (line[0] == '/') { if (line[0] == '/') {
if (strncmp(line, "/close", 6) == 0) { if (strncmp(line, "/close", strlen("/close")) == 0) {
int offset = 6; int offset = 6;
if (line[offset] != '\0') if (line[offset] != '\0')
@ -750,8 +802,10 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
exit_groupchat(self, m, self->num, line + offset, ctx->len - offset); exit_groupchat(self, m, self->num, line + offset, ctx->len - offset);
return; return;
} else if (strncmp(line, "/me ", 4) == 0) { } else if (strncmp(line, "/me ", strlen("/me ")) == 0) {
send_group_action(self, m, self->num, line + 4); send_group_action(self, m, self->num, line + 4);
} else if (strncmp(line, "/whisper ", strlen("/whisper ")) == 0) {
send_group_prvt_message(self, m, self->num, line + 9);
} else { } else {
execute(ctx->history, self, m, line, GROUPCHAT_COMMAND_MODE); execute(ctx->history, self, m, line, GROUPCHAT_COMMAND_MODE);
} }

View File

@ -246,7 +246,8 @@ static void help_draw_group(ToxWindow *self)
wprintw(win, " /ignore <nick> : Ignore peer\n"); wprintw(win, " /ignore <nick> : Ignore peer\n");
wprintw(win, " /rejoin : Rejoin the group (only works if not connected)\n"); wprintw(win, " /rejoin : Rejoin the group (only works if not connected)\n");
wprintw(win, " /topic <msg> : Set group topic (show current topic if no msg)\n"); wprintw(win, " /topic <msg> : Set group topic (show current topic if no msg)\n");
wprintw(win, " /unignore <nick> : Unignore peer \n\n"); wprintw(win, " /unignore <nick> : Unignore peer \n");
wprintw(win, " /whisper <nick> <msg> : Send private message to nick\n\n");
#ifdef AUDIO #ifdef AUDIO
wattron(win, A_BOLD); wattron(win, A_BOLD);
@ -313,9 +314,9 @@ void help_onKey(ToxWindow *self, wint_t key)
case 'r': case 'r':
#ifdef AUDIO #ifdef AUDIO
help_init_window(self, 14, 80); help_init_window(self, 15, 80);
#else #else
help_init_window(self, 10, 80); help_init_window(self, 11, 80);
#endif #endif
self->help->type = HELP_GROUP; self->help->type = HELP_GROUP;
break; break;

View File

@ -164,6 +164,11 @@ void line_info_add(ToxWindow *self, const char *timestr, const char *name1, cons
len += strlen(user_settings->line_normal) + 3; len += strlen(user_settings->line_normal) + 3;
break; break;
case IN_PRVT_MSG:
case OUT_PRVT_MSG:
len += strlen(user_settings->line_special) + 3;
break;
case CONNECTION: case CONNECTION:
len += strlen(user_settings->line_join) + 2; len += strlen(user_settings->line_join) + 2;
break; break;
@ -301,6 +306,8 @@ void line_info_print(ToxWindow *self)
case OUT_MSG: case OUT_MSG:
case OUT_MSG_READ: case OUT_MSG_READ:
case IN_MSG: case IN_MSG:
case IN_PRVT_MSG:
case OUT_PRVT_MSG:
wattron(win, COLOR_PAIR(BLUE)); wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "%s ", line->timestr); wprintw(win, "%s ", line->timestr);
wattroff(win, COLOR_PAIR(BLUE)); wattroff(win, COLOR_PAIR(BLUE));
@ -313,7 +320,10 @@ void line_info_print(ToxWindow *self)
nameclr = CYAN; nameclr = CYAN;
wattron(win, COLOR_PAIR(nameclr)); wattron(win, COLOR_PAIR(nameclr));
wprintw(win, "%s %s: ", user_settings->line_normal, line->name1); wprintw(win, "%s %s: ",(type != OUT_PRVT_MSG && type != IN_PRVT_MSG) ?
user_settings->line_normal :
user_settings->line_special,
line->name1);
wattroff(win, COLOR_PAIR(nameclr)); wattroff(win, COLOR_PAIR(nameclr));
if (line->msg[0] == '>') if (line->msg[0] == '>')

View File

@ -39,6 +39,8 @@ enum {
IN_ACTION, IN_ACTION,
OUT_ACTION, OUT_ACTION,
OUT_ACTION_READ, /* same as OUT_MSG_READ but for actions */ OUT_ACTION_READ, /* same as OUT_MSG_READ but for actions */
IN_PRVT_MSG, /* PRVT should only be used for groups */
OUT_PRVT_MSG,
PROMPT, PROMPT,
CONNECTION, CONNECTION,
DISCONNECTION, DISCONNECTION,

View File

@ -62,6 +62,7 @@ static struct ui_strings {
const char* line_quit; const char* line_quit;
const char* line_alert; const char* line_alert;
const char* line_normal; const char* line_normal;
const char* line_special;
const char* mplex_away; const char* mplex_away;
const char* mplex_away_note; const char* mplex_away_note;
@ -82,6 +83,7 @@ static struct ui_strings {
"line_quit", "line_quit",
"line_alert", "line_alert",
"line_normal", "line_normal",
"line_special",
"mplex_away", "mplex_away",
"mplex_away_note", "mplex_away_note",
}; };
@ -104,6 +106,7 @@ static void ui_defaults(struct user_settings* settings)
snprintf(settings->line_quit, LINE_HINT_MAX + 1, "%s", LINE_QUIT); snprintf(settings->line_quit, LINE_HINT_MAX + 1, "%s", LINE_QUIT);
snprintf(settings->line_alert, LINE_HINT_MAX + 1, "%s", LINE_ALERT); snprintf(settings->line_alert, LINE_HINT_MAX + 1, "%s", LINE_ALERT);
snprintf(settings->line_normal, LINE_HINT_MAX + 1, "%s", LINE_NORMAL); snprintf(settings->line_normal, LINE_HINT_MAX + 1, "%s", LINE_NORMAL);
snprintf(settings->line_special, LINE_HINT_MAX + 1, "%s", LINE_SPECIAL);
settings->mplex_away = MPLEX_ON; settings->mplex_away = MPLEX_ON;
snprintf (settings->mplex_away_note, snprintf (settings->mplex_away_note,
@ -321,6 +324,9 @@ int settings_load(struct user_settings *s, const char *patharg)
if ( config_setting_lookup_string(setting, ui_strings.line_normal, &str) ) { if ( config_setting_lookup_string(setting, ui_strings.line_normal, &str) ) {
snprintf(s->line_normal, sizeof(s->line_normal), "%s", str); snprintf(s->line_normal, sizeof(s->line_normal), "%s", str);
} }
if ( config_setting_lookup_string(setting, ui_strings.line_special, &str) ) {
snprintf(s->line_special, sizeof(s->line_special), "%s", str);
}
config_setting_lookup_bool (setting, ui_strings.mplex_away, &s->mplex_away); config_setting_lookup_bool (setting, ui_strings.mplex_away, &s->mplex_away);

View File

@ -49,6 +49,7 @@ struct user_settings {
char line_quit[LINE_HINT_MAX + 1]; char line_quit[LINE_HINT_MAX + 1];
char line_alert[LINE_HINT_MAX + 1]; char line_alert[LINE_HINT_MAX + 1];
char line_normal[LINE_HINT_MAX + 1]; char line_normal[LINE_HINT_MAX + 1];
char line_special[LINE_HINT_MAX + 1];
char download_path[PATH_MAX]; char download_path[PATH_MAX];
char chatlogs_path[PATH_MAX]; char chatlogs_path[PATH_MAX];
@ -104,6 +105,7 @@ enum {
#define LINE_QUIT "<--" #define LINE_QUIT "<--"
#define LINE_ALERT "-!-" #define LINE_ALERT "-!-"
#define LINE_NORMAL "---" #define LINE_NORMAL "---"
#define LINE_SPECIAL ">>>"
#define TIMESTAMP_DEFAULT "%H:%M:%S" #define TIMESTAMP_DEFAULT "%H:%M:%S"
#define LOG_TIMESTAMP_DEFAULT "%Y/%m/%d [%H:%M:%S]" #define LOG_TIMESTAMP_DEFAULT "%Y/%m/%d [%H:%M:%S]"
#define MPLEX_AWAY_NOTE "Detached from screen" #define MPLEX_AWAY_NOTE "Detached from screen"