diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index 2626b202b5be5c07e1c776c02ca52bb937062c5b..24f2a2ed7bdadc372cc0a5474c4d4230164166b4 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -193,7 +193,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl } public boolean setOutgoingChatState(ChatState state) { - if (mode == MODE_MULTI) { + if (mode == MODE_MULTI && getNextCounterpart() != null) { return false; } if (this.mOutgoingChatState != state) { diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index 3b1b64f982a00cb7ad96336bbe56b2c64bd06e16..9f9ba0a6b82020106df348dd2218b663a1001328 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -7,8 +7,10 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.xml.Namespace; +import eu.siacs.conversations.xmpp.chatstate.ChatState; import eu.siacs.conversations.xmpp.forms.Data; import eu.siacs.conversations.xmpp.forms.Field; import eu.siacs.conversations.xmpp.jid.InvalidJidException; @@ -49,6 +51,18 @@ public class MucOptions { return mAutoPushConfiguration; } + public boolean isSelf(Jid counterpart) { + return counterpart.getResourcepart().equals(getActualNick()); + } + + public void resetChatState() { + synchronized (users) { + for(User user : users) { + user.chatState = Config.DEFAULT_CHATSTATE; + } + } + } + public enum Affiliation { OWNER("owner", 4, R.string.owner), ADMIN("admin", 3, R.string.admin), @@ -154,6 +168,7 @@ public class MucOptions { private long pgpKeyId = 0; private Avatar avatar; private MucOptions options; + private ChatState chatState = Config.DEFAULT_CHATSTATE; public User(MucOptions options, Jid from) { this.options = options; @@ -319,6 +334,14 @@ public class MucOptions { public Jid getRealJid() { return realJid; } + + public boolean setChatState(ChatState chatState) { + if (this.chatState == chatState) { + return false; + } + this.chatState = chatState; + return true; + } } private Account account; @@ -521,6 +544,18 @@ public class MucOptions { } } + public ArrayList getUsersWithChatState(ChatState state) { + synchronized (users) { + ArrayList list = new ArrayList<>(); + for(User user : users) { + if (user.chatState == state) { + list.add(user); + } + } + return list; + } + } + public List getUsers(int max) { ArrayList subset = new ArrayList<>(); HashSet jids = new HashSet<>(); diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index ec0922baa2c572fcfc3f9b26d5a15d2ff900f717..bbe6455046a9abeae25efb9a7339e691e57dbe3a 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -155,7 +155,7 @@ public class MessageGenerator extends AbstractGenerator { public MessagePacket generateChatState(Conversation conversation) { final Account account = conversation.getAccount(); MessagePacket packet = new MessagePacket(); - packet.setType(MessagePacket.TYPE_CHAT); + packet.setType(conversation.getMode() == Conversation.MODE_MULTI ? MessagePacket.TYPE_GROUPCHAT : MessagePacket.TYPE_CHAT); packet.setTo(conversation.getJid().toBareJid()); packet.setFrom(account.getJid()); packet.addChild(ChatState.toElement(conversation.getOutgoingChatState())); diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 62075095679505cc7a6eb17f043210ec672f634c..1e9856bc53f8a54b7db585f5f6e16f933ea9f5f7 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -47,20 +47,29 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece super(service); } - private boolean extractChatState(Conversation conversation, final MessagePacket packet) { + private boolean extractChatState(Conversation c, final boolean isTypeGroupChat, final MessagePacket packet) { ChatState state = ChatState.parse(packet); - if (state != null && conversation != null) { - final Account account = conversation.getAccount(); + if (state != null && c != null) { + final Account account = c.getAccount(); Jid from = packet.getFrom(); if (from.toBareJid().equals(account.getJid().toBareJid())) { - conversation.setOutgoingChatState(state); + c.setOutgoingChatState(state); if (state == ChatState.ACTIVE || state == ChatState.COMPOSING) { - mXmppConnectionService.markRead(conversation); + mXmppConnectionService.markRead(c); activateGracePeriod(account); } return false; } else { - return conversation.setIncomingChatState(state); + if (isTypeGroupChat) { + MucOptions.User user = c.getMucOptions().findUserByFullJid(from); + if (user != null) { + return user.setChatState(state); + } else { + return false; + } + } else { + return c.setIncomingChatState(state); + } } } return false; @@ -396,9 +405,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece return; } - if (!isTypeGroupChat - && query == null - && extractChatState(mXmppConnectionService.find(account, counterpart.toBareJid()), packet)) { + if (query == null && extractChatState(mXmppConnectionService.find(account, counterpart.toBareJid()), isTypeGroupChat, packet)) { mXmppConnectionService.updateConversationUi(); } @@ -411,7 +418,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece } if (isTypeGroupChat) { - if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { + if (conversation.getMucOptions().isSelf(counterpart)) { status = Message.STATUS_SEND_RECEIVED; isCarbon = true; //not really carbon but received from another resource if (mXmppConnectionService.markMessage(conversation, remoteMsgId, status, serverMsgId)) { diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index aa8618adbe9b6e923d3752ecbd28e830ab47c379..e19d84903599473b977ee0d5638e79a2b5172425 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -2138,7 +2138,11 @@ public class XmppConnectionService extends Service { private void switchToForeground() { final boolean broadcastLastActivity = broadcastLastActivity(); for (Conversation conversation : getConversations()) { - conversation.setIncomingChatState(ChatState.ACTIVE); + if (conversation.getMode() == Conversation.MODE_MULTI) { + conversation.getMucOptions().resetChatState(); + } else { + conversation.setIncomingChatState(Config.DEFAULT_CHATSTATE); + } } for (Account account : getAccounts()) { if (account.getStatus() == Account.State.ONLINE) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 43fad234f342339a2cad9b4738ab9706af1d4f83..0b91e26c18ac2b6d916af0100ce4633acaca1c6a 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -828,7 +828,10 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } protected void privateMessageWith(final Jid counterpart) { - this.mEditMessage.setText(""); + if (conversation.setOutgoingChatState(Config.DEFAULT_CHATSTATE)) { + activity.xmppConnectionService.sendChatState(conversation); + } + this.mEditMessage.getEditableText().clear(); this.conversation.setNextCounterpart(counterpart); updateChatMsgHint(); updateSendButton();