irc, typing: display typing status for IRC nicks
This commit is contained in:
parent
bba300e191
commit
954f943e8e
@ -266,6 +266,8 @@
|
||||
./src/plugins/irc/irc-server.h
|
||||
./src/plugins/irc/irc-tag.c
|
||||
./src/plugins/irc/irc-tag.h
|
||||
./src/plugins/irc/irc-typing.c
|
||||
./src/plugins/irc/irc-typing.h
|
||||
./src/plugins/irc/irc-upgrade.c
|
||||
./src/plugins/irc/irc-upgrade.h
|
||||
./src/plugins/javascript/weechat-js-api.h
|
||||
@ -404,6 +406,8 @@
|
||||
./src/plugins/trigger/trigger-config.h
|
||||
./src/plugins/trigger/trigger.h
|
||||
./src/plugins/typing/typing.c
|
||||
./src/plugins/typing/typing-bar-item.c
|
||||
./src/plugins/typing/typing-bar-item.h
|
||||
./src/plugins/typing/typing-config.c
|
||||
./src/plugins/typing/typing-config.h
|
||||
./src/plugins/typing/typing.h
|
||||
|
@ -267,6 +267,8 @@ SET(WEECHAT_SOURCES
|
||||
./src/plugins/irc/irc-server.h
|
||||
./src/plugins/irc/irc-tag.c
|
||||
./src/plugins/irc/irc-tag.h
|
||||
./src/plugins/irc/irc-typing.c
|
||||
./src/plugins/irc/irc-typing.h
|
||||
./src/plugins/irc/irc-upgrade.c
|
||||
./src/plugins/irc/irc-upgrade.h
|
||||
./src/plugins/javascript/weechat-js-api.h
|
||||
@ -405,6 +407,8 @@ SET(WEECHAT_SOURCES
|
||||
./src/plugins/trigger/trigger-config.h
|
||||
./src/plugins/trigger/trigger.h
|
||||
./src/plugins/typing/typing.c
|
||||
./src/plugins/typing/typing-bar-item.c
|
||||
./src/plugins/typing/typing-bar-item.h
|
||||
./src/plugins/typing/typing-config.c
|
||||
./src/plugins/typing/typing-config.h
|
||||
./src/plugins/typing/typing.h
|
||||
|
@ -43,6 +43,7 @@ add_library(irc MODULE
|
||||
irc-sasl.c irc-sasl.h
|
||||
irc-server.c irc-server.h
|
||||
irc-tag.c irc-tag.h
|
||||
irc-typing.c irc-typing.h
|
||||
irc-upgrade.c irc-upgrade.h
|
||||
)
|
||||
set_target_properties(irc PROPERTIES PREFIX "")
|
||||
|
@ -73,6 +73,8 @@ irc_la_SOURCES = irc.c \
|
||||
irc-server.h \
|
||||
irc-tag.c \
|
||||
irc-tag.h \
|
||||
irc-typing.c \
|
||||
irc-typing.h \
|
||||
irc-upgrade.c \
|
||||
irc-upgrade.h
|
||||
|
||||
|
@ -40,8 +40,8 @@
|
||||
#include "irc-input.h"
|
||||
|
||||
|
||||
char *irc_channel_typing_status_string[IRC_CHANNEL_NUM_TYPING_STATUSES] =
|
||||
{ "off", "typing", "paused", "done" };
|
||||
char *irc_channel_typing_state_string[IRC_CHANNEL_NUM_TYPING_STATES] =
|
||||
{ "off", "active", "paused", "done" };
|
||||
|
||||
/* default CHANTYPES */
|
||||
char *irc_channel_default_chantypes = "#&";
|
||||
@ -511,7 +511,7 @@ irc_channel_new (struct t_irc_server *server, int channel_type,
|
||||
irc_modelist_new (new_channel, ptr_chanmode[0]);
|
||||
}
|
||||
new_channel->join_smart_filtered = NULL;
|
||||
new_channel->typing_status = IRC_CHANNEL_TYPING_STATUS_OFF;
|
||||
new_channel->typing_state = IRC_CHANNEL_TYPING_STATE_OFF;
|
||||
new_channel->typing_status_sent = 0;
|
||||
new_channel->buffer = ptr_buffer;
|
||||
new_channel->buffer_as_string = NULL;
|
||||
@ -1589,7 +1589,7 @@ irc_channel_hdata_channel_cb (const void *pointer, void *data,
|
||||
WEECHAT_HDATA_VAR(struct t_irc_channel, modelists, POINTER, 0, NULL, "irc_modelist");
|
||||
WEECHAT_HDATA_VAR(struct t_irc_channel, last_modelist, POINTER, 0, NULL, "irc_modelist");
|
||||
WEECHAT_HDATA_VAR(struct t_irc_channel, join_smart_filtered, HASHTABLE, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_channel, typing_status, INTEGER, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_channel, typing_state, INTEGER, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_channel, typing_status_sent, TIME, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_channel, buffer, POINTER, 0, NULL, "buffer");
|
||||
WEECHAT_HDATA_VAR(struct t_irc_channel, buffer_as_string, STRING, 0, NULL, NULL);
|
||||
@ -1781,7 +1781,7 @@ irc_channel_print_log (struct t_irc_channel *channel)
|
||||
channel->join_smart_filtered,
|
||||
weechat_hashtable_get_string (channel->join_smart_filtered,
|
||||
"keys_values"));
|
||||
weechat_log_printf (" typing_status. . . . . . : %d", channel->typing_status);
|
||||
weechat_log_printf (" typing_state . . . . . . : %d", channel->typing_state);
|
||||
weechat_log_printf (" typing_status_sent . . . : %lld", (long long)channel->typing_status_sent);
|
||||
weechat_log_printf (" buffer . . . . . . . . . : 0x%lx", channel->buffer);
|
||||
weechat_log_printf (" buffer_as_string . . . . : '%s'", channel->buffer_as_string);
|
||||
|
@ -32,14 +32,14 @@
|
||||
struct t_irc_server;
|
||||
struct t_irc_modelist;
|
||||
|
||||
enum t_irc_channel_typing_status
|
||||
enum t_irc_channel_typing_state
|
||||
{
|
||||
IRC_CHANNEL_TYPING_STATUS_OFF = 0,
|
||||
IRC_CHANNEL_TYPING_STATUS_TYPING,
|
||||
IRC_CHANNEL_TYPING_STATUS_PAUSED,
|
||||
IRC_CHANNEL_TYPING_STATUS_DONE,
|
||||
/* number of channel typing statuses */
|
||||
IRC_CHANNEL_NUM_TYPING_STATUSES,
|
||||
IRC_CHANNEL_TYPING_STATE_OFF = 0,
|
||||
IRC_CHANNEL_TYPING_STATE_ACTIVE,
|
||||
IRC_CHANNEL_TYPING_STATE_PAUSED,
|
||||
IRC_CHANNEL_TYPING_STATE_DONE,
|
||||
/* number of channel typing states */
|
||||
IRC_CHANNEL_NUM_TYPING_STATES,
|
||||
};
|
||||
|
||||
struct t_irc_channel_speaking
|
||||
@ -83,7 +83,7 @@ struct t_irc_channel
|
||||
struct t_irc_modelist *modelists; /* modelists in the channel */
|
||||
struct t_irc_modelist *last_modelist; /* last modelist in the channel */
|
||||
struct t_hashtable *join_smart_filtered; /* smart filtered joins */
|
||||
int typing_status; /* typing status */
|
||||
int typing_state; /* typing state */
|
||||
time_t typing_status_sent; /* last time typing status was sent */
|
||||
struct t_gui_buffer *buffer; /* buffer allocated for channel */
|
||||
char *buffer_as_string; /* used to return buffer info */
|
||||
@ -91,7 +91,7 @@ struct t_irc_channel
|
||||
struct t_irc_channel *next_channel; /* link to next channel */
|
||||
};
|
||||
|
||||
extern char *irc_channel_typing_status_string[IRC_CHANNEL_NUM_TYPING_STATUSES];
|
||||
extern char *irc_channel_typing_state_string[IRC_CHANNEL_NUM_TYPING_STATES];
|
||||
extern char *irc_channel_default_chantypes;
|
||||
|
||||
extern int irc_channel_valid (struct t_irc_server *server,
|
||||
|
@ -98,7 +98,8 @@ struct t_config_option *irc_config_look_part_closes_buffer;
|
||||
struct t_config_option *irc_config_look_pv_buffer;
|
||||
struct t_config_option *irc_config_look_pv_tags;
|
||||
struct t_config_option *irc_config_look_raw_messages;
|
||||
struct t_config_option *irc_config_look_send_typing_status;
|
||||
struct t_config_option *irc_config_look_typing_status_nicks;
|
||||
struct t_config_option *irc_config_look_typing_status_self;
|
||||
struct t_config_option *irc_config_look_server_buffer;
|
||||
struct t_config_option *irc_config_look_smart_filter;
|
||||
struct t_config_option *irc_config_look_smart_filter_account;
|
||||
@ -3116,11 +3117,21 @@ irc_config_init ()
|
||||
"closed (messages will be displayed when opening raw data buffer)"),
|
||||
NULL, 0, 65535, "256", NULL, 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
irc_config_look_send_typing_status = weechat_config_new_option (
|
||||
irc_config_look_typing_status_nicks = weechat_config_new_option (
|
||||
irc_config_file, ptr_section,
|
||||
"send_typing_status", "boolean",
|
||||
N_("send typing status to channels (capability \"message-tags\" must "
|
||||
"be enabled)"),
|
||||
"typing_status_nicks", "boolean",
|
||||
N_("display nicks typing on the channel in bar item \"typing\" "
|
||||
"(option typing.look.enabled must be enabled and capability "
|
||||
"\"message-tags\" must be enabled on the server)"),
|
||||
NULL, 0, 0, "off", NULL, 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
irc_config_look_typing_status_self = weechat_config_new_option (
|
||||
irc_config_file, ptr_section,
|
||||
"typing_status_self", "boolean",
|
||||
N_("send self typing status to channels so that other users see when "
|
||||
"you are typing a message "
|
||||
"(option typing.look.enabled must be enabled and capability "
|
||||
"\"message-tags\" must be enabled on the server)"),
|
||||
NULL, 0, 0, "off", NULL, 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
irc_config_look_server_buffer = weechat_config_new_option (
|
||||
|
@ -138,7 +138,8 @@ extern struct t_config_option *irc_config_look_part_closes_buffer;
|
||||
extern struct t_config_option *irc_config_look_pv_buffer;
|
||||
extern struct t_config_option *irc_config_look_pv_tags;
|
||||
extern struct t_config_option *irc_config_look_raw_messages;
|
||||
extern struct t_config_option *irc_config_look_send_typing_status;
|
||||
extern struct t_config_option *irc_config_look_typing_status_nicks;
|
||||
extern struct t_config_option *irc_config_look_typing_status_self;
|
||||
extern struct t_config_option *irc_config_look_server_buffer;
|
||||
extern struct t_config_option *irc_config_look_smart_filter;
|
||||
extern struct t_config_option *irc_config_look_smart_filter_account;
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include "irc-sasl.h"
|
||||
#include "irc-server.h"
|
||||
#include "irc-tag.h"
|
||||
#include "irc-typing.h"
|
||||
|
||||
|
||||
/*
|
||||
@ -2139,6 +2140,13 @@ IRC_PROTOCOL_CALLBACK(notice)
|
||||
if (ptr_channel)
|
||||
irc_channel_join_smart_filtered_unmask (ptr_channel, nick);
|
||||
|
||||
if (ptr_channel
|
||||
&& weechat_config_boolean (irc_config_look_typing_status_nicks))
|
||||
{
|
||||
irc_typing_channel_set_nick (ptr_channel, nick,
|
||||
IRC_CHANNEL_TYPING_STATE_OFF);
|
||||
}
|
||||
|
||||
ptr_nick = irc_nick_search (server, ptr_channel, nick);
|
||||
weechat_printf_date_tags (
|
||||
(ptr_channel) ? ptr_channel->buffer : server->buffer,
|
||||
@ -2207,6 +2215,12 @@ IRC_PROTOCOL_CALLBACK(notice)
|
||||
|
||||
if (ptr_channel)
|
||||
{
|
||||
if (weechat_config_boolean (irc_config_look_typing_status_nicks))
|
||||
{
|
||||
irc_typing_channel_set_nick (ptr_channel, nick,
|
||||
IRC_CHANNEL_TYPING_STATE_OFF);
|
||||
}
|
||||
|
||||
if (!ptr_channel->topic)
|
||||
irc_channel_set_topic (ptr_channel, address);
|
||||
|
||||
@ -2392,6 +2406,9 @@ IRC_PROTOCOL_CALLBACK(part)
|
||||
/* part request was issued by local client ? */
|
||||
if (local_part)
|
||||
{
|
||||
if (weechat_config_boolean (irc_config_look_typing_status_nicks))
|
||||
irc_typing_channel_reset (ptr_channel);
|
||||
|
||||
irc_nick_free_all (server, ptr_channel);
|
||||
|
||||
irc_channel_modelist_set_state (ptr_channel,
|
||||
@ -2431,12 +2448,20 @@ IRC_PROTOCOL_CALLBACK(part)
|
||||
}
|
||||
irc_bar_item_update_channel ();
|
||||
}
|
||||
else if (ptr_nick)
|
||||
else
|
||||
{
|
||||
/* part from another user */
|
||||
irc_channel_join_smart_filtered_remove (ptr_channel,
|
||||
ptr_nick->name);
|
||||
irc_nick_free (server, ptr_channel, ptr_nick);
|
||||
if (weechat_config_boolean (irc_config_look_typing_status_nicks))
|
||||
{
|
||||
irc_typing_channel_set_nick (ptr_channel, nick,
|
||||
IRC_CHANNEL_TYPING_STATE_OFF);
|
||||
}
|
||||
if (ptr_nick)
|
||||
{
|
||||
irc_channel_join_smart_filtered_remove (ptr_channel,
|
||||
ptr_nick->name);
|
||||
irc_nick_free (server, ptr_channel, ptr_nick);
|
||||
}
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
@ -2574,6 +2599,12 @@ IRC_PROTOCOL_CALLBACK(privmsg)
|
||||
}
|
||||
|
||||
/* other message */
|
||||
if (weechat_config_boolean (irc_config_look_typing_status_nicks))
|
||||
{
|
||||
irc_typing_channel_set_nick (ptr_channel, nick,
|
||||
IRC_CHANNEL_TYPING_STATE_OFF);
|
||||
}
|
||||
|
||||
ptr_nick = irc_nick_search (server, ptr_channel, nick);
|
||||
|
||||
if (ptr_nick)
|
||||
@ -2664,6 +2695,13 @@ IRC_PROTOCOL_CALLBACK(privmsg)
|
||||
return WEECHAT_RC_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (weechat_config_boolean (irc_config_look_typing_status_nicks))
|
||||
{
|
||||
irc_typing_channel_set_nick (ptr_channel, nick,
|
||||
IRC_CHANNEL_TYPING_STATE_OFF);
|
||||
}
|
||||
|
||||
irc_channel_set_topic (ptr_channel, address);
|
||||
|
||||
if (nick_is_me)
|
||||
@ -2751,6 +2789,12 @@ IRC_PROTOCOL_CALLBACK(quit)
|
||||
for (ptr_channel = server->channels; ptr_channel;
|
||||
ptr_channel = ptr_channel->next_channel)
|
||||
{
|
||||
if (weechat_config_boolean (irc_config_look_typing_status_nicks))
|
||||
{
|
||||
irc_typing_channel_set_nick (ptr_channel, nick,
|
||||
IRC_CHANNEL_TYPING_STATE_OFF);
|
||||
}
|
||||
|
||||
if (ptr_channel->type == IRC_CHANNEL_TYPE_PRIVATE)
|
||||
ptr_nick = NULL;
|
||||
else
|
||||
@ -2906,14 +2950,46 @@ IRC_PROTOCOL_CALLBACK(setname)
|
||||
* (received when capability "message-tags" is enabled).
|
||||
*
|
||||
* Message looks like:
|
||||
* @msgid=6gqz7dxd22v7r3x9pvukkp8nni;+tag1 :nick!user@host TAGMSG #channel
|
||||
* @msgid=6gqz7dxd22v7r3x9pvu;+typing=active :nick!user@host TAGMSG #channel
|
||||
*/
|
||||
|
||||
IRC_PROTOCOL_CALLBACK(tagmsg)
|
||||
{
|
||||
struct t_irc_channel *ptr_channel;
|
||||
const char *ptr_typing_value;
|
||||
int state;
|
||||
|
||||
IRC_PROTOCOL_MIN_ARGS(3);
|
||||
|
||||
/* no action by default */
|
||||
if (ignored)
|
||||
return WEECHAT_RC_OK;
|
||||
|
||||
if (!tags)
|
||||
return WEECHAT_RC_OK;
|
||||
|
||||
ptr_channel = NULL;
|
||||
if (irc_channel_is_channel (server, argv[2]))
|
||||
ptr_channel = irc_channel_search (server, argv[2]);
|
||||
else if (irc_server_strcasecmp (server, argv[2], server->nick) == 0)
|
||||
ptr_channel = irc_channel_search (server, nick);
|
||||
if (!ptr_channel)
|
||||
return WEECHAT_RC_OK;
|
||||
|
||||
if (weechat_config_boolean (irc_config_look_typing_status_nicks))
|
||||
{
|
||||
ptr_typing_value = weechat_hashtable_get (tags, "+typing");
|
||||
if (ptr_typing_value && ptr_typing_value[0])
|
||||
{
|
||||
if (strcmp (ptr_typing_value, "active") == 0)
|
||||
state = IRC_CHANNEL_TYPING_STATE_ACTIVE;
|
||||
else if (strcmp (ptr_typing_value, "paused") == 0)
|
||||
state = IRC_CHANNEL_TYPING_STATE_PAUSED;
|
||||
else
|
||||
state = IRC_CHANNEL_TYPING_STATE_OFF;
|
||||
irc_typing_channel_set_nick (ptr_channel, nick, state);
|
||||
}
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
@ -3202,7 +3278,7 @@ IRC_PROTOCOL_CALLBACK(001)
|
||||
irc_server_set_nick (server, argv[2]);
|
||||
|
||||
irc_protocol_cb_numeric (server,
|
||||
date, nick, address, host, command,
|
||||
date, tags, nick, address, host, command,
|
||||
ignored, argc, argv, argv_eol);
|
||||
|
||||
/* connection to IRC server is OK! */
|
||||
@ -3324,7 +3400,7 @@ IRC_PROTOCOL_CALLBACK(005)
|
||||
IRC_PROTOCOL_MIN_ARGS(4);
|
||||
|
||||
irc_protocol_cb_numeric (server,
|
||||
date, nick, address, host, command,
|
||||
date, tags, nick, address, host, command,
|
||||
ignored, argc, argv, argv_eol);
|
||||
|
||||
/* save prefix */
|
||||
@ -5868,7 +5944,7 @@ IRC_PROTOCOL_CALLBACK(432)
|
||||
struct t_gui_buffer *ptr_buffer;
|
||||
|
||||
irc_protocol_cb_generic_error (server,
|
||||
date, nick, address, host, command,
|
||||
date, tags, nick, address, host, command,
|
||||
ignored, argc, argv, argv_eol);
|
||||
|
||||
if (!server->is_connected)
|
||||
@ -5953,7 +6029,7 @@ IRC_PROTOCOL_CALLBACK(433)
|
||||
else
|
||||
{
|
||||
return irc_protocol_cb_generic_error (server,
|
||||
date, nick, address, host,
|
||||
date, tags, nick, address, host,
|
||||
command, ignored, argc, argv,
|
||||
argv_eol);
|
||||
}
|
||||
@ -5974,7 +6050,7 @@ IRC_PROTOCOL_CALLBACK(437)
|
||||
struct t_gui_buffer *ptr_buffer;
|
||||
|
||||
irc_protocol_cb_generic_error (server,
|
||||
date, nick, address, host, command,
|
||||
date, tags, nick, address, host, command,
|
||||
ignored, argc, argv, argv_eol);
|
||||
|
||||
if (!server->is_connected)
|
||||
@ -6076,7 +6152,7 @@ IRC_PROTOCOL_CALLBACK(470)
|
||||
int lines_count;
|
||||
|
||||
irc_protocol_cb_generic_error (server,
|
||||
date, nick, address, host, command,
|
||||
date, tags, nick, address, host, command,
|
||||
ignored, argc, argv, argv_eol);
|
||||
|
||||
if ((argc >= 5) && !irc_channel_search (server, argv[3]))
|
||||
@ -6563,7 +6639,7 @@ IRC_PROTOCOL_CALLBACK(901)
|
||||
else
|
||||
{
|
||||
irc_protocol_cb_numeric (server,
|
||||
date, nick, address, host, command,
|
||||
date, tags, nick, address, host, command,
|
||||
ignored, argc, argv, argv_eol);
|
||||
}
|
||||
|
||||
@ -6586,7 +6662,7 @@ IRC_PROTOCOL_CALLBACK(sasl_end_ok)
|
||||
}
|
||||
|
||||
irc_protocol_cb_numeric (server,
|
||||
date, nick, address, host, command,
|
||||
date, tags, nick, address, host, command,
|
||||
ignored, argc, argv, argv_eol);
|
||||
|
||||
if (!server->is_connected)
|
||||
@ -6615,7 +6691,7 @@ IRC_PROTOCOL_CALLBACK(sasl_end_fail)
|
||||
}
|
||||
|
||||
irc_protocol_cb_numeric (server,
|
||||
date, nick, address, host, command,
|
||||
date, tags, nick, address, host, command,
|
||||
ignored, argc, argv, argv_eol);
|
||||
|
||||
sasl_fail = IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_SASL_FAIL);
|
||||
@ -6826,6 +6902,7 @@ irc_protocol_recv_command (struct t_irc_server *server,
|
||||
argv = NULL;
|
||||
argv_eol = NULL;
|
||||
date = 0;
|
||||
hash_tags = NULL;
|
||||
|
||||
ptr_msg_after_tags = irc_message;
|
||||
|
||||
@ -6848,7 +6925,6 @@ irc_protocol_recv_command (struct t_irc_server *server,
|
||||
irc_tag_parse (tags, hash_tags, NULL);
|
||||
date = irc_protocol_parse_time (
|
||||
weechat_hashtable_get (hash_tags, "time"));
|
||||
weechat_hashtable_free (hash_tags);
|
||||
}
|
||||
free (tags);
|
||||
}
|
||||
@ -6991,11 +7067,10 @@ irc_protocol_recv_command (struct t_irc_server *server,
|
||||
argv_eol = weechat_string_split (message_colors_decoded, " ", NULL,
|
||||
flags, 0, NULL);
|
||||
|
||||
return_code = (int) (cmd_recv_func) (server,
|
||||
date, nick, address_color,
|
||||
host_color, cmd_name,
|
||||
message_ignored, argc, argv,
|
||||
argv_eol);
|
||||
return_code = (int) (cmd_recv_func) (server, date, hash_tags, nick,
|
||||
address_color, host_color,
|
||||
cmd_name, message_ignored,
|
||||
argc, argv, argv_eol);
|
||||
|
||||
if (return_code == WEECHAT_RC_ERROR)
|
||||
{
|
||||
@ -7040,4 +7115,6 @@ end:
|
||||
weechat_string_free_split (argv);
|
||||
if (argv_eol)
|
||||
weechat_string_free_split (argv_eol);
|
||||
if (hash_tags)
|
||||
weechat_hashtable_free (hash_tags);
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
int \
|
||||
irc_protocol_cb_##__command (struct t_irc_server *server, \
|
||||
time_t date, \
|
||||
struct t_hashtable *tags, \
|
||||
const char *nick, \
|
||||
const char *address, \
|
||||
const char *host, \
|
||||
@ -43,6 +44,7 @@
|
||||
|
||||
#define IRC_PROTOCOL_MIN_ARGS(__min_args) \
|
||||
(void) date; \
|
||||
(void) tags; \
|
||||
(void) nick; \
|
||||
(void) address; \
|
||||
(void) host; \
|
||||
@ -75,9 +77,9 @@
|
||||
struct t_irc_server;
|
||||
|
||||
typedef int (t_irc_recv_func)(struct t_irc_server *server,
|
||||
time_t date, const char *nick,
|
||||
const char *address, const char *host,
|
||||
const char *command,
|
||||
time_t date, struct t_hashtable *tags,
|
||||
const char *nick, const char *address,
|
||||
const char *host, const char *command,
|
||||
int ignored,
|
||||
int argc, char **argv, char **argv_eol);
|
||||
|
||||
|
@ -64,6 +64,7 @@
|
||||
#include "irc-raw.h"
|
||||
#include "irc-redirect.h"
|
||||
#include "irc-sasl.h"
|
||||
#include "irc-typing.h"
|
||||
|
||||
|
||||
struct t_irc_server *irc_servers = NULL;
|
||||
@ -3734,33 +3735,8 @@ irc_server_timer_cb (const void *pointer, void *data, int remaining_calls)
|
||||
ptr_redirect = ptr_next_redirect;
|
||||
}
|
||||
|
||||
/* send typing status on channels */
|
||||
if (weechat_config_boolean (irc_config_look_send_typing_status))
|
||||
{
|
||||
for (ptr_channel = ptr_server->channels; ptr_channel;
|
||||
ptr_channel = ptr_channel->next_channel)
|
||||
{
|
||||
if ((ptr_channel->typing_status != IRC_CHANNEL_TYPING_STATUS_OFF)
|
||||
&& (ptr_channel->typing_status_sent + 3 < current_time))
|
||||
{
|
||||
irc_server_sendf (
|
||||
ptr_server,
|
||||
IRC_SERVER_SEND_OUTQ_PRIO_LOW, NULL,
|
||||
"@+typing=%s TAGMSG %s",
|
||||
irc_channel_typing_status_string[ptr_channel->typing_status],
|
||||
ptr_channel->name);
|
||||
if (ptr_channel->typing_status == IRC_CHANNEL_TYPING_STATUS_TYPING)
|
||||
{
|
||||
ptr_channel->typing_status_sent = current_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_channel->typing_status = IRC_CHANNEL_TYPING_STATUS_OFF;
|
||||
ptr_channel->typing_status_sent = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* send typing status on channels/privates */
|
||||
irc_typing_send_to_targets (ptr_server);
|
||||
|
||||
/* purge some data (every 10 minutes) */
|
||||
if (current_time > ptr_server->last_data_purge + (60 * 10))
|
||||
|
159
src/plugins/irc/irc-typing.c
Normal file
159
src/plugins/irc/irc-typing.c
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* irc-typing.c - manage typing status on channels/private
|
||||
*
|
||||
* Copyright (C) 2021 Sébastien Helleu <flashcode@flashtux.org>
|
||||
*
|
||||
* This file is part of WeeChat, the extensible chat client.
|
||||
*
|
||||
* WeeChat is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with WeeChat. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "irc.h"
|
||||
#include "irc-buffer.h"
|
||||
#include "irc-channel.h"
|
||||
#include "irc-config.h"
|
||||
#include "irc-server.h"
|
||||
|
||||
|
||||
/*
|
||||
* Callback for signals "typing_self_*".
|
||||
*/
|
||||
|
||||
int
|
||||
irc_typing_signal_typing_self_cb (const void *pointer, void *data,
|
||||
const char *signal, const char *type_data,
|
||||
void *signal_data)
|
||||
{
|
||||
struct t_irc_server *ptr_server;
|
||||
struct t_irc_channel *ptr_channel;
|
||||
int new_state;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) signal;
|
||||
(void) type_data;
|
||||
|
||||
/* sending self typing status is allowed? */
|
||||
if (!weechat_config_boolean (irc_config_look_typing_status_self))
|
||||
return WEECHAT_RC_OK;
|
||||
|
||||
/* search server/channel with buffer */
|
||||
irc_buffer_get_server_and_channel (signal_data, &ptr_server, &ptr_channel);
|
||||
if (!ptr_server || !ptr_channel)
|
||||
return WEECHAT_RC_OK;
|
||||
|
||||
/* typing works only if capability "message-tags" is enabled */
|
||||
if (!weechat_hashtable_has_key (ptr_server->cap_list, "message-tags"))
|
||||
return WEECHAT_RC_OK;
|
||||
|
||||
if (strcmp (signal, "typing_self_typing") == 0)
|
||||
new_state = IRC_CHANNEL_TYPING_STATE_ACTIVE;
|
||||
else if (strcmp (signal, "typing_self_paused") == 0)
|
||||
new_state = IRC_CHANNEL_TYPING_STATE_PAUSED;
|
||||
else if (strcmp (signal, "typing_self_cleared") == 0)
|
||||
new_state = IRC_CHANNEL_TYPING_STATE_DONE;
|
||||
else if (strcmp (signal, "typing_self_sent") == 0)
|
||||
new_state = IRC_CHANNEL_TYPING_STATE_OFF;
|
||||
else
|
||||
new_state = -1;
|
||||
|
||||
if ((new_state >= 0) && (new_state != ptr_channel->typing_state))
|
||||
{
|
||||
ptr_channel->typing_state = new_state;
|
||||
ptr_channel->typing_status_sent = 0;
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sends self typing status to channels/privates of a server.
|
||||
*/
|
||||
|
||||
void
|
||||
irc_typing_send_to_targets (struct t_irc_server *server)
|
||||
{
|
||||
struct t_irc_channel *ptr_channel;
|
||||
time_t current_time;
|
||||
|
||||
if (!weechat_config_boolean (irc_config_look_typing_status_self))
|
||||
return;
|
||||
|
||||
current_time = time (NULL);
|
||||
|
||||
for (ptr_channel = server->channels; ptr_channel;
|
||||
ptr_channel = ptr_channel->next_channel)
|
||||
{
|
||||
if (!ptr_channel->part
|
||||
&& (ptr_channel->typing_state != IRC_CHANNEL_TYPING_STATE_OFF)
|
||||
&& (ptr_channel->typing_status_sent + 3 < current_time))
|
||||
{
|
||||
irc_server_sendf (
|
||||
server,
|
||||
IRC_SERVER_SEND_OUTQ_PRIO_LOW, NULL,
|
||||
"@+typing=%s TAGMSG %s",
|
||||
irc_channel_typing_state_string[ptr_channel->typing_state],
|
||||
ptr_channel->name);
|
||||
if (ptr_channel->typing_state == IRC_CHANNEL_TYPING_STATE_ACTIVE)
|
||||
{
|
||||
ptr_channel->typing_status_sent = current_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_channel->typing_state = IRC_CHANNEL_TYPING_STATE_OFF;
|
||||
ptr_channel->typing_status_sent = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets state of a nick on a channel.
|
||||
*/
|
||||
|
||||
void
|
||||
irc_typing_channel_set_nick (struct t_irc_channel *channel, const char *nick,
|
||||
int state)
|
||||
{
|
||||
char signal_data[1024];
|
||||
|
||||
snprintf (signal_data, sizeof (signal_data),
|
||||
"0x%lx;%s;%s",
|
||||
(unsigned long)channel->buffer,
|
||||
(state == IRC_CHANNEL_TYPING_STATE_ACTIVE) ? "typing" :
|
||||
((state == IRC_CHANNEL_TYPING_STATE_PAUSED) ? "paused" : "off"),
|
||||
nick);
|
||||
weechat_hook_signal_send ("typing_set_nick",
|
||||
WEECHAT_HOOK_SIGNAL_STRING,
|
||||
signal_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Resets all nicks state on a channel.
|
||||
*/
|
||||
|
||||
void
|
||||
irc_typing_channel_reset (struct t_irc_channel *channel)
|
||||
{
|
||||
weechat_hook_signal_send ("typing_reset_buffer",
|
||||
WEECHAT_HOOK_SIGNAL_POINTER,
|
||||
channel->buffer);
|
||||
}
|
35
src/plugins/irc/irc-typing.h
Normal file
35
src/plugins/irc/irc-typing.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Sébastien Helleu <flashcode@flashtux.org>
|
||||
*
|
||||
* This file is part of WeeChat, the extensible chat client.
|
||||
*
|
||||
* WeeChat is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with WeeChat. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WEECHAT_PLUGIN_IRC_TYPING_H
|
||||
#define WEECHAT_PLUGIN_IRC_TYPING_H
|
||||
|
||||
struct t_irc_server;
|
||||
|
||||
extern int irc_typing_signal_typing_self_cb (const void *pointer, void *data,
|
||||
const char *signal,
|
||||
const char *type_data,
|
||||
void *signal_data);
|
||||
extern void irc_typing_send_to_targets (struct t_irc_server *server);
|
||||
extern void irc_typing_channel_set_nick (struct t_irc_channel *channel,
|
||||
const char *nick,
|
||||
int state);
|
||||
extern void irc_typing_channel_reset (struct t_irc_channel *channel);
|
||||
|
||||
#endif /* WEECHAT_PLUGIN_IRC_TYPING_H */
|
@ -43,6 +43,7 @@
|
||||
#include "irc-redirect.h"
|
||||
#include "irc-server.h"
|
||||
#include "irc-tag.h"
|
||||
#include "irc-typing.h"
|
||||
#include "irc-upgrade.h"
|
||||
|
||||
|
||||
@ -159,53 +160,6 @@ irc_signal_upgrade_cb (const void *pointer, void *data,
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for signals "typing_*".
|
||||
*/
|
||||
|
||||
int
|
||||
irc_signal_typing_cb (const void *pointer, void *data,
|
||||
const char *signal, const char *type_data,
|
||||
void *signal_data)
|
||||
{
|
||||
struct t_irc_server *ptr_server;
|
||||
struct t_irc_channel *ptr_channel;
|
||||
int new_status;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) signal;
|
||||
(void) type_data;
|
||||
|
||||
/* search server/channel with buffer */
|
||||
irc_buffer_get_server_and_channel (signal_data, &ptr_server, &ptr_channel);
|
||||
if (!ptr_server || !ptr_channel)
|
||||
return WEECHAT_RC_OK;
|
||||
|
||||
/* typing works only if capability "message-tags" is enabled */
|
||||
if (!weechat_hashtable_has_key (ptr_server->cap_list, "message-tags"))
|
||||
return WEECHAT_RC_OK;
|
||||
|
||||
new_status = -1;
|
||||
if (strcmp (signal, "typing_active") == 0)
|
||||
new_status = IRC_CHANNEL_TYPING_STATUS_TYPING;
|
||||
else if (strcmp (signal, "typing_paused") == 0)
|
||||
new_status = IRC_CHANNEL_TYPING_STATUS_PAUSED;
|
||||
else if (strcmp (signal, "typing_cleared") == 0)
|
||||
new_status = IRC_CHANNEL_TYPING_STATUS_DONE;
|
||||
else if (strcmp (signal, "typing_sent") == 0)
|
||||
new_status = IRC_CHANNEL_TYPING_STATUS_OFF;
|
||||
|
||||
if ((new_status >= 0) && (new_status != ptr_channel->typing_status))
|
||||
{
|
||||
ptr_channel->typing_status = new_status;
|
||||
ptr_channel->typing_status_sent = 0;
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes IRC plugin.
|
||||
*/
|
||||
@ -247,8 +201,8 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
&irc_server_xfer_send_accept_resume_cb, NULL, NULL);
|
||||
weechat_hook_signal ("irc_input_send",
|
||||
&irc_input_send_cb, NULL, NULL);
|
||||
weechat_hook_signal ("typing_*",
|
||||
&irc_signal_typing_cb, NULL, NULL);
|
||||
weechat_hook_signal ("typing_self_*",
|
||||
&irc_typing_signal_typing_self_cb, NULL, NULL);
|
||||
|
||||
/* hook hsignals for redirection */
|
||||
weechat_hook_hsignal ("irc_redirect_pattern",
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
add_library(typing MODULE
|
||||
typing.c typing.h
|
||||
typing-bar-item.c typing-bar-item.h
|
||||
typing-config.c typing-config.h
|
||||
typing-status.c typing-status.h
|
||||
)
|
||||
|
@ -25,6 +25,8 @@ lib_LTLIBRARIES = typing.la
|
||||
|
||||
typing_la_SOURCES = typing.c \
|
||||
typing.h \
|
||||
typing-bar-item.c \
|
||||
typing-bar-item.h \
|
||||
typing-config.c \
|
||||
typing-config.h \
|
||||
typing-status.c \
|
||||
|
120
src/plugins/typing/typing-bar-item.c
Normal file
120
src/plugins/typing/typing-bar-item.c
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* typing-bar-item.c - bar items for typing plugin
|
||||
*
|
||||
* Copyright (C) 2021 Sébastien Helleu <flashcode@flashtux.org>
|
||||
*
|
||||
* This file is part of WeeChat, the extensible chat client.
|
||||
*
|
||||
* WeeChat is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with WeeChat. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "typing.h"
|
||||
#include "typing-bar-item.h"
|
||||
#include "typing-config.h"
|
||||
#include "typing-status.h"
|
||||
|
||||
|
||||
/*
|
||||
* Callback used to build a string with the list of nicks typing on the buffer.
|
||||
*/
|
||||
|
||||
void
|
||||
typing_bar_item_nicks_map_cb (void *data,
|
||||
struct t_hashtable *hashtable,
|
||||
const void *key, const void *value)
|
||||
{
|
||||
char **str_nicks_typing;
|
||||
const char *ptr_nick;
|
||||
struct t_typing_status *ptr_typing_status;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) hashtable;
|
||||
|
||||
str_nicks_typing = (char **)data;
|
||||
|
||||
ptr_nick = (const char *)key;
|
||||
ptr_typing_status = (struct t_typing_status *)value;
|
||||
|
||||
if ((ptr_typing_status->state == TYPING_STATUS_STATE_TYPING)
|
||||
|| (ptr_typing_status->state == TYPING_STATUS_STATE_PAUSED))
|
||||
{
|
||||
if (*str_nicks_typing[0])
|
||||
weechat_string_dyn_concat (str_nicks_typing, ", ", -1);
|
||||
if (ptr_typing_status->state == TYPING_STATUS_STATE_PAUSED)
|
||||
weechat_string_dyn_concat (str_nicks_typing, "(", -1);
|
||||
weechat_string_dyn_concat (str_nicks_typing, ptr_nick, -1);
|
||||
if (ptr_typing_status->state == TYPING_STATUS_STATE_PAUSED)
|
||||
weechat_string_dyn_concat (str_nicks_typing, ")", -1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns content of bar item "typing": users currently typing on the buffer.
|
||||
*/
|
||||
|
||||
char *
|
||||
typing_bar_item_typing (const void *pointer, void *data,
|
||||
struct t_gui_bar_item *item,
|
||||
struct t_gui_window *window,
|
||||
struct t_gui_buffer *buffer,
|
||||
struct t_hashtable *extra_info)
|
||||
{
|
||||
struct t_hashtable *ptr_nicks;
|
||||
char **str_nicks_typing, **str_typing;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) item;
|
||||
(void) window;
|
||||
(void) extra_info;
|
||||
|
||||
if (!weechat_config_boolean (typing_config_look_enabled_nicks))
|
||||
return NULL;
|
||||
|
||||
ptr_nicks = weechat_hashtable_get (typing_status_nicks, buffer);
|
||||
if (!ptr_nicks)
|
||||
return NULL;
|
||||
|
||||
if (weechat_hashtable_get_integer (ptr_nicks, "items_count") == 0)
|
||||
return NULL;
|
||||
|
||||
str_nicks_typing = weechat_string_dyn_alloc (128);
|
||||
weechat_hashtable_map (ptr_nicks,
|
||||
&typing_bar_item_nicks_map_cb, str_nicks_typing);
|
||||
|
||||
str_typing = weechat_string_dyn_alloc (256);
|
||||
weechat_string_dyn_concat (str_typing, _("Typing: "), -1);
|
||||
weechat_string_dyn_concat (str_typing, *str_nicks_typing, -1);
|
||||
|
||||
weechat_string_dyn_free (str_nicks_typing, 1);
|
||||
|
||||
return weechat_string_dyn_free (str_typing, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes typing bar items.
|
||||
*/
|
||||
|
||||
void
|
||||
typing_bar_item_init ()
|
||||
{
|
||||
weechat_bar_item_new (TYPING_BAR_ITEM_NAME,
|
||||
&typing_bar_item_typing, NULL, NULL);
|
||||
}
|
27
src/plugins/typing/typing-bar-item.h
Normal file
27
src/plugins/typing/typing-bar-item.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Sébastien Helleu <flashcode@flashtux.org>
|
||||
*
|
||||
* This file is part of WeeChat, the extensible chat client.
|
||||
*
|
||||
* WeeChat is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with WeeChat. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WEECHAT_PLUGIN_TYPING_BAR_ITEM_H
|
||||
#define WEECHAT_PLUGIN_TYPING_BAR_ITEM_H
|
||||
|
||||
#define TYPING_BAR_ITEM_NAME "typing"
|
||||
|
||||
extern void typing_bar_item_init ();
|
||||
|
||||
#endif /* WEECHAT_PLUGIN_TYPING_BAR_ITEM_H */
|
@ -26,6 +26,7 @@
|
||||
#include "../weechat-plugin.h"
|
||||
#include "typing.h"
|
||||
#include "typing-config.h"
|
||||
#include "typing-bar-item.h"
|
||||
|
||||
|
||||
struct t_config_file *typing_config_file = NULL;
|
||||
@ -34,8 +35,11 @@ struct t_config_section *typing_config_section_completion = NULL;
|
||||
|
||||
/* typing config, look section */
|
||||
|
||||
struct t_config_option *typing_config_look_enabled;
|
||||
struct t_config_option *typing_config_look_delay_pause;
|
||||
struct t_config_option *typing_config_look_delay_purge_paused;
|
||||
struct t_config_option *typing_config_look_delay_purge_typing;
|
||||
struct t_config_option *typing_config_look_delay_set_paused;
|
||||
struct t_config_option *typing_config_look_enabled_nicks;
|
||||
struct t_config_option *typing_config_look_enabled_self;
|
||||
|
||||
|
||||
/*
|
||||
@ -73,6 +77,7 @@ typing_config_change_enabled (const void *pointer, void *data,
|
||||
(void) option;
|
||||
|
||||
typing_setup_hooks ();
|
||||
weechat_bar_item_update (TYPING_BAR_ITEM_NAME);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -109,21 +114,44 @@ typing_config_init ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
typing_config_look_enabled = weechat_config_new_option (
|
||||
typing_config_look_delay_purge_paused = weechat_config_new_option (
|
||||
typing_config_file, ptr_section,
|
||||
"enabled", "boolean",
|
||||
N_("typing enabled"),
|
||||
NULL, 0, 0, "on", NULL, 0,
|
||||
NULL, NULL, NULL,
|
||||
&typing_config_change_enabled, NULL, NULL,
|
||||
NULL, NULL, NULL);
|
||||
typing_config_look_delay_pause = weechat_config_new_option (
|
||||
"delay_purge_paused", "integer",
|
||||
N_("number of seconds after paused status has been set: if reached, "
|
||||
"the typing status is removed"),
|
||||
NULL, 1, 3600, "30", NULL, 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
typing_config_look_delay_purge_typing = weechat_config_new_option (
|
||||
typing_config_file, ptr_section,
|
||||
"delay_pause", "integer",
|
||||
"delay_purge_typing", "integer",
|
||||
N_("number of seconds after typing status has been set: if reached, "
|
||||
"the typing status is removed"),
|
||||
NULL, 1, 3600, "6", NULL, 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
typing_config_look_delay_set_paused = weechat_config_new_option (
|
||||
typing_config_file, ptr_section,
|
||||
"delay_set_paused", "integer",
|
||||
N_("number of seconds after typing last char: if reached, the typing "
|
||||
"status becomes \"paused\" and no more typing signals are sent"),
|
||||
NULL, 1, 3600, "10", NULL, 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
typing_config_look_enabled_nicks = weechat_config_new_option (
|
||||
typing_config_file, ptr_section,
|
||||
"enabled_nicks", "boolean",
|
||||
N_("typing enabled for other nicks (display typing info for nicks "
|
||||
"typing in the current buffer)"),
|
||||
NULL, 0, 0, "off", NULL, 0,
|
||||
NULL, NULL, NULL,
|
||||
&typing_config_change_enabled, NULL, NULL,
|
||||
NULL, NULL, NULL);
|
||||
typing_config_look_enabled_self = weechat_config_new_option (
|
||||
typing_config_file, ptr_section,
|
||||
"enabled_self", "boolean",
|
||||
N_("typing enabled for self messages (send typing info to other users)"),
|
||||
NULL, 0, 0, "off", NULL, 0,
|
||||
NULL, NULL, NULL,
|
||||
&typing_config_change_enabled, NULL, NULL,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -22,8 +22,11 @@
|
||||
|
||||
#define TYPING_CONFIG_NAME "typing"
|
||||
|
||||
extern struct t_config_option *typing_config_look_enabled;
|
||||
extern struct t_config_option *typing_config_look_delay_pause;
|
||||
extern struct t_config_option *typing_config_look_delay_purge_paused;
|
||||
extern struct t_config_option *typing_config_look_delay_purge_typing;
|
||||
extern struct t_config_option *typing_config_look_delay_set_paused;
|
||||
extern struct t_config_option *typing_config_look_enabled_nicks;
|
||||
extern struct t_config_option *typing_config_look_enabled_self;
|
||||
|
||||
extern int typing_config_init ();
|
||||
extern int typing_config_read ();
|
||||
|
@ -32,16 +32,44 @@
|
||||
#include "typing-status.h"
|
||||
|
||||
|
||||
char *typing_status_state_string[TYPING_STATUS_NUM_STATES] =
|
||||
{ "off", "typing", "paused", "cleared" };
|
||||
|
||||
/* hashtable[buffer -> t_typing_status] */
|
||||
struct t_hashtable *typing_status_self = NULL;
|
||||
|
||||
/* hashtable[buffer -> hashtable[nick -> t_typing_status]] */
|
||||
struct t_hashtable *typing_status_nicks = NULL;
|
||||
|
||||
|
||||
/*
|
||||
* Removes a typing status.
|
||||
* Searches a state by name.
|
||||
*
|
||||
* Returns index of stats in enum t_typing_status_state, -1 if not found.
|
||||
*/
|
||||
|
||||
int
|
||||
typing_status_search_state (const char *state)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < TYPING_STATUS_NUM_STATES; i++)
|
||||
{
|
||||
if (strcmp (typing_status_state_string[i], state) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes self typing status for a buffer: key is a buffer pointer, value
|
||||
* is a t_typing_status pointer.
|
||||
*/
|
||||
|
||||
void
|
||||
typing_status_free_value_cb (struct t_hashtable *hashtable,
|
||||
const void *key, const void *value)
|
||||
typing_status_self_free_value_cb (struct t_hashtable *hashtable,
|
||||
const void *key, const void *value)
|
||||
{
|
||||
struct t_gui_buffer *ptr_buffer;
|
||||
struct t_typing_status *ptr_typing_status;
|
||||
@ -52,14 +80,14 @@ typing_status_free_value_cb (struct t_hashtable *hashtable,
|
||||
ptr_buffer = (struct t_gui_buffer *)key;
|
||||
ptr_typing_status = (struct t_typing_status *)value;
|
||||
|
||||
if (!ptr_typing_status)
|
||||
if (!ptr_buffer || !ptr_typing_status)
|
||||
return;
|
||||
|
||||
if (weechat_typing_plugin->debug)
|
||||
{
|
||||
weechat_printf_date_tags (
|
||||
NULL, 0, "no_log",
|
||||
"%s: stop typing status for buffer \"%s\"",
|
||||
"%s: removing self typing status for buffer \"%s\"",
|
||||
TYPING_PLUGIN_NAME,
|
||||
weechat_buffer_get_string (ptr_buffer, "name"));
|
||||
}
|
||||
@ -68,7 +96,7 @@ typing_status_free_value_cb (struct t_hashtable *hashtable,
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a new typing status.
|
||||
* Adds a new self typing status.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
@ -76,46 +104,241 @@ typing_status_free_value_cb (struct t_hashtable *hashtable,
|
||||
*/
|
||||
|
||||
struct t_typing_status *
|
||||
typing_status_add (struct t_gui_buffer *buffer)
|
||||
typing_status_self_add (struct t_gui_buffer *buffer, int state, int last_typed)
|
||||
{
|
||||
struct t_typing_status *new_typing_status;
|
||||
struct t_typing_status *ptr_typing_status;
|
||||
|
||||
if (!buffer)
|
||||
if (!buffer || (state < 0) || (state >= TYPING_STATUS_NUM_STATES))
|
||||
return NULL;
|
||||
|
||||
if (!typing_status_self)
|
||||
{
|
||||
typing_status_self = weechat_hashtable_new (64,
|
||||
WEECHAT_HASHTABLE_POINTER,
|
||||
WEECHAT_HASHTABLE_POINTER,
|
||||
NULL,
|
||||
NULL);
|
||||
typing_status_self = weechat_hashtable_new (
|
||||
64,
|
||||
WEECHAT_HASHTABLE_POINTER, /* buffer */
|
||||
WEECHAT_HASHTABLE_POINTER, /* t_typing_status */
|
||||
NULL,
|
||||
NULL);
|
||||
if (!typing_status_self)
|
||||
return NULL;
|
||||
weechat_hashtable_set_pointer (typing_status_self,
|
||||
"callback_free_value",
|
||||
&typing_status_free_value_cb);
|
||||
&typing_status_self_free_value_cb);
|
||||
}
|
||||
|
||||
new_typing_status = malloc (sizeof (*new_typing_status));
|
||||
if (!new_typing_status)
|
||||
ptr_typing_status = weechat_hashtable_get (typing_status_self, buffer);
|
||||
if (!ptr_typing_status)
|
||||
{
|
||||
if (weechat_typing_plugin->debug)
|
||||
{
|
||||
weechat_printf_date_tags (
|
||||
NULL, 0, "no_log",
|
||||
"%s: creating self typing status for buffer \"%s\"",
|
||||
TYPING_PLUGIN_NAME,
|
||||
weechat_buffer_get_string (buffer, "name"));
|
||||
}
|
||||
ptr_typing_status = malloc (sizeof (*ptr_typing_status));
|
||||
if (!ptr_typing_status)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr_typing_status->state = state;
|
||||
ptr_typing_status->last_typed = last_typed;
|
||||
|
||||
weechat_hashtable_set (typing_status_self, buffer, ptr_typing_status);
|
||||
|
||||
return ptr_typing_status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Searches a self typing status for a buffer.
|
||||
*
|
||||
* Returns pointer to t_typing_status found, NULL if not found.
|
||||
*/
|
||||
|
||||
struct t_typing_status *
|
||||
typing_status_self_search (struct t_gui_buffer *buffer)
|
||||
{
|
||||
if (!typing_status_self)
|
||||
return NULL;
|
||||
|
||||
return weechat_hashtable_get (typing_status_self, buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes nicks typing status: key is a buffer pointer, value is a hashtable
|
||||
* pointer.
|
||||
*/
|
||||
|
||||
void
|
||||
typing_status_nicks_free_value_cb (struct t_hashtable *hashtable,
|
||||
const void *key, const void *value)
|
||||
{
|
||||
struct t_gui_buffer *ptr_buffer;
|
||||
struct t_hashtable *ptr_nicks;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) hashtable;
|
||||
|
||||
ptr_buffer = (struct t_gui_buffer *)key;
|
||||
ptr_nicks = (struct t_hashtable *)value;
|
||||
|
||||
if (!ptr_buffer || !ptr_nicks)
|
||||
return;
|
||||
|
||||
if (weechat_typing_plugin->debug)
|
||||
{
|
||||
weechat_printf_date_tags (NULL, 0, "no_log",
|
||||
"%s: start typing status for buffer \"%s\"",
|
||||
TYPING_PLUGIN_NAME,
|
||||
weechat_buffer_get_string (buffer, "name"));
|
||||
weechat_printf_date_tags (
|
||||
NULL, 0, "no_log",
|
||||
"%s: removing nicks typing status for buffer \"%s\"",
|
||||
TYPING_PLUGIN_NAME,
|
||||
weechat_buffer_get_string (ptr_buffer, "name"));
|
||||
}
|
||||
|
||||
new_typing_status->status = TYPING_STATUS_STATUS_OFF;
|
||||
new_typing_status->last_typed = 0;
|
||||
new_typing_status->last_signal_sent = 0;
|
||||
weechat_hashtable_free (ptr_nicks);
|
||||
}
|
||||
|
||||
weechat_hashtable_set (typing_status_self, buffer, new_typing_status);
|
||||
/*
|
||||
* Removes a nick typing status: key is a nick (string), value is a
|
||||
* t_typing_status pointer.
|
||||
*/
|
||||
|
||||
return new_typing_status;
|
||||
void
|
||||
typing_status_nick_free_value_cb (struct t_hashtable *hashtable,
|
||||
const void *key, const void *value)
|
||||
{
|
||||
const char *ptr_nick;
|
||||
struct t_typing_status *ptr_typing_status;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) hashtable;
|
||||
|
||||
ptr_nick = (const char *)key;
|
||||
ptr_typing_status = (struct t_typing_status *)value;
|
||||
|
||||
if (!ptr_nick || !ptr_typing_status)
|
||||
return;
|
||||
|
||||
free (ptr_typing_status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a nick typing status for a buffer.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
struct t_typing_status *
|
||||
typing_status_nick_add (struct t_gui_buffer *buffer, const char *nick,
|
||||
int state, int last_typed)
|
||||
{
|
||||
struct t_hashtable *ptr_nicks;
|
||||
struct t_typing_status *ptr_typing_status;
|
||||
|
||||
if (!buffer || !nick || (state < 0) || (state >= TYPING_STATUS_NUM_STATES))
|
||||
return NULL;
|
||||
|
||||
if (!typing_status_nicks)
|
||||
{
|
||||
typing_status_nicks = weechat_hashtable_new (
|
||||
64,
|
||||
WEECHAT_HASHTABLE_POINTER, /* buffer */
|
||||
WEECHAT_HASHTABLE_POINTER, /* hashtable */
|
||||
NULL,
|
||||
NULL);
|
||||
if (!typing_status_nicks)
|
||||
return NULL;
|
||||
weechat_hashtable_set_pointer (typing_status_nicks,
|
||||
"callback_free_value",
|
||||
&typing_status_nicks_free_value_cb);
|
||||
}
|
||||
|
||||
ptr_nicks = weechat_hashtable_get (typing_status_nicks, buffer);
|
||||
if (!ptr_nicks)
|
||||
{
|
||||
ptr_nicks = weechat_hashtable_new (
|
||||
32,
|
||||
WEECHAT_HASHTABLE_STRING, /* nick */
|
||||
WEECHAT_HASHTABLE_POINTER, /* t_typing_status */
|
||||
NULL,
|
||||
NULL);
|
||||
if (!ptr_nicks)
|
||||
return NULL;
|
||||
weechat_hashtable_set_pointer (ptr_nicks,
|
||||
"callback_free_value",
|
||||
&typing_status_nick_free_value_cb);
|
||||
weechat_hashtable_set (typing_status_nicks, buffer, ptr_nicks);
|
||||
}
|
||||
|
||||
ptr_typing_status = weechat_hashtable_get (ptr_nicks, nick);
|
||||
if (!ptr_typing_status)
|
||||
{
|
||||
if (weechat_typing_plugin->debug)
|
||||
{
|
||||
weechat_printf_date_tags (
|
||||
NULL, 0, "no_log",
|
||||
"%s: creating typing status for buffer \"%s\" and nick \"%s\"",
|
||||
TYPING_PLUGIN_NAME,
|
||||
weechat_buffer_get_string (buffer, "name"),
|
||||
nick);
|
||||
}
|
||||
ptr_typing_status = malloc (sizeof (*ptr_typing_status));
|
||||
if (!ptr_typing_status)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr_typing_status->state = state;
|
||||
ptr_typing_status->last_typed = last_typed;
|
||||
|
||||
weechat_hashtable_set (ptr_nicks, nick, ptr_typing_status);
|
||||
|
||||
return ptr_typing_status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes a nick typing status from a buffer.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
void
|
||||
typing_status_nick_remove (struct t_gui_buffer *buffer, const char *nick)
|
||||
{
|
||||
struct t_hashtable *ptr_nicks;
|
||||
|
||||
if (!typing_status_nicks)
|
||||
return;
|
||||
|
||||
ptr_nicks = weechat_hashtable_get (typing_status_nicks, buffer);
|
||||
if (!ptr_nicks)
|
||||
return;
|
||||
|
||||
weechat_hashtable_remove (ptr_nicks, nick);
|
||||
}
|
||||
|
||||
/*
|
||||
* Searches a nick typing status for a buffer.
|
||||
*
|
||||
* Returns pointer to t_typing_status found, NULL if not found.
|
||||
*/
|
||||
|
||||
struct t_typing_status *
|
||||
typing_status_nick_search (struct t_gui_buffer *buffer, const char *nick)
|
||||
{
|
||||
struct t_hashtable *ptr_nicks;
|
||||
|
||||
if (!typing_status_nicks)
|
||||
return NULL;
|
||||
|
||||
ptr_nicks = weechat_hashtable_get (typing_status_nicks, buffer);
|
||||
if (!ptr_nicks)
|
||||
return NULL;
|
||||
|
||||
return weechat_hashtable_get (ptr_nicks, nick);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -130,4 +353,9 @@ typing_status_end ()
|
||||
weechat_hashtable_free (typing_status_self);
|
||||
typing_status_self = NULL;
|
||||
}
|
||||
if (typing_status_nicks)
|
||||
{
|
||||
weechat_hashtable_free (typing_status_nicks);
|
||||
typing_status_nicks = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -20,33 +20,42 @@
|
||||
#ifndef WEECHAT_PLUGIN_TYPING_STATUS_H
|
||||
#define WEECHAT_PLUGIN_TYPING_STATUS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
struct t_infolist;
|
||||
|
||||
enum t_typing_status_status
|
||||
enum t_typing_status_state
|
||||
{
|
||||
TYPING_STATUS_STATUS_OFF = 0,
|
||||
TYPING_STATUS_STATUS_TYPING,
|
||||
TYPING_STATUS_STATUS_PAUSED,
|
||||
TYPING_STATUS_STATUS_CLEARED,
|
||||
TYPING_STATUS_STATE_OFF = 0,
|
||||
TYPING_STATUS_STATE_TYPING,
|
||||
TYPING_STATUS_STATE_PAUSED,
|
||||
TYPING_STATUS_STATE_CLEARED,
|
||||
/* number of typing status statuses */
|
||||
TYPING_STATUS_NUM_STATUSES,
|
||||
TYPING_STATUS_NUM_STATES,
|
||||
};
|
||||
|
||||
/* self typing status */
|
||||
/* typing status */
|
||||
|
||||
struct t_typing_status
|
||||
{
|
||||
int status; /* status */
|
||||
time_t last_typed; /* last char typed */
|
||||
time_t last_signal_sent; /* last signal sent */
|
||||
int state; /* current state */
|
||||
time_t last_typed; /* when was last char typed */
|
||||
};
|
||||
|
||||
extern struct t_hashtable *typing_status_self;
|
||||
extern struct t_hashtable *typing_status_nicks;
|
||||
|
||||
extern struct t_typing_status *typing_status_add (struct t_gui_buffer *buffer);
|
||||
extern int typing_status_search_state (const char *state);
|
||||
extern struct t_typing_status *typing_status_self_add (struct t_gui_buffer *buffer,
|
||||
int state,
|
||||
int last_typed);
|
||||
extern struct t_typing_status *typing_status_self_search (struct t_gui_buffer *buffer);
|
||||
extern struct t_typing_status *typing_status_nick_add (struct t_gui_buffer *buffer,
|
||||
const char *nick,
|
||||
int state,
|
||||
int last_typed);
|
||||
extern void typing_status_nick_remove (struct t_gui_buffer *buffer,
|
||||
const char *nick);
|
||||
extern struct t_typing_status *typing_status_nick_search (struct t_gui_buffer *buffer,
|
||||
const char *nick);
|
||||
extern void typing_status_end ();
|
||||
|
||||
#endif /* WEECHAT_PLUGIN_TYPING_STATUS_H */
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "typing.h"
|
||||
#include "typing-bar-item.h"
|
||||
#include "typing-config.h"
|
||||
#include "typing-status.h"
|
||||
|
||||
@ -43,6 +44,10 @@ struct t_hook *typing_signal_buffer_closing = NULL;
|
||||
struct t_hook *typing_signal_input_text_changed = NULL;
|
||||
struct t_hook *typing_modifier_input_text_for_buffer = NULL;
|
||||
struct t_hook *typing_timer = NULL;
|
||||
struct t_hook *typing_signal_typing_set_nick = NULL;
|
||||
struct t_hook *typing_signal_typing_reset_buffer = NULL;
|
||||
|
||||
int typing_update_item = 0;
|
||||
|
||||
|
||||
/*
|
||||
@ -52,9 +57,7 @@ struct t_hook *typing_timer = NULL;
|
||||
*/
|
||||
|
||||
int
|
||||
typing_send_signal (struct t_gui_buffer *buffer,
|
||||
struct t_typing_status *typing_status,
|
||||
const char *signal_name)
|
||||
typing_send_signal (struct t_gui_buffer *buffer, const char *signal_name)
|
||||
{
|
||||
if (weechat_typing_plugin->debug)
|
||||
{
|
||||
@ -64,7 +67,6 @@ typing_send_signal (struct t_gui_buffer *buffer,
|
||||
weechat_buffer_get_string (buffer, "full_name"));
|
||||
}
|
||||
|
||||
typing_status->last_signal_sent = time (NULL);
|
||||
return weechat_hook_signal_send (signal_name,
|
||||
WEECHAT_HOOK_SIGNAL_POINTER,
|
||||
buffer);
|
||||
@ -86,6 +88,7 @@ typing_buffer_closing_signal_cb (const void *pointer, void *data,
|
||||
(void) type_data;
|
||||
|
||||
weechat_hashtable_remove (typing_status_self, signal_data);
|
||||
weechat_hashtable_remove (typing_status_nicks, signal_data);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
@ -126,30 +129,33 @@ typing_input_text_changed_signal_cb (const void *pointer, void *data,
|
||||
if (!ptr_input_for_buffer)
|
||||
return WEECHAT_RC_OK;
|
||||
|
||||
ptr_typing_status = weechat_hashtable_get (typing_status_self,
|
||||
ptr_buffer);
|
||||
ptr_typing_status = typing_status_self_search (ptr_buffer);
|
||||
if (!ptr_typing_status)
|
||||
ptr_typing_status = typing_status_add (ptr_buffer);
|
||||
{
|
||||
ptr_typing_status = typing_status_self_add (
|
||||
ptr_buffer,
|
||||
TYPING_STATUS_STATE_TYPING,
|
||||
0);
|
||||
}
|
||||
if (!ptr_typing_status)
|
||||
return WEECHAT_RC_OK;
|
||||
ptr_typing_status->status = TYPING_STATUS_STATUS_TYPING;
|
||||
ptr_typing_status->state = TYPING_STATUS_STATE_TYPING;
|
||||
ptr_typing_status->last_typed = time (NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* user was typing something? */
|
||||
ptr_typing_status = weechat_hashtable_get (typing_status_self,
|
||||
ptr_buffer);
|
||||
ptr_typing_status = typing_status_self_search (ptr_buffer);
|
||||
if (ptr_typing_status
|
||||
&& ((ptr_typing_status->status == TYPING_STATUS_STATUS_TYPING)
|
||||
|| (ptr_typing_status->status == TYPING_STATUS_STATUS_PAUSED)))
|
||||
&& ((ptr_typing_status->state == TYPING_STATUS_STATE_TYPING)
|
||||
|| (ptr_typing_status->state == TYPING_STATUS_STATE_PAUSED)))
|
||||
{
|
||||
/*
|
||||
* input cleared: maybe something was sent, not sure, so we just
|
||||
* set the status to "cleared", a signal can be sent later
|
||||
* set the state to "cleared", a signal can be sent later
|
||||
* in timer
|
||||
*/
|
||||
ptr_typing_status->status = TYPING_STATUS_STATUS_CLEARED;
|
||||
ptr_typing_status->state = TYPING_STATUS_STATE_CLEARED;
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,13 +200,17 @@ typing_input_text_for_buffer_modifier_cb (const void *pointer,
|
||||
if (!ptr_input_for_buffer)
|
||||
return NULL;
|
||||
|
||||
ptr_typing_status = weechat_hashtable_get (typing_status_self, ptr_buffer);
|
||||
ptr_typing_status = typing_status_self_search (ptr_buffer);
|
||||
if (!ptr_typing_status)
|
||||
ptr_typing_status = typing_status_add (ptr_buffer);
|
||||
{
|
||||
ptr_typing_status = typing_status_self_add (ptr_buffer,
|
||||
TYPING_STATUS_STATE_OFF,
|
||||
0);
|
||||
}
|
||||
if (!ptr_typing_status)
|
||||
return NULL;
|
||||
|
||||
typing_send_signal (ptr_buffer, ptr_typing_status, "typing_sent");
|
||||
typing_send_signal (ptr_buffer, "typing_self_sent");
|
||||
weechat_hashtable_remove (typing_status_self, ptr_buffer);
|
||||
|
||||
return NULL;
|
||||
@ -212,73 +222,251 @@ typing_input_text_for_buffer_modifier_cb (const void *pointer,
|
||||
*/
|
||||
|
||||
void
|
||||
typing_status_self_map_cb (void *data,
|
||||
struct t_hashtable *hashtable,
|
||||
const void *key, const void *value)
|
||||
typing_status_self_status_map_cb (void *data,
|
||||
struct t_hashtable *hashtable,
|
||||
const void *key, const void *value)
|
||||
{
|
||||
struct t_gui_buffer *ptr_buffer;
|
||||
struct t_typing_status *ptr_typing_status;
|
||||
const char *ptr_input, *ptr_input_for_buffer;
|
||||
time_t current_time;
|
||||
int delay_pause;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
current_time = *((time_t *)data);
|
||||
|
||||
ptr_buffer = (struct t_gui_buffer *)key;
|
||||
ptr_typing_status = (struct t_typing_status *)value;
|
||||
|
||||
if (ptr_typing_status->status == TYPING_STATUS_STATUS_TYPING)
|
||||
if (!ptr_buffer || !ptr_typing_status)
|
||||
return;
|
||||
|
||||
if (ptr_typing_status->state == TYPING_STATUS_STATE_TYPING)
|
||||
{
|
||||
ptr_input = weechat_buffer_get_string (ptr_buffer, "input");
|
||||
ptr_input_for_buffer = weechat_string_input_for_buffer (ptr_input);
|
||||
if (ptr_input_for_buffer)
|
||||
{
|
||||
/* check if typing is paused */
|
||||
delay_pause = weechat_config_integer (typing_config_look_delay_pause);
|
||||
if (ptr_typing_status->last_typed < time (NULL) - delay_pause)
|
||||
delay_pause = weechat_config_integer (typing_config_look_delay_set_paused);
|
||||
if (ptr_typing_status->last_typed < current_time - delay_pause)
|
||||
{
|
||||
ptr_typing_status->status = TYPING_STATUS_STATUS_PAUSED;
|
||||
typing_send_signal (ptr_buffer, ptr_typing_status,
|
||||
"typing_paused");
|
||||
ptr_typing_status->state = TYPING_STATUS_STATE_PAUSED;
|
||||
typing_send_signal (ptr_buffer, "typing_self_paused");
|
||||
weechat_hashtable_remove (hashtable, ptr_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
typing_send_signal (ptr_buffer, ptr_typing_status,
|
||||
"typing_active");
|
||||
typing_send_signal (ptr_buffer, "typing_self_typing");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
typing_send_signal (ptr_buffer, ptr_typing_status,
|
||||
"typing_cleared");
|
||||
typing_send_signal (ptr_buffer, "typing_self_cleared");
|
||||
weechat_hashtable_remove (hashtable, ptr_buffer);
|
||||
}
|
||||
}
|
||||
else if (ptr_typing_status->status == TYPING_STATUS_STATUS_CLEARED)
|
||||
else if (ptr_typing_status->state == TYPING_STATUS_STATE_CLEARED)
|
||||
{
|
||||
typing_send_signal (ptr_buffer, ptr_typing_status,
|
||||
"typing_cleared");
|
||||
typing_send_signal (ptr_buffer, "typing_self_cleared");
|
||||
weechat_hashtable_remove (hashtable, ptr_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for modifier "input_text_for_buffer".
|
||||
* Callback called periodically (via a timer) for each entry in hashtable
|
||||
* "typing_status_nicks".
|
||||
*/
|
||||
|
||||
void
|
||||
typing_status_nicks_status_map_cb (void *data,
|
||||
struct t_hashtable *hashtable,
|
||||
const void *key, const void *value)
|
||||
{
|
||||
const char *ptr_nick;
|
||||
struct t_typing_status *ptr_typing_status;
|
||||
time_t current_time;
|
||||
int delay_purge_pause, delay_purge_typing;
|
||||
|
||||
current_time = *((time_t *)data);
|
||||
|
||||
ptr_nick = (const char *)key;
|
||||
ptr_typing_status = (struct t_typing_status *)value;
|
||||
|
||||
if (!ptr_nick || !ptr_typing_status)
|
||||
return;
|
||||
|
||||
delay_purge_pause = weechat_config_integer (
|
||||
typing_config_look_delay_purge_paused);
|
||||
delay_purge_typing = weechat_config_integer (
|
||||
typing_config_look_delay_purge_typing);
|
||||
|
||||
if (((ptr_typing_status->state == TYPING_STATUS_STATE_PAUSED)
|
||||
&& (ptr_typing_status->last_typed < current_time - delay_purge_pause))
|
||||
|| ((ptr_typing_status->state == TYPING_STATUS_STATE_TYPING)
|
||||
&& (ptr_typing_status->last_typed < current_time - delay_purge_typing)))
|
||||
{
|
||||
weechat_hashtable_remove (hashtable, key);
|
||||
typing_update_item = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback called periodically (via a timer) for each entry in hashtable
|
||||
* "typing_status_nicks".
|
||||
*/
|
||||
|
||||
void
|
||||
typing_status_nicks_hash_map_cb (void *data,
|
||||
struct t_hashtable *hashtable,
|
||||
const void *key, const void *value)
|
||||
{
|
||||
struct t_hashtable *ptr_nicks;
|
||||
|
||||
ptr_nicks = (struct t_hashtable *)value;
|
||||
|
||||
if (!ptr_nicks)
|
||||
return;
|
||||
|
||||
weechat_hashtable_map (ptr_nicks,
|
||||
&typing_status_nicks_status_map_cb,
|
||||
data);
|
||||
|
||||
/* no more nicks for the buffer? then remove the buffer */
|
||||
if (weechat_hashtable_get_integer (ptr_nicks, "items_count") == 0)
|
||||
weechat_hashtable_remove (hashtable, key);
|
||||
}
|
||||
|
||||
/*
|
||||
* Typing timer used to send continuously the self typing status.
|
||||
*/
|
||||
|
||||
int
|
||||
typing_timer_cb (const void *pointer,
|
||||
void *data,
|
||||
int remaining_calls)
|
||||
typing_timer_cb (const void *pointer, void *data, int remaining_calls)
|
||||
{
|
||||
time_t current_time;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) remaining_calls;
|
||||
|
||||
typing_update_item = 0;
|
||||
current_time = time (NULL);
|
||||
|
||||
weechat_hashtable_map (typing_status_self,
|
||||
&typing_status_self_map_cb, NULL);
|
||||
&typing_status_self_status_map_cb, ¤t_time);
|
||||
weechat_hashtable_map (typing_status_nicks,
|
||||
&typing_status_nicks_hash_map_cb, ¤t_time);
|
||||
|
||||
if (typing_update_item)
|
||||
weechat_bar_item_update (TYPING_BAR_ITEM_NAME);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for signal "typing_set_nick".
|
||||
*/
|
||||
|
||||
int
|
||||
typing_typing_set_nick_signal_cb (const void *pointer, void *data,
|
||||
const char *signal,
|
||||
const char *type_data, void *signal_data)
|
||||
{
|
||||
char **items;
|
||||
int num_items, rc, state, updated;
|
||||
unsigned long value;
|
||||
struct t_gui_buffer *ptr_buffer;
|
||||
struct t_typing_status *ptr_typing_status;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) signal;
|
||||
(void) type_data;
|
||||
|
||||
items = weechat_string_split ((const char *)signal_data, ";", NULL,
|
||||
0, 3, &num_items);
|
||||
if (!items || (num_items != 3))
|
||||
goto end;
|
||||
|
||||
rc = sscanf (items[0], "%lx", &value);
|
||||
if ((rc == EOF) || (rc == 0))
|
||||
goto end;
|
||||
ptr_buffer = (struct t_gui_buffer *)value;
|
||||
if (!ptr_buffer)
|
||||
goto end;
|
||||
|
||||
state = typing_status_search_state (items[1]);
|
||||
if (state < 0)
|
||||
goto end;
|
||||
|
||||
if (!items[2][0])
|
||||
goto end;
|
||||
|
||||
updated = 0;
|
||||
ptr_typing_status = typing_status_nick_search (ptr_buffer, items[2]);
|
||||
if ((state == TYPING_STATUS_STATE_TYPING)
|
||||
|| (state == TYPING_STATUS_STATE_PAUSED))
|
||||
{
|
||||
if (ptr_typing_status)
|
||||
{
|
||||
if (ptr_typing_status->state != state)
|
||||
updated = 1;
|
||||
ptr_typing_status->state = state;
|
||||
ptr_typing_status->last_typed = time (NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
typing_status_nick_add (ptr_buffer, items[2], state, time (NULL));
|
||||
updated = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ptr_typing_status)
|
||||
updated = 1;
|
||||
typing_status_nick_remove (ptr_buffer, items[2]);
|
||||
}
|
||||
|
||||
if (updated)
|
||||
weechat_bar_item_update (TYPING_BAR_ITEM_NAME);
|
||||
|
||||
end:
|
||||
if (items)
|
||||
weechat_string_free_split (items);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for signal "typing_reset_buffer".
|
||||
*/
|
||||
|
||||
int
|
||||
typing_typing_reset_buffer_signal_cb (const void *pointer, void *data,
|
||||
const char *signal,
|
||||
const char *type_data, void *signal_data)
|
||||
{
|
||||
int items_count;
|
||||
struct t_gui_buffer *ptr_buffer;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) signal;
|
||||
(void) type_data;
|
||||
|
||||
ptr_buffer = (struct t_gui_buffer *)signal_data;
|
||||
|
||||
if (!typing_status_nicks)
|
||||
return WEECHAT_RC_OK;
|
||||
|
||||
items_count = weechat_hashtable_get_integer (typing_status_nicks,
|
||||
"items_count");
|
||||
weechat_hashtable_remove (typing_status_nicks, ptr_buffer);
|
||||
if (items_count > 0)
|
||||
weechat_bar_item_update (TYPING_BAR_ITEM_NAME);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
@ -290,12 +478,15 @@ typing_timer_cb (const void *pointer,
|
||||
void
|
||||
typing_setup_hooks ()
|
||||
{
|
||||
if (weechat_config_boolean (typing_config_look_enabled))
|
||||
if (weechat_config_boolean (typing_config_look_enabled_self))
|
||||
{
|
||||
if (!typing_signal_buffer_closing)
|
||||
{
|
||||
if (weechat_typing_plugin->debug >= 2)
|
||||
weechat_printf (NULL, "%s: creating hooks", TYPING_PLUGIN_NAME);
|
||||
{
|
||||
weechat_printf (NULL, "%s: creating hooks (self)",
|
||||
TYPING_PLUGIN_NAME);
|
||||
}
|
||||
typing_signal_buffer_closing = weechat_hook_signal (
|
||||
"buffer_closing",
|
||||
&typing_buffer_closing_signal_cb, NULL, NULL);
|
||||
@ -315,7 +506,10 @@ typing_setup_hooks ()
|
||||
if (typing_signal_buffer_closing)
|
||||
{
|
||||
if (weechat_typing_plugin->debug >= 2)
|
||||
weechat_printf (NULL, "%s: removing hooks", TYPING_PLUGIN_NAME);
|
||||
{
|
||||
weechat_printf (NULL, "%s: removing hooks (self)",
|
||||
TYPING_PLUGIN_NAME);
|
||||
}
|
||||
weechat_unhook (typing_signal_buffer_closing);
|
||||
typing_signal_buffer_closing = NULL;
|
||||
weechat_unhook (typing_signal_input_text_changed);
|
||||
@ -326,6 +520,39 @@ typing_setup_hooks ()
|
||||
typing_timer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (weechat_config_boolean (typing_config_look_enabled_nicks))
|
||||
{
|
||||
if (!typing_signal_typing_set_nick)
|
||||
{
|
||||
if (weechat_typing_plugin->debug >= 2)
|
||||
{
|
||||
weechat_printf (NULL, "%s: creating hooks (nicks)",
|
||||
TYPING_PLUGIN_NAME);
|
||||
}
|
||||
typing_signal_typing_set_nick = weechat_hook_signal (
|
||||
"typing_set_nick",
|
||||
&typing_typing_set_nick_signal_cb, NULL, NULL);
|
||||
typing_signal_typing_reset_buffer = weechat_hook_signal (
|
||||
"typing_reset_buffer",
|
||||
&typing_typing_reset_buffer_signal_cb, NULL, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (typing_signal_typing_set_nick)
|
||||
{
|
||||
if (weechat_typing_plugin->debug >= 2)
|
||||
{
|
||||
weechat_printf (NULL, "%s: removing hooks (nicks)",
|
||||
TYPING_PLUGIN_NAME);
|
||||
}
|
||||
weechat_unhook (typing_signal_typing_set_nick);
|
||||
typing_signal_typing_set_nick = NULL;
|
||||
weechat_unhook (typing_signal_typing_reset_buffer);
|
||||
typing_signal_typing_reset_buffer = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -348,6 +575,8 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
|
||||
typing_setup_hooks ();
|
||||
|
||||
typing_bar_item_init ();
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user