mirror of
https://github.com/profanity-im/profanity.git
synced 2024-11-03 19:37:16 -05:00
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.
This commit is contained in:
parent
e9da694265
commit
6429698f18
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user