From ea83165a35370c9ebcf10da9dd6d1c53f6517008 Mon Sep 17 00:00:00 2001 From: MarcoPolo-PasTonMolo Date: Sun, 3 Jul 2022 21:29:36 +0300 Subject: Get messages from history when scrolling up. --- src/ui/buffer.c | 28 ++++++++++++++++++++++++++++ src/ui/buffer.h | 1 + src/ui/chatwin.c | 30 ++++++++++++++++++++++++++++-- src/ui/ui.h | 1 + src/ui/window.c | 39 ++++++++++++++++++++++++++++++++++++--- src/ui/window.h | 1 + 6 files changed, 95 insertions(+), 5 deletions(-) (limited to 'src/ui') diff --git a/src/ui/buffer.c b/src/ui/buffer.c index e38aaaec..0203c35c 100644 --- a/src/ui/buffer.c +++ b/src/ui/buffer.c @@ -110,6 +110,34 @@ buffer_append(ProfBuff buffer, const char* show_char, int pad_indent, GDateTime* buffer->entries = g_slist_append(buffer->entries, e); } +void +buffer_prepend(ProfBuff buffer, const char* show_char, int pad_indent, GDateTime* time, int flags, theme_item_t theme_item, const char* const display_from, const char* const from_jid, const char* const message, DeliveryReceipt* receipt, const char* const id) +{ + ProfBuffEntry* e = malloc(sizeof(struct prof_buff_entry_t)); + e->show_char = strdup(show_char); + e->pad_indent = pad_indent; + e->flags = flags; + e->theme_item = theme_item; + e->time = g_date_time_ref(time); + e->display_from = display_from ? strdup(display_from) : NULL; + e->from_jid = from_jid ? strdup(from_jid) : NULL; + e->message = strdup(message); + e->receipt = receipt; + if (id) { + e->id = strdup(id); + } else { + e->id = NULL; + } + + if (g_slist_length(buffer->entries) == BUFF_SIZE) { + GSList* last = g_slist_last(buffer->entries); + _free_entry(last->data); + buffer->entries = g_slist_delete_link(buffer->entries, last); + } + + buffer->entries = g_slist_prepend(buffer->entries, e); +} + void buffer_remove_entry_by_id(ProfBuff buffer, const char* const id) { diff --git a/src/ui/buffer.h b/src/ui/buffer.h index 5d363902..e3e79655 100644 --- a/src/ui/buffer.h +++ b/src/ui/buffer.h @@ -70,6 +70,7 @@ typedef struct prof_buff_t* ProfBuff; ProfBuff buffer_create(); void buffer_free(ProfBuff buffer); void buffer_append(ProfBuff buffer, const char* show_char, int pad_indent, GDateTime* time, int flags, theme_item_t theme_item, const char* const display_from, const char* const barejid, const char* const message, DeliveryReceipt* receipt, const char* const id); +void buffer_prepend(ProfBuff buffer, const char* show_char, int pad_indent, GDateTime* time, int flags, theme_item_t theme_item, const char* const display_from, const char* const barejid, const char* const message, DeliveryReceipt* receipt, const char* const id); void buffer_remove_entry_by_id(ProfBuff buffer, const char* const id); int buffer_size(ProfBuff buffer); ProfBuffEntry* buffer_get_entry(ProfBuff buffer, int entry); diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c index b9fae2af..02068837 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -66,7 +66,7 @@ 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))) { _chatwin_history(chatwin, barejid); } @@ -518,7 +518,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); + GSList* history = log_database_get_previous_chat(contact_barejid, NULL, FALSE); GSList* curr = history; while (curr) { @@ -537,6 +537,32 @@ _chatwin_history(ProfChatWin* chatwin, const char* const contact_barejid) } } +gboolean +chatwin_old_history(ProfChatWin* chatwin) +{ + // 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); + gboolean has_items = g_slist_length(history) != 0; + GSList* curr = history; + + while (curr) { + ProfMessage* msg = curr->data; + char* msg_plain = msg->plain; + msg->plain = plugins_pre_chat_message_display(msg->from_jid->barejid, msg->from_jid->resourcepart, msg->plain); + // This is dirty workaround for memory leak. We reassign msg->plain above so have to free previous object + // TODO: Make a better solution, for example, pass msg object to the function and it will replace msg->plain properly if needed. + free(msg_plain); + win_print_old_history((ProfWin*)chatwin, msg); + curr = g_slist_next(curr); + } + + g_slist_free_full(history, (GDestroyNotify)message_free); + win_redraw((ProfWin*)chatwin); + + return has_items; +} + static void _chatwin_set_last_message(ProfChatWin* chatwin, const char* const id, const char* const message) { diff --git a/src/ui/ui.h b/src/ui/ui.h index a7886ab3..264ce38b 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -145,6 +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); // MUC window ProfMucWin* mucwin_new(const char* const barejid); diff --git a/src/ui/window.c b/src/ui/window.c index 7bd403da..b6130348 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -600,6 +600,10 @@ win_page_up(ProfWin* window) *page_start -= page_space; + if (*page_start == -page_space && prefs_get_boolean(PREF_MAM) && window->type == WIN_CHAT) { + ProfChatWin* chatwin = (ProfChatWin*) window; + chatwin_old_history(chatwin); + } // went past beginning, show first page if (*page_start < 0) *page_start = 0; @@ -1289,6 +1293,34 @@ win_print_history(ProfWin* window, const ProfMessage* const message) g_date_time_unref(message->timestamp); } +void +win_print_old_history(ProfWin* window, const ProfMessage* const message) +{ + g_date_time_ref(message->timestamp); + + char* display_name; + int flags = 0; + const char* jid = connection_get_fulljid(); + Jid* jidp = jid_create(jid); + + if (g_strcmp0(jidp->barejid, message->from_jid->barejid) == 0) { + display_name = strdup("me"); + } else { + display_name = roster_get_msg_display_name(message->from_jid->barejid, message->from_jid->resourcepart); + flags = NO_ME; + } + + jid_destroy(jidp); + + buffer_prepend(window->layout->buffer, "-", 0, message->timestamp, flags, THEME_TEXT_HISTORY, display_name, NULL, message->plain, NULL, NULL); + _win_print_internal(window, "-", 0, message->timestamp, flags, THEME_TEXT_HISTORY, display_name, message->plain, NULL); + + free(display_name); + + inp_nonblocking(TRUE); + g_date_time_unref(message->timestamp); +} + void win_print(ProfWin* window, theme_item_t theme_item, const char* show_char, const char* const message, ...) { @@ -1504,9 +1536,10 @@ _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); - 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); + 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); + } inp_nonblocking(TRUE); g_date_time_unref(timestamp); diff --git a/src/ui/window.h b/src/ui/window.h index 669734ff..174785b1 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -71,6 +71,7 @@ void win_print_outgoing_with_receipt(ProfWin* window, const char* show_char, con void win_println_incoming_muc_msg(ProfWin* window, char* show_char, int flags, const ProfMessage* const message); void win_print_outgoing_muc_msg(ProfWin* window, char* show_char, const char* const me, const char* const id, const char* const replace_id, const char* const message); void win_print_history(ProfWin* window, const ProfMessage* const message); +void win_print_old_history(ProfWin* window, const ProfMessage* const message); void win_print_http_transfer(ProfWin* window, const char* const message, char* url); -- cgit 1.4.1-2-gfad0 From 97a610e915d178ff136d3c93bdb3c7c6f97666ff Mon Sep 17 00:00:00 2001 From: MarcoPolo-PasTonMolo Date: Sun, 3 Jul 2022 21:30:02 +0300 Subject: Fech data from mam when all history gets displayed Fetch from mam without displaying when all mam messages get received display new messages from db. Unstable, initial mam doesn't get displayed unless we start scrolling. --- src/ui/window.c | 8 +++++++- src/xmpp/iq.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/xmpp/xmpp.h | 2 ++ 3 files changed, 52 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/window.c b/src/ui/window.c index b6130348..4794e5c0 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -602,8 +602,14 @@ win_page_up(ProfWin* window) if (*page_start == -page_space && prefs_get_boolean(PREF_MAM) && window->type == WIN_CHAT) { ProfChatWin* chatwin = (ProfChatWin*) window; - chatwin_old_history(chatwin); + if (!chatwin_old_history(chatwin)) { + cons_show("Fetched mam"); + iq_mam_request_older(chatwin); + } else { + cons_show("Showed history"); + } } + // went past beginning, show first page if (*page_start < 0) *page_start = 0; diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index dd28b358..d51560be 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -2575,6 +2575,49 @@ _iq_free_affiliation_list(ProfAffiliationList* affiliation_list) } } +static int +_mam_buffer_commit_handler(xmpp_stanza_t* const stanza, void* const userdata) +{ + ProfChatWin* chatwin = (ProfChatWin*)userdata; + cons_show("Comitted history"); + chatwin_old_history(chatwin); + return 0; +} + +void +iq_mam_request_older(ProfChatWin* win) +{ + if (connection_supports(XMPP_FEATURE_MAM2) == FALSE) { + log_warning("Server doesn't advertise %s feature.", XMPP_FEATURE_MAM2); + cons_show_error("Server doesn't support MAM (%s).", XMPP_FEATURE_MAM2); + return; + } + + ProfMessage* first_msg = log_database_get_limits_info(win->barejid, FALSE); + char* firstid = NULL; + char* enddate = NULL; + + // If first message found + if (first_msg->timestamp) { + firstid = first_msg->stanzaid; + enddate = g_date_time_format(first_msg->timestamp, "%FT%T.%f%:z"); + } else { + return; + } + + xmpp_ctx_t* const ctx = connection_get_ctx(); + xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, win->barejid, NULL, enddate, firstid, NULL); + iq_id_handler_add(xmpp_stanza_get_id(iq), _mam_buffer_commit_handler, NULL, win); + + g_free(enddate); + message_free(first_msg); + + iq_send_stanza(iq); + xmpp_stanza_release(iq); + + return; +} + void iq_mam_request(ProfChatWin* win) { diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 2cc22e55..6b1f21df 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -64,6 +64,7 @@ #define XMPP_FEATURE_USER_AVATAR_METADATA_NOTIFY "urn:xmpp:avatar:metadata+notify" #define XMPP_FEATURE_LAST_MESSAGE_CORRECTION "urn:xmpp:message-correct:0" #define XMPP_FEATURE_MAM2 "urn:xmpp:mam:2" +#define XMPP_FEATURE_MAM2_EXTENDED "urn:xmpp:mam:2#extended" #define XMPP_FEATURE_SPAM_REPORTING "urn:xmpp:reporting:1" typedef enum { @@ -261,6 +262,7 @@ void iq_http_upload_request(HTTPUpload* upload); void iq_command_list(const char* const target); void iq_command_exec(const char* const target, const char* const command); void iq_mam_request(ProfChatWin* win); +void iq_mam_request_older(ProfChatWin* win); void iq_register_change_password(const char* const user, const char* const password); void iq_muc_register_nick(const char* const roomjid); -- cgit 1.4.1-2-gfad0 From e9da69426527c242c72f88e74f82724c0ea20c39 Mon Sep 17 00:00:00 2001 From: MarcoPolo-PasTonMolo Date: Mon, 4 Jul 2022 12:39:59 +0300 Subject: Add 'Loading messages' message when scrolling up --- src/ui/buffer.c | 8 ++++++++ src/ui/buffer.h | 1 + src/ui/window.c | 18 +++++++++++++----- src/xmpp/iq.c | 2 ++ 4 files changed, 24 insertions(+), 5 deletions(-) (limited to 'src/ui') diff --git a/src/ui/buffer.c b/src/ui/buffer.c index 0203c35c..553dc325 100644 --- a/src/ui/buffer.c +++ b/src/ui/buffer.c @@ -153,6 +153,14 @@ buffer_remove_entry_by_id(ProfBuff buffer, const char* const id) } } +void +buffer_remove_entry(ProfBuff buffer, int entry) +{ + GSList* node = g_slist_nth(buffer->entries, entry); + _free_entry(node->data); + buffer->entries = g_slist_delete_link(buffer->entries, node); +} + gboolean buffer_mark_received(ProfBuff buffer, const char* const id) { diff --git a/src/ui/buffer.h b/src/ui/buffer.h index e3e79655..535df882 100644 --- a/src/ui/buffer.h +++ b/src/ui/buffer.h @@ -72,6 +72,7 @@ void buffer_free(ProfBuff buffer); void buffer_append(ProfBuff buffer, const char* show_char, int pad_indent, GDateTime* time, int flags, theme_item_t theme_item, const char* const display_from, const char* const barejid, const char* const message, DeliveryReceipt* receipt, const char* const id); void buffer_prepend(ProfBuff buffer, const char* show_char, int pad_indent, GDateTime* time, int flags, theme_item_t theme_item, const char* const display_from, const char* const barejid, const char* const message, DeliveryReceipt* receipt, const char* const id); void buffer_remove_entry_by_id(ProfBuff buffer, const char* const id); +void buffer_remove_entry(ProfBuff buffer, int entry); int buffer_size(ProfBuff buffer); ProfBuffEntry* buffer_get_entry(ProfBuff buffer, int entry); ProfBuffEntry* buffer_get_entry_by_id(ProfBuff buffer, const char* const id); diff --git a/src/ui/window.c b/src/ui/window.c index 4794e5c0..1dedb1d8 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -602,11 +602,19 @@ win_page_up(ProfWin* window) if (*page_start == -page_space && prefs_get_boolean(PREF_MAM) && window->type == WIN_CHAT) { ProfChatWin* chatwin = (ProfChatWin*) window; - if (!chatwin_old_history(chatwin)) { - cons_show("Fetched mam"); - iq_mam_request_older(chatwin); - } else { - cons_show("Showed history"); + ProfBuffEntry* first_entry = buffer_size(window->layout->buffer) != 0 ? buffer_get_entry(window->layout->buffer, 0) : NULL; + char* loading_text = "Loading older messages ..."; + + // 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)) { + 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); + iq_mam_request_older(chatwin); + } else { + cons_show("Showed history"); + } } } diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index d51560be..d2ae7de2 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -2580,6 +2580,8 @@ _mam_buffer_commit_handler(xmpp_stanza_t* const stanza, void* const userdata) { ProfChatWin* chatwin = (ProfChatWin*)userdata; cons_show("Comitted history"); + // Remove the "Loading messages ..." message + buffer_remove_entry(((ProfWin*)chatwin)->layout->buffer, 0); chatwin_old_history(chatwin); return 0; } -- cgit 1.4.1-2-gfad0 From 6429698f18b8b1fe3f8252402104c9701e62b620 Mon Sep 17 00:00:00 2001 From: MarcoPolo-PasTonMolo Date: Tue, 5 Jul 2022 00:06:04 +0300 Subject: Fix initial MAM not displaying Did this by waiting for a batch of MAM messages to arrive before prepending them to the buffer. Also limited the number of messages to fetch to 10 so that the user gets more frequent updates. --- src/database.c | 13 ++++++++----- src/database.h | 4 +++- src/ui/chatwin.c | 15 +++++++++------ src/ui/ui.h | 2 +- src/ui/window.c | 13 ++++++------- src/xmpp/iq.c | 47 +++++++++++++++++++++-------------------------- src/xmpp/stanza.c | 30 ++++++++++++++++++++---------- src/xmpp/stanza.h | 1 + 8 files changed, 69 insertions(+), 56 deletions(-) (limited to 'src/ui') 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" -- cgit 1.4.1-2-gfad0 From 4d6e95d6911eab8fc9f6ddc0706c7b2ac5a25437 Mon Sep 17 00:00:00 2001 From: MarcoPolo-PasTonMolo Date: Tue, 5 Jul 2022 11:12:29 +0300 Subject: Add loading history message on initial MAM request This prevents scrolling to top and initiating another MAM request while still fetching the initial one. Also free timestamp object in database.c --- src/database.c | 4 +++- src/ui/chatwin.c | 1 + src/ui/window.c | 12 ++++++++++-- src/ui/window.h | 1 + src/xmpp/iq.c | 5 +++++ 5 files changed, 20 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/database.c b/src/database.c index ea971d4e..966f6ca4 100644 --- a/src/database.c +++ b/src/database.c @@ -246,7 +246,8 @@ log_database_get_previous_chat(const gchar* const contact_barejid, char* start_t // Flip order when querying older pages gchar* sort = !flip ? "ASC" : "DESC"; - gchar* end_date_fmt = end_time ? end_time : g_date_time_format_iso8601(g_date_time_new_now_local()); + GDateTime* now = g_date_time_new_now_local(); + gchar* end_date_fmt = end_time ? end_time : g_date_time_format_iso8601(now); 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) { @@ -254,6 +255,7 @@ log_database_get_previous_chat(const gchar* const contact_barejid, char* start_t return NULL; } + g_date_time_unref(now); g_free(end_date_fmt); jid_destroy(myjid); diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c index 82df1e80..a89e4626 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -102,6 +102,7 @@ chatwin_new(const char* const barejid) if (prefs_get_boolean(PREF_MAM)) { iq_mam_request(chatwin); + win_print_loading_history(window); } return chatwin; diff --git a/src/ui/window.c b/src/ui/window.c index 391aec21..e168b70c 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -610,8 +610,7 @@ win_page_up(ProfWin* window) if (first_entry && !(first_entry->theme_item == THEME_ROOMINFO && g_strcmp0(first_entry->message, loading_text) == 0)) { 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); + win_print_loading_history(window); iq_mam_request_older(chatwin); } else { cons_show("Showed history"); @@ -1855,6 +1854,15 @@ win_redraw(ProfWin* window) } } +void +win_print_loading_history(ProfWin* window) +{ + char* loading_text = "Loading older messages ..."; + GDateTime* timestamp = buffer_size(window->layout->buffer) != 0 ? buffer_get_entry(window->layout->buffer, 0)->time : g_date_time_new_now_local(); + buffer_prepend(window->layout->buffer, "-", 0, timestamp, NO_DATE, THEME_ROOMINFO, NULL, NULL, loading_text, NULL, NULL); + win_redraw(window); +} + gboolean win_has_active_subwin(ProfWin* window) { diff --git a/src/ui/window.h b/src/ui/window.h index 174785b1..822f12b0 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -77,6 +77,7 @@ void win_print_http_transfer(ProfWin* window, const char* const message, char* u void win_newline(ProfWin* window); void win_redraw(ProfWin* window); +void win_print_loading_history(ProfWin* window); int win_roster_cols(void); int win_occpuants_cols(void); void win_sub_print(WINDOW* win, char* msg, gboolean newline, gboolean wrap, int indent); diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 098d19db..1c851cbd 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -67,6 +67,7 @@ #include "xmpp/roster.h" #include "xmpp/muc.h" #include "src/database.h" +#include "ui/window.h" #ifdef HAVE_OMEMO #include "omemo/omemo.h" @@ -2681,7 +2682,9 @@ _mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata) if (fin) { gboolean is_complete = g_strcmp0(xmpp_stanza_get_attribute(fin, "complete"), "true") == 0; MamRsmUserdata* data = (MamRsmUserdata*)userdata; + ProfWin* window = (ProfWin*)data->win; + buffer_remove_entry(window->layout->buffer, 0); if (is_complete || data->end_datestr) { chatwin_old_history(data->win, is_complete ? NULL : data->start_datestr); return 0; @@ -2690,6 +2693,8 @@ _mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata) xmpp_stanza_t* set = xmpp_stanza_get_child_by_name_and_ns(fin, STANZA_TYPE_SET, STANZA_NS_RSM); if (set) { + win_print_loading_history(window); + char* firstid = NULL; xmpp_stanza_t* first = xmpp_stanza_get_child_by_name(set, STANZA_NAME_FIRST); firstid = xmpp_stanza_get_text(first); -- cgit 1.4.1-2-gfad0 From b03c3bda980056f65cd696fd65883a1c351ac8d7 Mon Sep 17 00:00:00 2001 From: MarcoPolo-PasTonMolo Date: Tue, 5 Jul 2022 11:30:04 +0300 Subject: Cleanup --- src/ui/chatwin.c | 7 ++----- src/ui/window.c | 9 ++------- src/ui/window.h | 1 + src/xmpp/iq.c | 1 - 4 files changed, 5 insertions(+), 13 deletions(-) (limited to 'src/ui') diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c index a89e4626..ec7f3f7a 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -66,11 +66,8 @@ 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 (0) { - + if (!prefs_get_boolean(PREF_MAM) && (prefs_get_boolean(PREF_CHLOG) && prefs_get_boolean(PREF_HISTORY))) { _chatwin_history(chatwin, barejid); - } } // if the contact is offline, show a message @@ -311,7 +308,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 diff --git a/src/ui/window.c b/src/ui/window.c index e168b70c..3bbdad01 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -604,16 +604,12 @@ win_page_up(ProfWin* window) if (*page_start == -page_space && prefs_get_boolean(PREF_MAM) && window->type == WIN_CHAT) { ProfChatWin* chatwin = (ProfChatWin*) window; ProfBuffEntry* first_entry = buffer_size(window->layout->buffer) != 0 ? buffer_get_entry(window->layout->buffer, 0) : NULL; - char* loading_text = "Loading older messages ..."; // 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 (first_entry && !(first_entry->theme_item == THEME_ROOMINFO && g_strcmp0(first_entry->message, LOADING_MESSAGE) == 0)) { if (!chatwin_old_history(chatwin, NULL)) { - cons_show("Fetched mam"); win_print_loading_history(window); iq_mam_request_older(chatwin); - } else { - cons_show("Showed history"); } } } @@ -1857,9 +1853,8 @@ win_redraw(ProfWin* window) void win_print_loading_history(ProfWin* window) { - char* loading_text = "Loading older messages ..."; GDateTime* timestamp = buffer_size(window->layout->buffer) != 0 ? buffer_get_entry(window->layout->buffer, 0)->time : g_date_time_new_now_local(); - buffer_prepend(window->layout->buffer, "-", 0, timestamp, NO_DATE, THEME_ROOMINFO, NULL, NULL, loading_text, NULL, NULL); + buffer_prepend(window->layout->buffer, "-", 0, timestamp, NO_DATE, THEME_ROOMINFO, NULL, NULL, LOADING_MESSAGE, NULL, NULL); win_redraw(window); } diff --git a/src/ui/window.h b/src/ui/window.h index 822f12b0..c8a5e03a 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -57,6 +57,7 @@ #include "xmpp/muc.h" #define PAD_SIZE 1000 +#define LOADING_MESSAGE "Loading older messages ..." void win_move_to_end(ProfWin* window); void win_show_status_string(ProfWin* window, const char* const from, diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 1c851cbd..e5d6b13a 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -2581,7 +2581,6 @@ static int _mam_buffer_commit_handler(xmpp_stanza_t* const stanza, void* const userdata) { ProfChatWin* chatwin = (ProfChatWin*)userdata; - cons_show("Comitted history"); // Remove the "Loading messages ..." message buffer_remove_entry(((ProfWin*)chatwin)->layout->buffer, 0); chatwin_old_history(chatwin, NULL); -- cgit 1.4.1-2-gfad0 From 47b3e528e2c13a63316fa7ad2c02d9b702741dea Mon Sep 17 00:00:00 2001 From: MarcoPolo-PasTonMolo Date: Tue, 5 Jul 2022 13:09:16 +0300 Subject: Handle scrolling down when buffer fills up --- src/database.c | 10 +++++----- src/ui/chatwin.c | 18 +++++++++++++----- src/ui/ui.h | 2 +- src/ui/window.c | 16 +++++++++++++++- src/xmpp/iq.c | 6 +++--- 5 files changed, 37 insertions(+), 15 deletions(-) (limited to 'src/ui') diff --git a/src/database.c b/src/database.c index 966f6ca4..d5f12ae9 100644 --- a/src/database.c +++ b/src/database.c @@ -248,16 +248,16 @@ log_database_get_previous_chat(const gchar* const contact_barejid, char* start_t gchar* sort = !flip ? "ASC" : "DESC"; GDateTime* now = g_date_time_new_now_local(); gchar* end_date_fmt = end_time ? end_time : g_date_time_format_iso8601(now); - 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); + 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` %s LIMIT %d) ORDER BY `timestamp` %s;", contact_barejid, myjid->barejid, myjid->barejid, contact_barejid, end_date_fmt, start_time, start_time, sort, MESSAGES_TO_RETRIEVE, sort); + + g_date_time_unref(now); + g_free(end_date_fmt); + if (!query) { log_error("log_database_get_previous_chat(): SQL query. could not allocate memory"); return NULL; } - g_date_time_unref(now); - g_free(end_date_fmt); - jid_destroy(myjid); int rc = sqlite3_prepare_v2(g_chatlog_database, query, -1, &stmt, NULL); diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c index ec7f3f7a..0b2724d3 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -538,12 +538,16 @@ _chatwin_history(ProfChatWin* chatwin, const char* const contact_barejid) } } +// Print history starting from start_time to end_time if end_time is null the +// first entrie's timestamp in the buffer is used. Flip true to prepend to buffer. gboolean -chatwin_old_history(ProfChatWin* chatwin, char* start_time) +chatwin_db_history(ProfChatWin* chatwin, char* start_time, char* end_time, gboolean flip) { - // TODO: not correct location but check whether notifications get screwed - 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); + if (!end_time) { + 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, flip); gboolean has_items = g_slist_length(history) != 0; GSList* curr = history; @@ -554,7 +558,11 @@ chatwin_old_history(ProfChatWin* chatwin, char* start_time) // This is dirty workaround for memory leak. We reassign msg->plain above so have to free previous object // TODO: Make a better solution, for example, pass msg object to the function and it will replace msg->plain properly if needed. free(msg_plain); - win_print_old_history((ProfWin*)chatwin, msg); + if (flip) { + win_print_old_history((ProfWin*)chatwin, msg); + } else { + win_print_history((ProfWin*)chatwin, msg); + } curr = g_slist_next(curr); } diff --git a/src/ui/ui.h b/src/ui/ui.h index 1b87783a..e396b18a 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, char* start_date); +gboolean chatwin_db_history(ProfChatWin* chatwin, char* start_time, char* end_time, gboolean flip); // MUC window ProfMucWin* mucwin_new(const char* const barejid); diff --git a/src/ui/window.c b/src/ui/window.c index 3bbdad01..e56b14fa 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -607,7 +607,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_MESSAGE) == 0)) { - if (!chatwin_old_history(chatwin, NULL)) { + if (!chatwin_db_history(chatwin, NULL, NULL, TRUE)) { win_print_loading_history(window); iq_mam_request_older(chatwin); } @@ -637,6 +637,20 @@ win_page_down(ProfWin* window) *page_start += page_space; + // Scrolled down after reaching the bottom of the page + if ((*page_start == y || (*page_start == page_space && *page_start >= y)) && prefs_get_boolean(PREF_MAM) && window->type == WIN_CHAT) { + int bf_size = buffer_size(window->layout->buffer); + if (bf_size > 0) { + char* start = g_date_time_format_iso8601(buffer_get_entry(window->layout->buffer, bf_size - 1)->time); + GDateTime* now = g_date_time_new_now_local(); + char* end = g_date_time_format_iso8601(now); + chatwin_db_history((ProfChatWin*)window, start, end, FALSE); + + g_free(start); + g_date_time_unref(now); + } + } + // only got half a screen, show full screen if ((y - (*page_start)) < page_space) *page_start = y - page_space; diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index e5d6b13a..a1784b45 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -2583,7 +2583,7 @@ _mam_buffer_commit_handler(xmpp_stanza_t* const stanza, void* const userdata) ProfChatWin* chatwin = (ProfChatWin*)userdata; // Remove the "Loading messages ..." message buffer_remove_entry(((ProfWin*)chatwin)->layout->buffer, 0); - chatwin_old_history(chatwin, NULL); + chatwin_db_history(chatwin, NULL, NULL, TRUE); return 0; } @@ -2685,10 +2685,10 @@ _mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata) buffer_remove_entry(window->layout->buffer, 0); if (is_complete || data->end_datestr) { - chatwin_old_history(data->win, is_complete ? NULL : data->start_datestr); + chatwin_db_history(data->win, is_complete ? NULL : data->start_datestr, NULL, TRUE); return 0; } - chatwin_old_history(data->win, data->start_datestr); + chatwin_db_history(data->win, data->start_datestr, NULL, TRUE); xmpp_stanza_t* set = xmpp_stanza_get_child_by_name_and_ns(fin, STANZA_TYPE_SET, STANZA_NS_RSM); if (set) { -- cgit 1.4.1-2-gfad0 From 85aaf40432d50a99c50ae8d1baa7c02ff5ae43ba Mon Sep 17 00:00:00 2001 From: MarcoPolo-PasTonMolo Date: Sun, 10 Jul 2022 10:44:06 +0300 Subject: Have ability to scroll through history even without MAM --- src/database.c | 11 +++++++---- src/database.h | 2 +- src/ui/chatwin.c | 4 ++-- src/ui/window.c | 6 +++--- 4 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src/ui') diff --git a/src/database.c b/src/database.c index d5f12ae9..80effb71 100644 --- a/src/database.c +++ b/src/database.c @@ -233,9 +233,11 @@ log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_las return msg; } -// Query previous chat +// Query previous chats, constraints start_time and end_time. If end_time is +// null the current time is used. from_start gets first few messages if true +// otherwise the last ones. Flip flips the order of the results GSList* -log_database_get_previous_chat(const gchar* const contact_barejid, char* start_time, char* end_time, gboolean flip) +log_database_get_previous_chat(const gchar* const contact_barejid, char* start_time, char* end_time, gboolean from_start, gboolean flip) { sqlite3_stmt* stmt = NULL; gchar* query; @@ -245,10 +247,11 @@ log_database_get_previous_chat(const gchar* const contact_barejid, char* start_t return NULL; // Flip order when querying older pages - gchar* sort = !flip ? "ASC" : "DESC"; + gchar* sort1 = from_start ? "ASC" : "DESC"; + gchar* sort2 = !flip ? "ASC" : "DESC"; GDateTime* now = g_date_time_new_now_local(); gchar* end_date_fmt = end_time ? end_time : g_date_time_format_iso8601(now); - 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` %s LIMIT %d) ORDER BY `timestamp` %s;", contact_barejid, myjid->barejid, myjid->barejid, contact_barejid, end_date_fmt, start_time, start_time, sort, MESSAGES_TO_RETRIEVE, sort); + 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` %s LIMIT %d) ORDER BY `timestamp` %s;", contact_barejid, myjid->barejid, myjid->barejid, contact_barejid, end_date_fmt, start_time, start_time, sort1, MESSAGES_TO_RETRIEVE, sort2); g_date_time_unref(now); g_free(end_date_fmt); diff --git a/src/database.h b/src/database.h index d575d62e..4913aae0 100644 --- a/src/database.h +++ b/src/database.h @@ -47,7 +47,7 @@ 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, char* start_time, char* end_time, gboolean flip); +GSList* log_database_get_previous_chat(const gchar* const contact_barejid, char* start_time, char* end_time, gboolean from_start, 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 0b2724d3..530739ae 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -519,7 +519,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, NULL, FALSE); + GSList* history = log_database_get_previous_chat(contact_barejid, NULL, NULL, FALSE, FALSE); GSList* curr = history; while (curr) { @@ -547,7 +547,7 @@ chatwin_db_history(ProfChatWin* chatwin, char* start_time, char* end_time, gbool 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, flip); + GSList* history = log_database_get_previous_chat(chatwin->barejid, start_time, end_time, !flip, flip); gboolean has_items = g_slist_length(history) != 0; GSList* curr = history; diff --git a/src/ui/window.c b/src/ui/window.c index e56b14fa..4ac45f9c 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -601,13 +601,13 @@ win_page_up(ProfWin* window) *page_start -= page_space; - if (*page_start == -page_space && prefs_get_boolean(PREF_MAM) && window->type == WIN_CHAT) { + if (*page_start == -page_space && window->type == WIN_CHAT) { ProfChatWin* chatwin = (ProfChatWin*) window; ProfBuffEntry* first_entry = buffer_size(window->layout->buffer) != 0 ? buffer_get_entry(window->layout->buffer, 0) : NULL; // Don't do anything if still fetching mam messages if (first_entry && !(first_entry->theme_item == THEME_ROOMINFO && g_strcmp0(first_entry->message, LOADING_MESSAGE) == 0)) { - if (!chatwin_db_history(chatwin, NULL, NULL, TRUE)) { + if (!chatwin_db_history(chatwin, NULL, NULL, TRUE) && prefs_get_boolean(PREF_MAM)) { win_print_loading_history(window); iq_mam_request_older(chatwin); } @@ -638,7 +638,7 @@ win_page_down(ProfWin* window) *page_start += page_space; // Scrolled down after reaching the bottom of the page - if ((*page_start == y || (*page_start == page_space && *page_start >= y)) && prefs_get_boolean(PREF_MAM) && window->type == WIN_CHAT) { + if ((*page_start == y || (*page_start == page_space && *page_start >= y)) && window->type == WIN_CHAT) { int bf_size = buffer_size(window->layout->buffer); if (bf_size > 0) { char* start = g_date_time_format_iso8601(buffer_get_entry(window->layout->buffer, bf_size - 1)->time); -- cgit 1.4.1-2-gfad0 From 72f613a014080c4b4988d749ee5f682aed253546 Mon Sep 17 00:00:00 2001 From: MarcoPolo-PasTonMolo Date: Sun, 10 Jul 2022 12:28:14 +0300 Subject: Handle MAM when chatwin gets created from incoming message --- src/event/server_events.c | 6 ++++++ src/ui/chatwin.c | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/event/server_events.c b/src/event/server_events.c index 0f18c4e9..26c4963e 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -54,6 +54,7 @@ #include "event/common.h" #include "plugins/plugins.h" #include "ui/window_list.h" +#include "ui/window.h" #include "tools/bookmark_ignore.h" #include "xmpp/xmpp.h" #include "xmpp/muc.h" @@ -638,6 +639,11 @@ sv_ev_incoming_message(ProfMessage* message) chatwin = (ProfChatWin*)window; new_win = TRUE; + if (prefs_get_boolean(PREF_MAM)) { + iq_mam_request(chatwin); + win_print_loading_history(window); + } + #ifdef HAVE_OMEMO if (!message->is_mam) { if (omemo_automatic_start(message->from_jid->barejid)) { diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c index 530739ae..7d583b43 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -320,7 +320,10 @@ chatwin_incoming_msg(ProfChatWin* chatwin, ProfMessage* message, gboolean win_cr } win_insert_last_read_position_marker((ProfWin*)chatwin, chatwin->barejid); - win_print_incoming(window, display_name, message); + + if (!win_created || !prefs_get_boolean(PREF_MAM)) { + win_print_incoming(window, display_name, message); + } } wins_add_urls_ac(window, message); -- cgit 1.4.1-2-gfad0 From a704838152b9aec0bef2446f742b1eb548f71d1a Mon Sep 17 00:00:00 2001 From: MarcoPolo-PasTonMolo Date: Sat, 20 Aug 2022 22:48:02 +0300 Subject: Handle late delivery --- src/event/server_events.c | 2 +- src/ui/chatwin.c | 10 ++-- src/ui/window.c | 1 + src/xmpp/iq.c | 121 ++++++++++++++++++++++++++++++++++++++-------- src/xmpp/xmpp.h | 2 +- 5 files changed, 109 insertions(+), 27 deletions(-) (limited to 'src/ui') diff --git a/src/event/server_events.c b/src/event/server_events.c index 26c4963e..8c1ee04f 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -640,8 +640,8 @@ sv_ev_incoming_message(ProfMessage* message) new_win = TRUE; if (prefs_get_boolean(PREF_MAM)) { - iq_mam_request(chatwin); win_print_loading_history(window); + iq_mam_request(chatwin, g_date_time_add_seconds(message->timestamp, 0)); // copy timestamp } #ifdef HAVE_OMEMO diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c index 7d583b43..fbb5183f 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -98,7 +98,7 @@ chatwin_new(const char* const barejid) #endif // HAVE_OMEMO if (prefs_get_boolean(PREF_MAM)) { - iq_mam_request(chatwin); + iq_mam_request(chatwin, NULL); win_print_loading_history(window); } @@ -320,10 +320,7 @@ chatwin_incoming_msg(ProfChatWin* chatwin, ProfMessage* message, gboolean win_cr } win_insert_last_read_position_marker((ProfWin*)chatwin, chatwin->barejid); - - if (!win_created || !prefs_get_boolean(PREF_MAM)) { - win_print_incoming(window, display_name, message); - } + win_print_incoming(window, display_name, message); } wins_add_urls_ac(window, message); @@ -542,7 +539,8 @@ _chatwin_history(ProfChatWin* chatwin, const char* const contact_barejid) } // Print history starting from start_time to end_time if end_time is null the -// first entrie's timestamp in the buffer is used. Flip true to prepend to buffer. +// first entry's timestamp in the buffer is used. Flip true to prepend to buffer. +// Timestamps should be in iso8601 gboolean chatwin_db_history(ProfChatWin* chatwin, char* start_time, char* end_time, gboolean flip) { diff --git a/src/ui/window.c b/src/ui/window.c index 4ac45f9c..0470b3de 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -1869,6 +1869,7 @@ win_print_loading_history(ProfWin* window) { GDateTime* timestamp = buffer_size(window->layout->buffer) != 0 ? buffer_get_entry(window->layout->buffer, 0)->time : g_date_time_new_now_local(); buffer_prepend(window->layout->buffer, "-", 0, timestamp, NO_DATE, THEME_ROOMINFO, NULL, NULL, LOADING_MESSAGE, NULL, NULL); + g_date_time_unref(timestamp); win_redraw(window); } diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index a1784b45..4c1ec90b 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -109,9 +109,17 @@ typedef struct mam_rsm_userdata char* barejid; char* start_datestr; char* end_datestr; + gboolean fetch_next; ProfChatWin* win; } MamRsmUserdata; +typedef struct late_delivery_userdata +{ + ProfChatWin* win; + GDateTime* enddate; + GDateTime* startdate; +} LateDeliveryUserdata; + static int _iq_handler(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* const userdata); static void _error_handler(xmpp_stanza_t* const stanza); @@ -149,6 +157,7 @@ static int _command_exec_response_handler(xmpp_stanza_t* const stanza, void* con static int _mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata); static int _register_change_password_result_id_handler(xmpp_stanza_t* const stanza, void* const userdata); +static void _iq_mam_request(ProfChatWin* win, GDateTime* startdate, GDateTime* enddate); static void _iq_free_room_data(ProfRoomInfoData* roominfo); static void _iq_free_affiliation_set(ProfPrivilegeSet* affiliation_set); static void _iq_free_affiliation_list(ProfAffiliationList* affiliation_list); @@ -164,6 +173,8 @@ static gboolean autoping_wait = FALSE; static GTimer* autoping_time = NULL; static GHashTable* id_handlers; static GHashTable* rooms_cache = NULL; +static GSList* late_delivery_windows = NULL; +static gboolean received_disco_items = FALSE; static int _iq_handler(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* const userdata) @@ -258,6 +269,8 @@ iq_handlers_init(void) id_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)_iq_id_handler_free); rooms_cache = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)xmpp_stanza_release); + late_delivery_windows = malloc(sizeof(GSList *)); + late_delivery_windows->data = NULL; } void @@ -2525,7 +2538,16 @@ _disco_items_result_handler(xmpp_stanza_t* const stanza) if (g_strcmp0(id, "discoitemsreq") == 0) { cons_show_disco_items(items, from); } else if (g_strcmp0(id, "discoitemsreq_onconnect") == 0) { + received_disco_items = TRUE; connection_set_disco_items(items); + + while (late_delivery_windows->data) { + LateDeliveryUserdata* del_data = late_delivery_windows->data; + _iq_mam_request(del_data->win, del_data->startdate, del_data->enddate); + + late_delivery_windows = g_slist_next(late_delivery_windows); + free(del_data); + } } g_slist_free_full(items, (GDestroyNotify)_item_destroy); @@ -2622,7 +2644,7 @@ iq_mam_request_older(ProfChatWin* win) } void -iq_mam_request(ProfChatWin* win) +_iq_mam_request(ProfChatWin* win, GDateTime* startdate, GDateTime* enddate) { if (connection_supports(XMPP_FEATURE_MAM2) == FALSE) { log_warning("Server doesn't advertise %s feature.", XMPP_FEATURE_MAM2); @@ -2630,43 +2652,72 @@ iq_mam_request(ProfChatWin* win) return; } - ProfMessage* last_msg = log_database_get_limits_info(win->barejid, TRUE); - // To get last page and have flipped paging set firstid to empty string char* firstid = ""; - char* startdate = NULL; - char* enddate = NULL; - - // If last message found - if (last_msg->timestamp) { - startdate = g_date_time_format(last_msg->timestamp, "%FT%T.%f%:z"); - } else { + char* startdate_str = NULL; + char* enddate_str = NULL; + gboolean fetch_next = FALSE; + + if (startdate) { + startdate_str = g_date_time_format(startdate, "%FT%T.%f%:z"); + fetch_next = TRUE; + g_date_time_unref(startdate); + } else if (!enddate) { GDateTime* now = g_date_time_new_now_utc(); - enddate = g_date_time_format(now, "%FT%T.%f%:z"); + enddate_str = g_date_time_format(now, "%FT%T.%f%:z"); g_date_time_unref(now); } + if (enddate) { + enddate_str = g_date_time_format(enddate, "%FT%T.%f%:z"); + g_date_time_unref(enddate); + } + xmpp_ctx_t* const ctx = connection_get_ctx(); - xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, win->barejid, startdate, enddate, firstid, NULL); + xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, win->barejid, startdate_str, enddate_str, firstid, NULL); MamRsmUserdata* data = malloc(sizeof(MamRsmUserdata)); if (data) { - data->start_datestr = startdate; - data->end_datestr = enddate; + data->start_datestr = startdate_str; + data->end_datestr = enddate_str; data->barejid = strdup(win->barejid); + data->fetch_next = fetch_next; data->win = win; iq_id_handler_add(xmpp_stanza_get_id(iq), _mam_rsm_id_handler, NULL, data); } - message_free(last_msg); - iq_send_stanza(iq); xmpp_stanza_release(iq); return; } +void +iq_mam_request(ProfChatWin* win, GDateTime* enddate) +{ + ProfMessage* last_msg = log_database_get_limits_info(win->barejid, TRUE); + GDateTime* startdate = last_msg->timestamp ? g_date_time_add_seconds(last_msg->timestamp, 0) : NULL; // copy timestamp + message_free(last_msg); + + // Save request for later if disco items haven't been received yet + if (!received_disco_items) { + if (late_delivery_windows->data == NULL) { + LateDeliveryUserdata* cur_del_data = malloc(sizeof(LateDeliveryUserdata)); + cur_del_data->win = win; + cur_del_data->enddate = enddate; + cur_del_data->startdate = startdate; + late_delivery_windows->data = cur_del_data; + } + late_delivery_windows = g_slist_append(late_delivery_windows, NULL); + } + + + _iq_mam_request(win, startdate, enddate); + + return; +} + static int _mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata) { @@ -2684,11 +2735,39 @@ _mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata) ProfWin* window = (ProfWin*)data->win; buffer_remove_entry(window->layout->buffer, 0); - if (is_complete || data->end_datestr) { - chatwin_db_history(data->win, is_complete ? NULL : data->start_datestr, NULL, TRUE); + + char *start_str = NULL; + if (data->start_datestr) { + start_str = strdup(data->start_datestr); + // Convert to iso8601 + start_str[strlen(start_str) - 3] = '\0'; + } + char *end_str = NULL; + if (data->end_datestr) { + end_str = strdup(data->end_datestr); + // Convert to iso8601 + end_str[strlen(end_str) - 3] = '\0'; + } + + if (is_complete || !data->fetch_next) { + chatwin_db_history(data->win, is_complete ? NULL : start_str, end_str, TRUE); + // TODO free memory + if (start_str) { + free(start_str); + free(data->start_datestr); + } + + if (end_str) { + free(data->end_datestr); + } + + free(data->barejid); + free(data); return 0; } - chatwin_db_history(data->win, data->start_datestr, NULL, TRUE); + + chatwin_db_history(data->win, start_str, end_str, TRUE); + if (start_str) free(start_str); xmpp_stanza_t* set = xmpp_stanza_get_child_by_name_and_ns(fin, STANZA_TYPE_SET, STANZA_NS_RSM); if (set) { @@ -2701,6 +2780,10 @@ _mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata) // 4.3.2. send same stanza with set,max stanza xmpp_ctx_t* const ctx = connection_get_ctx(); + if (end_str) { + free(data->end_datestr); + } + data->end_datestr = NULL; xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, data->barejid, data->start_datestr, data->end_datestr, firstid, NULL); free(firstid); diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 6b1f21df..dc14285a 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -261,7 +261,7 @@ void iq_autoping_check(void); void iq_http_upload_request(HTTPUpload* upload); void iq_command_list(const char* const target); void iq_command_exec(const char* const target, const char* const command); -void iq_mam_request(ProfChatWin* win); +void iq_mam_request(ProfChatWin* win, GDateTime* enddate); void iq_mam_request_older(ProfChatWin* win); void iq_register_change_password(const char* const user, const char* const password); void iq_muc_register_nick(const char* const roomjid); -- cgit 1.4.1-2-gfad0 From d692aec32ed22377c34efd94845b3201b5a12217 Mon Sep 17 00:00:00 2001 From: MarcoPolo-PasTonMolo Date: Sat, 20 Aug 2022 23:03:46 +0300 Subject: Don't notify on MAM messages --- src/ui/chatwin.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'src/ui') diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c index fbb5183f..452ac609 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -280,7 +280,7 @@ chatwin_incoming_msg(ProfChatWin* chatwin, ProfMessage* message, gboolean win_cr free(mybarejid); gboolean is_current = wins_is_current(window); - gboolean notify = prefs_do_chat_notify(is_current); + gboolean notify = prefs_do_chat_notify(is_current) && !message->is_mam; // currently viewing chat window with sender if (wins_is_current(window)) { @@ -291,13 +291,16 @@ chatwin_incoming_msg(ProfChatWin* chatwin, ProfMessage* message, gboolean win_cr // not currently viewing chat window with sender } else { status_bar_new(num, WIN_CHAT, chatwin->barejid); - cons_show_incoming_message(display_name, num, chatwin->unread, window); - if (prefs_get_boolean(PREF_FLASH)) { - flash(); - } + if (!message->is_mam) { + cons_show_incoming_message(display_name, num, chatwin->unread, window); + + if (prefs_get_boolean(PREF_FLASH)) { + flash(); + } - chatwin->unread++; + chatwin->unread++; + } // TODO: so far we don't ask for MAM when incoming message occurs. // Need to figure out: @@ -326,7 +329,7 @@ chatwin_incoming_msg(ProfChatWin* chatwin, ProfMessage* message, gboolean win_cr wins_add_urls_ac(window, message); wins_add_quotes_ac(window, message->plain); - if (prefs_get_boolean(PREF_BEEP)) { + if (prefs_get_boolean(PREF_BEEP) && !message->is_mam) { beep(); } -- cgit 1.4.1-2-gfad0