@@ -5,6 +5,10 @@ import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.services.AvatarService;
@@ -20,6 +24,7 @@ import eu.siacs.conversations.xmpp.pep.Avatar;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -331,12 +336,19 @@ public class MucOptions {
return null;
}
+ public User findUserByOccupantId(final String occupantId) {
+ synchronized (this.users) {
+ return Strings.isNullOrEmpty(occupantId) ? null : Iterables.find(this.users, u -> occupantId.equals(u.occupantId),null);
+ }
+ }
+
public User findOrCreateUserByRealJid(Jid jid, Jid fullJid) {
- User user = findUserByRealJid(jid);
- if (user == null) {
- user = new User(this, fullJid);
- user.setRealJid(jid);
+ final User existing = findUserByRealJid(jid);
+ if (existing != null) {
+ return existing;
}
+ final var user = new User(this, fullJid);
+ user.setRealJid(jid);
return user;
}
@@ -350,6 +362,31 @@ public class MucOptions {
}
}
+ private User findUser(final Reaction reaction) {
+ if (reaction.trueJid != null) {
+ return findOrCreateUserByRealJid(reaction.trueJid.asBareJid(), reaction.from);
+ }
+ final var existing = findUserByOccupantId(reaction.occupantId);
+ if (existing != null) {
+ return existing;
+ } else if (reaction.from != null) {
+ return new User(this,reaction.from);
+ } else {
+ return null;
+ }
+ }
+
+ public List<User> findUsers(final Collection<Reaction> reactions) {
+ final ImmutableList.Builder<User> builder = new ImmutableList.Builder<>();
+ for(final Reaction reaction : reactions) {
+ final var user = findUser(reaction);
+ if (user != null) {
+ builder.add(user);
+ }
+ }
+ return builder.build();
+ }
+
public boolean isContactInRoom(Contact contact) {
return contact != null && findUserByRealJid(contact.getJid().asBareJid()) != null;
}
@@ -16,6 +16,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.Consumer;
+import java.util.function.Function;
public class BindingAdapters {
@@ -23,15 +24,18 @@ public class BindingAdapters {
final ChipGroup chipGroup,
final Reaction.Aggregated reactions,
final Consumer<Collection<String>> onModifiedReactions,
+ final Function<String, Boolean> onDetailsClicked,
final Runnable addReaction) {
- setReactions(chipGroup, reactions, true, onModifiedReactions, addReaction);
+ setReactions(
+ chipGroup, reactions, true, onModifiedReactions, onDetailsClicked, addReaction);
}
public static void setReactionsOnSent(
final ChipGroup chipGroup,
final Reaction.Aggregated reactions,
- final Consumer<Collection<String>> onModifiedReactions) {
- setReactions(chipGroup, reactions, false, onModifiedReactions, null);
+ final Consumer<Collection<String>> onModifiedReactions,
+ final Function<String, Boolean> onDetailsClicked) {
+ setReactions(chipGroup, reactions, false, onModifiedReactions, onDetailsClicked, null);
}
private static void setReactions(
@@ -39,6 +43,7 @@ public class BindingAdapters {
final Reaction.Aggregated aggregated,
final boolean onReceived,
final Consumer<Collection<String>> onModifiedReactions,
+ final Function<String, Boolean> onDetailsClicked,
final Runnable addReaction) {
final var context = chipGroup.getContext();
final List<Map.Entry<String, Integer>> reactions = aggregated.reactions;
@@ -89,6 +94,7 @@ public class BindingAdapters {
.build());
}
});
+ chip.setOnLongClickListener(v -> onDetailsClicked.apply(emoji));
chipGroup.addView(chip);
}
if (onReceived) {
@@ -45,8 +45,10 @@ import com.google.android.material.color.MaterialColors;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
+import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
import eu.siacs.conversations.AppSettings;
import eu.siacs.conversations.Config;
@@ -1077,18 +1079,41 @@ public class MessageAdapter extends ArrayAdapter<Message> {
viewHolder.reactions,
message.getAggregatedReactions(),
reactions -> sendReactions(message, reactions),
+ emoji -> showDetailedReaction(message, emoji),
() -> addReaction(message));
} else if (type == SENT) {
BindingAdapters.setReactionsOnSent(
viewHolder.reactions,
message.getAggregatedReactions(),
- reactions -> sendReactions(message, reactions));
+ reactions -> sendReactions(message, reactions),
+ emoji -> showDetailedReaction(message, emoji));
}
displayStatus(viewHolder, message, type, bubbleColor);
return view;
}
+ private boolean showDetailedReaction(final Message message, final String emoji) {
+ final var c = message.getConversation();
+ if (c instanceof Conversation conversation && c.getMode() == Conversational.MODE_MULTI) {
+ final var reactions =
+ Collections2.filter(message.getReactions(), r -> r.reaction.equals(emoji));
+ final var mucOptions = conversation.getMucOptions();
+ final var users = mucOptions.findUsers(reactions);
+ if (users.isEmpty()) {
+ return true;
+ }
+ final MaterialAlertDialogBuilder dialogBuilder =
+ new MaterialAlertDialogBuilder(activity);
+ dialogBuilder.setTitle(emoji);
+ dialogBuilder.setMessage(UIHelper.concatNames(users));
+ dialogBuilder.create().show();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
private void sendReactions(final Message message, final Collection<String> reactions) {
if (activity.xmppConnectionService.sendReactions(message, reactions)) {
return;