Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MUC MAM #1862

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft

MUC MAM #1862

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 36 additions & 7 deletions src/database.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,9 @@ log_database_add_outgoing_muc_pm(const char* const id, const char* const barejid
_log_database_add_outgoing("mucpm", id, barejid, message, replace_id, enc);
}

// Get info (timestamp and stanza_id) of the first or last message in db
// Get info (timestamp and stanza_id) of the first or last message in db after or before from_timestamp
ProfMessage*
log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_last)
log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_last, char* from_timestamp)
{
sqlite3_stmt* stmt = NULL;
gchar* query;
Expand All @@ -212,10 +212,10 @@ log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_las
if (!myjid)
return NULL;

if (is_last) {
query = sqlite3_mprintf("SELECT * FROM (SELECT `archive_id`, `timestamp` from `ChatLogs` WHERE (`from_jid` = '%q' AND `to_jid` = '%q') OR (`from_jid` = '%q' AND `to_jid` = '%q') ORDER BY `timestamp` DESC LIMIT 1) ORDER BY `timestamp` ASC;", contact_barejid, myjid->barejid, myjid->barejid, contact_barejid);
if (from_timestamp) {
query = sqlite3_mprintf("SELECT * FROM (SELECT `archive_id`, `timestamp` from `ChatLogs` WHERE ((`from_jid` = '%q' AND `to_jid` = '%q') OR (`from_jid` = '%q' AND `to_jid` = '%q')) AND `timestamp` %c '%q' ORDER BY `timestamp` %s LIMIT 1) ORDER BY `timestamp` ASC;", contact_barejid, myjid->barejid, myjid->barejid, contact_barejid, is_last ? '<' : '>', from_timestamp, is_last ? "DESC" : "ASC");
} else {
query = sqlite3_mprintf("SELECT * FROM (SELECT `archive_id`, `timestamp` from `ChatLogs` WHERE (`from_jid` = '%q' AND `to_jid` = '%q') OR (`from_jid` = '%q' AND `to_jid` = '%q') ORDER BY `timestamp` ASC LIMIT 1) ORDER BY `timestamp` ASC;", contact_barejid, myjid->barejid, myjid->barejid, contact_barejid);
query = sqlite3_mprintf("SELECT * FROM (SELECT `archive_id`, `timestamp` from `ChatLogs` WHERE (`from_jid` = '%q' AND `to_jid` = '%q') OR (`from_jid` = '%q' AND `to_jid` = '%q') ORDER BY `timestamp` %s LIMIT 1) ORDER BY `timestamp` ASC;", contact_barejid, myjid->barejid, myjid->barejid, contact_barejid, is_last ? "DESC" : "ASC");
}

if (!query) {
Expand Down Expand Up @@ -250,7 +250,7 @@ log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_las
// 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, const char* start_time, char* end_time, gboolean from_start, gboolean flip)
log_database_get_previous_chat(const gchar* const contact_barejid, const char* start_time, char* end_time, gboolean from_start, gboolean flip, gboolean limit_results)
{
sqlite3_stmt* stmt = NULL;
const char* jid = connection_get_fulljid();
Expand All @@ -263,7 +263,36 @@ log_database_get_previous_chat(const gchar* const contact_barejid, const char* s
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);
auto_sqlite gchar* query = sqlite3_mprintf("SELECT * FROM (SELECT COALESCE(B.`message`, A.`message`) AS message, A.`timestamp`, A.`from_jid`, A.`type`, A.`encryption` from `ChatLogs` AS A LEFT JOIN `ChatLogs` AS B ON A.`stanza_id` = B.`replace_id` WHERE A.`replace_id` = '' AND ((A.`from_jid` = '%q' AND A.`to_jid` = '%q') OR (A.`from_jid` = '%q' AND A.`to_jid` = '%q')) AND A.`timestamp` < '%q' AND (%Q IS NULL OR A.`timestamp` > %Q) ORDER BY A.`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);
auto_sqlite gchar* query;

if (limit_results) {
query = sqlite3_mprintf(
"SELECT * FROM (SELECT COALESCE(B.`message`, A.`message`) AS message, A.`timestamp`, A.`from_jid`, A.`type`, A.`encryption` from `ChatLogs` AS A LEFT JOIN `ChatLogs` AS B ON A.`stanza_id` = B.`replace_id` WHERE A.`replace_id` = '' AND ((A.`from_jid` = '%q' AND A.`to_jid` = '%q') OR (A.`from_jid` = '%q' AND A.`to_jid` = '%q')) AND A.`timestamp` < '%q' AND (%Q IS NULL OR A.`timestamp` > %Q) ORDER BY A.`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
);
} else {
query = sqlite3_mprintf(
"SELECT * FROM (SELECT COALESCE(B.`message`, A.`message`) AS message, A.`timestamp`, A.`from_jid`, A.`type`, A.`encryption` from `ChatLogs` AS A LEFT JOIN `ChatLogs` AS B ON A.`stanza_id` = B.`replace_id` WHERE A.`replace_id` = '' AND ((A.`from_jid` = '%q' AND A.`to_jid` = '%q') OR (A.`from_jid` = '%q' AND A.`to_jid` = '%q')) AND A.`timestamp` < '%q' AND (%Q IS NULL OR A.`timestamp` > %Q) ORDER BY A.`timestamp`) ORDER BY `timestamp` %s;",
contact_barejid,
myjid->barejid,
myjid->barejid,
contact_barejid,
end_date_fmt,
start_time,
start_time,
sort1,
sort2
);
}

g_date_time_unref(now);
g_free(end_date_fmt);
Expand Down
4 changes: 2 additions & 2 deletions src/database.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ 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, const 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);
GSList* log_database_get_previous_chat(const gchar* const contact_barejid, const char* start_time, char* end_time, gboolean from_start, gboolean flip, gboolean limit_results);
ProfMessage* log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_last, char* from_timestamp);
void log_database_close(void);

#endif // DATABASE_H
1 change: 1 addition & 0 deletions src/event/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ ev_disconnect_cleanup(void)
ui_disconnected();
session_disconnect();
roster_destroy();
iq_disco_items_on_disconnect();
iq_autoping_timer_cancel();
muc_invites_clear();
muc_confserver_clear();
Expand Down
38 changes: 18 additions & 20 deletions src/event/server_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,21 @@ sv_ev_room_subject(const char* const room, const char* const nick, const char* c
}
}

static void
_log_muc(ProfMessage* message)
{
if (message->enc == PROF_MSG_ENC_OMEMO) {
groupchat_log_omemo_msg_in(message->from_jid->barejid, message->from_jid->resourcepart, message->plain);
} else {
groupchat_log_msg_in(message->from_jid->barejid, message->from_jid->resourcepart, message->plain);
}
log_database_add_incoming(message);
}

void
sv_ev_room_history(ProfMessage* message)
{
_log_muc(message);
if (prefs_get_boolean(PREF_NOTIFY_ROOM_OFFLINE)) {
// check if this message was sent while we were offline.
// if so, treat it as a new message rather than a history event.
Expand Down Expand Up @@ -314,25 +326,9 @@ sv_ev_room_history(ProfMessage* message)
}
mucwin->last_msg_timestamp = g_date_time_new_now_local();
}

gboolean younger = g_date_time_compare(mucwin->last_msg_timestamp, message->timestamp) < 0 ? TRUE : FALSE;
if (ev_is_first_connect() || younger) {
mucwin_history(mucwin, message);
}
}
}

