diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index bd1b0a6c..cfb78cd4 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -8703,6 +8703,18 @@ cmd_correct(ProfWin *window, const char *const command, gchar **args) // send message again, with replace flag cl_ev_send_msg_correct(chatwin, args[0], FALSE, TRUE); return TRUE; + } else if (window->type == WIN_MUC) { + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); + + if (mucwin->last_msg_id == NULL || mucwin->last_message == NULL) { + win_println(window, THEME_DEFAULT, '!', "No last message to correct."); + return TRUE; + } + + // send message again, with replace flag + cl_ev_send_muc_msg_corrected(mucwin, args[0], FALSE, TRUE); + return TRUE; } win_println(window, THEME_DEFAULT, '!', "Command /correct only valid in regular chat windows."); diff --git a/src/event/client_events.c b/src/event/client_events.c index d3f63455..0f50594f 100644 --- a/src/event/client_events.c +++ b/src/event/client_events.c @@ -344,24 +344,28 @@ cl_ev_send_msg(ProfChatWin *chatwin, const char *const msg, const char *const oo } void -cl_ev_send_muc_msg(ProfMucWin *mucwin, const char *const msg, const char *const oob_url) +cl_ev_send_muc_msg_corrected(ProfMucWin *mucwin, const char *const msg, const char *const oob_url, gboolean correct_last_msg) { char *plugin_msg = plugins_pre_room_message_send(mucwin->roomjid, msg); if (plugin_msg == NULL) { return; } + char *replace_id = NULL; + if (correct_last_msg) { + replace_id = mucwin->last_msg_id; + } + #ifdef HAVE_OMEMO if (mucwin->is_omemo) { - // TODO: replace_id for MUC - char *id = omemo_on_message_send((ProfWin *)mucwin, plugin_msg, FALSE, TRUE, NULL); + char *id = omemo_on_message_send((ProfWin *)mucwin, plugin_msg, FALSE, TRUE, replace_id); groupchat_log_omemo_msg_out(mucwin->roomjid, plugin_msg); - mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_OMEMO); + mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_OMEMO, replace_id); free(id); } else { - char *id = message_send_groupchat(mucwin->roomjid, plugin_msg, oob_url); + char *id = message_send_groupchat(mucwin->roomjid, plugin_msg, oob_url, replace_id); groupchat_log_msg_out(mucwin->roomjid, plugin_msg); - mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_PLAIN); + mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_PLAIN, replace_id); free(id); } @@ -371,9 +375,9 @@ cl_ev_send_muc_msg(ProfMucWin *mucwin, const char *const msg, const char *const #endif #ifndef HAVE_OMEMO - char *id = message_send_groupchat(mucwin->roomjid, plugin_msg, oob_url); + char *id = message_send_groupchat(mucwin->roomjid, plugin_msg, oob_url, replace_id); groupchat_log_msg_out(mucwin->roomjid, plugin_msg); - mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_PLAIN); + mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_PLAIN, replace_out); free(id); plugins_post_room_message_send(mucwin->roomjid, plugin_msg); @@ -382,6 +386,12 @@ cl_ev_send_muc_msg(ProfMucWin *mucwin, const char *const msg, const char *const #endif } +void +cl_ev_send_muc_msg(ProfMucWin *mucwin, const char *const msg, const char *const oob_url) +{ + cl_ev_send_muc_msg_corrected(mucwin, msg, oob_url, FALSE); +} + void cl_ev_send_priv_msg(ProfPrivateWin *privwin, const char *const msg, const char *const oob_url) { diff --git a/src/event/client_events.h b/src/event/client_events.h index 66ade679..87276331 100644 --- a/src/event/client_events.h +++ b/src/event/client_events.h @@ -47,6 +47,7 @@ void cl_ev_presence_send(const resource_presence_t presence_type, const int idle void cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char *const oob_url, gboolean correct_last_msg); void cl_ev_send_msg(ProfChatWin *chatwin, const char *const msg, const char *const oob_url); +void cl_ev_send_muc_msg_corrected(ProfMucWin *mucwin, const char *const msg, const char *const oob_url, gboolean correct_last_msg); void cl_ev_send_muc_msg(ProfMucWin *mucwin, const char *const msg, const char *const oob_url); void cl_ev_send_priv_msg(ProfPrivateWin *privwin, const char *const msg, const char *const oob_url); diff --git a/src/ui/mucwin.c b/src/ui/mucwin.c index b501af76..dddcb825 100644 --- a/src/ui/mucwin.c +++ b/src/ui/mucwin.c @@ -50,6 +50,8 @@ #include "omemo/omemo.h" #endif +static void _mucwin_set_last_message(ProfMucWin *mucwin, const char *const id, const char *const message); + ProfMucWin* mucwin_new(const char *const barejid) { @@ -501,7 +503,7 @@ _mucwin_print_triggers(ProfWin *window, const char *const message, GList *trigge } void -mucwin_outgoing_msg(ProfMucWin *mucwin, const char *const message, const char *const id, prof_enc_t enc_mode) +mucwin_outgoing_msg(ProfMucWin *mucwin, const char *const message, const char *const id, prof_enc_t enc_mode, const char *const replace_id) { assert(mucwin != NULL); @@ -519,7 +521,12 @@ mucwin_outgoing_msg(ProfMucWin *mucwin, const char *const message, const char *c ch = prefs_get_omemo_char(); } - win_println_me_message(window, ch, mynick, "%s", message); + win_print_outgoing_muc_msg(window, ch, mynick, id, replace_id, "%s", message); + + // save last id and message for LMC + if (id) { + _mucwin_set_last_message(mucwin, id, message); + } } void @@ -951,3 +958,13 @@ mucwin_unset_message_char(ProfMucWin *mucwin) mucwin->message_char = NULL; } } + +static void +_mucwin_set_last_message(ProfMucWin *mucwin, const char *const id, const char *const message) +{ + free(mucwin->last_message); + mucwin->last_message = strdup(message); + + free(mucwin->last_msg_id); + mucwin->last_msg_id = strdup(id); +} diff --git a/src/ui/ui.h b/src/ui/ui.h index c1c2b6cf..addb50b2 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -158,7 +158,7 @@ void mucwin_occupant_role_and_affiliation_change(ProfMucWin *mucwin, const char const char *const role, const char *const affiliation, const char *const actor, const char *const reason); void mucwin_roster(ProfMucWin *mucwin, GList *occupants, const char *const presence); void mucwin_history(ProfMucWin *mucwin, const char *const nick, GDateTime *timestamp, const char *const message); -void mucwin_outgoing_msg(ProfMucWin *mucwin, const char *const message, const char *const id, prof_enc_t enc_mode); +void mucwin_outgoing_msg(ProfMucWin *mucwin, const char *const message, const char *const id, prof_enc_t enc_mode, const char *const replace_id); void mucwin_incoming_msg(ProfMucWin *mucwin, ProfMessage *message, GSList *mentions, GList *triggers); void mucwin_subject(ProfMucWin *mucwin, const char *const nick, const char *const subject); void mucwin_requires_config(ProfMucWin *mucwin); diff --git a/src/ui/win_types.h b/src/ui/win_types.h index 0a0545bd..81944bc0 100644 --- a/src/ui/win_types.h +++ b/src/ui/win_types.h @@ -178,6 +178,9 @@ typedef struct prof_muc_win_t { char *enctext; char *message_char; GDateTime *last_msg_timestamp; + // For LMC + char *last_message; + char *last_msg_id; } ProfMucWin; typedef struct prof_conf_win_t ProfConfWin; diff --git a/src/ui/window.c b/src/ui/window.c index 0e7dbded..8181d473 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -203,6 +203,8 @@ win_create_muc(const char *const roomjid) new_win->enctext = NULL; new_win->message_char = NULL; new_win->is_omemo = FALSE; + new_win->last_message = NULL; + new_win->last_msg_id = NULL; new_win->memcheck = PROFMUCWIN_MEMCHECK; @@ -1169,7 +1171,7 @@ win_println_them_message(ProfWin *window, char ch, int flags, const char *const } void -win_println_me_message(ProfWin *window, char ch, const char *const me, const char *const message, ...) +win_print_outgoing_muc_msg(ProfWin *window, char ch, const char *const me, const char *const id, const char *const replace_id, const char *const message, ...) { GDateTime *timestamp = g_date_time_new_now_local(); @@ -1178,8 +1180,13 @@ win_println_me_message(ProfWin *window, char ch, const char *const me, const cha GString *fmt_msg = g_string_new(NULL); g_string_vprintf(fmt_msg, message, arg); - buffer_append(window->layout->buffer, ch, 0, timestamp, 0, THEME_TEXT_ME, me, fmt_msg->str, NULL, NULL); - _win_print_internal(window, ch, 0, timestamp, 0, THEME_TEXT_ME, me, fmt_msg->str, NULL); + if (replace_id) { + _win_correct(window, fmt_msg->str, id, replace_id); + } else { + _win_printf(window, ch, 0, timestamp, 0, THEME_TEXT_ME, me, id, "%s", fmt_msg->str); + } +// buffer_append(window->layout->buffer, ch, 0, timestamp, 0, THEME_TEXT_ME, me, fmt_msg->str, NULL, NULL); +// _win_print_internal(window, ch, 0, timestamp, 0, THEME_TEXT_ME, me, 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 8db2c2a7..66c6e5ff 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -63,7 +63,7 @@ void win_show_status_string(ProfWin *window, const char *const from, void win_print_them(ProfWin *window, theme_item_t theme_item, char ch, int flags, const char *const them); void win_println_them_message(ProfWin *window, char ch, int flags, const char *const them, const char *const id, const char *const replace_id, const char *const message, ...); -void win_println_me_message(ProfWin *window, char ch, const char *const me, const char *const message, ...); +void win_print_outgoing_muc_msg(ProfWin *window, char ch, const char *const me, const char *const id, const char *const replace_id, const char *const message, ...); void win_print_outgoing(ProfWin *window, const char ch, const char *const id, const char *const replace_id, const char *const message, ...); void win_print_incoming(ProfWin *window, const char *const from, ProfMessage *message); diff --git a/src/xmpp/message.c b/src/xmpp/message.c index fe4c6de0..a3f37baf 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -528,7 +528,7 @@ message_send_private(const char *const fulljid, const char *const msg, const cha } char* -message_send_groupchat(const char *const roomjid, const char *const msg, const char *const oob_url) +message_send_groupchat(const char *const roomjid, const char *const msg, const char *const oob_url, const char *const replace_id) { xmpp_ctx_t * const ctx = connection_get_ctx(); char *id = connection_create_stanza_id(); @@ -541,6 +541,10 @@ message_send_groupchat(const char *const roomjid, const char *const msg, const c stanza_attach_x_oob_url(ctx, message, oob_url); } + if (replace_id) { + stanza_attach_correction(ctx, message, replace_id); + } + _send_message_stanza(message); xmpp_stanza_release(message); diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index cb94b348..0563948a 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -176,7 +176,7 @@ char* message_send_chat_otr(const char *const barejid, const char *const msg, gb char* message_send_chat_pgp(const char *const barejid, const char *const msg, gboolean request_receipt, const char *const replace_id); char* message_send_chat_omemo(const char *const jid, uint32_t sid, GList *keys, const unsigned char *const iv, size_t iv_len, const unsigned char *const ciphertext, size_t ciphertext_len, gboolean request_receipt, gboolean muc, const char *const replace_id); void message_send_private(const char *const fulljid, const char *const msg, const char *const oob_url); -char* message_send_groupchat(const char *const roomjid, const char *const msg, const char *const oob_url); +char* message_send_groupchat(const char *const roomjid, const char *const msg, const char *const oob_url, const char *const replace_id); void message_send_groupchat_subject(const char *const roomjid, const char *const subject); void message_send_inactive(const char *const jid); void message_send_composing(const char *const jid);