mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-12-25 20:18:00 +01:00
Add Chat State Notifications support for group chat
This commit is contained in:
parent
8831961afe
commit
467a0821a0
1 changed files with 60 additions and 16 deletions
|
@ -33,18 +33,23 @@ import org.jivesoftware.smack.StanzaListener;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.chat2.Chat;
|
import org.jivesoftware.smack.chat2.Chat;
|
||||||
import org.jivesoftware.smack.chat2.ChatManager;
|
import org.jivesoftware.smack.chat2.ChatManager;
|
||||||
import org.jivesoftware.smack.chat2.OutgoingChatMessageListener;
|
|
||||||
import org.jivesoftware.smack.filter.AndFilter;
|
import org.jivesoftware.smack.filter.AndFilter;
|
||||||
import org.jivesoftware.smack.filter.FromTypeFilter;
|
|
||||||
import org.jivesoftware.smack.filter.MessageTypeFilter;
|
import org.jivesoftware.smack.filter.MessageTypeFilter;
|
||||||
|
import org.jivesoftware.smack.filter.MessageWithBodiesFilter;
|
||||||
import org.jivesoftware.smack.filter.NotFilter;
|
import org.jivesoftware.smack.filter.NotFilter;
|
||||||
|
import org.jivesoftware.smack.filter.OrFilter;
|
||||||
import org.jivesoftware.smack.filter.StanzaExtensionFilter;
|
import org.jivesoftware.smack.filter.StanzaExtensionFilter;
|
||||||
import org.jivesoftware.smack.filter.StanzaFilter;
|
import org.jivesoftware.smack.filter.StanzaFilter;
|
||||||
|
import org.jivesoftware.smack.filter.StanzaTypeFilter;
|
||||||
|
import org.jivesoftware.smack.filter.ToTypeFilter;
|
||||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
import org.jivesoftware.smack.packet.Stanza;
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
import org.jivesoftware.smackx.chatstates.packet.ChatStateExtension;
|
import org.jivesoftware.smackx.chatstates.packet.ChatStateExtension;
|
||||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||||
|
import org.jivesoftware.smackx.muc.MultiUserChat;
|
||||||
|
import org.jivesoftware.smackx.muc.MultiUserChatManager;
|
||||||
|
import org.jivesoftware.smackx.xhtmlim.packet.XHTMLExtension;
|
||||||
|
|
||||||
import org.jxmpp.jid.EntityBareJid;
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
import org.jxmpp.jid.EntityFullJid;
|
import org.jxmpp.jid.EntityFullJid;
|
||||||
|
@ -60,6 +65,7 @@ import org.jxmpp.jid.EntityFullJid;
|
||||||
*
|
*
|
||||||
* @author Alexander Wenckus
|
* @author Alexander Wenckus
|
||||||
* @author Paul Schaub
|
* @author Paul Schaub
|
||||||
|
* @author Eng ChongMeng
|
||||||
* @see org.jivesoftware.smackx.chatstates.ChatState
|
* @see org.jivesoftware.smackx.chatstates.ChatState
|
||||||
* @see org.jivesoftware.smackx.chatstates.packet.ChatStateExtension
|
* @see org.jivesoftware.smackx.chatstates.packet.ChatStateExtension
|
||||||
*/
|
*/
|
||||||
|
@ -72,9 +78,18 @@ public final class ChatStateManager extends Manager {
|
||||||
private static final Map<XMPPConnection, ChatStateManager> INSTANCES = new WeakHashMap<>();
|
private static final Map<XMPPConnection, ChatStateManager> INSTANCES = new WeakHashMap<>();
|
||||||
|
|
||||||
private static final StanzaFilter filter = new NotFilter(new StanzaExtensionFilter(NAMESPACE));
|
private static final StanzaFilter filter = new NotFilter(new StanzaExtensionFilter(NAMESPACE));
|
||||||
private static final StanzaFilter INCOMING_MESSAGE_FILTER =
|
private static final StanzaFilter INCOMING_CHAT_STATE_FILTER =
|
||||||
new AndFilter(MessageTypeFilter.NORMAL_OR_CHAT, FromTypeFilter.ENTITY_FULL_JID);
|
new AndFilter(StanzaTypeFilter.MESSAGE, new StanzaExtensionFilter(NAMESPACE)
|
||||||
private static final StanzaFilter INCOMING_CHAT_STATE_FILTER = new AndFilter(INCOMING_MESSAGE_FILTER, new StanzaExtensionFilter(NAMESPACE));
|
);
|
||||||
|
|
||||||
|
private static final StanzaFilter MESSAGE_FILTER = new AndFilter(
|
||||||
|
new OrFilter(MessageTypeFilter.NORMAL_OR_CHAT, MessageTypeFilter.GROUPCHAT),
|
||||||
|
new OrFilter(MessageWithBodiesFilter.INSTANCE, new StanzaExtensionFilter(XHTMLExtension.ELEMENT, XHTMLExtension.NAMESPACE))
|
||||||
|
);
|
||||||
|
|
||||||
|
private static final StanzaFilter OUTGOING_MESSAGE_FILTER =
|
||||||
|
new AndFilter( MESSAGE_FILTER, ToTypeFilter.ENTITY_FULL_OR_BARE_JID
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registered ChatStateListeners
|
* Registered ChatStateListeners
|
||||||
|
@ -82,9 +97,9 @@ public final class ChatStateManager extends Manager {
|
||||||
private final Set<ChatStateListener> chatStateListeners = new HashSet<>();
|
private final Set<ChatStateListener> chatStateListeners = new HashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps chat to last chat state.
|
* Maps chat/mucChat to last chat state.
|
||||||
*/
|
*/
|
||||||
private final Map<Chat, ChatState> chatStates = new WeakHashMap<>();
|
private final Map<Object, ChatState> chatStates = new WeakHashMap<>();
|
||||||
|
|
||||||
private final AsyncButOrdered<Chat> asyncButOrdered = new AsyncButOrdered<>();
|
private final AsyncButOrdered<Chat> asyncButOrdered = new AsyncButOrdered<>();
|
||||||
|
|
||||||
|
@ -113,24 +128,32 @@ public final class ChatStateManager extends Manager {
|
||||||
private ChatStateManager(XMPPConnection connection) {
|
private ChatStateManager(XMPPConnection connection) {
|
||||||
super(connection);
|
super(connection);
|
||||||
ChatManager chatManager = ChatManager.getInstanceFor(connection);
|
ChatManager chatManager = ChatManager.getInstanceFor(connection);
|
||||||
chatManager.addOutgoingListener(new OutgoingChatMessageListener() {
|
MultiUserChatManager multiUserChatManager = MultiUserChatManager.getInstanceFor(connection);
|
||||||
|
|
||||||
|
connection.addStanzaInterceptor(new StanzaListener() {
|
||||||
@Override
|
@Override
|
||||||
public void newOutgoingMessage(EntityBareJid to, Message message, Chat chat) {
|
public void processStanza(Stanza stanza) throws NotConnectedException, InterruptedException {
|
||||||
if (chat == null) {
|
Message message = (Message) stanza;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if message already has a chatStateExtension, then do nothing,
|
// if message already has a chatStateExtension, then do nothing,
|
||||||
if (!filter.accept(message)) {
|
if (!filter.accept(message)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object chat;
|
||||||
|
EntityBareJid entityBareJid = message.getTo().asEntityBareJidIfPossible();
|
||||||
|
if (message.getType() == Message.Type.groupchat) {
|
||||||
|
chat = multiUserChatManager.getMultiUserChat(entityBareJid);
|
||||||
|
} else {
|
||||||
|
chat = chatManager.chatWith(entityBareJid);
|
||||||
|
}
|
||||||
|
|
||||||
// otherwise add a chatState extension if necessary.
|
// otherwise add a chatState extension if necessary.
|
||||||
if (updateChatState(chat, ChatState.active)) {
|
if (updateChatState(chat, ChatState.active)) {
|
||||||
message.addExtension(new ChatStateExtension(ChatState.active));
|
message.addExtension(new ChatStateExtension(ChatState.active));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}, OUTGOING_MESSAGE_FILTER);
|
||||||
|
|
||||||
connection.addSyncStanzaListener(new StanzaListener() {
|
connection.addSyncStanzaListener(new StanzaListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -199,7 +222,6 @@ public final class ChatStateManager extends Manager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current state of the provided chat. This method will send an empty bodied Message
|
* Sets the current state of the provided chat. This method will send an empty bodied Message
|
||||||
* stanza with the state attached as a {@link org.jivesoftware.smack.packet.ExtensionElement}, if
|
* stanza with the state attached as a {@link org.jivesoftware.smack.packet.ExtensionElement}, if
|
||||||
|
@ -224,6 +246,29 @@ public final class ChatStateManager extends Manager {
|
||||||
chat.send(message);
|
chat.send(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current state of the provided mucchat. This method will send an empty bodied Message
|
||||||
|
* stanza with the state attached as a {@link org.jivesoftware.smack.packet.ExtensionElement}, if
|
||||||
|
* and only if the new chat state is different than the last state.
|
||||||
|
*
|
||||||
|
* @param newState the new state of the chat
|
||||||
|
* @param mucChat the MultiUserChat instance
|
||||||
|
* @throws NotConnectedException if the XMPP connection is not connected.
|
||||||
|
* @throws InterruptedException if the calling thread was interrupted.
|
||||||
|
*/
|
||||||
|
public void setCurrentState(ChatState newState, MultiUserChat mucChat) throws NotConnectedException, InterruptedException {
|
||||||
|
if (mucChat == null || newState == null) {
|
||||||
|
throw new IllegalArgumentException("Arguments cannot be null.");
|
||||||
|
}
|
||||||
|
if (!updateChatState(mucChat, newState)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Message message = new Message();
|
||||||
|
ChatStateExtension extension = new ChatStateExtension(newState);
|
||||||
|
message.addExtension(extension);
|
||||||
|
|
||||||
|
mucChat.sendMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
|
@ -241,7 +286,7 @@ public final class ChatStateManager extends Manager {
|
||||||
return connection().hashCode();
|
return connection().hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized boolean updateChatState(Chat chat, ChatState newState) {
|
private synchronized boolean updateChatState(Object chat, ChatState newState) {
|
||||||
ChatState lastChatState = chatStates.get(chat);
|
ChatState lastChatState = chatStates.get(chat);
|
||||||
if (lastChatState != newState) {
|
if (lastChatState != newState) {
|
||||||
chatStates.put(chat, newState);
|
chatStates.put(chat, newState);
|
||||||
|
@ -249,5 +294,4 @@ public final class ChatStateManager extends Manager {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue