Handle incoming own read marker in private MUCs
This commit is contained in:
parent
3b6e8700b4
commit
cd3a119eff
|
@ -206,7 +206,7 @@ public class ChatInteraction : StreamInteractionModule, Object {
|
||||||
break;
|
break;
|
||||||
case Xep.ChatMarkers.MARKER_DISPLAYED:
|
case Xep.ChatMarkers.MARKER_DISPLAYED:
|
||||||
if (conversation.get_send_marker_setting(stream_interactor) == Conversation.Setting.ON) {
|
if (conversation.get_send_marker_setting(stream_interactor) == Conversation.Setting.ON) {
|
||||||
if (message.type_ == Message.Type.GROUPCHAT) {
|
if (message.type_ == Message.Type.GROUPCHAT || message.type_ == Message.Type.GROUPCHAT_PM) {
|
||||||
if (message.server_id == null) return;
|
if (message.server_id == null) return;
|
||||||
stream.get_module(Xep.ChatMarkers.Module.IDENTITY).send_marker(stream, message.from.bare_jid, message.server_id, message.get_type_string(), Xep.ChatMarkers.MARKER_DISPLAYED);
|
stream.get_module(Xep.ChatMarkers.Module.IDENTITY).send_marker(stream, message.from.bare_jid, message.server_id, message.get_type_string(), Xep.ChatMarkers.MARKER_DISPLAYED);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -64,8 +64,8 @@ public class CounterpartInteractionManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_account_added(Account account) {
|
private void on_account_added(Account account) {
|
||||||
stream_interactor.module_manager.get_module(account, Xep.ChatMarkers.Module.IDENTITY).marker_received.connect( (stream, jid, marker, id) => {
|
stream_interactor.module_manager.get_module(account, Xep.ChatMarkers.Module.IDENTITY).marker_received.connect( (stream, jid, marker, id, message_stanza) => {
|
||||||
on_chat_marker_received(account, jid, marker, id);
|
on_chat_marker_received(account, jid, marker, id, message_stanza);
|
||||||
});
|
});
|
||||||
stream_interactor.module_manager.get_module(account, Xep.MessageDeliveryReceipts.Module.IDENTITY).receipt_received.connect((stream, jid, id) => {
|
stream_interactor.module_manager.get_module(account, Xep.MessageDeliveryReceipts.Module.IDENTITY).receipt_received.connect((stream, jid, id) => {
|
||||||
on_receipt_received(account, jid, id);
|
on_receipt_received(account, jid, id);
|
||||||
|
@ -119,12 +119,20 @@ public class CounterpartInteractionManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_chat_marker_received(Account account, Jid jid, string marker, string stanza_id) {
|
private async void on_chat_marker_received(Account account, Jid jid, string marker, string stanza_id, MessageStanza message_stanza) {
|
||||||
|
Message message = yield stream_interactor.get_module(MessageProcessor.IDENTITY).parse_message_stanza(account, message_stanza);
|
||||||
|
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation_for_message(message);
|
||||||
|
if (conversation == null) return;
|
||||||
|
handle_chat_marker(conversation, jid, marker, stanza_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handle_chat_marker(Conversation conversation, Jid jid, string marker, string stanza_id) {
|
||||||
// Check if the marker comes from ourselves (own jid or our jid in a MUC)
|
// Check if the marker comes from ourselves (own jid or our jid in a MUC)
|
||||||
bool own_marker = account.bare_jid.to_string() == jid.bare_jid.to_string();
|
bool own_marker = false;
|
||||||
if (stream_interactor.get_module(MucManager.IDENTITY).is_groupchat_occupant(jid, account)) {
|
if (conversation.type_ == Conversation.Type.CHAT) {
|
||||||
Jid? own_muc_jid = stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(jid.bare_jid, account);
|
own_marker = conversation.account.bare_jid.to_string() == jid.bare_jid.to_string();
|
||||||
|
} else {
|
||||||
|
Jid? own_muc_jid = stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(jid.bare_jid, conversation.account);
|
||||||
if (own_muc_jid != null && own_muc_jid.equals(jid)) {
|
if (own_muc_jid != null && own_muc_jid.equals(jid)) {
|
||||||
own_marker = true;
|
own_marker = true;
|
||||||
}
|
}
|
||||||
|
@ -133,31 +141,31 @@ public class CounterpartInteractionManager : StreamInteractionModule, Object {
|
||||||
if (own_marker) {
|
if (own_marker) {
|
||||||
// If we received a display marker from ourselves (other device), set the conversation read up to that message.
|
// If we received a display marker from ourselves (other device), set the conversation read up to that message.
|
||||||
if (marker != Xep.ChatMarkers.MARKER_DISPLAYED && marker != Xep.ChatMarkers.MARKER_ACKNOWLEDGED) return;
|
if (marker != Xep.ChatMarkers.MARKER_DISPLAYED && marker != Xep.ChatMarkers.MARKER_ACKNOWLEDGED) return;
|
||||||
Conversation? conversation = stream_interactor.get_module(MessageStorage.IDENTITY).get_conversation_for_stanza_id(account, stanza_id);
|
Entities.Message? message = null;
|
||||||
if (conversation == null || conversation.type_ == Conversation.Type.GROUPCHAT) return;
|
if (conversation.type_ == Conversation.Type.GROUPCHAT || conversation.type_ == Conversation.Type.GROUPCHAT_PM) {
|
||||||
Entities.Message? message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_stanza_id(stanza_id, conversation);
|
message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_server_id(stanza_id, conversation);
|
||||||
|
} else {
|
||||||
|
message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_stanza_id(stanza_id, conversation);
|
||||||
|
}
|
||||||
if (message == null) return;
|
if (message == null) return;
|
||||||
// Don't move read marker backwards because we get old info from another client
|
// Don't move read marker backwards because we get old info from another client
|
||||||
if (conversation.read_up_to == null || conversation.read_up_to.local_time.compare(message.local_time) > 0) return;
|
if (conversation.read_up_to == null || conversation.read_up_to.local_time.compare(message.local_time) > 0) return;
|
||||||
conversation.read_up_to = message;
|
conversation.read_up_to = message;
|
||||||
} else {
|
} else {
|
||||||
// We received a marker from someone else. Search the respective message and mark it.
|
|
||||||
foreach (Conversation conversation in stream_interactor.get_module(ConversationManager.IDENTITY).get_conversations(jid, account)) {
|
|
||||||
|
|
||||||
// We can't currently handle chat markers in MUCs
|
// We can't currently handle chat markers in MUCs
|
||||||
if (conversation.type_ == Conversation.Type.GROUPCHAT) continue;
|
if (conversation.type_ == Conversation.Type.GROUPCHAT) return;
|
||||||
|
|
||||||
Entities.Message? message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_stanza_id(stanza_id, conversation);
|
Entities.Message? message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_stanza_id(stanza_id, conversation);
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
switch (marker) {
|
switch (marker) {
|
||||||
case Xep.ChatMarkers.MARKER_RECEIVED:
|
case Xep.ChatMarkers.MARKER_RECEIVED:
|
||||||
// If we got a received marker, mark the respective message received.
|
// If we got a received marker, mark the respective message received.
|
||||||
received_message_received(account, jid, message);
|
received_message_received(conversation.account, jid, message);
|
||||||
message.marked = Entities.Message.Marked.RECEIVED;
|
message.marked = Entities.Message.Marked.RECEIVED;
|
||||||
break;
|
break;
|
||||||
case Xep.ChatMarkers.MARKER_DISPLAYED:
|
case Xep.ChatMarkers.MARKER_DISPLAYED:
|
||||||
// If we got a display marker, set all messages up to that message as read (if we know they've been received).
|
// If we got a display marker, set all messages up to that message as read (if we know they've been received).
|
||||||
received_message_displayed(account, jid, message);
|
received_message_displayed(conversation.account, jid, message);
|
||||||
Gee.List<Entities.Message> messages = stream_interactor.get_module(MessageStorage.IDENTITY).get_messages(conversation);
|
Gee.List<Entities.Message> messages = stream_interactor.get_module(MessageStorage.IDENTITY).get_messages(conversation);
|
||||||
foreach (Entities.Message m in messages) {
|
foreach (Entities.Message m in messages) {
|
||||||
if (m.equals(message)) break;
|
if (m.equals(message)) break;
|
||||||
|
@ -176,17 +184,18 @@ public class CounterpartInteractionManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void check_if_got_marker(Entities.Message message, Conversation conversation) {
|
private void check_if_got_marker(Entities.Message message, Conversation conversation) {
|
||||||
if (marker_wo_message.has_key(message.stanza_id)) {
|
if (marker_wo_message.has_key(message.stanza_id)) {
|
||||||
on_chat_marker_received(conversation.account, conversation.counterpart, marker_wo_message[message.stanza_id], message.stanza_id);
|
handle_chat_marker(conversation, conversation.counterpart, marker_wo_message[message.stanza_id], message.stanza_id);
|
||||||
marker_wo_message.unset(message.stanza_id);
|
marker_wo_message.unset(message.stanza_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_receipt_received(Account account, Jid jid, string id) {
|
private void on_receipt_received(Account account, Jid jid, string id) {
|
||||||
on_chat_marker_received(account, jid, Xep.ChatMarkers.MARKER_RECEIVED, id);
|
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation(jid, account, Conversation.Type.CHAT);
|
||||||
|
if (conversation == null) return;
|
||||||
|
handle_chat_marker(conversation, jid,Xep.ChatMarkers.MARKER_RECEIVED, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,14 @@ public class MessageStorage : StreamInteractionModule, Object {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Message? get_message_by_server_id(string server_id, Conversation conversation) {
|
||||||
|
init_conversation(conversation);
|
||||||
|
foreach (Message message in messages[conversation]) {
|
||||||
|
if (message.server_id == server_id) return message;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public Conversation? get_conversation_for_stanza_id(Account account, string stanza_id) {
|
public Conversation? get_conversation_for_stanza_id(Account account, string stanza_id) {
|
||||||
foreach (Conversation conversation in messages.keys) {
|
foreach (Conversation conversation in messages.keys) {
|
||||||
if (!conversation.account.equals(account)) continue;
|
if (!conversation.account.equals(account)) continue;
|
||||||
|
|
|
@ -12,7 +12,7 @@ private const string[] MARKERS = {MARKER_RECEIVED, MARKER_DISPLAYED, MARKER_ACKN
|
||||||
public class Module : XmppStreamModule {
|
public class Module : XmppStreamModule {
|
||||||
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "0333_chat_markers");
|
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "0333_chat_markers");
|
||||||
|
|
||||||
public signal void marker_received(XmppStream stream, Jid jid, string marker, string id);
|
public signal void marker_received(XmppStream stream, Jid jid, string marker, string id, MessageStanza message);
|
||||||
|
|
||||||
private SendPipelineListener send_pipeline_listener = new SendPipelineListener();
|
private SendPipelineListener send_pipeline_listener = new SendPipelineListener();
|
||||||
|
|
||||||
|
@ -48,7 +48,10 @@ public class Module : XmppStreamModule {
|
||||||
Gee.List<StanzaNode> nodes = message.stanza.get_all_subnodes();
|
Gee.List<StanzaNode> nodes = message.stanza.get_all_subnodes();
|
||||||
foreach (StanzaNode node in nodes) {
|
foreach (StanzaNode node in nodes) {
|
||||||
if (node.ns_uri == NS_URI && node.name in MARKERS) {
|
if (node.ns_uri == NS_URI && node.name in MARKERS) {
|
||||||
marker_received(stream, message.from, node.name, node.get_attribute("id", NS_URI));
|
string? to_stanza_id = node.get_attribute("id", NS_URI);
|
||||||
|
if (to_stanza_id != null) {
|
||||||
|
marker_received(stream, message.from, node.name, to_stanza_id, message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue