diff options
author | Joanna Hulboj <joanna.hulboj@isode.com> | 2017-02-09 11:55:31 (GMT) |
---|---|---|
committer | Kevin Smith <kevin.smith@isode.com> | 2017-02-22 16:24:03 (GMT) |
commit | 773c181d57085905d8a989f2f1cb644c747e63ab (patch) | |
tree | 7ccccc13f7aeda67b182ea441b1489dadf35f0c1 /Swift/Controllers/Chat/MUCController.cpp | |
parent | ce307c6531053fc7edb966ba9bc2149f73cd18c2 (diff) | |
download | swift-773c181d57085905d8a989f2f1cb644c747e63ab.zip swift-773c181d57085905d8a989f2f1cb644c747e63ab.tar.bz2 |
Fix double entries in MUC participant lists after merging nicks
Test-Information:
Tested using Psi and Swift.
Log in to Psi and Swift as UserOne. Enter Room (e.g. testRoom) using Swift and join the same room from Psi using drop down menu Join Groupchat.
Splitting: change nick from UserOne to UserTwo. Swift correctly
displays: UserOne, UserTwo.
Merging: change nick back from UserTwo to UsetOne. Swift correctly
displays: UserOne.
Change-Id: I291eddd5aed154fb0babe1b0ada0a15a317eacdb
Diffstat (limited to 'Swift/Controllers/Chat/MUCController.cpp')
-rw-r--r-- | Swift/Controllers/Chat/MUCController.cpp | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index 8f43b08..9d1459d 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -60,82 +60,82 @@ namespace Swift { class MUCBookmarkPredicate { public: MUCBookmarkPredicate(const JID& mucJID) : roomJID_(mucJID) { } bool operator()(const MUCBookmark& operand) { return operand.getRoom() == roomJID_; } private: JID roomJID_; }; /** * The controller does not gain ownership of the stanzaChannel, nor the factory. */ MUCController::MUCController ( const JID& self, MUC::ref muc, const boost::optional<std::string>& password, const std::string &nick, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* uiEventStream, bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController, EntityCapsProvider* entityCapsProvider, - XMPPRoster* roster, + XMPPRoster* xmppRoster, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, std::shared_ptr<ChatMessageParser> chatMessageParser, bool isImpromptu, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider, VCardManager* vcardManager, MUCBookmarkManager* mucBookmarkManager) : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc->getJID(), presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager, chatMessageParser, autoAcceptMUCInviteDecider), muc_(muc), nick_(nick), desiredNick_(nick), password_(password), renameCounter_(0), isImpromptu_(isImpromptu), isImpromptuAlreadyConfigured_(false), clientBlockListManager_(clientBlockListManager), mucBookmarkManager_(mucBookmarkManager) { parting_ = true; joined_ = false; lastWasPresence_ = false; shouldJoinOnReconnect_ = true; doneGettingHistory_ = false; - xmppRoster_ = roster; + xmppRoster_ = xmppRoster; - roster_ = new Roster(false, true); - rosterVCardProvider_ = new RosterVCardProvider(roster_, vcardManager, JID::WithResource); + roster_ = std::unique_ptr<Roster>(new Roster(false, true)); + rosterVCardProvider_ = new RosterVCardProvider(roster_.get(), vcardManager, JID::WithResource); completer_ = new TabComplete(); - chatWindow_->setRosterModel(roster_); + chatWindow_->setRosterModel(roster_.get()); chatWindow_->setTabComplete(completer_); chatWindow_->onClosed.connect(boost::bind(&MUCController::handleWindowClosed, this)); chatWindow_->onOccupantSelectionChanged.connect(boost::bind(&MUCController::handleWindowOccupantSelectionChanged, this, _1)); chatWindow_->onOccupantActionSelected.connect(boost::bind(&MUCController::handleActionRequestedOnOccupant, this, _1, _2)); chatWindow_->onChangeSubjectRequest.connect(boost::bind(&MUCController::handleChangeSubjectRequest, this, _1)); chatWindow_->onBookmarkRequest.connect(boost::bind(&MUCController::handleBookmarkRequest, this)); chatWindow_->onConfigureRequest.connect(boost::bind(&MUCController::handleConfigureRequest, this, _1)); chatWindow_->onConfigurationFormCancelled.connect(boost::bind(&MUCController::handleConfigurationCancelled, this)); chatWindow_->onDestroyRequest.connect(boost::bind(&MUCController::handleDestroyRoomRequest, this)); chatWindow_->onInviteToChat.connect(boost::bind(&MUCController::handleInvitePersonToThisMUCRequest, this, _1)); chatWindow_->onGetAffiliationsRequest.connect(boost::bind(&MUCController::handleGetAffiliationsRequest, this)); chatWindow_->onChangeAffiliationsRequest.connect(boost::bind(&MUCController::handleChangeAffiliationsRequest, this, _1)); chatWindow_->onUnblockUserRequest.connect(boost::bind(&MUCController::handleUnblockUserRequest, this)); muc_->onJoinComplete.connect(boost::bind(&MUCController::handleJoinComplete, this, _1)); muc_->onJoinFailed.connect(boost::bind(&MUCController::handleJoinFailed, this, _1)); muc_->onOccupantJoined.connect(boost::bind(&MUCController::handleOccupantJoined, this, _1)); muc_->onOccupantNicknameChanged.connect(boost::bind(&MUCController::handleOccupantNicknameChanged, this, _1, _2)); muc_->onOccupantPresenceChange.connect(boost::bind(&MUCController::handleOccupantPresenceChange, this, _1)); muc_->onOccupantLeft.connect(boost::bind(&MUCController::handleOccupantLeft, this, _1, _2, _3)); muc_->onRoleChangeFailed.connect(boost::bind(&MUCController::handleOccupantRoleChangeFailed, this, _1, _2, _3)); muc_->onAffiliationListReceived.connect(boost::bind(&MUCController::handleAffiliationListReceived, this, _1, _2)); muc_->onConfigurationFailed.connect(boost::bind(&MUCController::handleConfigurationFailed, this, _1)); muc_->onConfigurationFormReceived.connect(boost::bind(&MUCController::handleConfigurationFormReceived, this, _1)); highlighter_->setMode(isImpromptu_ ? Highlighter::ChatMode : Highlighter::MUCMode); highlighter_->setNick(nick_); if (timerFactory && stanzaChannel_->isAvailable()) { loginCheckTimer_ = std::shared_ptr<Timer>(timerFactory->createTimer(MUC_JOIN_WARNING_TIMEOUT_MILLISECONDS)); loginCheckTimer_->onTick.connect(boost::bind(&MUCController::handleJoinTimeoutTick, this)); loginCheckTimer_->start(); } @@ -152,61 +152,60 @@ MUCController::MUCController ( chatWindow_->setName(muc->getJID().getNode()); } if (stanzaChannel->isAvailable()) { MUCController::setOnline(true); } if (avatarManager_ != nullptr) { avatarChangedConnection_ = (avatarManager_->onAvatarChanged.connect(boost::bind(&MUCController::handleAvatarChanged, this, _1))); } MUCController::handleBareJIDCapsChanged(muc->getJID()); eventStream_->onUIEvent.connect(boost::bind(&MUCController::handleUIEvent, this, _1)); // setup handling of MUC bookmark changes mucBookmarkManagerBookmarkAddedConnection_ = (mucBookmarkManager_->onBookmarkAdded.connect(boost::bind(&MUCController::handleMUCBookmarkAdded, this, _1))); mucBookmarkManagerBookmarkRemovedConnection_ = (mucBookmarkManager_->onBookmarkRemoved.connect(boost::bind(&MUCController::handleMUCBookmarkRemoved, this, _1))); std::vector<MUCBookmark> mucBookmarks = mucBookmarkManager_->getBookmarks(); std::vector<MUCBookmark>::iterator bookmarkIterator = std::find_if(mucBookmarks.begin(), mucBookmarks.end(), MUCBookmarkPredicate(muc->getJID())); if (bookmarkIterator != mucBookmarks.end()) { updateChatWindowBookmarkStatus(*bookmarkIterator); } else { updateChatWindowBookmarkStatus(boost::optional<MUCBookmark>()); } } MUCController::~MUCController() { eventStream_->onUIEvent.disconnect(boost::bind(&MUCController::handleUIEvent, this, _1)); chatWindow_->setRosterModel(nullptr); delete rosterVCardProvider_; - delete roster_; if (loginCheckTimer_) { loginCheckTimer_->stop(); } chatWindow_->setTabComplete(nullptr); delete completer_; } void MUCController::cancelReplaces() { lastWasPresence_ = false; } void MUCController::handleWindowOccupantSelectionChanged(ContactRosterItem* item) { std::vector<ChatWindow::OccupantAction> actions; if (item) { MUCOccupant::Affiliation affiliation = muc_->getOccupant(getNick()).getAffiliation(); MUCOccupant::Role role = muc_->getOccupant(getNick()).getRole(); if (role == MUCOccupant::Moderator && !isImpromptu_) { if (affiliation == MUCOccupant::Admin || affiliation == MUCOccupant::Owner) { actions.push_back(ChatWindow::Ban); } actions.push_back(ChatWindow::Kick); actions.push_back(ChatWindow::MakeModerator); actions.push_back(ChatWindow::MakeParticipant); actions.push_back(ChatWindow::MakeVisitor); } // Add contact is available only if the real JID is also available if (muc_->getOccupant(item->getJID().getResource()).getRealJID()) { @@ -737,60 +736,65 @@ void MUCController::handleOccupantLeft(const MUCOccupant& occupant, MUC::Leaving roster_->removeContact(JID(toJID_.getNode(), toJID_.getDomain(), occupant.getNick())); } else { addPresenceMessage(partMessage); parting_ = true; processUserPart(); } if (clearAfter) { clearPresenceQueue(); } if (isImpromptu_) { setImpromptuWindowTitle(); } } void MUCController::handleOccupantNicknameChanged(const std::string& oldNickname, const std::string& newNickname) { addPresenceMessage(generateNicknameChangeString(oldNickname, newNickname)); JID oldJID = muc_->getJID().withResource(oldNickname); JID newJID = muc_->getJID().withResource(newNickname); // adjust occupants currentOccupants_.erase(oldNickname); currentOccupants_.insert(newNickname); // adjust completer completer_->removeWord(oldNickname); completer_->addWord(newNickname); // update contact roster_->removeContact(oldJID); + auto it = currentOccupants_.find(newNickname); + if (it != currentOccupants_.end()) { + roster_->removeContact(newJID); + } + MUCOccupant occupant = muc_->getOccupant(newNickname); JID realJID; if (occupant.getRealJID()) { realJID = occupant.getRealJID().get(); } MUCOccupant::Role role = MUCOccupant::Participant; MUCOccupant::Affiliation affiliation = MUCOccupant::NoAffiliation; if (!isImpromptu_) { role = occupant.getRole(); affiliation = occupant.getAffiliation(); } std::string groupName(roleToGroupName(role)); roster_->addContact(newJID, realJID, newNickname, groupName, avatarManager_->getAvatarPath(newJID)); roster_->applyOnItems(SetMUC(newJID, role, affiliation)); if (avatarManager_ != nullptr) { handleAvatarChanged(newJID); } clearPresenceQueue(); onUserNicknameChanged(oldNickname, newNickname); } void MUCController::handleOccupantPresenceChange(std::shared_ptr<Presence> presence) { receivedActivity(); roster_->applyOnItems(SetPresence(presence, JID::WithResource)); } bool MUCController::isIncomingMessageFromMe(std::shared_ptr<Message> message) { JID from = message->getFrom(); |