diff --git a/src/chat_log.c b/src/chat_log.c index 5ea40911..43ba820a 100644 --- a/src/chat_log.c +++ b/src/chat_log.c @@ -58,7 +58,7 @@ chat_log_init(void) void chat_log_chat(const gchar * const login, gchar *other, - const gchar * const msg, chat_log_direction_t direction) + const gchar * const msg, chat_log_direction_t direction, GTimeVal *tv_stamp) { gchar *other_copy = strdup(other); struct dated_chat_log *dated_log = g_hash_table_lookup(logs, other_copy); @@ -74,8 +74,15 @@ chat_log_chat(const gchar * const login, gchar *other, g_hash_table_replace(logs, other_copy, dated_log); } - GDateTime *dt = g_date_time_new_now_local(); - gchar *date_fmt = g_date_time_format(dt, "%H:%M:%S"); + gchar *date_fmt = NULL; + GDateTime *dt = NULL; + if (tv_stamp == NULL) { + dt = g_date_time_new_now_local(); + } else { + dt = g_date_time_new_from_timeval_utc(tv_stamp); + } + + date_fmt = g_date_time_format(dt, "%H:%M:%S"); FILE *logp = fopen(dated_log->filename, "a"); @@ -97,6 +104,7 @@ chat_log_chat(const gchar * const login, gchar *other, if (result == EOF) { log_error("Error closing file %s, errno = %d", dated_log->filename, errno); } + g_free(date_fmt); g_date_time_unref(dt); } diff --git a/src/chat_log.h b/src/chat_log.h index 238e087f..e0aac551 100644 --- a/src/chat_log.h +++ b/src/chat_log.h @@ -32,7 +32,7 @@ typedef enum { void chat_log_init(void); void chat_log_chat(const gchar * const login, gchar *other, - const gchar * const msg, chat_log_direction_t direction); + const gchar * const msg, chat_log_direction_t direction, GTimeVal *tv_stamp); void chat_log_close(void); GSList * chat_log_get_previous(const gchar * const login, const gchar * const recipient, GSList *history); diff --git a/src/command.c b/src/command.c index 53ec184e..938a6a08 100644 --- a/src/command.c +++ b/src/command.c @@ -624,7 +624,7 @@ cmd_execute_default(const char * const inp) if (prefs_get_chlog()) { const char *jid = jabber_get_jid(); - chat_log_chat(jid, recipient, inp, OUT); + chat_log_chat(jid, recipient, inp, OUT, NULL); } win_show_outgoing_msg("me", recipient, inp); @@ -980,7 +980,7 @@ _cmd_msg(const char * const inp, struct cmd_help_t help) if (prefs_get_chlog()) { const char *jid = jabber_get_jid(); - chat_log_chat(jid, usr, msg, OUT); + chat_log_chat(jid, usr, msg, OUT, NULL); } } else { @@ -1061,7 +1061,7 @@ _cmd_tiny(const char * const inp, struct cmd_help_t help) if (prefs_get_chlog()) { const char *jid = jabber_get_jid(); - chat_log_chat(jid, recipient, tiny, OUT); + chat_log_chat(jid, recipient, tiny, OUT, NULL); } win_show_outgoing_msg("me", recipient, tiny); diff --git a/src/jabber.c b/src/jabber.c index 6c513f91..4c8250eb 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -489,14 +489,11 @@ _chat_message_handler(xmpp_stanza_t * const stanza) chat_session_set_recipient_supports(short_from, recipient_supports); } - gboolean historic_notification = FALSE; // determine if the notifications happened whilst offline - if (xmpp_stanza_get_child_by_name(stanza, "delay") != NULL) { - historic_notification = TRUE; - } + xmpp_stanza_t *delay = xmpp_stanza_get_child_by_name(stanza, "delay"); // deal with chat states if recipient supports them - if (recipient_supports && !historic_notification) { + if (recipient_supports && (delay == NULL)) { if (xmpp_stanza_get_child_by_name(stanza, "composing") != NULL) { if (prefs_get_notify_typing() || prefs_get_intype()) { prof_handle_typing(short_from); @@ -516,7 +513,20 @@ _chat_message_handler(xmpp_stanza_t * const stanza) xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, "body"); if (body != NULL) { char *message = xmpp_stanza_get_text(body); - prof_handle_incoming_message(short_from, message); + if (delay != NULL) { + char *utc_stamp = xmpp_stanza_get_attribute(delay, "stamp"); + GTimeVal tv_stamp; + + if (g_time_val_from_iso8601(utc_stamp, &tv_stamp)) { + if (message != NULL) { + prof_handle_delayed_message(short_from, message, tv_stamp); + } + } else { + log_error("Couldn't parse datetime string of historic message: %s", utc_stamp); + } + } else { + prof_handle_incoming_message(short_from, message); + } } return 1; diff --git a/src/profanity.c b/src/profanity.c index edb15bed..cdccb3f9 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -103,7 +103,7 @@ prof_handle_typing(char *from) void prof_handle_incoming_message(char *from, char *message) { - win_show_incomming_msg(from, message); + win_show_incomming_msg(from, message, NULL); win_page_off(); if (prefs_get_chlog()) { @@ -112,7 +112,23 @@ prof_handle_incoming_message(char *from, char *message) char *short_from = strtok(from_cpy, "/"); const char *jid = jabber_get_jid(); - chat_log_chat(jid, short_from, message, IN); + chat_log_chat(jid, short_from, message, IN, NULL); + } +} + +void +prof_handle_delayed_message(char *from, char *message, GTimeVal tv_stamp) +{ + win_show_incomming_msg(from, message, &tv_stamp); + win_page_off(); + + if (prefs_get_chlog()) { + char from_cpy[strlen(from) + 1]; + strcpy(from_cpy, from); + char *short_from = strtok(from_cpy, "/"); + const char *jid = jabber_get_jid(); + + chat_log_chat(jid, short_from, message, IN, &tv_stamp); } } diff --git a/src/profanity.h b/src/profanity.h index b7430ed9..c2018144 100644 --- a/src/profanity.h +++ b/src/profanity.h @@ -32,6 +32,7 @@ void prof_handle_typing(char *from); void prof_handle_contact_online(char *contact, char *show, char *status); void prof_handle_contact_offline(char *contact, char *show, char *status); void prof_handle_incoming_message(char *from, char *message); +void prof_handle_delayed_message(char *from, char *message, GTimeVal tv_stamp); void prof_handle_error_message(const char *from, const char *err_msg); void prof_handle_roster(GSList *roster); void prof_handle_gone(const char * const from); diff --git a/src/ui.h b/src/ui.h index acdde2be..333dd3ee 100644 --- a/src/ui.h +++ b/src/ui.h @@ -88,7 +88,8 @@ int win_in_chat(void); char *win_get_recipient(void); void win_show_typing(const char * const from); void win_show_gone(const char * const from); -void win_show_incomming_msg(const char * const from, const char * const message); +void win_show_incomming_msg(const char * const from, const char * const message, + GTimeVal *tv_stamp); void win_show_error_msg(const char * const from, const char *err_msg); 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 d51d7b5d..3007e3ab 100644 --- a/src/windows.c +++ b/src/windows.c @@ -263,7 +263,8 @@ win_remind(void) } void -win_show_incomming_msg(const char * const from, const char * const message) +win_show_incomming_msg(const char * const from, const char * const message, + GTimeVal *tv_stamp) { char from_cpy[strlen(from) + 1]; strcpy(from_cpy, from); @@ -277,7 +278,15 @@ win_show_incomming_msg(const char * const from, const char * const message) // currently viewing chat window with sender if (win_index == _curr_prof_win) { - _win_show_time(win); + if (tv_stamp == NULL) { + _win_show_time(win); + } else { + GDateTime *time = g_date_time_new_from_timeval_utc(tv_stamp); + gchar *date_fmt = g_date_time_format(time, "%H:%M:%S"); + wprintw(win, "%s - ", date_fmt); + g_date_time_unref(time); + g_free(date_fmt); + } if (strncmp(message, "/me ", 4) == 0) { wattron(win, COLOUR_ONLINE); @@ -306,7 +315,16 @@ win_show_incomming_msg(const char * const from, const char * const message) _win_show_history(win, win_index, short_from); } - _win_show_time(win); + if (tv_stamp == NULL) { + _win_show_time(win); + } else { + GDateTime *time = g_date_time_new_from_timeval_utc(tv_stamp); + gchar *date_fmt = g_date_time_format(time, "%H:%M:%S"); + wprintw(win, "%s - ", date_fmt); + g_date_time_unref(time); + g_free(date_fmt); + } + if (strncmp(message, "/me ", 4) == 0) { wattron(win, COLOUR_ONLINE); wprintw(win, "*%s ", short_from);