Detailed changes
@@ -486,11 +486,11 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
for (int i = this.messages.size() - 1; i >= 0; --i) {
final Message message = messages.get(i);
final Jid mcp = message.getCounterpart();
- if (mcp == null) {
+ if (mcp == null && counterpart != null) {
continue;
}
- if (mcp.equals(counterpart) || mcp.asBareJid().equals(counterpart)) {
- final boolean idMatch = id.equals(message.getRemoteMsgId()) || message.remoteMsgIdMatchInEdit(id) || (getMode() == MODE_MULTI && id.equals(message.getServerMsgId()));
+ if (counterpart == null || mcp.equals(counterpart) || mcp.asBareJid().equals(counterpart)) {
+ final boolean idMatch = id.equals(message.getUuid()) || id.equals(message.getRemoteMsgId()) || message.remoteMsgIdMatchInEdit(id) || (getMode() == MODE_MULTI && id.equals(message.getServerMsgId()));
if (idMatch) return message;
}
}
@@ -543,19 +543,26 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
return false;
}
- public Set<String> findOwnReactionsTo(String id) {
- Set<String> reactionEmoji = new HashSet<>();
- Element reactions = null;
+ public Message findMessageReactingTo(String id, Jid reactor) {
synchronized (this.messages) {
- for (Message message : this.messages) {
- if (message.getStatus() < Message.STATUS_SEND) continue;
+ for (int i = this.messages.size() - 1; i >= 0; --i) {
+ final Message message = messages.get(i);
+ if (reactor == null && message.getStatus() < Message.STATUS_SEND) continue;
+ if (reactor != null && !(message.getCounterpart().equals(reactor) || message.getCounterpart().asBareJid().equals(reactor))) continue;
final Element r = message.getReactions();
if (r != null && r.getAttribute("id") != null && id.equals(r.getAttribute("id"))) {
- reactions = r;
+ return message;
}
}
}
+ return null;
+ }
+
+ public Set<String> findReactionsTo(String id, Jid reactor) {
+ Set<String> reactionEmoji = new HashSet<>();
+ Message reactM = findMessageReactingTo(id, reactor);
+ Element reactions = reactM == null ? null : reactM.getReactions();
if (reactions != null) {
for (Element el : reactions.getChildren()) {
if (el.getName().equals("reaction") && el.getNamespace().equals("urn:xmpp:reactions:0")) {
@@ -403,7 +403,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
public Message react(String emoji) {
Set<String> emojis = new HashSet<>();
- if (conversation instanceof Conversation) emojis = ((Conversation) conversation).findOwnReactionsTo(replyId());
+ if (conversation instanceof Conversation) emojis = ((Conversation) conversation).findReactionsTo(replyId(), null);
emojis.add(emoji);
final Message m = reply();
m.appendBody(emoji);
@@ -418,6 +418,13 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
return m;
}
+ public void setReactions(Element reactions) {
+ if (this.payloads != null) {
+ this.payloads.remove(getReactions());
+ }
+ addPayload(reactions);
+ }
+
public Element getReactions() {
if (this.payloads == null) return null;
@@ -441,7 +441,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
}
}
}
- final LocalizedContent body = packet.getBody();
+ LocalizedContent body = packet.getBody();
final Element axolotlEncrypted = packet.findChildEnsureSingle(XmppAxolotlMessage.CONTAINERTAG, AxolotlService.PEP_PREFIX);
int status;
@@ -500,6 +500,28 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
}
}
+ final Element reactions = packet.findChild("reactions", "urn:xmpp:reactions:0");
+ if (body == null && html == null) {
+ if (reactions != null && reactions.getAttribute("id") != null) {
+ final Conversation conversation = mXmppConnectionService.find(account, counterpart.asBareJid());
+ if (conversation != null) {
+ final Message reactionTo = conversation.findMessageWithRemoteIdAndCounterpart(reactions.getAttribute("id"), null);
+ if (reactionTo != null) {
+ String bodyS = reactionTo.reply().getBody();
+ for (Element el : reactions.getChildren()) {
+ if (el.getName().equals("reaction") && el.getNamespace().equals("urn:xmpp:reactions:0")) {
+ bodyS += el.getContent();
+ }
+ }
+ body = new LocalizedContent(bodyS, "en", 1);
+ final Message previousReaction = conversation.findMessageReactingTo(reactions.getAttribute("id"), counterpart);
+Log.d("WUT", "" + previousReaction + " " + counterpart);
+ if (previousReaction != null) replacementId = previousReaction.replyId();
+ }
+ }
+ }
+ }
+
if ((body != null || pgpEncrypted != null || (axolotlEncrypted != null && axolotlEncrypted.hasChild("payload")) || !attachments.isEmpty() || html != null) && !isMucStatusMessage) {
final boolean conversationIsProbablyMuc = isTypeGroupChat || mucUserElement != null || account.getXmppConnection().getMucServersWithholdAccount().contains(counterpart.getDomain().toEscapedString());
final Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.asBareJid(), conversationIsProbablyMuc, false, query, false);
@@ -637,6 +659,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
}
}
message.markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0");
+ if (reactions != null) message.addPayload(reactions);
for (Element el : packet.getChildren()) {
if ((el.getName().equals("query") && el.getNamespace().equals("http://jabber.org/protocol/disco#items") && el.getAttribute("node").equals("http://jabber.org/protocol/commands")) ||
(el.getName().equals("fallback") && el.getNamespace().equals("urn:xmpp:fallback:0"))) {
@@ -693,7 +716,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
replacedMessage.setBody(message.getBody());
replacedMessage.putEdited(replacedMessage.getRemoteMsgId(), replacedMessage.getServerMsgId());
replacedMessage.setRemoteMsgId(remoteMsgId);
- if (!replaceElement.getName().equals("replace")) {
+ if (replaceElement != null && !replaceElement.getName().equals("replace")) {
mXmppConnectionService.getFileBackend().deleteFile(replacedMessage);
mXmppConnectionService.evictPreview(message.getUuid());
replacedMessage.clearPayloads();
@@ -1490,6 +1490,10 @@ public class ConversationFragment extends XmppFragment
correctMessage.setVisible(true);
if (!relevantForCorrection.getBody().equals("") && !relevantForCorrection.getBody().equals(" ")) retractMessage.setVisible(true);
}
+ if (relevantForCorrection.getReactions() != null) {
+ correctMessage.setVisible(false);
+ retractMessage.setVisible(true);
+ }
if (conversation.getMode() == Conversation.MODE_MULTI && m.getServerMsgId() != null && m.getModerated() == null && conversation.getMucOptions().getSelf().getRole().ranks(MucOptions.Role.MODERATOR) && conversation.getMucOptions().hasFeature("urn:xmpp:message-moderate:0")) {
moderateMessage.setVisible(true);
}
@@ -1575,11 +1579,18 @@ public class ConversationFragment extends XmppFragment
}
Element reactions = message.getReactions();
if (reactions != null) {
+ final Message previousReaction = conversation.findMessageReactingTo(reactions.getAttribute("id"), null);
+ if (previousReaction != null) reactions = previousReaction.getReactions();
for (Element el : reactions.getChildren()) {
if (message.getQuoteableBody().endsWith(el.getContent())) {
reactions.removeChild(el);
}
}
+ message.setReactions(reactions);
+ if (previousReaction != null) {
+ previousReaction.setReactions(reactions);
+ activity.xmppConnectionService.updateMessage(previousReaction);
+ }
}
message.setBody(" ");
message.putEdited(message.getUuid(), message.getServerMsgId());
@@ -14,7 +14,7 @@ public class LocalizedContent {
public final String language;
public final int count;
- private LocalizedContent(String content, String language, int count) {
+ public LocalizedContent(String content, String language, int count) {
this.content = content;
this.language = language;
this.count = count;