add helper method to count reactions

This commit is contained in:
Daniel Gultsch 2023-02-12 17:25:26 +01:00
parent 7e2bff9d03
commit 2728a96ab9
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
7 changed files with 94 additions and 7 deletions

View file

@ -80,6 +80,48 @@ public class TransformationTest {
Assert.assertEquals(REMOTE, onlyReaction.reactionBy);
}
@Test
public void multipleReactions() {
final var group = Jid.ofEscaped("a@group.example.com");
final var message = new Message(Message.Type.GROUPCHAT);
message.addExtension(new Body("Please give me a thumbs up"));
message.setFrom(group.withResource("user-a"));
this.transformer.transform(
Transformation.of(message, Instant.now(), REMOTE, "stanza-a", "id-user-a"));
final var reactionA = new Message(Message.Type.GROUPCHAT);
reactionA.setFrom(group.withResource("user-b"));
reactionA.addExtension(Reactions.to("stanza-a")).addExtension(new Reaction("Y"));
this.transformer.transform(
Transformation.of(reactionA, Instant.now(), REMOTE, "stanza-b", "id-user-b"));
final var reactionB = new Message(Message.Type.GROUPCHAT);
reactionB.setFrom(group.withResource("user-c"));
reactionB.addExtension(Reactions.to("stanza-a")).addExtension(new Reaction("Y"));
this.transformer.transform(
Transformation.of(reactionB, Instant.now(), REMOTE, "stanza-c", "id-user-c"));
final var reactionC = new Message(Message.Type.GROUPCHAT);
reactionC.setFrom(group.withResource("user-d"));
final var reactions = reactionC.addExtension(Reactions.to("stanza-a"));
reactions.addExtension(new Reaction("Y"));
reactions.addExtension(new Reaction("Z"));
this.transformer.transform(
Transformation.of(reactionC, Instant.now(), REMOTE, "stanza-d", "id-user-d"));
final var messages = database.messageDao().getMessages(1L);
Assert.assertEquals(1, messages.size());
final var dbMessage = Iterables.getOnlyElement(messages);
Assert.assertEquals(4, dbMessage.reactions.size());
final var aggregated = dbMessage.getAggregatedReactions();
final var mostFrequentReaction = Iterables.get(aggregated, 0);
Assert.assertEquals("Y", mostFrequentReaction.getKey());
Assert.assertEquals(3L, (long) mostFrequentReaction.getValue());
final var secondReaction = Iterables.get(aggregated, 1);
Assert.assertEquals("Z", secondReaction.getKey());
Assert.assertEquals(1L, (long) secondReaction.getValue());
}
@Test
public void correctionBeforeOriginal() {

View file

@ -1,6 +1,7 @@
package eu.siacs.conversations.xml;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
@ -159,18 +160,18 @@ public class Element {
return content;
}
public Element setAttribute(String name, String value) {
if (name != null && value != null) {
public Element setAttribute(final String name, final String value) {
Preconditions.checkArgument(name != null, "The attribute must have a name");
if (value == null) {
this.attributes.remove(name);
} else {
this.attributes.put(name, value);
}
return this;
}
public Element setAttribute(String name, Jid value) {
if (name != null && value != null) {
this.attributes.put(name, value.toEscapedString());
}
return this;
public Element setAttribute(final String name, final Jid value) {
return this.setAttribute(name, value == null ? null : value.toEscapedString());
}
public void removeAttribute(final String name) {

View file

@ -1,11 +1,17 @@
package im.conversations.android.database.model;
import androidx.room.Relation;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimaps;
import eu.siacs.conversations.xmpp.Jid;
import im.conversations.android.database.entity.MessageContentEntity;
import im.conversations.android.database.entity.MessageReactionEntity;
import java.time.Instant;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class MessageWithContentReactions {
@ -34,4 +40,13 @@ public class MessageWithContentReactions {
parentColumn = "id",
entityColumn = "messageEntityId")
public List<MessageReaction> reactions;
public Set<Map.Entry<String, Integer>> getAggregatedReactions() {
final Map<String, Integer> aggregatedReactions =
Maps.transformValues(
Multimaps.index(reactions, r -> r.reaction).asMap(), Collection::size);
return ImmutableSortedSet.copyOf(
(a, b) -> Integer.compare(b.getValue(), a.getValue()),
aggregatedReactions.entrySet());
}
}

View file

@ -10,6 +10,11 @@ public class Body extends Extension {
super(Body.class);
}
public Body(final String content) {
this();
setContent(content);
}
public String getLang() {
return this.getAttribute("xml:lang");
}

View file

@ -9,4 +9,9 @@ public class Reaction extends Extension {
public Reaction() {
super(Reaction.class);
}
public Reaction(final String reaction) {
this();
setContent(reaction);
}
}

View file

@ -27,4 +27,10 @@ public class Reactions extends Extension {
public void setId(String id) {
this.setAttribute("id", id);
}
public static Reactions to(final String id) {
final var reactions = new Reactions();
reactions.setId(id);
return reactions;
}
}

View file

@ -10,6 +10,11 @@ public class Message extends Stanza {
super(Message.class);
}
public Message(Type type) {
this();
this.setType(type);
}
public String getBody() {
return this.findChildContent("body");
}
@ -27,6 +32,14 @@ public class Message extends Stanza {
}
}
public void setType(final Type type) {
if (type == null || type == Type.NORMAL) {
this.removeAttribute("type");
} else {
this.setAttribute("type", type.toString().toLowerCase(Locale.ROOT));
}
}
public enum Type {
ERROR,
NORMAL,