1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-12-04 14:46:46 -05:00

Basic state handling

This commit is contained in:
James Booth 2012-10-31 01:36:52 +00:00
parent 7f1e3084b3
commit 5ce977284b
5 changed files with 194 additions and 4 deletions

View File

@ -28,13 +28,26 @@
#include "chat_session.h" #include "chat_session.h"
#include "log.h" #include "log.h"
#define INACTIVE_TIMOUT 10.0
#define GONE_TIMOUT 20.0
static ChatSession _chat_session_new(const char * const recipient, static ChatSession _chat_session_new(const char * const recipient,
gboolean recipient_supports); gboolean recipient_supports);
static void _chat_session_free(ChatSession session); 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 { struct chat_session_t {
char *recipient; char *recipient;
gboolean recipient_supports; gboolean recipient_supports;
chat_state_t state;
GTimer *active_timer;
gboolean sent;
}; };
static GHashTable *sessions; static GHashTable *sessions;
@ -67,9 +80,72 @@ chat_session_exists(const char * const recipient)
void void
chat_session_start(const char * const recipient, gboolean recipient_supports) chat_session_start(const char * const recipient, gboolean recipient_supports)
{ {
char *key = strdup(recipient); ChatSession session = _chat_session_new(recipient, recipient_supports);
ChatSession session = _chat_session_new(key, recipient_supports); g_hash_table_insert(sessions, strdup(recipient), session);
g_hash_table_insert(sessions, key, 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 void
@ -78,6 +154,32 @@ chat_session_end(const char * const recipient)
g_hash_table_remove(sessions, recipient); g_hash_table_remove(sessions, 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 gboolean
chat_session_recipient_supports(const char * const recipient) chat_session_recipient_supports(const char * const recipient)
{ {
@ -97,6 +199,9 @@ _chat_session_new(const char * const recipient, gboolean recipient_supports)
ChatSession new_session = malloc(sizeof(struct chat_session_t)); ChatSession new_session = malloc(sizeof(struct chat_session_t));
new_session->recipient = strdup(recipient); new_session->recipient = strdup(recipient);
new_session->recipient_supports = recipient_supports; 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; return new_session;
} }
@ -105,7 +210,14 @@ static void
_chat_session_free(ChatSession session) _chat_session_free(ChatSession session)
{ {
if (session != NULL) { 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); g_free(session);
} }
session = NULL; session = NULL;

View File

@ -35,4 +35,11 @@ gboolean chat_session_exists(const char * const recipient);
void chat_session_end(const char * const recipient); void chat_session_end(const char * const recipient);
gboolean chat_session_recipient_supports(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 #endif

View File

@ -51,10 +51,12 @@
#include <ncurses/ncurses.h> #include <ncurses/ncurses.h>
#endif #endif
#include "chat_session.h"
#include "common.h" #include "common.h"
#include "command.h" #include "command.h"
#include "contact_list.h" #include "contact_list.h"
#include "history.h" #include "history.h"
#include "log.h"
#include "preferences.h" #include "preferences.h"
#include "ui.h" #include "ui.h"
@ -135,6 +137,31 @@ inp_get_char(int *ch, char *input, int *size)
noecho(); noecho();
*ch = wgetch(inp_win); *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 it wasn't an arrow key etc
if (!_handle_edit(*ch, input, size)) { if (!_handle_edit(*ch, input, size)) {
if (_printable(*ch)) { if (_printable(*ch)) {

View File

@ -175,6 +175,48 @@ jabber_send(const char * const msg, const char * const recipient)
free(coded_msg3); free(coded_msg3);
} }
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 void
jabber_subscribe(const char * const recipient) jabber_subscribe(const char * const recipient)
{ {

View File

@ -47,6 +47,8 @@ void jabber_disconnect(void);
void jabber_process_events(void); void jabber_process_events(void);
void jabber_subscribe(const char * const recipient); void jabber_subscribe(const char * const recipient);
void jabber_send(const char * const msg, 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); void jabber_update_presence(jabber_presence_t status, const char * const msg);
const char * jabber_get_jid(void); const char * jabber_get_jid(void);
jabber_conn_status_t jabber_get_connection_status(void); jabber_conn_status_t jabber_get_connection_status(void);