diff options
author | Tobias Markmann <tm@ayena.de> | 2015-10-15 09:48:29 (GMT) |
---|---|---|
committer | Tobias Markmann <tm@ayena.de> | 2015-10-15 11:44:29 (GMT) |
commit | 582ca915b5b82ada46d1183a7b882455ee01b7b1 (patch) | |
tree | 27e0fdbf3bf457763003baf838eaab82fd6adf19 | |
parent | ac6cf9659718a18b1ea22f72dbf0cdb64cbf9a24 (diff) | |
download | swift-582ca915b5b82ada46d1183a7b882455ee01b7b1.zip swift-582ca915b5b82ada46d1183a7b882455ee01b7b1.tar.bz2 |
Only bind full JID to ChatController on non-empty or typing messages
With this commit a ChatController is only bound to a full JID
of a contact, if the incoming message of the contact has a
non-empty body or is a 'typing' chat state notification.
This avoids random binding to an arbitrary resource of a contact,
that has multiple online resources and responds with delivery
receipts.
Test-Information:
Tested with a conversation of a one resource account (A) to a
two resource account (B). Sending two messages to B, the first
used to go to both resources, then A would bind to the full
JID and the second message would only go to one resource.
With this fix all messages go to both resources, i.e. are
send to the bare JID, until one resource of B replies. This
binds the controller at A to the full JID of the reply of B.
Change-Id: I8d9321a4226ab798e1196351ad087990d5dff8c3
-rw-r--r-- | Swift/Controllers/Chat/ChatController.cpp | 6 | ||||
-rw-r--r-- | Swift/Controllers/Chat/ChatsManager.cpp | 17 | ||||
-rw-r--r-- | Swiften/Elements/ChatState.h | 3 |
3 files changed, 23 insertions, 3 deletions
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp index 8c132d0..bedc427 100644 --- a/Swift/Controllers/Chat/ChatController.cpp +++ b/Swift/Controllers/Chat/ChatController.cpp @@ -175,7 +175,11 @@ void ChatController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> me JID from = message->getFrom(); if (!from.equals(toJID_, JID::WithResource)) { if (toJID_.equals(from, JID::WithoutResource) && toJID_.isBare()){ - setToJID(from); + // Bind controller to a full JID if message contains body text or is a typing chat state. + ChatState::ref chatState = message->getPayload<ChatState>(); + if (!message->getBody().empty() || (chatState && chatState->getChatState() == ChatState::Composing)) { + setToJID(from); + } } } chatStateTracker_->handleMessageReceived(message); diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index e11d14b..343f490 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -750,7 +750,12 @@ ChatController* ChatsManager::getChatControllerIfExists(const JID &contact, bool //Need to look for an unbound window to bind first JID bare(contact.toBare()); if (chatControllers_.find(bare) != chatControllers_.end()) { - rebindControllerJID(bare, contact); + if (rebindIfNeeded) { + rebindControllerJID(bare, contact); + } + else { + return chatControllers_[bare]; + } } else { foreach (JIDChatControllerPair pair, chatControllers_) { if (pair.first.toBare() == contact.toBare()) { @@ -909,7 +914,15 @@ void ChatsManager::handleIncomingMessage(boost::shared_ptr<Message> message) { //if not a mucroom if (!event->isReadable() && !isInvite && !isMediatedInvite) { /* Only route such messages if a window exists, don't open new windows for them.*/ - ChatController* controller = getChatControllerIfExists(jid); + + // Do not bind a controller to a full JID, for delivery receipts or chat state notifications. + bool bindControllerToJID = false; + ChatState::ref chatState = message->getPayload<ChatState>(); + if (!message->getBody().empty() || (chatState && chatState->getChatState() == ChatState::Composing)) { + bindControllerToJID = true; + } + + ChatController* controller = getChatControllerIfExists(jid, bindControllerToJID); if (controller) { controller->handleIncomingMessage(event); } diff --git a/Swiften/Elements/ChatState.h b/Swiften/Elements/ChatState.h index a7a8b1d..5f0bb9b 100644 --- a/Swiften/Elements/ChatState.h +++ b/Swiften/Elements/ChatState.h @@ -14,6 +14,9 @@ namespace Swift { class SWIFTEN_API ChatState : public Payload { public: + typedef boost::shared_ptr<ChatState> ref; + + public: enum ChatStateType {Active, Composing, Paused, Inactive, Gone}; ChatState(ChatStateType state = Active) { state_ = state; |