summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoanna Hulboj <joanna.hulboj@isode.com>2017-02-09 11:55:31 (GMT)
committerKevin Smith <kevin.smith@isode.com>2017-02-22 16:24:03 (GMT)
commit773c181d57085905d8a989f2f1cb644c747e63ab (patch)
tree7ccccc13f7aeda67b182ea441b1489dadf35f0c1 /Swift/Controllers/Chat/MUCController.cpp
parentce307c6531053fc7edb966ba9bc2149f73cd18c2 (diff)
downloadswift-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.cpp16
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();