From 8774d67aabd02086ec0663bb4567cef14bd513c6 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Mon, 8 Nov 2010 22:39:28 +0000
Subject: Brute force application of presence to roster items on add/modify.

Resolves: #655
Resolves: #672
Release-Notes: The roster should no longer sometimes show online users as offline.

diff --git a/Swift/Controllers/RosterController.cpp b/Swift/Controllers/RosterController.cpp
index 242f974..4df8d13 100644
--- a/Swift/Controllers/RosterController.cpp
+++ b/Swift/Controllers/RosterController.cpp
@@ -115,6 +115,13 @@ void RosterController::handleOnJIDAdded(const JID& jid) {
 	else {
 		roster_->addContact(jid, jid, name, "Contacts", avatarManager_->getAvatarPath(jid).string());
 	}
+	applyAllPresenceTo(jid);
+}
+
+void RosterController::applyAllPresenceTo(const JID& jid) {
+	foreach (Presence::ref presence, presenceOracle_->getAllPresence(jid)) {
+		roster_->applyOnItems(SetPresence(presence));
+	}
 }
 
 void RosterController::handleRosterCleared() {
@@ -150,10 +157,7 @@ void RosterController::handleOnJIDUpdated(const JID& jid, const String& oldName,
 			roster_->removeContactFromGroup(jid, group);
 		}
 	}
-	Presence::ref presence(presenceOracle_->getHighestPriorityPresence(jid));
-	if (presence) {
-		roster_->applyOnItems(SetPresence(presence));
-	}
+	applyAllPresenceTo(jid);
 }
 
 void RosterController::handleUIEvent(boost::shared_ptr<UIEvent> event) {
diff --git a/Swift/Controllers/RosterController.h b/Swift/Controllers/RosterController.h
index cc51d23..70f1288 100644
--- a/Swift/Controllers/RosterController.h
+++ b/Swift/Controllers/RosterController.h
@@ -60,6 +60,7 @@ namespace Swift {
 			void handleUIEvent(boost::shared_ptr<UIEvent> event);
 			void handleRosterSetError(boost::optional<ErrorPayload> error, boost::shared_ptr<RosterPayload> rosterPayload);
 			void handleOwnNickChanged(const String& nick);
+			void applyAllPresenceTo(const JID& jid);
 			JID myJID_;
 			XMPPRoster* xmppRoster_;
 			MainWindowFactory* mainWindowFactory_;
diff --git a/Swiften/Presence/PresenceOracle.cpp b/Swiften/Presence/PresenceOracle.cpp
index 387ad42..90e403c 100644
--- a/Swiften/Presence/PresenceOracle.cpp
+++ b/Swiften/Presence/PresenceOracle.cpp
@@ -76,6 +76,21 @@ Presence::ref PresenceOracle::getLastPresence(const JID& jid) const {
 	}
 }
 
+std::vector<Presence::ref> PresenceOracle::getAllPresence(const JID& bareJID) const {
+	std::vector<Presence::ref> results;
+	PresencesMap::const_iterator i = entries_.find(bareJID);
+	if (i == entries_.end()) {
+		return results;
+	}
+	PresenceMap presenceMap = i->second;
+	PresenceMap::const_iterator j = presenceMap.begin();
+	for (; j != presenceMap.end(); j++) {
+		Presence::ref current = j->second;
+		results.push_back(current);
+	}
+	return results;
+}
+
 Presence::ref PresenceOracle::getHighestPriorityPresence(const JID& bareJID) const {
 	PresencesMap::const_iterator i = entries_.find(bareJID);
 	if (i == entries_.end()) {
diff --git a/Swiften/Presence/PresenceOracle.h b/Swiften/Presence/PresenceOracle.h
index e846984..4e16e41 100644
--- a/Swiften/Presence/PresenceOracle.h
+++ b/Swiften/Presence/PresenceOracle.h
@@ -22,6 +22,7 @@ class StanzaChannel;
 
 			Presence::ref getLastPresence(const JID&) const;
 			Presence::ref getHighestPriorityPresence(const JID& bareJID) const;
+			std::vector<Presence::ref> getAllPresence(const JID& bareJID) const;
 
 		public:
 			boost::signal<void (Presence::ref)> onPresenceChange;
-- 
cgit v0.10.2-6-g49f6