diff options
author | James Booth <boothj5@gmail.com> | 2012-10-31 01:36:52 +0000 |
---|---|---|
committer | James Booth <boothj5@gmail.com> | 2012-10-31 01:36:52 +0000 |
commit | 5ce977284b1d8b4243902640c3be09db214c875e (patch) | |
tree | a80855321b0a99123e3ed54ab37d46de756f698e /src | |
parent | 7f1e3084b37c20094ee80e6fd63d93c0aa9d1dc9 (diff) | |
download | profani-tty-5ce977284b1d8b4243902640c3be09db214c875e.tar.gz |
Basic state handling
Diffstat (limited to 'src')
-rw-r--r-- | src/chat_session.c | 120 | ||||
-rw-r--r-- | src/chat_session.h | 7 | ||||
-rw-r--r-- | src/input_win.c | 27 | ||||
-rw-r--r-- | src/jabber.c | 42 | ||||
-rw-r--r-- | src/jabber.h | 2 |
5 files changed, 194 insertions, 4 deletions
diff --git a/src/chat_session.c b/src/chat_session.c index 283860de..a272f3f6 100644 --- a/src/chat_session.c +++ b/src/chat_session.c @@ -28,13 +28,26 @@ #include "chat_session.h" #include "log.h" +#define INACTIVE_TIMOUT 10.0 +#define GONE_TIMOUT 20.0 + static ChatSession _chat_session_new(const char * const recipient, gboolean recipient_supports); static void _chat_session_free(ChatSession session); +typedef enum { + CHAT_STATE_STARTED, + CHAT_STATE_ACTIVE, + CHAT_STATE_INACTIVE, + CHAT_STATE_GONE +} chat_state_t; + struct chat_session_t { char *recipient; gboolean recipient_supports; + chat_state_t state; + GTimer *active_timer; + gboolean sent; }; static GHashTable *sessions; @@ -67,9 +80,72 @@ chat_session_exists(const char * const recipient) void chat_session_start(const char * const recipient, gboolean recipient_supports) { - char *key = strdup(recipient); - ChatSession session = _chat_session_new(key, recipient_supports); - g_hash_table_insert(sessions, key, session); + ChatSession session = _chat_session_new(recipient, recipient_supports); + g_hash_table_insert(sessions, strdup(recipient), session); +} + +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; + g_timer_start(session->active_timer); + } +} + +void +chat_session_no_activity(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 { + if (session->active_timer != NULL) { + gdouble elapsed = g_timer_elapsed(session->active_timer, NULL); + + if (elapsed > GONE_TIMOUT) { + if (session->state != CHAT_STATE_GONE) { + session->sent = FALSE; + } + session->state = CHAT_STATE_GONE; + } else if (elapsed > INACTIVE_TIMOUT) { + if (session->state != CHAT_STATE_INACTIVE) { + session->sent = FALSE; + } + session->state = CHAT_STATE_INACTIVE; + } + } + } +} + +void +chat_session_set_sent(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->sent = TRUE; + } +} + +gboolean +chat_session_get_sent(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->sent; + } } void @@ -79,6 +155,32 @@ chat_session_end(const char * const recipient) } gboolean +chat_session_inactive(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_INACTIVE); + } +} + +gboolean +chat_session_gone(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_GONE); + } +} + +gboolean chat_session_recipient_supports(const char * const recipient) { ChatSession session = g_hash_table_lookup(sessions, recipient); @@ -97,6 +199,9 @@ _chat_session_new(const char * const recipient, gboolean recipient_supports) ChatSession new_session = malloc(sizeof(struct chat_session_t)); new_session->recipient = strdup(recipient); new_session->recipient_supports = recipient_supports; + new_session->state = CHAT_STATE_STARTED; + new_session->active_timer = g_timer_new(); + new_session->sent = FALSE; return new_session; } @@ -105,7 +210,14 @@ static void _chat_session_free(ChatSession session) { if (session != NULL) { - g_free(session->recipient); + if (session->recipient != NULL) { + g_free(session->recipient); + session->recipient = NULL; + } + if (session->active_timer != NULL) { + g_timer_destroy(session->active_timer); + session->active_timer = NULL; + } g_free(session); } session = NULL; diff --git a/src/chat_session.h b/src/chat_session.h index 7cfc8de5..fc58cb49 100644 --- a/src/chat_session.h +++ b/src/chat_session.h @@ -35,4 +35,11 @@ gboolean chat_session_exists(const char * const recipient); void chat_session_end(const char * const recipient); gboolean chat_session_recipient_supports(const char * const recipient); +void chat_session_set_active(const char * const recipient); +void chat_session_no_activity(const char * const recipient); +gboolean chat_session_inactive(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); + #endif diff --git a/src/input_win.c b/src/input_win.c index 1c12e8a1..21f2ca86 100644 --- a/src/input_win.c +++ b/src/input_win.c @@ -51,10 +51,12 @@ #include <ncurses/ncurses.h> #endif +#include "chat_session.h" #include "common.h" #include "command.h" #include "contact_list.h" #include "history.h" +#include "log.h" #include "preferences.h" #include "ui.h" @@ -135,6 +137,31 @@ inp_get_char(int *ch, char *input, int *size) noecho(); *ch = wgetch(inp_win); + // if not got char, and in chat window, flag as no activity + // send inactive or gone, depending how long inactive + if (*ch == ERR) { + if (win_in_chat()) { + char *recipient = win_get_recipient(); + chat_session_no_activity(recipient); + + if (chat_session_gone(recipient) && + !chat_session_get_sent(recipient)) { + jabber_send_gone(recipient); + } else if (chat_session_inactive(recipient) && + !chat_session_get_sent(recipient)) { + jabber_send_inactive(recipient); + } + } + } + + // if got char and in chat window, chat session active + if (*ch != ERR) { + if (win_in_chat()) { + char *recipient = win_get_recipient(); + chat_session_set_active(recipient); + } + } + // if it wasn't an arrow key etc if (!_handle_edit(*ch, input, size)) { if (_printable(*ch)) { diff --git a/src/jabber.c b/src/jabber.c index 23f7f444..584b8f4c 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -176,6 +176,48 @@ jabber_send(const char * const msg, const char * const recipient) } void +jabber_send_inactive(const char * const recipient) +{ + xmpp_stanza_t *message, *inactive; + + 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); + + inactive = xmpp_stanza_new(jabber_conn.ctx); + xmpp_stanza_set_name(inactive, "inactive"); + xmpp_stanza_set_ns(inactive, "http://jabber.org/protocol/chatstates"); + xmpp_stanza_add_child(message, inactive); + + xmpp_send(jabber_conn.conn, message); + xmpp_stanza_release(message); + + chat_session_set_sent(recipient); +} + +void +jabber_send_gone(const char * const recipient) +{ + xmpp_stanza_t *message, *gone; + + 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); + + gone = xmpp_stanza_new(jabber_conn.ctx); + xmpp_stanza_set_name(gone, "gone"); + xmpp_stanza_set_ns(gone, "http://jabber.org/protocol/chatstates"); + xmpp_stanza_add_child(message, gone); + + xmpp_send(jabber_conn.conn, message); + xmpp_stanza_release(message); + + chat_session_set_sent(recipient); +} + +void jabber_subscribe(const char * const recipient) { xmpp_stanza_t *presence; diff --git a/src/jabber.h b/src/jabber.h index 726fb1a5..773b3c68 100644 --- a/src/jabber.h +++ b/src/jabber.h @@ -47,6 +47,8 @@ void jabber_disconnect(void); 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_gone(const char * const recipient); void jabber_update_presence(jabber_presence_t status, const char * const msg); const char * jabber_get_jid(void); jabber_conn_status_t jabber_get_connection_status(void); |