mirror of
https://github.com/profanity-im/profanity.git
synced 2024-12-04 14:46:46 -05:00
Handle late delivery
This commit is contained in:
parent
4b9ff6d4dc
commit
a704838152
@ -640,8 +640,8 @@ sv_ev_incoming_message(ProfMessage* message)
|
|||||||
new_win = TRUE;
|
new_win = TRUE;
|
||||||
|
|
||||||
if (prefs_get_boolean(PREF_MAM)) {
|
if (prefs_get_boolean(PREF_MAM)) {
|
||||||
iq_mam_request(chatwin);
|
|
||||||
win_print_loading_history(window);
|
win_print_loading_history(window);
|
||||||
|
iq_mam_request(chatwin, g_date_time_add_seconds(message->timestamp, 0)); // copy timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_OMEMO
|
#ifdef HAVE_OMEMO
|
||||||
|
@ -98,7 +98,7 @@ chatwin_new(const char* const barejid)
|
|||||||
#endif // HAVE_OMEMO
|
#endif // HAVE_OMEMO
|
||||||
|
|
||||||
if (prefs_get_boolean(PREF_MAM)) {
|
if (prefs_get_boolean(PREF_MAM)) {
|
||||||
iq_mam_request(chatwin);
|
iq_mam_request(chatwin, NULL);
|
||||||
win_print_loading_history(window);
|
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);
|
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);
|
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
|
// 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
|
gboolean
|
||||||
chatwin_db_history(ProfChatWin* chatwin, char* start_time, char* end_time, gboolean flip)
|
chatwin_db_history(ProfChatWin* chatwin, char* start_time, char* end_time, gboolean flip)
|
||||||
{
|
{
|
||||||
|
@ -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();
|
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);
|
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);
|
win_redraw(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
119
src/xmpp/iq.c
119
src/xmpp/iq.c
@ -109,9 +109,17 @@ typedef struct mam_rsm_userdata
|
|||||||
char* barejid;
|
char* barejid;
|
||||||
char* start_datestr;
|
char* start_datestr;
|
||||||
char* end_datestr;
|
char* end_datestr;
|
||||||
|
gboolean fetch_next;
|
||||||
ProfChatWin* win;
|
ProfChatWin* win;
|
||||||
} MamRsmUserdata;
|
} 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 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);
|
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 _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 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_room_data(ProfRoomInfoData* roominfo);
|
||||||
static void _iq_free_affiliation_set(ProfPrivilegeSet* affiliation_set);
|
static void _iq_free_affiliation_set(ProfPrivilegeSet* affiliation_set);
|
||||||
static void _iq_free_affiliation_list(ProfAffiliationList* affiliation_list);
|
static void _iq_free_affiliation_list(ProfAffiliationList* affiliation_list);
|
||||||
@ -164,6 +173,8 @@ static gboolean autoping_wait = FALSE;
|
|||||||
static GTimer* autoping_time = NULL;
|
static GTimer* autoping_time = NULL;
|
||||||
static GHashTable* id_handlers;
|
static GHashTable* id_handlers;
|
||||||
static GHashTable* rooms_cache = NULL;
|
static GHashTable* rooms_cache = NULL;
|
||||||
|
static GSList* late_delivery_windows = NULL;
|
||||||
|
static gboolean received_disco_items = FALSE;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_iq_handler(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* const userdata)
|
_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);
|
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);
|
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
|
void
|
||||||
@ -2525,7 +2538,16 @@ _disco_items_result_handler(xmpp_stanza_t* const stanza)
|
|||||||
if (g_strcmp0(id, "discoitemsreq") == 0) {
|
if (g_strcmp0(id, "discoitemsreq") == 0) {
|
||||||
cons_show_disco_items(items, from);
|
cons_show_disco_items(items, from);
|
||||||
} else if (g_strcmp0(id, "discoitemsreq_onconnect") == 0) {
|
} else if (g_strcmp0(id, "discoitemsreq_onconnect") == 0) {
|
||||||
|
received_disco_items = TRUE;
|
||||||
connection_set_disco_items(items);
|
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);
|
g_slist_free_full(items, (GDestroyNotify)_item_destroy);
|
||||||
@ -2622,7 +2644,7 @@ iq_mam_request_older(ProfChatWin* win)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
iq_mam_request(ProfChatWin* win)
|
_iq_mam_request(ProfChatWin* win, GDateTime* startdate, GDateTime* enddate)
|
||||||
{
|
{
|
||||||
if (connection_supports(XMPP_FEATURE_MAM2) == FALSE) {
|
if (connection_supports(XMPP_FEATURE_MAM2) == FALSE) {
|
||||||
log_warning("Server doesn't advertise %s feature.", XMPP_FEATURE_MAM2);
|
log_warning("Server doesn't advertise %s feature.", XMPP_FEATURE_MAM2);
|
||||||
@ -2630,43 +2652,72 @@ iq_mam_request(ProfChatWin* win)
|
|||||||
return;
|
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* firstid = "";
|
||||||
char* startdate = NULL;
|
char* startdate_str = NULL;
|
||||||
char* enddate = NULL;
|
char* enddate_str = NULL;
|
||||||
|
gboolean fetch_next = FALSE;
|
||||||
|
|
||||||
// If last message found
|
if (startdate) {
|
||||||
if (last_msg->timestamp) {
|
startdate_str = g_date_time_format(startdate, "%FT%T.%f%:z");
|
||||||
startdate = g_date_time_format(last_msg->timestamp, "%FT%T.%f%:z");
|
fetch_next = TRUE;
|
||||||
} else {
|
g_date_time_unref(startdate);
|
||||||
|
} else if (!enddate) {
|
||||||
GDateTime* now = g_date_time_new_now_utc();
|
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);
|
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_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));
|
MamRsmUserdata* data = malloc(sizeof(MamRsmUserdata));
|
||||||
if (data) {
|
if (data) {
|
||||||
data->start_datestr = startdate;
|
data->start_datestr = startdate_str;
|
||||||
data->end_datestr = enddate;
|
data->end_datestr = enddate_str;
|
||||||
data->barejid = strdup(win->barejid);
|
data->barejid = strdup(win->barejid);
|
||||||
|
data->fetch_next = fetch_next;
|
||||||
data->win = win;
|
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);
|
|
||||||
|
|
||||||
iq_send_stanza(iq);
|
iq_send_stanza(iq);
|
||||||
xmpp_stanza_release(iq);
|
xmpp_stanza_release(iq);
|
||||||
|
|
||||||
return;
|
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
|
static int
|
||||||
_mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata)
|
_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;
|
ProfWin* window = (ProfWin*)data->win;
|
||||||
|
|
||||||
buffer_remove_entry(window->layout->buffer, 0);
|
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;
|
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);
|
xmpp_stanza_t* set = xmpp_stanza_get_child_by_name_and_ns(fin, STANZA_TYPE_SET, STANZA_NS_RSM);
|
||||||
if (set) {
|
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
|
// 4.3.2. send same stanza with set,max stanza
|
||||||
xmpp_ctx_t* const ctx = connection_get_ctx();
|
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);
|
xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, data->barejid, data->start_datestr, data->end_datestr, firstid, NULL);
|
||||||
free(firstid);
|
free(firstid);
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ void iq_autoping_check(void);
|
|||||||
void iq_http_upload_request(HTTPUpload* upload);
|
void iq_http_upload_request(HTTPUpload* upload);
|
||||||
void iq_command_list(const char* const target);
|
void iq_command_list(const char* const target);
|
||||||
void iq_command_exec(const char* const target, const char* const command);
|
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_mam_request_older(ProfChatWin* win);
|
||||||
void iq_register_change_password(const char* const user, const char* const password);
|
void iq_register_change_password(const char* const user, const char* const password);
|
||||||
void iq_muc_register_nick(const char* const roomjid);
|
void iq_muc_register_nick(const char* const roomjid);
|
||||||
|
Loading…
Reference in New Issue
Block a user