Reply with a single emoji is a reaction

(cherry picked from commit ba47a5f1639fdb0b8d2a1b3a8cd89bb2c9eef931)
This commit is contained in:
Stephen Paul Weber 2024-09-30 15:21:10 -05:00 committed by Arne
parent 873f091218
commit 0aea687411
2 changed files with 66 additions and 4 deletions
src/main/java/eu/siacs/conversations

View file

@ -82,6 +82,21 @@ public class Reaction {
}
}
public static Collection<Reaction> append(
final Collection<Reaction> existing,
final Collection<String> reactions,
final boolean received,
final Jid from,
final Jid trueJid,
final String occupantId) {
final ImmutableSet.Builder<Reaction> builder = new ImmutableSet.Builder<>();
builder.addAll(existing);
builder.addAll(
Collections2.transform(
reactions, r -> new Reaction(r, received, from, trueJid, occupantId)));
return builder.build();
}
public static Collection<Reaction> withOccupantId(
final Collection<Reaction> existing,
final Collection<String> reactions,
@ -89,7 +104,7 @@ public class Reaction {
final Jid from,
final Jid trueJid,
final String occupantId) {
final ImmutableList.Builder<Reaction> builder = new ImmutableList.Builder<>();
final ImmutableSet.Builder<Reaction> builder = new ImmutableSet.Builder<>();
builder.addAll(Collections2.filter(existing, e -> !occupantId.equals(e.occupantId)));
builder.addAll(
Collections2.transform(
@ -109,12 +124,22 @@ public class Reaction {
.toString();
}
public int hashCode() {
return toString().hashCode();
}
public boolean equals(Object o) {
if (o == null) return false;
if (!(o instanceof Reaction)) return false;
return toString().equals(o.toString());
}
public static Collection<Reaction> withFrom(
final Collection<Reaction> existing,
final Collection<String> reactions,
final boolean received,
final Jid from) {
final ImmutableList.Builder<Reaction> builder = new ImmutableList.Builder<>();
final ImmutableSet.Builder<Reaction> builder = new ImmutableSet.Builder<>();
builder.addAll(
Collections2.filter(existing, e -> !from.asBareJid().equals(e.from.asBareJid())));
builder.addAll(

View file

@ -59,6 +59,7 @@ import eu.siacs.conversations.services.MessageArchiveService;
import eu.siacs.conversations.services.QuickConversationsService;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.Emoticons;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xml.LocalizedContent;
import eu.siacs.conversations.xml.Namespace;
@ -574,7 +575,6 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
if (timestamp == null) {
timestamp = AbstractParser.parseTimestamp(original, AbstractParser.parseTimestamp(packet));
}
final Reactions reactions = packet.getExtension(Reactions.class);
final Element mucUserElement = packet.findChild("x", Namespace.MUC_USER);
final String pgpEncrypted = packet.findChildContent("x", "jabber:x:encrypted");
Element replaceElement = packet.findChild("replace", "urn:xmpp:message-correct:0");
@ -610,6 +610,33 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
}
LocalizedContent body = packet.getBody();
var appendReactions = false;
var reactions = packet.getExtension(Reactions.class);
final var reply = packet.findChild("reply", "urn:xmpp:reply:0");
if (reactions == null && reply != null && reply.getAttribute("id") != null && body != null) {
StringBuilder bodyB = new StringBuilder(body.content);
for (Element el : packet.getChildren()) {
if ("fallback".equals(el.getName()) && "urn:xmpp:fallback:0".equals(el.getNamespace()) && "urn:xmpp:reply:0".equals(el.getAttribute("for"))) {
for (final var span : el.getChildren()) {
if (!span.getName().equals("body") && !span.getNamespace().equals("urn:xmpp:fallback:0")) continue;
if (span.getAttribute("start") == null || span.getAttribute("end") == null) {
bodyB.setLength(0);
} else {
bodyB.delete(bodyB.offsetByCodePoints(0, parseInt(span.getAttribute("start"))), bodyB.offsetByCodePoints(0, parseInt(span.getAttribute("end"))));
}
}
}
}
final var emojiMaybe = bodyB.toString().replaceAll("\\s", "");
if (Emoticons.isEmoji(emojiMaybe)) {
appendReactions = true;
reactions = im.conversations.android.xmpp.model.reactions.Reactions.to(reply.getAttribute("id"));
reactions.addExtension(new im.conversations.android.xmpp.model.reactions.Reaction(emojiMaybe));
}
}
final Element axolotlEncrypted = packet.findChildEnsureSingle(XmppAxolotlMessage.CONTAINERTAG, AxolotlService.PEP_PREFIX);
int status;
final Jid counterpart;
@ -718,7 +745,7 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
}
}
if ((body != null || pgpEncrypted != null || (axolotlEncrypted != null && axolotlEncrypted.hasChild("payload")) || !attachments.isEmpty() || html != null || (packet.hasChild("subject") && packet.hasChild("thread"))) && !isMucStatusMessage) {
if (reactions == null && (body != null || pgpEncrypted != null || (axolotlEncrypted != null && axolotlEncrypted.hasChild("payload")) || !attachments.isEmpty() || html != null || (packet.hasChild("subject") && packet.hasChild("thread"))) && !isMucStatusMessage) {
final Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.asBareJid(), conversationIsProbablyMuc, false, query, false);
final boolean conversationMultiMode = conversation.getMode() == Conversation.MODE_MULTI;
@ -1428,6 +1455,7 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
final boolean isReceived = !mucOptions.isSelf(counterpart);
if (occupantId != null && message != null) {
final var combinedReactions =
appendReactions ? Reaction.append(message.getReactions(), reactions.getReactions(), isReceived, counterpart, null, occupantId) :
Reaction.withOccupantId(
message.getReactions(),
reactions.getReactions(),
@ -1454,6 +1482,7 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
packet.fromAccount(account);
if (message != null) {
final var combinedReactions =
appendReactions ? Reaction.append(message.getReactions(), reactions.getReactions(), isReceived, reactionFrom, null, null) :
Reaction.withFrom(
message.getReactions(),
reactions.getReactions(),
@ -1598,4 +1627,12 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
return true;
}
}
private static int parseInt(String value) {
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
return 0;
}
}
}