diff --git a/source/org/jivesoftware/smack/Chat.java b/source/org/jivesoftware/smack/Chat.java index 14429e630..9dcdd3a24 100644 --- a/source/org/jivesoftware/smack/Chat.java +++ b/source/org/jivesoftware/smack/Chat.java @@ -169,4 +169,12 @@ public class Chat { listener.processMessage(this, message); } } + + + @Override + public boolean equals(Object obj) { + return obj instanceof Chat + && threadID.equals(((Chat)obj).getThreadID()) + && participant.equals(((Chat)obj).getParticipant()); + } } \ No newline at end of file diff --git a/source/org/jivesoftware/smack/ChatManager.java b/source/org/jivesoftware/smack/ChatManager.java index d45502685..90184e597 100644 --- a/source/org/jivesoftware/smack/ChatManager.java +++ b/source/org/jivesoftware/smack/ChatManager.java @@ -177,7 +177,7 @@ public class ChatManager { return jidChats.get(userJID); } - private Chat getThreadChat(String thread) { + public Chat getThreadChat(String thread) { return threadChats.get(thread); } diff --git a/source/org/jivesoftware/smackx/ChatStateManager.java b/source/org/jivesoftware/smackx/ChatStateManager.java index 72e7c2333..40c43aee4 100644 --- a/source/org/jivesoftware/smackx/ChatStateManager.java +++ b/source/org/jivesoftware/smackx/ChatStateManager.java @@ -21,6 +21,7 @@ package org.jivesoftware.smackx; import org.jivesoftware.smack.*; +import org.jivesoftware.smack.util.collections.ReferenceMap; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.filter.NotFilter; import org.jivesoftware.smack.filter.PacketExtensionFilter; @@ -46,6 +47,9 @@ public class ChatStateManager { private static Map managers = new WeakHashMap(); + private static PacketFilter filter = new NotFilter( + new PacketExtensionFilter("http://jabber.org/protocol/chatstates")); + /** * Returns the ChatStateManager related to the XMPPConnection and it will create one if it does * not yet exist. @@ -72,13 +76,17 @@ public class ChatStateManager { private IncomingMessageInterceptor incomingInterceptor = new IncomingMessageInterceptor(); + /** + * Maps chat to last chat state. + */ + private Map chatStates = new ReferenceMap(ReferenceMap.WEAK, + ReferenceMap.HARD); + private ChatStateManager(XMPPConnection connection) { this.connection = connection; } private void init() { - PacketFilter filter = new NotFilter( - new PacketExtensionFilter("http://jabber.org/protocol/chatstates")); connection.getChatManager().addOutgoingMessageInterceptor(outgoingInterceptor, filter); connection.getChatManager().addChatListener(incomingInterceptor); @@ -98,6 +106,9 @@ public class ChatStateManager { * packet. */ public void setCurrentState(ChatState newState, Chat chat) throws XMPPException { + if(!updateChatState(chat, newState)) { + return; + } Message message = new Message(); ChatStateExtension extension = new ChatStateExtension(newState); message.addExtension(extension); @@ -105,6 +116,15 @@ public class ChatStateManager { chat.sendMessage(message); } + private boolean updateChatState(Chat chat, ChatState newState) { + ChatState lastChatState = chatStates.get(chat); + if (lastChatState == null || lastChatState != newState) { + chatStates.put(chat, lastChatState); + return true; + } + return false; + } + private void fireNewChatState(Chat chat, ChatState state) { for (MessageListener listener : chat.getListeners()) { if (listener instanceof ChatStateListener) { @@ -116,11 +136,14 @@ public class ChatStateManager { private class OutgoingMessageInterceptor implements PacketInterceptor { public void interceptPacket(Packet packet) { - if (!(packet instanceof Message)) { + Message message = (Message) packet; + Chat chat = connection.getChatManager().getThreadChat(message.getThread()); + if (chat == null) { return; } - Message message = (Message) packet; - message.addExtension(new ChatStateExtension(ChatState.active)); + if (updateChatState(chat, ChatState.active)) { + message.addExtension(new ChatStateExtension(ChatState.active)); + } } }