Add keyboard shortcut (up key) to activate last message correction
This commit is contained in:
parent
8f75954188
commit
d091a6c3cd
|
@ -91,6 +91,12 @@ public class MessageCorrection : StreamInteractionModule, MessageListener {
|
||||||
public override string[] after_actions { get { return after_actions_const; } }
|
public override string[] after_actions { get { return after_actions_const; } }
|
||||||
|
|
||||||
public override async bool run(Entities.Message message, Xmpp.MessageStanza stanza, Conversation conversation) {
|
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);
|
string? replace_id = Xep.LastMessageCorrection.get_replace_id(stanza);
|
||||||
if (replace_id == null) {
|
if (replace_id == null) {
|
||||||
if (!last_messages.has_key(conversation)) {
|
if (!last_messages.has_key(conversation)) {
|
||||||
|
@ -126,11 +132,13 @@ public class MessageCorrection : StreamInteractionModule, MessageListener {
|
||||||
message.edit_to = replace_id;
|
message.edit_to = replace_id;
|
||||||
|
|
||||||
on_received_correction(conversation, current_correction_message_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) {
|
private void on_received_correction(Conversation conversation, int message_id) {
|
||||||
ContentItem? content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_item(conversation, 1, message_id);
|
ContentItem? content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_item(conversation, 1, message_id);
|
||||||
received_correction(content_item);
|
received_correction(content_item);
|
||||||
|
|
|
@ -122,7 +122,7 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
||||||
if (id == null) return;
|
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");
|
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;
|
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;
|
if (time == null) return;
|
||||||
mam_times[account][id] = time;
|
mam_times[account][id] = time;
|
||||||
|
|
||||||
|
|
|
@ -51,13 +51,13 @@
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="cancel_button">
|
<object class="GtkButton" id="cancel_button">
|
||||||
<property name="label">Cancel</property>
|
<property name="label" translatable="yes">Cancel</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="send_button">
|
<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>
|
<property name="visible">True</property>
|
||||||
<style>
|
<style>
|
||||||
<class name="suggested-action"/>
|
<class name="suggested-action"/>
|
||||||
|
|
|
@ -8,6 +8,8 @@ namespace Dino.Ui {
|
||||||
|
|
||||||
public class ChatInputController : Object {
|
public class ChatInputController : Object {
|
||||||
|
|
||||||
|
public signal void activate_last_message_correction();
|
||||||
|
|
||||||
public new string? conversation_display_name { get; set; }
|
public new string? conversation_display_name { get; set; }
|
||||||
public string? conversation_topic { get; set; }
|
public string? conversation_topic { get; set; }
|
||||||
|
|
||||||
|
@ -30,6 +32,7 @@ public class ChatInputController : Object {
|
||||||
reset_input_field_status();
|
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.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_text_view_controller.send_text.connect(send_text);
|
||||||
|
|
||||||
chat_input.encryption_widget.encryption_changed.connect(on_encryption_changed);
|
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);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,24 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins
|
||||||
return this;
|
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) {
|
private bool on_enter_notify_event(Gdk.EventCrossing event) {
|
||||||
mouse_inside = true;
|
mouse_inside = true;
|
||||||
update_highlight((int)event.x_root, (int)event.y_root);
|
update_highlight((int)event.x_root, (int)event.y_root);
|
||||||
|
|
|
@ -28,6 +28,16 @@ public class MessageMetaItem : ContentMetaItem {
|
||||||
|
|
||||||
stream_interactor.get_module(MessageCorrection.IDENTITY).received_correction.connect(on_received_correction);
|
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;
|
return message_item_widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +116,11 @@ public class MessageItemWidget : SizeRequestBin {
|
||||||
unset_edit_mode();
|
unset_edit_mode();
|
||||||
});
|
});
|
||||||
edit_mode.send.connect(() => {
|
edit_mode.send.connect(() => {
|
||||||
|
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);
|
edit_sent(edit_mode.chat_text_view.text_view.buffer.text);
|
||||||
|
} else {
|
||||||
|
edit_cancelled();
|
||||||
|
}
|
||||||
unset_edit_mode();
|
unset_edit_mode();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -122,6 +136,9 @@ public class MessageItemWidget : SizeRequestBin {
|
||||||
public void unset_edit_mode() {
|
public void unset_edit_mode() {
|
||||||
this.remove(edit_mode);
|
this.remove(edit_mode);
|
||||||
this.add(label);
|
this.add(label);
|
||||||
|
label.grab_focus();
|
||||||
|
label.selectable = false;
|
||||||
|
label.selectable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update_label() {
|
public void update_label() {
|
||||||
|
@ -200,11 +217,16 @@ public class MessageItemEditMode : Box {
|
||||||
});
|
});
|
||||||
emoji_button.set_popover(chooser);
|
emoji_button.set_popover(chooser);
|
||||||
|
|
||||||
|
chat_text_view.text_view.buffer.changed.connect_after(on_text_view_changed);
|
||||||
|
|
||||||
cancel_button.clicked.connect(() => cancelled());
|
cancel_button.clicked.connect(() => cancelled());
|
||||||
send_button.clicked.connect(() => send());
|
send_button.clicked.connect(() => send());
|
||||||
chat_text_view.cancel_input.connect(() => cancelled());
|
chat_text_view.cancel_input.connect(() => cancelled());
|
||||||
chat_text_view.send_text.connect(() => send());
|
chat_text_view.send_text.connect(() => send());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void on_text_view_changed() {
|
||||||
|
send_button.sensitive = chat_text_view.text_view.buffer.text != "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ public class ConversationViewController : Object {
|
||||||
view.drag_data_received.connect(this.on_drag_data_received);
|
view.drag_data_received.connect(this.on_drag_data_received);
|
||||||
|
|
||||||
// forward key presses
|
// 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.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);
|
view.conversation_frame.key_press_event.connect(forward_key_press_to_chat_input);
|
||||||
titlebar.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;
|
return false;
|
||||||
}
|
}
|
||||||
if (view.chat_input.chat_text_view.text_view.key_press_event(event)) {
|
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 true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -2,6 +2,21 @@ namespace Xmpp.Xep.DelayedDelivery {
|
||||||
|
|
||||||
private const string NS_URI = "urn:xmpp:delay";
|
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 class Module : XmppStreamModule {
|
||||||
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "0203_delayed_delivery");
|
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);
|
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) {
|
public override void attach(XmppStream stream) {
|
||||||
stream.get_module(MessageModule.IDENTITY).received_pipeline.connect(received_pipeline_listener);
|
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 string[] after_actions { get { return after_actions_const; } }
|
||||||
|
|
||||||
public override async bool run(XmppStream stream, MessageStanza message) {
|
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));
|
if (datetime != null) message.add_flag(new MessageFlag(datetime));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
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? 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");
|
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));
|
message.add_flag(new MessageFlag(datetime, mam_id, query_id));
|
||||||
|
|
Loading…
Reference in a new issue