Process read marker from other devices for MUCs to adjust read-up-to state

This commit is contained in:
fiaxh 2019-05-11 19:10:36 +02:00
parent f4778ef3e6
commit 9d19cdbf4e
2 changed files with 14 additions and 1 deletions

View file

@ -64,8 +64,18 @@ public class CounterpartInteractionManager : StreamInteractionModule, Object {
} }
private void on_chat_marker_received(Account account, Jid jid, string marker, string stanza_id) { private void on_chat_marker_received(Account account, Jid jid, string marker, string stanza_id) {
// 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 = account.bare_jid.to_string() == jid.bare_jid.to_string();
if (stream_interactor.get_module(MucManager.IDENTITY).is_groupchat_occupant(jid, account)) {
Jid? own_muc_jid = stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(jid.bare_jid, account);
if (own_muc_jid != null && own_muc_jid.equals(jid)) {
own_marker = true;
}
}
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 (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); Conversation? conversation = stream_interactor.get_module(MessageStorage.IDENTITY).get_conversation_for_stanza_id(account, stanza_id);
if (conversation == null) return; if (conversation == null) return;
@ -73,15 +83,18 @@ public class CounterpartInteractionManager : StreamInteractionModule, Object {
if (message == null) return; if (message == null) 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)) { foreach (Conversation conversation in stream_interactor.get_module(ConversationManager.IDENTITY).get_conversations(jid, account)) {
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.
received_message_received(account, jid, message); received_message_received(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).
received_message_displayed(account, jid, message); received_message_displayed(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) {
@ -92,6 +105,7 @@ public class CounterpartInteractionManager : StreamInteractionModule, Object {
break; break;
} }
} else { } else {
// We might get a marker before the actual message (on catchup). Save the marker.
if (marker_wo_message.has_key(stanza_id) && if (marker_wo_message.has_key(stanza_id) &&
marker_wo_message[stanza_id] == Xep.ChatMarkers.MARKER_DISPLAYED && marker == Xep.ChatMarkers.MARKER_RECEIVED) { marker_wo_message[stanza_id] == Xep.ChatMarkers.MARKER_DISPLAYED && marker == Xep.ChatMarkers.MARKER_RECEIVED) {
return; return;

View file

@ -44,7 +44,6 @@ public class Module : XmppStreamModule {
public override string get_id() { return IDENTITY.id; } public override string get_id() { return IDENTITY.id; }
private void on_received_message(XmppStream stream, MessageStanza message) { private void on_received_message(XmppStream stream, MessageStanza message) {
if (message.type_ != MessageStanza.TYPE_CHAT) return;
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) {