send and parse Chat States to and from conferences

This commit is contained in:
Daniel Gultsch 2017-03-07 14:36:05 +01:00
parent 8a3c996164
commit 5ea4322d3f
6 changed files with 63 additions and 14 deletions

View file

@ -193,7 +193,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
} }
public boolean setOutgoingChatState(ChatState state) { public boolean setOutgoingChatState(ChatState state) {
if (mode == MODE_MULTI) { if (mode == MODE_MULTI && getNextCounterpart() != null) {
return false; return false;
} }
if (this.mOutgoingChatState != state) { if (this.mOutgoingChatState != state) {

View file

@ -7,8 +7,10 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
import eu.siacs.conversations.xml.Namespace; 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.Data;
import eu.siacs.conversations.xmpp.forms.Field; import eu.siacs.conversations.xmpp.forms.Field;
import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.InvalidJidException;
@ -49,6 +51,18 @@ public class MucOptions {
return mAutoPushConfiguration; 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 { public enum Affiliation {
OWNER("owner", 4, R.string.owner), OWNER("owner", 4, R.string.owner),
ADMIN("admin", 3, R.string.admin), ADMIN("admin", 3, R.string.admin),
@ -154,6 +168,7 @@ public class MucOptions {
private long pgpKeyId = 0; private long pgpKeyId = 0;
private Avatar avatar; private Avatar avatar;
private MucOptions options; private MucOptions options;
private ChatState chatState = Config.DEFAULT_CHATSTATE;
public User(MucOptions options, Jid from) { public User(MucOptions options, Jid from) {
this.options = options; this.options = options;
@ -319,6 +334,14 @@ public class MucOptions {
public Jid getRealJid() { public Jid getRealJid() {
return realJid; return realJid;
} }
public boolean setChatState(ChatState chatState) {
if (this.chatState == chatState) {
return false;
}
this.chatState = chatState;
return true;
}
} }
private Account account; private Account account;
@ -521,6 +544,18 @@ public class MucOptions {
} }
} }
public ArrayList<User> getUsersWithChatState(ChatState state) {
synchronized (users) {
ArrayList<User> list = new ArrayList<>();
for(User user : users) {
if (user.chatState == state) {
list.add(user);
}
}
return list;
}
}
public List<User> getUsers(int max) { public List<User> getUsers(int max) {
ArrayList<User> subset = new ArrayList<>(); ArrayList<User> subset = new ArrayList<>();
HashSet<Jid> jids = new HashSet<>(); HashSet<Jid> jids = new HashSet<>();

View file

@ -155,7 +155,7 @@ public class MessageGenerator extends AbstractGenerator {
public MessagePacket generateChatState(Conversation conversation) { public MessagePacket generateChatState(Conversation conversation) {
final Account account = conversation.getAccount(); final Account account = conversation.getAccount();
MessagePacket packet = new MessagePacket(); 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.setTo(conversation.getJid().toBareJid());
packet.setFrom(account.getJid()); packet.setFrom(account.getJid());
packet.addChild(ChatState.toElement(conversation.getOutgoingChatState())); packet.addChild(ChatState.toElement(conversation.getOutgoingChatState()));

View file

@ -47,20 +47,29 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
super(service); 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); ChatState state = ChatState.parse(packet);
if (state != null && conversation != null) { if (state != null && c != null) {
final Account account = conversation.getAccount(); final Account account = c.getAccount();
Jid from = packet.getFrom(); Jid from = packet.getFrom();
if (from.toBareJid().equals(account.getJid().toBareJid())) { if (from.toBareJid().equals(account.getJid().toBareJid())) {
conversation.setOutgoingChatState(state); c.setOutgoingChatState(state);
if (state == ChatState.ACTIVE || state == ChatState.COMPOSING) { if (state == ChatState.ACTIVE || state == ChatState.COMPOSING) {
mXmppConnectionService.markRead(conversation); mXmppConnectionService.markRead(c);
activateGracePeriod(account); activateGracePeriod(account);
} }
return false; return false;
} else { } 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; return false;
@ -396,9 +405,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
return; return;
} }
if (!isTypeGroupChat if (query == null && extractChatState(mXmppConnectionService.find(account, counterpart.toBareJid()), isTypeGroupChat, packet)) {
&& query == null
&& extractChatState(mXmppConnectionService.find(account, counterpart.toBareJid()), packet)) {
mXmppConnectionService.updateConversationUi(); mXmppConnectionService.updateConversationUi();
} }
@ -411,7 +418,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
} }
if (isTypeGroupChat) { if (isTypeGroupChat) {
if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { if (conversation.getMucOptions().isSelf(counterpart)) {
status = Message.STATUS_SEND_RECEIVED; status = Message.STATUS_SEND_RECEIVED;
isCarbon = true; //not really carbon but received from another resource isCarbon = true; //not really carbon but received from another resource
if (mXmppConnectionService.markMessage(conversation, remoteMsgId, status, serverMsgId)) { if (mXmppConnectionService.markMessage(conversation, remoteMsgId, status, serverMsgId)) {

View file

@ -2138,7 +2138,11 @@ public class XmppConnectionService extends Service {
private void switchToForeground() { private void switchToForeground() {
final boolean broadcastLastActivity = broadcastLastActivity(); final boolean broadcastLastActivity = broadcastLastActivity();
for (Conversation conversation : getConversations()) { 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()) { for (Account account : getAccounts()) {
if (account.getStatus() == Account.State.ONLINE) { if (account.getStatus() == Account.State.ONLINE) {

View file

@ -828,7 +828,10 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
} }
protected void privateMessageWith(final Jid counterpart) { 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); this.conversation.setNextCounterpart(counterpart);
updateChatMsgHint(); updateChatMsgHint();
updateSendButton(); updateSendButton();