From 8b1653f7076c61f317446b7c80093ab0a0381e35 Mon Sep 17 00:00:00 2001 From: James Booth Date: Thu, 16 Aug 2012 00:50:32 +0100 Subject: [PATCH] Added typing notifications and related preferences --- src/command.c | 32 +++++++++++++++ src/jabber.c | 18 +++++---- src/preferences.c | 13 +++++++ src/preferences.h | 2 + src/ui.h | 1 + src/windows.c | 99 ++++++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 152 insertions(+), 13 deletions(-) diff --git a/src/command.c b/src/command.c index f8bd2a32..8397bbd9 100644 --- a/src/command.c +++ b/src/command.c @@ -66,6 +66,7 @@ static gboolean _cmd_tiny(const char * const inp, struct cmd_help_t help); static gboolean _cmd_close(const char * const inp, struct cmd_help_t help); static gboolean _cmd_set_beep(const char * const inp, struct cmd_help_t help); static gboolean _cmd_set_notify(const char * const inp, struct cmd_help_t help); +static gboolean _cmd_set_typing(const char * const inp, struct cmd_help_t help); static gboolean _cmd_set_flash(const char * const inp, struct cmd_help_t help); static gboolean _cmd_set_showsplash(const char * const inp, struct cmd_help_t help); static gboolean _cmd_set_chlog(const char * const inp, struct cmd_help_t help); @@ -207,6 +208,19 @@ static struct cmd_t setting_commands[] = "Config file value : notify=true|false", NULL } } }, + { "/typing", + _cmd_set_typing, + { "/typing on|off", "Enable/disable typing notifications.", + { "/typing on|off", + "--------------", + "Switch the typing notifications on or off for incoming messages", + "If desktop notifications are also enabled you will receive them", + "for typing notifications also.", + "", + "Config file section : [ui]", + "Config file value : typing=true|false", + NULL } } }, + { "/flash", _cmd_set_flash, { "/flash on|off", "Enable/disable screen flash notifications.", @@ -696,6 +710,24 @@ _cmd_set_notify(const char * const inp, struct cmd_help_t help) return TRUE; } +static gboolean +_cmd_set_typing(const char * const inp, struct cmd_help_t help) +{ + if (strcmp(inp, "/typing on") == 0) { + cons_show("Incoming typing notifications enabled."); + prefs_set_typing(TRUE); + } else if (strcmp(inp, "/typing off") == 0) { + cons_show("Incoming typing notifications disabled."); + prefs_set_typing(FALSE); + } else { + char usage[strlen(help.usage + 8)]; + sprintf(usage, "Usage: %s", help.usage); + cons_show(usage); + } + + return TRUE; +} + static gboolean _cmd_set_flash(const char * const inp, struct cmd_help_t help) { diff --git a/src/jabber.c b/src/jabber.c index 1d8a3dde..1090302c 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -259,18 +259,22 @@ _jabber_message_handler(xmpp_conn_t * const conn, // if no message, check for chatstates if (body == NULL) { - if (xmpp_stanza_get_child_by_name(stanza, "active") != NULL) { - // active - } else if (xmpp_stanza_get_child_by_name(stanza, "composing") != NULL) { - // composing - char *from = xmpp_stanza_get_attribute(stanza, "from"); - cons_show(from); - cons_show("is composing a message"); + + if (prefs_get_typing()) { + if (xmpp_stanza_get_child_by_name(stanza, "active") != NULL) { + // active + } else if (xmpp_stanza_get_child_by_name(stanza, "composing") != NULL) { + // composing + char *from = xmpp_stanza_get_attribute(stanza, "from"); + win_show_typing(from); + win_page_off(); + } } return 1; } + // message body recieved char *type = xmpp_stanza_get_attribute(stanza, "type"); if(strcmp(type, "error") == 0) return 1; diff --git a/src/preferences.c b/src/preferences.c index b77d9a09..84b057bd 100644 --- a/src/preferences.c +++ b/src/preferences.c @@ -206,6 +206,19 @@ prefs_set_notify(gboolean value) _save_prefs(); } +gboolean +prefs_get_typing(void) +{ + return g_key_file_get_boolean(prefs, "ui", "typing", NULL); +} + +void +prefs_set_typing(gboolean value) +{ + g_key_file_set_boolean(prefs, "ui", "typing", value); + _save_prefs(); +} + gboolean prefs_get_flash(void) { diff --git a/src/preferences.h b/src/preferences.h index 160d9d9d..83704529 100644 --- a/src/preferences.h +++ b/src/preferences.h @@ -35,6 +35,8 @@ gboolean prefs_get_beep(void); void prefs_set_beep(gboolean value); gboolean prefs_get_notify(void); void prefs_set_notify(gboolean value); +gboolean prefs_get_typing(void); +void prefs_set_typing(gboolean value); gboolean prefs_get_flash(void); void prefs_set_flash(gboolean value); gboolean prefs_get_chlog(void); diff --git a/src/ui.h b/src/ui.h index f0811aca..b2bca2b1 100644 --- a/src/ui.h +++ b/src/ui.h @@ -60,6 +60,7 @@ void title_bar_set_status(jabber_presence_t status); int win_close_win(void); int win_in_chat(void); char *win_get_recipient(void); +void win_show_typing(const char * const from); void win_show_incomming_msg(const char * const from, const char * const message); void win_show_outgoing_msg(const char * const from, const char * const to, const char * const message); diff --git a/src/windows.c b/src/windows.c index 27693b7c..90f97e73 100644 --- a/src/windows.c +++ b/src/windows.c @@ -64,10 +64,12 @@ static void _current_window_refresh(void); static void _win_switch_if_active(const int i); static void _win_show_time(WINDOW *win); static void _win_show_user(WINDOW *win, const char * const user, const int colour); +static void _win_show_typing(WINDOW *win, const char * const short_from); static void _win_show_message(WINDOW *win, const char * const message); static void _show_status_string(WINDOW *win, const char * const from, const char * const show, const char * const status, const char * const pre, const char * const default_show); +static void _cons_show_typing(const char * const short_from); static void _cons_show_incoming_message(const char * const short_from, const int win_index); static void _win_handle_switch(const int * const ch); @@ -75,7 +77,8 @@ static void _win_handle_page(const int * const ch); static void _win_resize_all(void); #ifdef HAVE_LIBNOTIFY -static void _win_notify(char * short_from); +static void _win_notify_message(char * short_from); +static void _win_notify_typing(char * short_from); #endif void @@ -180,6 +183,44 @@ win_get_recipient(void) return recipient; } +void +win_show_typing(const char * const from) +{ + char from_cpy[strlen(from) + 1]; + strcpy(from_cpy, from); + char *short_from = strtok(from_cpy, "/"); + + int win_index = _find_prof_win_index(short_from); + + // no chat window for user + if (win_index == NUM_WINS) { + _cons_show_typing(short_from); + + // have chat window but not currently in it + } else if (win_index != _curr_prof_win) { + WINDOW *win = _wins[win_index].win; + _win_show_time(win); + _win_show_typing(win, short_from); + _cons_show_typing(short_from); + status_bar_new(win_index); + dirty = TRUE; + + // in chat window with user + } else { + WINDOW *win = _wins[win_index].win; + _win_show_time(win); + _win_show_typing(win, short_from); + + status_bar_active(win_index); + dirty = TRUE; + } + +#ifdef HAVE_LIBNOTIFY + if (prefs_get_notify()) + _win_notify_typing(short_from); +#endif +} + void win_show_incomming_msg(const char * const from, const char * const message) { @@ -211,19 +252,48 @@ win_show_incomming_msg(const char * const from, const char * const message) beep(); #ifdef HAVE_LIBNOTIFY if (prefs_get_notify()) - _win_notify(short_from); + _win_notify_message(short_from); #endif } #ifdef HAVE_LIBNOTIFY static void -_win_notify(char * short_from) +_win_notify_message(char * short_from) { notify_init("Profanity"); + + char message[strlen(short_from) + 1 + 10]; + sprintf(message, "%s: message.", short_from); // create a new notification NotifyNotification *incoming; - incoming = notify_notification_new("Profanity", short_from, NULL); + incoming = notify_notification_new("Profanity", message, NULL); + + // set the timeout of the notification to 10 secs + notify_notification_set_timeout(incoming, 10000); + + // set the category so as to tell what kind it is + char category[30] = "Incoming message"; + notify_notification_set_category(incoming, category); + + // set the urgency level of the notification + notify_notification_set_urgency(incoming, NOTIFY_URGENCY_NORMAL); + + GError *error = NULL; + notify_notification_show(incoming, &error); +} + +static void +_win_notify_typing(char * short_from) +{ + notify_init("Profanity"); + + char message[strlen(short_from) + 1 + 11]; + sprintf(message, "%s: typing...", short_from); + + // create a new notification + NotifyNotification *incoming; + incoming = notify_notification_new("Profanity", message, NULL); // set the timeout of the notification to 10 secs notify_notification_set_timeout(incoming, 10000); @@ -359,6 +429,11 @@ cons_prefs(void) else cons_show("Desktop notifications : OFF"); + if (prefs_get_typing()) + cons_show("Typing notifications : ON"); + else + cons_show("Typing notifications : OFF"); + if (prefs_get_showsplash()) cons_show("Splash screen : ON"); else @@ -669,12 +744,16 @@ _win_show_user(WINDOW *win, const char * const user, const int colour) wattroff(win, COLOR_PAIR(2)); } +static void +_win_show_typing(WINDOW *win, const char * const short_from) +{ + wprintw(win, "%s is typing...\n", short_from); +} + static void _win_show_message(WINDOW *win, const char * const message) { -// wattroff(win, A_BOLD); wprintw(win, "%s\n", message); -// wattron(win, A_BOLD); } static void @@ -740,6 +819,14 @@ _show_status_string(WINDOW *win, const char * const from, } } +static void +_cons_show_typing(const char * const short_from) +{ + _win_show_time(_cons_win); + wattron(_cons_win, COLOR_PAIR(7)); + wprintw(_cons_win, "!! %s is typing a message...\n", short_from); + wattroff(_cons_win, COLOR_PAIR(7)); +} static void _cons_show_incoming_message(const char * const short_from, const int win_index)