diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index b7faccecc..146c8cc91 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -289,6 +289,17 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl return null; } + public boolean hasMessageWithCounterpart(Jid counterpart) { + synchronized (this.messages) { + for(Message message : this.messages) { + if (counterpart.equals(message.getCounterpart())) { + return true; + } + } + } + return false; + } + public void populateWithMessages(final List messages) { synchronized (this.messages) { messages.clear(); diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index fe38108df..88596d173 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -43,8 +43,11 @@ import android.widget.Toast; import net.java.otr4j.session.SessionStatus; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; @@ -71,6 +74,7 @@ import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureClicked; import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureLongClicked; import eu.siacs.conversations.ui.widget.ListSelectionManager; import eu.siacs.conversations.utils.GeoHelper; +import eu.siacs.conversations.utils.NickValidityChecker; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.chatstate.ChatState; @@ -845,13 +849,15 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa editable.insert(pos, nick + ": "); } else { if (pos > 2 && editable.subSequence(pos-2,pos).toString().equals(": ")) { - editable.insert(pos-2,", "+nick); - } else { - editable.insert(pos, (Character.isWhitespace(before) ? "" : " ") + nick + (Character.isWhitespace(after) ? "" : " ")); - if (Character.isWhitespace(after)) { - mEditMessage.setSelection(mEditMessage.getSelectionStart() + 1); + if (NickValidityChecker.check(conversation,Arrays.asList(editable.subSequence(0,pos-2).toString().split(", ")))) { + editable.insert(pos - 2, ", " + nick); + return; } } + editable.insert(pos, (Character.isWhitespace(before) ? "" : " ") + nick + (Character.isWhitespace(after) ? "" : " ")); + if (Character.isWhitespace(after)) { + mEditMessage.setSelection(mEditMessage.getSelectionStart() + 1); + } } } } diff --git a/src/main/java/eu/siacs/conversations/utils/NickValidityChecker.java b/src/main/java/eu/siacs/conversations/utils/NickValidityChecker.java new file mode 100644 index 000000000..7db6ebd2c --- /dev/null +++ b/src/main/java/eu/siacs/conversations/utils/NickValidityChecker.java @@ -0,0 +1,33 @@ +package eu.siacs.conversations.utils; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.xmpp.jid.InvalidJidException; +import eu.siacs.conversations.xmpp.jid.Jid; + +public class NickValidityChecker { + + private static boolean check(final Conversation conversation, final String nick) { + Jid room = conversation.getJid(); + try { + Jid full = Jid.fromParts(room.getLocalpart(), room.getDomainpart(), nick); + return conversation.hasMessageWithCounterpart(full) + || conversation.getMucOptions().findUserByFullJid(full) != null; + } catch (InvalidJidException e) { + return false; + } + } + + public static boolean check(final Conversation conversation, final List nicks) { + Set previousNicks = new HashSet<>(nicks); + for(String previousNick : previousNicks) { + if (!NickValidityChecker.check(conversation,previousNick)) { + return false; + } + } + return true; + } +}