diff options
9 files changed, 84 insertions, 21 deletions
diff --git a/libdino/src/service/message_correction.vala b/libdino/src/service/message_correction.vala index 320c0b7e..90d0580f 100644 --- a/libdino/src/service/message_correction.vala +++ b/libdino/src/service/message_correction.vala @@ -91,6 +91,12 @@ public class MessageCorrection : StreamInteractionModule, MessageListener { public override string[] after_actions { get { return after_actions_const; } } public override async bool run(Entities.Message message, Xmpp.MessageStanza stanza, Conversation conversation) { + if (conversation.type_ != Conversation.Type.CHAT) { + // Don't process messages or corrections from MUC history + DateTime? mam_delay = Xep.DelayedDelivery.get_time_for_message(stanza, message.from.bare_jid); + if (mam_delay != null) return false; + } + string? replace_id = Xep.LastMessageCorrection.get_replace_id(stanza); if (replace_id == null) { if (!last_messages.has_key(conversation)) { @@ -126,9 +132,11 @@ public class MessageCorrection : StreamInteractionModule, MessageListener { message.edit_to = replace_id; on_received_correction(conversation, current_correction_message_id); + + return true; } - return true; + return false; } private void on_received_correction(Conversation conversation, int message_id) { diff --git a/libdino/src/service/message_processor.vala b/libdino/src/service/message_processor.vala index 0120fcd4..6bc4fc9e 100644 --- a/libdino/src/service/message_processor.vala +++ b/libdino/src/service/message_processor.vala @@ -122,7 +122,7 @@ public class MessageProcessor : StreamInteractionModule, Object { if (id == null) return; StanzaNode? delay_node = message.stanza.get_deep_subnode(mam_flag.ns_ver + ":result", "urn:xmpp:forward:0:forwarded", "urn:xmpp:delay:delay"); if (delay_node == null) return; - DateTime? time = DelayedDelivery.Module.get_time_for_node(delay_node); + DateTime? time = DelayedDelivery.get_time_for_node(delay_node); if (time == null) return; mam_times[account][id] = time; diff --git a/main/data/message_item_widget_edit_mode.ui b/main/data/message_item_widget_edit_mode.ui index 8a4faca2..b33d8aa3 100644 --- a/main/data/message_item_widget_edit_mode.ui +++ b/main/data/message_item_widget_edit_mode.ui @@ -51,13 +51,13 @@ <property name="visible">True</property> <child> <object class="GtkButton" id="cancel_button"> - <property name="label">Cancel</property> + <property name="label" translatable="yes">Cancel</property> <property name="visible">True</property> </object> </child> <child> <object class="GtkButton" id="send_button"> - <property name="label">Update message</property> + <property name="label" translatable="yes">Update message</property> <property name="visible">True</property> <style> <class name="suggested-action"/> diff --git a/main/src/ui/chat_input/chat_input_controller.vala b/main/src/ui/chat_input/chat_input_controller.vala index c0878c36..4844ff6c 100644 --- a/main/src/ui/chat_input/chat_input_controller.vala +++ b/main/src/ui/chat_input/chat_input_controller.vala @@ -8,6 +8,8 @@ namespace Dino.Ui { public class ChatInputController : Object { + public signal void activate_last_message_correction(); + public new string? conversation_display_name { get; set; } public string? conversation_topic { get; set; } @@ -30,6 +32,7 @@ public class ChatInputController : Object { reset_input_field_status(); chat_input.chat_text_view.text_view.buffer.changed.connect(on_text_input_changed); + chat_input.chat_text_view.text_view.key_press_event.connect(on_text_input_key_press); chat_text_view_controller.send_text.connect(send_text); chat_input.encryption_widget.encryption_changed.connect(on_encryption_changed); @@ -145,6 +148,16 @@ public class ChatInputController : Object { stream_interactor.get_module(ChatInteraction.IDENTITY).on_message_cleared(conversation); } } + + private bool on_text_input_key_press(EventKey event) { + if (event.keyval == Gdk.Key.Up && chat_input.chat_text_view.text_view.buffer.text == "") { + activate_last_message_correction(); + return true; + } else { + chat_input.chat_text_view.text_view.grab_focus(); + } + return false; + } } } diff --git a/main/src/ui/conversation_content_view/conversation_view.vala b/main/src/ui/conversation_content_view/conversation_view.vala index 808c6cad..aadb5fdc 100644 --- a/main/src/ui/conversation_content_view/conversation_view.vala +++ b/main/src/ui/conversation_content_view/conversation_view.vala @@ -76,6 +76,24 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins return this; } + public void activate_last_message_correction() { + Gee.BidirIterator<Plugins.MetaConversationItem> iter = content_items.bidir_iterator(); + iter.last(); + for (int i = 0; i < 10 && content_items.size > i; i++) { + Plugins.MetaConversationItem item = iter.get(); + MessageMetaItem message_item = item as MessageMetaItem; + if (message_item != null) { + if ((conversation.type_ == Conversation.Type.CHAT && message_item.jid.equals_bare(conversation.account.bare_jid)) || + (conversation.type_ == Conversation.Type.GROUPCHAT && + message_item.jid.equals(stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(conversation.counterpart, conversation.account)))) { + message_item.in_edit_mode = true; + break; + } + } + iter.previous(); + } + } + private bool on_enter_notify_event(Gdk.EventCrossing event) { mouse_inside = true; update_highlight((int)event.x_root, (int)event.y_root); diff --git a/main/src/ui/conversation_content_view/message_widget.vala b/main/src/ui/conversation_content_view/message_widget.vala index 71094c71..aefab6e1 100644 --- a/main/src/ui/conversation_content_view/message_widget.vala +++ b/main/src/ui/conversation_content_view/message_widget.vala @@ -28,6 +28,16 @@ public class MessageMetaItem : ContentMetaItem { stream_interactor.get_module(MessageCorrection.IDENTITY).received_correction.connect(on_received_correction); + this.notify["in-edit-mode"].connect(() => { + if (in_edit_mode == false) return; + bool allowed = stream_interactor.get_module(MessageCorrection.IDENTITY).is_own_correction_allowed(message_item.conversation, message_item.message); + if (allowed) { + message_item_widget.set_edit_mode(); + } else { + this.in_edit_mode = false; + } + }); + return message_item_widget; } @@ -106,7 +116,11 @@ public class MessageItemWidget : SizeRequestBin { unset_edit_mode(); }); edit_mode.send.connect(() => { - edit_sent(edit_mode.chat_text_view.text_view.buffer.text); + if (((MessageItem) content_item).message.body != edit_mode.chat_text_view.text_view.buffer.text) { + edit_sent(edit_mode.chat_text_view.text_view.buffer.text); + } else { + edit_cancelled(); + } unset_edit_mode(); }); } @@ -122,6 +136,9 @@ public class MessageItemWidget : SizeRequestBin { public void unset_edit_mode() { this.remove(edit_mode); this.add(label); + label.grab_focus(); + label.selectable = false; + label.selectable = true; } public void update_label() { @@ -200,11 +217,16 @@ public class MessageItemEditMode : Box { }); emoji_button.set_popover(chooser); + chat_text_view.text_view.buffer.changed.connect_after(on_text_view_changed); + cancel_button.clicked.connect(() => cancelled()); send_button.clicked.connect(() => send()); chat_text_view.cancel_input.connect(() => cancelled()); chat_text_view.send_text.connect(() => send()); + } + private void on_text_view_changed() { + send_button.sensitive = chat_text_view.text_view.buffer.text != ""; } } diff --git a/main/src/ui/conversation_view_controller.vala b/main/src/ui/conversation_view_controller.vala index 2e03de8f..31c7e612 100644 --- a/main/src/ui/conversation_view_controller.vala +++ b/main/src/ui/conversation_view_controller.vala @@ -44,6 +44,7 @@ public class ConversationViewController : Object { view.drag_data_received.connect(this.on_drag_data_received); // forward key presses + chat_input_controller.activate_last_message_correction.connect(() => view.conversation_frame.activate_last_message_correction()); view.chat_input.key_press_event.connect(forward_key_press_to_chat_input); view.conversation_frame.key_press_event.connect(forward_key_press_to_chat_input); titlebar.key_press_event.connect(forward_key_press_to_chat_input); @@ -160,7 +161,6 @@ public class ConversationViewController : Object { return false; } if (view.chat_input.chat_text_view.text_view.key_press_event(event)) { - view.chat_input.chat_text_view.text_view.grab_focus(); return true; } return false; diff --git a/xmpp-vala/src/module/xep/0203_delayed_delivery.vala b/xmpp-vala/src/module/xep/0203_delayed_delivery.vala index 39666fa8..5105ac19 100644 --- a/xmpp-vala/src/module/xep/0203_delayed_delivery.vala +++ b/xmpp-vala/src/module/xep/0203_delayed_delivery.vala @@ -2,6 +2,21 @@ namespace Xmpp.Xep.DelayedDelivery { private const string NS_URI = "urn:xmpp:delay"; +public static DateTime? get_time_for_node(StanzaNode node) { + string? time = node.get_attribute("stamp"); + if (time != null) return DateTimeProfiles.parse_string(time); + return null; +} + +public static DateTime? get_time_for_message(MessageStanza message, Jid? jid = null) { + foreach (StanzaNode delay_node in message.stanza.get_subnodes("delay", NS_URI)) { + if (jid == null || delay_node.get_attribute("from") == jid.to_string()) { + return get_time_for_node(delay_node); + } + } + return null; +} + public class Module : XmppStreamModule { public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "0203_delayed_delivery"); @@ -13,19 +28,6 @@ public class Module : XmppStreamModule { message.stanza.put_node(delay_node); } - public static DateTime? get_time_for_message(MessageStanza message) { - StanzaNode? delay_node = message.stanza.get_subnode("delay", NS_URI); - if (delay_node != null) { - return get_time_for_node(delay_node); - } - return null; - } - - public static DateTime? get_time_for_node(StanzaNode node) { - string? time = node.get_attribute("stamp"); - if (time != null) return DateTimeProfiles.parse_string(time); - return null; - } public override void attach(XmppStream stream) { stream.get_module(MessageModule.IDENTITY).received_pipeline.connect(received_pipeline_listener); @@ -52,7 +54,7 @@ public class ReceivedPipelineListener : StanzaListener<MessageStanza> { public override string[] after_actions { get { return after_actions_const; } } public override async bool run(XmppStream stream, MessageStanza message) { - DateTime? datetime = Module.get_time_for_message(message); + DateTime? datetime = get_time_for_message(message); if (datetime != null) message.add_flag(new MessageFlag(datetime)); return false; } diff --git a/xmpp-vala/src/module/xep/0313_message_archive_management.vala b/xmpp-vala/src/module/xep/0313_message_archive_management.vala index 504996e6..78d0aaff 100644 --- a/xmpp-vala/src/module/xep/0313_message_archive_management.vala +++ b/xmpp-vala/src/module/xep/0313_message_archive_management.vala @@ -141,7 +141,7 @@ public class ReceivedPipelineListener : StanzaListener<MessageStanza> { } StanzaNode? forward_node = message.stanza.get_deep_subnode(NS_VER(stream) + ":result", "urn:xmpp:forward:0:forwarded", DelayedDelivery.NS_URI + ":delay"); - DateTime? datetime = DelayedDelivery.Module.get_time_for_node(forward_node); + DateTime? datetime = DelayedDelivery.get_time_for_node(forward_node); string? mam_id = message.stanza.get_deep_attribute(NS_VER(stream) + ":result", NS_VER(stream) + ":id"); string? query_id = message.stanza.get_deep_attribute(NS_VER(stream) + ":result", NS_VER(stream) + ":queryid"); message.add_flag(new MessageFlag(datetime, mam_id, query_id)); |