summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2021-07-02 21:54:27 +0200
committerSébastien Helleu <flashcode@flashtux.org>2021-07-04 13:27:33 +0200
commit954f943e8e058ae1db708857ef53806abedbaea9 (patch)
treeff725c8099a6d93b40dea71312fb4629c315b758 /src
parentbba300e1914302ee72818ad49ecc45fb76afc9f1 (diff)
downloadweechat-954f943e8e058ae1db708857ef53806abedbaea9.zip
irc, typing: display typing status for IRC nicks
Diffstat (limited to 'src')
-rw-r--r--src/plugins/irc/CMakeLists.txt1
-rw-r--r--src/plugins/irc/Makefile.am2
-rw-r--r--src/plugins/irc/irc-channel.c10
-rw-r--r--src/plugins/irc/irc-channel.h18
-rw-r--r--src/plugins/irc/irc-config.c21
-rw-r--r--src/plugins/irc/irc-config.h3
-rw-r--r--src/plugins/irc/irc-protocol.c119
-rw-r--r--src/plugins/irc/irc-protocol.h8
-rw-r--r--src/plugins/irc/irc-server.c30
-rw-r--r--src/plugins/irc/irc-typing.c159
-rw-r--r--src/plugins/irc/irc-typing.h35
-rw-r--r--src/plugins/irc/irc.c52
-rw-r--r--src/plugins/typing/CMakeLists.txt1
-rw-r--r--src/plugins/typing/Makefile.am2
-rw-r--r--src/plugins/typing/typing-bar-item.c120
-rw-r--r--src/plugins/typing/typing-bar-item.h27
-rw-r--r--src/plugins/typing/typing-config.c50
-rw-r--r--src/plugins/typing/typing-config.h7
-rw-r--r--src/plugins/typing/typing-status.c280
-rw-r--r--src/plugins/typing/typing-status.h39
-rw-r--r--src/plugins/typing/typing.c315
21 files changed, 1082 insertions, 217 deletions
diff --git a/src/plugins/irc/CMakeLists.txt b/src/plugins/irc/CMakeLists.txt
index c638605e7..e037ef138 100644
--- a/src/plugins/irc/CMakeLists.txt
+++ b/src/plugins/irc/CMakeLists.txt
@@ -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 "")
diff --git a/src/plugins/irc/Makefile.am b/src/plugins/irc/Makefile.am
index fa5833350..324bdd802 100644
--- a/src/plugins/irc/Makefile.am
+++ b/src/plugins/irc/Makefile.am
@@ -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
diff --git a/src/plugins/irc/irc-channel.c b/src/plugins/irc/irc-channel.c
index 5dfa4163c..36e79c5a5 100644
--- a/src/plugins/irc/irc-channel.c
+++ b/src/plugins/irc/irc-channel.c
@@ -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);
diff --git a/src/plugins/irc/irc-channel.h b/src/plugins/irc/irc-channel.h
index 0094be4a8..231207c51 100644
--- a/src/plugins/irc/irc-channel.h
+++ b/src/plugins/irc/irc-channel.h
@@ -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,
diff --git a/src/plugins/irc/irc-config.c b/src/plugins/irc/irc-config.c
index f68df8d36..78f58ad96 100644
--- a/src/plugins/irc/irc-config.c
+++ b/src/plugins/irc/irc-config.c
@@ -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 (
diff --git a/src/plugins/irc/irc-config.h b/src/plugins/irc/irc-config.h
index c21093b67..0b930b36b 100644
--- a/src/plugins/irc/irc-config.h
+++ b/src/plugins/irc/irc-config.h
@@ -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;
diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c
index 98115d261..99ba1435d 100644
--- a/src/plugins/irc/irc-protocol.c
+++ b/src/plugins/irc/irc-protocol.c
@@ -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);
}
diff --git a/src/plugins/irc/irc-protocol.h b/src/plugins/irc/irc-protocol.h
index 29d27a08d..c34b4bdae 100644
--- a/src/plugins/irc/irc-protocol.h
+++ b/src/plugins/irc/irc-protocol.h
@@ -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);
diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c
index 6dcf5bb18..d06d5bafd 100644
--- a/src/plugins/irc/irc-server.c
+++ b/src/plugins/irc/irc-server.c
@@ -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))
diff --git a/src/plugins/irc/irc-typing.c b/src/plugins/irc/irc-typing.c
new file mode 100644
index 000000000..49ecc1502
--- /dev/null
+++ b/src/plugins/irc/irc-typing.c
@@ -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);
+}
diff --git a/src/plugins/irc/irc-typing.h b/src/plugins/irc/irc-typing.h
new file mode 100644
index 000000000..ad3139aa7
--- /dev/null
+++ b/src/plugins/irc/irc-typing.h
@@ -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 */
diff --git a/src/plugins/irc/irc.c b/src/plugins/irc/irc.c
index e0029f1fd..7c600d339 100644
--- a/src/plugins/irc/irc.c
+++ b/src/plugins/irc/irc.c
@@ -43,6 +43,7 @@
#include "irc-redirect.h"
#include "irc-server.h"
#include "irc-tag.h"
+#include "irc-typing.h"
#include "irc-upgrade.h"
@@ -160,53 +161,6 @@ irc_signal_upgrade_cb (const void *pointer, void *data,
}
/*
- * 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",
diff --git a/src/plugins/typing/CMakeLists.txt b/src/plugins/typing/CMakeLists.txt
index c755217a1..f08223e3f 100644
--- a/src/plugins/typing/CMakeLists.txt
+++ b/src/plugins/typing/CMakeLists.txt
@@ -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
)
diff --git a/src/plugins/typing/Makefile.am b/src/plugins/typing/Makefile.am
index ad9d38276..ba6345f09 100644
--- a/src/plugins/typing/Makefile.am
+++ b/src/plugins/typing/Makefile.am
@@ -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 \
diff --git a/src/plugins/typing/typing-bar-item.c b/src/plugins/typing/typing-bar-item.c
new file mode 100644
index 000000000..2ecae5870
--- /dev/null
+++ b/src/plugins/typing/typing-bar-item.c
@@ -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);
+}
diff --git a/src/plugins/typing/typing-bar-item.h b/src/plugins/typing/typing-bar-item.h
new file mode 100644
index 000000000..864697668
--- /dev/null
+++ b/src/plugins/typing/typing-bar-item.h
@@ -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 */
diff --git a/src/plugins/typing/typing-config.c b/src/plugins/typing/typing-config.c
index 42d0d1051..dacfd6b70 100644
--- a/src/plugins/typing/typing-config.c
+++ b/src/plugins/typing/typing-config.c
@@ -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;
}
diff --git a/src/plugins/typing/typing-config.h b/src/plugins/typing/typing-config.h
index e367f724c..c0da80558 100644
--- a/src/plugins/typing/typing-config.h
+++ b/src/plugins/typing/typing-config.h
@@ -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 ();
diff --git a/src/plugins/typing/typing-status.c b/src/plugins/typing/typing-status.c
index b3b31f679..298b9d496 100644
--- a/src/plugins/typing/typing-status.c
+++ b/src/plugins/typing/typing-status.c
@@ -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);
+}
+
+/*
+ * Removes a nick typing status: key is a nick (string), value is a
+ * t_typing_status pointer.
+ */
+
+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;
- weechat_hashtable_set (typing_status_self, buffer, new_typing_status);
+ if (!ptr_nick || !ptr_typing_status)
+ return;
- return new_typing_status;
+ 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;
+ }
}
diff --git a/src/plugins/typing/typing-status.h b/src/plugins/typing/typing-status.h
index 868db775e..8b5cc2417 100644
--- a/src/plugins/typing/typing-status.h
+++ b/src/plugins/typing/typing-status.h
@@ -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_typing_status *typing_status_add (struct t_gui_buffer *buffer);
+extern struct t_hashtable *typing_status_nicks;
+
+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 */
diff --git a/src/plugins/typing/typing.c b/src/plugins/typing/typing.c
index a061591e2..033ac5838 100644
--- a/src/plugins/typing/typing.c
+++ b/src/plugins/typing/typing.c
@@ -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, &current_time);
+ weechat_hashtable_map (typing_status_nicks,
+ &typing_status_nicks_hash_map_cb, &current_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;
}