diff --git a/src/chat_session.c b/src/chat_session.c index 2031dcd4..a0649b76 100644 --- a/src/chat_session.c +++ b/src/chat_session.c @@ -28,6 +28,7 @@ #include "chat_session.h" #include "log.h" +#define PAUSED_TIMOUT 10.0 #define INACTIVE_TIMOUT 120.0 #define GONE_TIMOUT 600.0 @@ -38,6 +39,8 @@ static void _chat_session_free(ChatSession session); typedef enum { CHAT_STATE_STARTED, CHAT_STATE_ACTIVE, + CHAT_STATE_PAUSED, + CHAT_STATE_COMPOSING, CHAT_STATE_INACTIVE, CHAT_STATE_GONE } chat_state_t; @@ -85,14 +88,17 @@ chat_session_start(const char * const recipient, gboolean recipient_supports) } void -chat_session_set_active(const char * const recipient) +chat_session_set_composing(const char * const recipient) { ChatSession session = g_hash_table_lookup(sessions, recipient); if (session == NULL) { log_error("No chat session found for %s.", recipient); } else { - session->state = CHAT_STATE_ACTIVE; + if (session->state != CHAT_STATE_COMPOSING) { + session->sent = FALSE; + } + session->state = CHAT_STATE_COMPOSING; g_timer_start(session->active_timer); } } @@ -118,6 +124,11 @@ chat_session_no_activity(const char * const recipient) session->sent = FALSE; } session->state = CHAT_STATE_INACTIVE; + } else if (elapsed > PAUSED_TIMOUT) { + if (session->state != CHAT_STATE_PAUSED) { + session->sent = FALSE; + } + session->state = CHAT_STATE_PAUSED; } } } @@ -167,6 +178,32 @@ chat_session_inactive(const char * const recipient) } } +void +chat_session_set_active(const char * const recipient) +{ + ChatSession session = g_hash_table_lookup(sessions, recipient); + + if (session == NULL) { + log_error("No chat session found for %s.", recipient); + } else { + session->state = CHAT_STATE_ACTIVE; + session->sent = FALSE; + } +} + +gboolean +chat_session_paused(const char * const recipient) +{ + ChatSession session = g_hash_table_lookup(sessions, recipient); + + if (session == NULL) { + log_error("No chat session found for %s.", recipient); + return FALSE; + } else { + return (session->state == CHAT_STATE_PAUSED); + } +} + gboolean chat_session_gone(const char * const recipient) { diff --git a/src/chat_session.h b/src/chat_session.h index 01a85e2f..34c1681b 100644 --- a/src/chat_session.h +++ b/src/chat_session.h @@ -37,9 +37,11 @@ gboolean chat_session_get_recipient_supports(const char * const recipient); void chat_session_set_recipient_supports(const char * const recipient, gboolean recipient_supports); -void chat_session_set_active(const char * const recipient); +void chat_session_set_composing(const char * const recipient); void chat_session_no_activity(const char * const recipient); gboolean chat_session_inactive(const char * const recipient); +void chat_session_set_active(const char * const recipient); +gboolean chat_session_paused(const char * const recipient); gboolean chat_session_gone(const char * const recipient); void chat_session_set_sent(const char * const recipient); gboolean chat_session_get_sent(const char * const recipient); diff --git a/src/input_win.c b/src/input_win.c index 050156f0..7defee6a 100644 --- a/src/input_win.c +++ b/src/input_win.c @@ -152,6 +152,9 @@ inp_get_char(int *ch, char *input, int *size) } else if (chat_session_inactive(recipient) && !chat_session_get_sent(recipient)) { jabber_send_inactive(recipient); + } else if (chat_session_paused(recipient) && + !chat_session_get_sent(recipient)) { + jabber_send_paused(recipient); } } } @@ -160,7 +163,11 @@ inp_get_char(int *ch, char *input, int *size) if (*ch != ERR) { if (win_in_chat()) { char *recipient = win_get_recipient(); - chat_session_set_active(recipient); + chat_session_set_composing(recipient); + if (!chat_session_get_sent(recipient) || + chat_session_paused(recipient)) { + jabber_send_composing(recipient); + } } } } diff --git a/src/jabber.c b/src/jabber.c index 1a24be47..150f7c6f 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -164,6 +164,7 @@ jabber_send(const char * const msg, const char * const recipient) // always send with messages when recipient supports chat states if (chat_session_get_recipient_supports(recipient)) { + chat_session_set_active(recipient); active = xmpp_stanza_new(jabber_conn.ctx); xmpp_stanza_set_name(active, "active"); xmpp_stanza_set_ns(active, "http://jabber.org/protocol/chatstates"); @@ -202,6 +203,48 @@ jabber_send_inactive(const char * const recipient) chat_session_set_sent(recipient); } +void +jabber_send_composing(const char * const recipient) +{ + xmpp_stanza_t *message, *composing; + + message = xmpp_stanza_new(jabber_conn.ctx); + xmpp_stanza_set_name(message, "message"); + xmpp_stanza_set_type(message, "chat"); + xmpp_stanza_set_attribute(message, "to", recipient); + + composing = xmpp_stanza_new(jabber_conn.ctx); + xmpp_stanza_set_name(composing, "composing"); + xmpp_stanza_set_ns(composing, "http://jabber.org/protocol/chatstates"); + xmpp_stanza_add_child(message, composing); + + xmpp_send(jabber_conn.conn, message); + xmpp_stanza_release(message); + + chat_session_set_sent(recipient); +} + +void +jabber_send_paused(const char * const recipient) +{ + xmpp_stanza_t *message, *paused; + + message = xmpp_stanza_new(jabber_conn.ctx); + xmpp_stanza_set_name(message, "message"); + xmpp_stanza_set_type(message, "chat"); + xmpp_stanza_set_attribute(message, "to", recipient); + + paused = xmpp_stanza_new(jabber_conn.ctx); + xmpp_stanza_set_name(paused, "paused"); + xmpp_stanza_set_ns(paused, "http://jabber.org/protocol/chatstates"); + xmpp_stanza_add_child(message, paused); + + xmpp_send(jabber_conn.conn, message); + xmpp_stanza_release(message); + + chat_session_set_sent(recipient); +} + void jabber_send_gone(const char * const recipient) { diff --git a/src/jabber.h b/src/jabber.h index 773b3c68..3ae84610 100644 --- a/src/jabber.h +++ b/src/jabber.h @@ -48,6 +48,8 @@ void jabber_process_events(void); void jabber_subscribe(const char * const recipient); void jabber_send(const char * const msg, const char * const recipient); void jabber_send_inactive(const char * const recipient); +void jabber_send_composing(const char * const recipient); +void jabber_send_paused(const char * const recipient); void jabber_send_gone(const char * const recipient); void jabber_update_presence(jabber_presence_t status, const char * const msg); const char * jabber_get_jid(void);