diff options
-rw-r--r-- | src/database.c | 13 | ||||
-rw-r--r-- | src/database.h | 4 | ||||
-rw-r--r-- | src/ui/chatwin.c | 15 | ||||
-rw-r--r-- | src/ui/ui.h | 2 | ||||
-rw-r--r-- | src/ui/window.c | 13 | ||||
-rw-r--r-- | src/xmpp/iq.c | 47 | ||||
-rw-r--r-- | src/xmpp/stanza.c | 30 | ||||
-rw-r--r-- | src/xmpp/stanza.h | 1 |
8 files changed, 69 insertions, 56 deletions
diff --git a/src/database.c b/src/database.c index 82cd380f..ea971d4e 100644 --- a/src/database.c +++ b/src/database.c @@ -46,6 +46,7 @@ #include "log.h" #include "common.h" #include "config/files.h" +#include "database.h" static sqlite3* g_chatlog_database; @@ -234,7 +235,7 @@ log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_las // Query previous chat GSList* -log_database_get_previous_chat(const gchar* const contact_barejid, GDateTime* end_time, gboolean flip) +log_database_get_previous_chat(const gchar* const contact_barejid, char* start_time, char* end_time, gboolean flip) { sqlite3_stmt* stmt = NULL; gchar* query; @@ -244,15 +245,17 @@ log_database_get_previous_chat(const gchar* const contact_barejid, GDateTime* en return NULL; // Flip order when querying older pages - char* sort = !flip ? "ASC" : "DESC"; - gchar* date_fmt = g_date_time_format_iso8601(end_time ? end_time : g_date_time_new_now_local()); - query = sqlite3_mprintf("SELECT * FROM (SELECT `message`, `timestamp`, `from_jid`, `type` from `ChatLogs` WHERE ((`from_jid` = '%q' AND `to_jid` = '%q') OR (`from_jid` = '%q' AND `to_jid` = '%q')) AND `timestamp` < '%q' ORDER BY `timestamp` DESC LIMIT 10) ORDER BY `timestamp` %s;", contact_barejid, myjid->barejid, myjid->barejid, contact_barejid, date_fmt, sort); + gchar* sort = !flip ? "ASC" : "DESC"; + gchar* end_date_fmt = end_time ? end_time : g_date_time_format_iso8601(g_date_time_new_now_local()); + gchar* start_date_fmt = start_time ? start_time : NULL; + query = sqlite3_mprintf("SELECT * FROM (SELECT `message`, `timestamp`, `from_jid`, `type` from `ChatLogs` WHERE ((`from_jid` = '%q' AND `to_jid` = '%q') OR (`from_jid` = '%q' AND `to_jid` = '%q')) AND `timestamp` < '%q' AND (%Q IS NULL OR `timestamp` > %Q) ORDER BY `timestamp` DESC LIMIT %d) ORDER BY `timestamp` %s;", contact_barejid, myjid->barejid, myjid->barejid, contact_barejid, end_date_fmt, start_date_fmt, start_date_fmt, MESSAGES_TO_RETRIEVE, sort); if (!query) { log_error("log_database_get_previous_chat(): SQL query. could not allocate memory"); return NULL; } - g_free(date_fmt); + g_free(end_date_fmt); + jid_destroy(myjid); int rc = sqlite3_prepare_v2(g_chatlog_database, query, -1, &stmt, NULL); diff --git a/src/database.h b/src/database.h index 08a6bab0..d575d62e 100644 --- a/src/database.h +++ b/src/database.h @@ -40,12 +40,14 @@ #include "config/account.h" #include "xmpp/xmpp.h" +#define MESSAGES_TO_RETRIEVE 10 + gboolean log_database_init(ProfAccount* account); void log_database_add_incoming(ProfMessage* message); void log_database_add_outgoing_chat(const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc); void log_database_add_outgoing_muc(const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc); void log_database_add_outgoing_muc_pm(const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc); -GSList* log_database_get_previous_chat(const gchar* const contact_barejid, GDateTime* end_time, gboolean flip); +GSList* log_database_get_previous_chat(const gchar* const contact_barejid, char* start_time, char* end_time, gboolean flip); ProfMessage* log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_last); void log_database_close(void); diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c index 02068837..82df1e80 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -66,8 +66,11 @@ chatwin_new(const char* const barejid) ProfWin* window = wins_new_chat(barejid); ProfChatWin* chatwin = (ProfChatWin*)window; - if (prefs_get_boolean(PREF_MAM) || (prefs_get_boolean(PREF_CHLOG) && prefs_get_boolean(PREF_HISTORY))) { + if (!prefs_get_boolean(PREF_MAM) || (prefs_get_boolean(PREF_CHLOG) && prefs_get_boolean(PREF_HISTORY))) { + if (0) { + _chatwin_history(chatwin, barejid); + } } // if the contact is offline, show a message @@ -307,7 +310,7 @@ chatwin_incoming_msg(ProfChatWin* chatwin, ProfMessage* message, gboolean win_cr // MUCPMs also get printed here. In their case we don't save any logs (because nick owners can change) and thus we shouldn't read logs // (and if we do we need to check the resourcepart) if (!prefs_get_boolean(PREF_MAM) && prefs_get_boolean(PREF_CHLOG) && prefs_get_boolean(PREF_HISTORY) && message->type == PROF_MSG_TYPE_CHAT) { - _chatwin_history(chatwin, chatwin->barejid); + /* _chatwin_history(chatwin, chatwin->barejid); */ } // show users status first, when receiving message via delayed delivery @@ -518,7 +521,7 @@ static void _chatwin_history(ProfChatWin* chatwin, const char* const contact_barejid) { if (!chatwin->history_shown) { - GSList* history = log_database_get_previous_chat(contact_barejid, NULL, FALSE); + GSList* history = log_database_get_previous_chat(contact_barejid, NULL, NULL, FALSE); GSList* curr = history; while (curr) { @@ -538,11 +541,11 @@ _chatwin_history(ProfChatWin* chatwin, const char* const contact_barejid) } gboolean -chatwin_old_history(ProfChatWin* chatwin) +chatwin_old_history(ProfChatWin* chatwin, char* start_time) { // TODO: not correct location but check whether notifications get screwed - GDateTime* time = buffer_size(((ProfWin*)chatwin)->layout->buffer) == 0 ? NULL : buffer_get_entry(((ProfWin*)chatwin)->layout->buffer, 0)->time; - GSList* history = log_database_get_previous_chat(chatwin->barejid, time, TRUE); + char* end_time = buffer_size(((ProfWin*)chatwin)->layout->buffer) == 0 ? NULL : g_date_time_format_iso8601(buffer_get_entry(((ProfWin*)chatwin)->layout->buffer, 0)->time); + GSList* history = log_database_get_previous_chat(chatwin->barejid, start_time, end_time, TRUE); gboolean has_items = g_slist_length(history) != 0; GSList* curr = history; diff --git a/src/ui/ui.h b/src/ui/ui.h index 264ce38b..1b87783a 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -145,7 +145,7 @@ void chatwin_set_incoming_char(ProfChatWin* chatwin, const char* const ch); void chatwin_unset_incoming_char(ProfChatWin* chatwin); void chatwin_set_outgoing_char(ProfChatWin* chatwin, const char* const ch); void chatwin_unset_outgoing_char(ProfChatWin* chatwin); -gboolean chatwin_old_history(ProfChatWin* chatwin); +gboolean chatwin_old_history(ProfChatWin* chatwin, char* start_date); // MUC window ProfMucWin* mucwin_new(const char* const barejid); diff --git a/src/ui/window.c b/src/ui/window.c index 1dedb1d8..391aec21 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -61,6 +61,7 @@ #include "xmpp/xmpp.h" #include "xmpp/roster_list.h" #include "xmpp/connection.h" +#include "database.h" #define CONS_WIN_TITLE "Profanity. Type /help for help information." #define XML_WIN_TITLE "XML Console" @@ -607,7 +608,7 @@ win_page_up(ProfWin* window) // Don't do anything if still fetching mam messages if (first_entry && !(first_entry->theme_item == THEME_ROOMINFO && g_strcmp0(first_entry->message, loading_text) == 0)) { - if (!chatwin_old_history(chatwin)) { + if (!chatwin_old_history(chatwin, NULL)) { cons_show("Fetched mam"); buffer_prepend(window->layout->buffer, "-", 0, first_entry->time, NO_DATE, THEME_ROOMINFO, NULL, NULL, loading_text, NULL, NULL); win_redraw(window); @@ -1211,8 +1212,8 @@ win_print_incoming(ProfWin* window, const char* const display_name_from, ProfMes if (prefs_get_boolean(PREF_CORRECTION_ALLOW) && message->replace_id) { _win_correct(window, message->plain, message->id, message->replace_id, message->from_jid->barejid); } else { - // Prevent duplicate messages when current client is sending a message - if (g_strcmp0(message->from_jid->fulljid, connection_get_fulljid()) != 0) { + // Prevent duplicate messages when current client is sending a message or if it's mam + if (g_strcmp0(message->from_jid->fulljid, connection_get_fulljid()) != 0 && !message->is_mam) { _win_printf(window, enc_char, 0, message->timestamp, flags, THEME_TEXT_THEM, display_name_from, message->from_jid->barejid, message->id, "%s", message->plain); } } @@ -1550,10 +1551,8 @@ _win_printf(ProfWin* window, const char* show_char, int pad_indent, GDateTime* t GString* fmt_msg = g_string_new(NULL); g_string_vprintf(fmt_msg, message, arg); - if (buffer_size(window->layout->buffer) == 0 || g_date_time_compare(buffer_get_entry(window->layout->buffer, 0)->time, timestamp) != 1) { - buffer_append(window->layout->buffer, show_char, pad_indent, timestamp, flags, theme_item, display_from, from_jid, fmt_msg->str, NULL, message_id); - _win_print_internal(window, show_char, pad_indent, timestamp, flags, theme_item, display_from, fmt_msg->str, NULL); - } + buffer_append(window->layout->buffer, show_char, pad_indent, timestamp, flags, theme_item, display_from, from_jid, fmt_msg->str, NULL, message_id); + _win_print_internal(window, show_char, pad_indent, timestamp, flags, theme_item, display_from, fmt_msg->str, NULL); inp_nonblocking(TRUE); g_date_time_unref(timestamp); diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index d2ae7de2..098d19db 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -108,6 +108,7 @@ typedef struct mam_rsm_userdata char* barejid; char* start_datestr; char* end_datestr; + ProfChatWin* win; } MamRsmUserdata; static int _iq_handler(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* const userdata); @@ -2582,7 +2583,7 @@ _mam_buffer_commit_handler(xmpp_stanza_t* const stanza, void* const userdata) cons_show("Comitted history"); // Remove the "Loading messages ..." message buffer_remove_entry(((ProfWin*)chatwin)->layout->buffer, 0); - chatwin_old_history(chatwin); + chatwin_old_history(chatwin, NULL); return 0; } @@ -2630,39 +2631,32 @@ iq_mam_request(ProfChatWin* win) } ProfMessage* last_msg = log_database_get_limits_info(win->barejid, TRUE); - char* lastid = NULL; - char* firstid = NULL; + // To get last page and have flipped paging set firstid to empty string + char* firstid = ""; char* startdate = NULL; char* enddate = NULL; - gboolean should_add_rsm_handler = TRUE; // If last message found if (last_msg->timestamp) { - lastid = last_msg->stanzaid; startdate = g_date_time_format(last_msg->timestamp, "%FT%T.%f%:z"); - } else { GDateTime* now = g_date_time_new_now_utc(); enddate = g_date_time_format(now, "%FT%T.%f%:z"); g_date_time_unref(now); - // To get last page we need to set before to empty string - firstid = ""; - should_add_rsm_handler = FALSE; } xmpp_ctx_t* const ctx = connection_get_ctx(); - xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, win->barejid, startdate, enddate, firstid, lastid); + xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, win->barejid, startdate, enddate, firstid, NULL); - if (should_add_rsm_handler) { - MamRsmUserdata* data = malloc(sizeof(MamRsmUserdata)); - if (data) { - data->start_datestr = startdate; - data->end_datestr = enddate; - data->barejid = strdup(win->barejid); + MamRsmUserdata* data = malloc(sizeof(MamRsmUserdata)); + if (data) { + data->start_datestr = startdate; + data->end_datestr = enddate; + data->barejid = strdup(win->barejid); + data->win = win; - iq_id_handler_add(xmpp_stanza_get_id(iq), _mam_rsm_id_handler, NULL, data); - } + iq_id_handler_add(xmpp_stanza_get_id(iq), _mam_rsm_id_handler, NULL, data); } message_free(last_msg); @@ -2686,24 +2680,25 @@ _mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata) xmpp_stanza_t* fin = xmpp_stanza_get_child_by_name_and_ns(stanza, STANZA_NAME_FIN, STANZA_NS_MAM2); if (fin) { gboolean is_complete = g_strcmp0(xmpp_stanza_get_attribute(fin, "complete"), "true") == 0; + MamRsmUserdata* data = (MamRsmUserdata*)userdata; - if (is_complete) { + if (is_complete || data->end_datestr) { + chatwin_old_history(data->win, is_complete ? NULL : data->start_datestr); return 0; } + chatwin_old_history(data->win, data->start_datestr); xmpp_stanza_t* set = xmpp_stanza_get_child_by_name_and_ns(fin, STANZA_TYPE_SET, STANZA_NS_RSM); if (set) { - char* lastid = NULL; - xmpp_stanza_t* last = xmpp_stanza_get_child_by_name(set, STANZA_NAME_LAST); - lastid = xmpp_stanza_get_text(last); + char* firstid = NULL; + xmpp_stanza_t* first = xmpp_stanza_get_child_by_name(set, STANZA_NAME_FIRST); + firstid = xmpp_stanza_get_text(first); // 4.3.2. send same stanza with set,max stanza xmpp_ctx_t* const ctx = connection_get_ctx(); - MamRsmUserdata* data = (MamRsmUserdata*)userdata; - - xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, data->barejid, data->start_datestr, data->end_datestr, NULL, lastid); - free(lastid); + xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, data->barejid, data->start_datestr, data->end_datestr, firstid, NULL); + free(firstid); iq_id_handler_add(xmpp_stanza_get_id(iq), _mam_rsm_id_handler, NULL, data); diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 86791d94..4d56ebf4 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -58,6 +58,7 @@ #include "xmpp/connection.h" #include "xmpp/form.h" #include "xmpp/muc.h" +#include "database.h" static void _stanza_add_unique_id(xmpp_stanza_t* stanza); static char* _stanza_create_sha1_hash(char* str); @@ -2780,12 +2781,21 @@ stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const s } // 4.3.2 set/rsm - xmpp_stanza_t *set; - if (lastid || firstid) { - set = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(set, STANZA_TYPE_SET); - xmpp_stanza_set_ns(set, STANZA_NS_RSM); - } + xmpp_stanza_t *set, *max, *max_text; + set = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(set, STANZA_TYPE_SET); + xmpp_stanza_set_ns(set, STANZA_NS_RSM); + + max = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(max, STANZA_NAME_MAX); + + max_text = xmpp_stanza_new(ctx); + char* txt = g_strdup_printf("%d", MESSAGES_TO_RETRIEVE); + xmpp_stanza_set_text(max_text, txt); + g_free(txt); + + xmpp_stanza_add_child(max, max_text); + xmpp_stanza_add_child(set, max); xmpp_stanza_t *after, *after_text; if (lastid) { @@ -2831,10 +2841,10 @@ stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const s xmpp_stanza_release(end_date_text); } - if (firstid || lastid) { - xmpp_stanza_add_child(query, set); - xmpp_stanza_release(set); - } + xmpp_stanza_add_child(query, set); + xmpp_stanza_release(set); + xmpp_stanza_release(max_text); + xmpp_stanza_release(max); if (lastid) { xmpp_stanza_release(after_text); diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index 71454e9d..4d41ef87 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -118,6 +118,7 @@ #define STANZA_NAME_FIRST "first" #define STANZA_NAME_AFTER "after" #define STANZA_NAME_BEFORE "before" +#define STANZA_NAME_MAX "max" #define STANZA_NAME_USERNAME "username" #define STANZA_NAME_PROPOSE "propose" #define STANZA_NAME_REPORT "report" |