summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2015-10-15 09:48:29 (GMT)
committerTobias Markmann <tm@ayena.de>2015-10-15 11:44:29 (GMT)
commit582ca915b5b82ada46d1183a7b882455ee01b7b1 (patch)
tree27e0fdbf3bf457763003baf838eaab82fd6adf19
parentac6cf9659718a18b1ea22f72dbf0cdb64cbf9a24 (diff)
downloadswift-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.cpp6
-rw-r--r--Swift/Controllers/Chat/ChatsManager.cpp17
-rw-r--r--Swiften/Elements/ChatState.h3
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
@@ -173,11 +173,15 @@ void ChatController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> me
173 } 173 }
174 boost::shared_ptr<Message> message = messageEvent->getStanza(); 174 boost::shared_ptr<Message> message = messageEvent->getStanza();
175 JID from = message->getFrom(); 175 JID from = message->getFrom();
176 if (!from.equals(toJID_, JID::WithResource)) { 176 if (!from.equals(toJID_, JID::WithResource)) {
177 if (toJID_.equals(from, JID::WithoutResource) && toJID_.isBare()){ 177 if (toJID_.equals(from, JID::WithoutResource) && toJID_.isBare()){
178 setToJID(from); 178 // Bind controller to a full JID if message contains body text or is a typing chat state.
179 ChatState::ref chatState = message->getPayload<ChatState>();
180 if (!message->getBody().empty() || (chatState && chatState->getChatState() == ChatState::Composing)) {
181 setToJID(from);
182 }
179 } 183 }
180 } 184 }
181 chatStateTracker_->handleMessageReceived(message); 185 chatStateTracker_->handleMessageReceived(message);
182 chatStateNotifier_->receivedMessageFromContact(!!message->getPayload<ChatState>()); 186 chatStateNotifier_->receivedMessageFromContact(!!message->getPayload<ChatState>());
183 187
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
@@ -748,11 +748,16 @@ ChatController* ChatsManager::getChatControllerIfExists(const JID &contact, bool
748 return NULL; 748 return NULL;
749 } 749 }
750 //Need to look for an unbound window to bind first 750 //Need to look for an unbound window to bind first
751 JID bare(contact.toBare()); 751 JID bare(contact.toBare());
752 if (chatControllers_.find(bare) != chatControllers_.end()) { 752 if (chatControllers_.find(bare) != chatControllers_.end()) {
753 rebindControllerJID(bare, contact); 753 if (rebindIfNeeded) {
754 rebindControllerJID(bare, contact);
755 }
756 else {
757 return chatControllers_[bare];
758 }
754 } else { 759 } else {
755 foreach (JIDChatControllerPair pair, chatControllers_) { 760 foreach (JIDChatControllerPair pair, chatControllers_) {
756 if (pair.first.toBare() == contact.toBare()) { 761 if (pair.first.toBare() == contact.toBare()) {
757 if (rebindIfNeeded) { 762 if (rebindIfNeeded) {
758 rebindControllerJID(pair.first, contact); 763 rebindControllerJID(pair.first, contact);
@@ -907,11 +912,19 @@ void ChatsManager::handleIncomingMessage(boost::shared_ptr<Message> message) {
907 } 912 }
908 913
909 //if not a mucroom 914 //if not a mucroom
910 if (!event->isReadable() && !isInvite && !isMediatedInvite) { 915 if (!event->isReadable() && !isInvite && !isMediatedInvite) {
911 /* Only route such messages if a window exists, don't open new windows for them.*/ 916 /* Only route such messages if a window exists, don't open new windows for them.*/
912 ChatController* controller = getChatControllerIfExists(jid); 917
918 // Do not bind a controller to a full JID, for delivery receipts or chat state notifications.
919 bool bindControllerToJID = false;
920 ChatState::ref chatState = message->getPayload<ChatState>();
921 if (!message->getBody().empty() || (chatState && chatState->getChatState() == ChatState::Composing)) {
922 bindControllerToJID = true;
923 }
924
925 ChatController* controller = getChatControllerIfExists(jid, bindControllerToJID);
913 if (controller) { 926 if (controller) {
914 controller->handleIncomingMessage(event); 927 controller->handleIncomingMessage(event);
915 } 928 }
916 } else { 929 } else {
917 getChatControllerOrCreate(jid)->handleIncomingMessage(event); 930 getChatControllerOrCreate(jid)->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
@@ -12,10 +12,13 @@
12#include <Swiften/Elements/Payload.h> 12#include <Swiften/Elements/Payload.h>
13 13
14namespace Swift { 14namespace Swift {
15 class SWIFTEN_API ChatState : public Payload { 15 class SWIFTEN_API ChatState : public Payload {
16 public: 16 public:
17 typedef boost::shared_ptr<ChatState> ref;
18
19 public:
17 enum ChatStateType {Active, Composing, Paused, Inactive, Gone}; 20 enum ChatStateType {Active, Composing, Paused, Inactive, Gone};
18 ChatState(ChatStateType state = Active) { 21 ChatState(ChatStateType state = Active) {
19 state_ = state; 22 state_ = state;
20 } 23 }
21 24