static void
_log_muc(ProfMessage* message)
{
if (message->enc == PROF_MSG_ENC_OMEMO) {
groupchat_log_omemo_msg_in(message->from_jid->barejid, message->from_jid->resourcepart, message->plain);
} else {
groupchat_log_msg_in(message->from_jid->barejid, message->from_jid->resourcepart, message->plain);
}
log_database_add_incoming(message);
}

void
sv_ev_room_message(ProfMessage* message)
{
Expand All @@ -357,7 +353,9 @@ sv_ev_room_message(ProfMessage* message)
GList* triggers = prefs_message_get_triggers(message->plain);

_clean_incoming_message(message);
mucwin_incoming_msg(mucwin, message, mentions, triggers, TRUE);
if (!message->is_mam) {
mucwin_incoming_msg(mucwin, message, mentions, triggers, TRUE, FALSE);
}

g_slist_free(mentions);

Expand All @@ -375,7 +373,7 @@ sv_ev_room_message(ProfMessage* message)
}

// not currently on groupchat window
} else {
} else if (!message->is_mam) {
status_bar_new(num, WIN_MUC, mucwin->roomjid);

if ((g_strcmp0(mynick, message->from_jid->resourcepart) != 0) && (prefs_get_boolean(PREF_FLASH))) {
Expand All @@ -400,7 +398,7 @@ sv_ev_room_message(ProfMessage* message)
}
mucwin->last_msg_timestamp = g_date_time_new_now_local();

if (prefs_do_room_notify(is_current, mucwin->roomjid, mynick, message->from_jid->resourcepart, message->plain, mention, triggers != NULL)) {
if (prefs_do_room_notify(is_current, mucwin->roomjid, mynick, message->from_jid->resourcepart, message->plain, mention, triggers != NULL) && !message->is_mam) {
Jid* jidp = jid_create(mucwin->roomjid);
if (jidp) {
notify_room_message(message->from_jid->resourcepart, jidp->localpart, num, message->plain);
Expand Down Expand Up @@ -652,7 +650,7 @@ sv_ev_incoming_message(ProfMessage* message)

if (prefs_get_boolean(PREF_MAM)) {
win_print_loading_history(window);
iq_mam_request(chatwin, g_date_time_add_seconds(message->timestamp, 0)); // copy timestamp
iq_mam_request(window, g_date_time_add_seconds(message->timestamp, 0), FALSE); // copy timestamp
}

#ifdef HAVE_OMEMO
Expand Down
8 changes: 4 additions & 4 deletions src/ui/chatwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ chatwin_new(const char* const barejid)
}

if (prefs_get_boolean(PREF_MAM)) {
iq_mam_request(chatwin, NULL);
iq_mam_request(window, NULL, FALSE);
win_print_loading_history(window);
}

Expand Down Expand Up @@ -575,7 +575,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, FALSE);
GSList* history = log_database_get_previous_chat(contact_barejid, NULL, NULL, FALSE, FALSE, TRUE);
GSList* curr = history;

while (curr) {
Expand All @@ -598,13 +598,13 @@ _chatwin_history(ProfChatWin* chatwin, const char* const contact_barejid)
// 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, const char* start_time, char* end_time, gboolean flip)
chatwin_db_history(ProfChatWin* chatwin, const char* start_time, char* end_time, gboolean flip, gboolean limit_results)
{
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, flip);
GSList* history = log_database_get_previous_chat(chatwin->barejid, start_time, end_time, !flip, flip, limit_results);
gboolean has_items = g_slist_length(history) != 0;
GSList* curr = history;

Expand Down
2 changes: 2 additions & 0 deletions src/ui/inputwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
*
*/

#include "xmpp/session.h"
#define _XOPEN_SOURCE_EXTENDED
#include "config.h"

Expand Down Expand Up @@ -913,6 +914,7 @@ _inp_rl_win_pageup_handler(int count, int key)
static int
_inp_rl_win_pagedown_handler(int count, int key)
{
session_lost_connection();
ProfWin* current = wins_get_current();
win_page_down(current);
return 0;
Expand Down
Loading