Allow removing custom reaction tapping the chip

(cherry picked from commit fbf28124e02ff2d514deca7ca6df66b814e6e09f)
This commit is contained in:
Stephen Paul Weber 2024-10-04 01:21:10 -05:00 committed by Arne
parent de026e8c13
commit 334ab8f2ff
6 changed files with 72 additions and 17 deletions

View file

@ -313,6 +313,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
for (int i = messages.size() - 1; i >= 0; --i) {
final Message message = messages.get(i);
if (message.getSubject() != null && !message.isOOb() && (message.getRawBody() == null || message.getRawBody().length() == 0)) continue;
if ((message.getRawBody() == null || "".equals(message.getRawBody()) || " ".equals(message.getRawBody())) && message.getReply() != null && message.edited() && message.getHtml() != null) continue;
if (asReaction(message) != null) continue;
if (message.isRead()) {
return first;
@ -329,6 +330,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
synchronized (this.messages) {
for (final Message message : Lists.reverse(this.messages)) {
if (message.getSubject() != null && !message.isOOb() && (message.getRawBody() == null || message.getRawBody().length() == 0)) continue;
if ((message.getRawBody() == null || "".equals(message.getRawBody()) || " ".equals(message.getRawBody())) && message.getReply() != null && message.edited() && message.getHtml() != null) continue;
if (asReaction(message) != null) continue;
if (message.getStatus() == Message.STATUS_RECEIVED) {
final String serverMsgId = message.getServerMsgId();
@ -741,6 +743,12 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
thread.first = m;
}
}
if ((m.getRawBody() == null || "".equals(m.getRawBody()) || " ".equals(m.getRawBody())) && m.getReply() != null && m.edited() && m.getHtml() != null) {
iterator.remove();
continue;
}
final var asReaction = asReaction(m);
if (asReaction != null) {
reactions.put(asReaction.first, asReaction.second);
@ -761,9 +769,16 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
protected Pair<String, Reaction> asReaction(Message m) {
final var reply = m.getReply();
if (reply != null && reply.getAttribute("id") != null) {
final String envelopeId;
if (m.isCarbon() || m.getStatus() == Message.STATUS_RECEIVED) {
envelopeId = m.getRemoteMsgId();
} else {
envelopeId = m.getUuid();
}
final var body = m.getBody(true).toString().replaceAll("\\s", "");
if (Emoticons.isEmoji(body)) {
return new Pair<>(reply.getAttribute("id"), new Reaction(body, null, m.getStatus() <= Message.STATUS_RECEIVED, m.getCounterpart(), m.getTrueCounterpart(), m.getOccupantId()));
return new Pair<>(reply.getAttribute("id"), new Reaction(body, null, m.getStatus() <= Message.STATUS_RECEIVED, m.getCounterpart(), m.getTrueCounterpart(), m.getOccupantId(), envelopeId));
} else {
final var html = m.getHtml();
if (html == null) return null;
@ -785,7 +800,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
}
if (source != null && source.length() > 0 && source.substring(0, 4).equals("cid:")) {
final Cid cid = BobTransfer.cid(Uri.parse(source));
return new Pair<>(reply.getAttribute("id"), new Reaction(shortcode, cid, m.getStatus() <= Message.STATUS_RECEIVED, m.getCounterpart(), m.getTrueCounterpart(), m.getOccupantId()));
return new Pair<>(reply.getAttribute("id"), new Reaction(shortcode, cid, m.getStatus() <= Message.STATUS_RECEIVED, m.getCounterpart(), m.getTrueCounterpart(), m.getOccupantId(), envelopeId));
}
}
}
@ -976,6 +991,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
for(final Message message : Lists.reverse(this.messages)) {
if (message.getSubject() != null && !message.isOOb() && (message.getRawBody() == null || message.getRawBody().length() == 0)) continue;
if (asReaction(message) != null) continue;
if ((message.getRawBody() == null || "".equals(message.getRawBody()) || " ".equals(message.getRawBody())) && message.getReply() != null && message.edited() && message.getHtml() != null) continue;
return message;
}
@ -1576,6 +1592,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
for(final Message message : Lists.reverse(this.messages)) {
if (message.getSubject() != null && !message.isOOb() && (message.getRawBody() == null || message.getRawBody().length() == 0)) continue;
if (asReaction(message) != null) continue;
if ((message.getRawBody() == null || "".equals(message.getRawBody()) || " ".equals(message.getRawBody())) && message.getReply() != null && message.edited() && message.getHtml() != null) continue;
final boolean muted = xmppConnectionService != null && message.getStatus() == Message.STATUS_RECEIVED && getMode() == Conversation.MODE_MULTI && xmppConnectionService.isMucUserMuted(new MucOptions.User(null, getJid(), message.getOccupantId(), null, null));
if (muted) continue;
if (message.isRead()) {
@ -1596,6 +1613,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
for (Message message : messages) {
if (message.getSubject() != null && !message.isOOb() && (message.getRawBody() == null || message.getRawBody().length() == 0)) continue;
if (asReaction(message) != null) continue;
if ((message.getRawBody() == null || "".equals(message.getRawBody()) || " ".equals(message.getRawBody())) && message.getReply() != null && message.edited() && message.getHtml() != null) continue;
if (message.getStatus() == Message.STATUS_RECEIVED) {
++count;
}

View file

@ -58,6 +58,7 @@ public class Reaction {
public final Jid trueJid;
public final String occupantId;
public final Cid cid;
public final String envelopeId;
public Reaction(
final String reaction,
@ -65,13 +66,15 @@ public class Reaction {
boolean received,
final Jid from,
final Jid trueJid,
final String occupantId) {
final String occupantId,
final String envelopeId) {
this.reaction = reaction;
this.cid = cid;
this.received = received;
this.from = from;
this.trueJid = trueJid;
this.occupantId = occupantId;
this.envelopeId = envelopeId;
}
public static String toString(final Collection<Reaction> reactions) {
@ -95,12 +98,13 @@ public class Reaction {
final boolean received,
final Jid from,
final Jid trueJid,
final String occupantId) {
final String occupantId,
final String envelopeId) {
final ImmutableSet.Builder<Reaction> builder = new ImmutableSet.Builder<>();
builder.addAll(Collections2.filter(existing, e -> !occupantId.equals(e.occupantId)));
builder.addAll(
Collections2.transform(
reactions, r -> new Reaction(r, null, received, from, trueJid, occupantId)));
reactions, r -> new Reaction(r, null, received, from, trueJid, occupantId, envelopeId)));
return builder.build();
}
@ -131,13 +135,14 @@ public class Reaction {
final Collection<Reaction> existing,
final Collection<String> reactions,
final boolean received,
final Jid from) {
final Jid from,
final String envelopeId) {
final ImmutableSet.Builder<Reaction> builder = new ImmutableSet.Builder<>();
builder.addAll(
Collections2.filter(existing, e -> !from.asBareJid().equals(e.from.asBareJid())));
builder.addAll(
Collections2.transform(
reactions, r -> new Reaction(r, null, received, from, null, null)));
reactions, r -> new Reaction(r, null, received, from, null, null, envelopeId)));
return builder.build();
}

View file

@ -1435,7 +1435,8 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
isReceived,
counterpart,
null,
occupantId);
occupantId,
message.getRemoteMsgId());
message.setReactions(combinedReactions);
mXmppConnectionService.updateMessage(message, false);
} else {
@ -1459,7 +1460,8 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
message.getReactions(),
reactions.getReactions(),
isReceived,
reactionFrom);
reactionFrom,
message.getRemoteMsgId());
message.setReactions(combinedReactions);
mXmppConnectionService.updateMessage(message, false);
}

View file

@ -5393,7 +5393,8 @@ public class XmppConnectionService extends Service {
false,
self.getFullJid(),
conversation.getAccount().getJid(),
occupantId);
occupantId,
null);
} else {
if (message.isCarbon() || message.getStatus() == Message.STATUS_RECEIVED) {
reactToId = message.getRemoteMsgId();
@ -5405,7 +5406,8 @@ public class XmppConnectionService extends Service {
message.getReactions(),
reactions,
false,
conversation.getAccount().getJid());
conversation.getAccount().getJid(),
null);
}
if (Strings.isNullOrEmpty(reactToId)) {
return false;

View file

@ -32,15 +32,16 @@ public class BindingAdapters {
final Reaction.Aggregated reactions,
final Consumer<Collection<String>> onModifiedReactions,
final Consumer<EmojiSearch.CustomEmoji> onCustomReaction,
final Consumer<Reaction> onCustomReactionRemove,
final Runnable addReaction) {
setReactions(chipGroup, conversation, reactions, true, onModifiedReactions, onCustomReaction, addReaction);
setReactions(chipGroup, conversation, reactions, true, onModifiedReactions, onCustomReaction, onCustomReactionRemove, addReaction);
}
public static void setReactionsOnSent(
final ChipGroup chipGroup,
final Reaction.Aggregated reactions,
final Consumer<Collection<String>> onModifiedReactions) {
setReactions(chipGroup, null, reactions, false, onModifiedReactions, null, null);
setReactions(chipGroup, null, reactions, false, onModifiedReactions, null, null, null);
}
private static void setReactions(
@ -50,6 +51,7 @@ public class BindingAdapters {
final boolean onReceived,
final Consumer<Collection<String>> onModifiedReactions,
final Consumer<EmojiSearch.CustomEmoji> onCustomReaction,
final Consumer<Reaction> onCustomReactionRemove,
final Runnable addReaction) {
final var context = chipGroup.getContext();
final var size = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 35, context.getResources().getDisplayMetrics());
@ -71,9 +73,9 @@ public class BindingAdapters {
chip.setLayoutParams(layoutParams);
chip.setChipCornerRadius(corner);
emoji.setupChip(chip, count);
final boolean oneOfOurs = aggregated.ourReactions.contains(emoji.toString());
final var oneOfOurs = reaction.getValue().stream().filter(r -> !r.received).findFirst();
// received = surface; sent = surface high matches bubbles
if (oneOfOurs) {
if (oneOfOurs.isPresent()) {
chip.setChipBackgroundColor(
MaterialColors.getColorStateListOrNull(
context,
@ -89,12 +91,16 @@ public class BindingAdapters {
chip.setTextStartPadding(0.0f);
chip.setOnClickListener(
v -> {
if (oneOfOurs) {
onModifiedReactions.accept(
if (oneOfOurs.isPresent()) {
if (emoji instanceof EmojiSearch.CustomEmoji) {
onCustomReactionRemove.accept(oneOfOurs.get());
} else {
onModifiedReactions.accept(
ImmutableSet.copyOf(
Collections2.filter(
aggregated.ourReactions,
r -> !r.equals(emoji.toString()))));
}
} else {
if (emoji instanceof EmojiSearch.CustomEmoji) {
onCustomReaction.accept((EmojiSearch.CustomEmoji) emoji);

View file

@ -1617,6 +1617,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
aggregatedReactions,
reactions -> sendReactions(message, reactions),
emoji -> sendCustomReaction(message, emoji),
reaction -> removeCustomReaction(conversation, reaction),
() -> addReaction(message));
} else if (type == SENT) {
final var aggregatedReactions = conversation instanceof Conversation ? ((Conversation) conversation).aggregatedReactionsFor(message, reactionThumbnailer) : message.getAggregatedReactions();
@ -1626,6 +1627,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
aggregatedReactions,
reactions -> sendReactions(message, reactions),
emoji -> sendCustomReaction(message, emoji),
reaction -> removeCustomReaction(conversation, reaction),
() -> addReaction(message));
}
@ -1708,6 +1710,26 @@ public class MessageAdapter extends ArrayAdapter<Message> {
new Thread(() -> activity.xmppConnectionService.sendMessage(message)).start();
}
private void removeCustomReaction(final Conversational conversation, final Reaction reaction) {
if (!(conversation instanceof Conversation)) {
Toast.makeText(activity, R.string.could_not_add_reaction, Toast.LENGTH_LONG).show();
return;
}
final var message = new Message(conversation, " ", ((Conversation) conversation).getNextEncryption());
final var envelope = ((Conversation) conversation).findMessageWithUuidOrRemoteId(reaction.envelopeId);
if (envelope != null) {
((Conversation) conversation).remove(envelope);
message.addPayload(envelope.getReply());
message.getOrMakeHtml();
message.putEdited(reaction.envelopeId, envelope.getServerMsgId());
} else {
message.putEdited(reaction.envelopeId, null);
}
new Thread(() -> activity.xmppConnectionService.sendMessage(message)).start();
}
private void addReaction(final Message message) {
activity.addReaction(message, reactions -> activity.xmppConnectionService.sendReactions(message,reactions));
}