diff options
| author | Kevin Smith <git@kismith.co.uk> | 2010-08-31 19:10:57 (GMT) | 
|---|---|---|
| committer | Kevin Smith <git@kismith.co.uk> | 2010-09-03 10:02:35 (GMT) | 
| commit | eb50ea03ab7fc41610a8945002fe19dd30ffb5d7 (patch) | |
| tree | d26d378e2996b163f13562488eb2bbc31d89db04 /Swift/Controllers/Chat/MUCController.cpp | |
| parent | 276d7f82ba42cdbc65ec5c9f35873a265a69bd73 (diff) | |
| download | swift-contrib-eb50ea03ab7fc41610a8945002fe19dd30ffb5d7.zip swift-contrib-eb50ea03ab7fc41610a8945002fe19dd30ffb5d7.tar.bz2  | |
Squash presence in chat and MUC windows.
Join/Parts will be shown in one block if they're uninterrupted, and only the last presence change in a row will be shown for chats.
Resolves: #230
Resolves: #430
Diffstat (limited to 'Swift/Controllers/Chat/MUCController.cpp')
| -rw-r--r-- | Swift/Controllers/Chat/MUCController.cpp | 86 | 
1 files changed, 84 insertions, 2 deletions
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index 5858127..3b37179 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -10,6 +10,7 @@  #include "Swiften/Network/Timer.h"  #include "Swiften/Network/TimerFactory.h" +#include "Swiften/Base/foreach.h"  #include "SwifTools/TabComplete.h"  #include "Swiften/Base/foreach.h"  #include "Swift/Controllers/EventController.h" @@ -50,6 +51,7 @@ MUCController::MUCController (  			ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc, presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController), muc_(new MUC(stanzaChannel, presenceSender, muc)), nick_(nick) {  	parting_ = true;  	joined_ = false; +	lastWasPresence_ = false;  	events_ = uiEventStream;  	roster_ = new Roster(false, true); @@ -142,6 +144,7 @@ void MUCController::handleJoinComplete(const String& nick) {  	String joinMessage = "You have joined room " + toJID_.toString() + " as " + nick;  	nick_ = nick;  	chatWindow_->addSystemMessage(joinMessage); +	clearPresenceQueue();  	setEnabled(true);  } @@ -170,6 +173,8 @@ void MUCController::handleOccupantJoined(const MUCOccupant& occupant) {  		realJID = occupant.getRealJID().get();  	}  	currentOccupants_.insert(occupant.getNick()); +	NickJoinPart event(occupant.getNick(), Join); +	appendToJoinParts(joinParts_, event);  	roster_->addContact(jid, realJID, occupant.getNick(), roleToGroupName(occupant.getRole()));  	if (joined_) {  		String joinString = occupant.getNick() + " has joined the room"; @@ -179,13 +184,28 @@ void MUCController::handleOccupantJoined(const MUCOccupant& occupant) {  		}  		joinString += "."; -		chatWindow_->addPresenceMessage(joinString); +		if (shouldUpdateJoinParts()) { +			updateJoinParts(); +		} else { +			addPresenceMessage(joinString); + +		}  	}  	if (avatarManager_ != NULL) {  		handleAvatarChanged(jid, "dummy");  	}  } +void MUCController::addPresenceMessage(const String& message) { +	lastWasPresence_ = true; +	chatWindow_->addPresenceMessage(message); +} + +void MUCController::clearPresenceQueue() { +	lastWasPresence_ = false; +	joinParts_.clear(); +} +  String MUCController::roleToFriendlyName(MUCOccupant::Role role) {  	switch (role) {  	case MUCOccupant::Moderator: return "moderator"; @@ -205,6 +225,7 @@ bool MUCController::messageTargetsMe(boost::shared_ptr<Message> message) {  }  void MUCController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) { +	clearPresenceQueue();  	boost::shared_ptr<Message> message = messageEvent->getStanza();  	if (joined_ && messageTargetsMe(message) && !message->getPayload<Delay>()) {  		eventController_->handleIncomingEvent(messageEvent); @@ -260,7 +281,13 @@ void MUCController::setEnabled(bool enabled) {  	}  } +bool MUCController::shouldUpdateJoinParts() { +	return lastWasPresence_; +} +  void MUCController::handleOccupantLeft(const MUCOccupant& occupant, MUC::LeavingType, const String& reason) { +	NickJoinPart event(occupant.getNick(), Part); +	appendToJoinParts(joinParts_, event);  	currentOccupants_.erase(occupant.getNick());  	completer_->removeWord(occupant.getNick());  	String partMessage = (occupant.getNick() != nick_) ? occupant.getNick() + " has left the room" : "You have left the room"; @@ -268,10 +295,16 @@ void MUCController::handleOccupantLeft(const MUCOccupant& occupant, MUC::Leaving  		partMessage += " (" + reason + ")";  	}  	partMessage += "."; -	chatWindow_->addPresenceMessage(partMessage); +  	if (occupant.getNick() != nick_) { +		if (shouldUpdateJoinParts()) { +			updateJoinParts(); +		} else { +			addPresenceMessage(partMessage); +		}  		roster_->removeContact(JID(toJID_.getNode(), toJID_.getDomain(), occupant.getNick()));  	} else { +		addPresenceMessage(partMessage);  		parting_ = true;  		setEnabled(false);  	} @@ -299,4 +332,53 @@ boost::optional<boost::posix_time::ptime> MUCController::getMessageTimestamp(boo  	return message->getTimestampFrom(toJID_);  } +void MUCController::updateJoinParts() { +	chatWindow_->replaceLastMessage(generateJoinPartString(joinParts_)); +} + +void MUCController::appendToJoinParts(std::vector<NickJoinPart>& joinParts, const NickJoinPart& newEvent) { +	std::vector<NickJoinPart>::iterator it = joinParts.begin(); +	bool matched = false; +	for (; it != joinParts.end(); it++) { +		if ((*it).nick == newEvent.nick) { +			matched = true; +			JoinPart type = (*it).type; +			switch (newEvent.type) { +				case Join: type = (type == Part) ? PartThenJoin : Join; break; +				case Part: type = (type == Join) ? JoinThenPart : Part; break; +				default: /*Nothing to see here */;break; +			} +			(*it).type = type; +			break; +		} +	} +	if (!matched) { +		joinParts.push_back(newEvent); +	} +} + +String MUCController::generateJoinPartString(std::vector<NickJoinPart> joinParts) { +	String result; +	for (size_t i = 0; i < joinParts.size(); i++) { +		if (i > 0) { +			if (i < joinParts.size() - 1) { +				result += ", "; +			} else { +				result += " and "; +			} +		} +		NickJoinPart event = joinParts[i]; +		result += event.nick; +		switch (event.type) { +			case Join: result += " has joined";break; +			case Part: result += " has left";break; +			case JoinThenPart: result += " joined then left";break; +			case PartThenJoin: result += " left then rejoined";break; +		} +		result += " the room"; +	} +	result += "."; +	return result; +} +  }  | 
 Swift