From 90c9b9e9c5cd9be3a620bf5e1d5b5d233573548c Mon Sep 17 00:00:00 2001
From: paul_productengine <none@none>
Date: Fri, 11 Feb 2011 13:49:10 +0200
Subject: [PATCH] STORM-680 FIXED (Avaline callers are added to the Recent
 list)

- When accepting an avaline call, add a caller to the recent list as AvalineListItem

- When adding item to the LLRecentPeople, check whether item with the same phone number exists and delete it if exists. This is need to avoid duplication in the Recent list of the panel People.
---
 indra/newview/llavatarlist.cpp   | 35 ++++++++++++++++---
 indra/newview/llavatarlist.h     |  2 ++
 indra/newview/llrecentpeople.cpp | 58 ++++++++++++++++++++++++++++----
 indra/newview/llrecentpeople.h   | 33 ++++++++++++++++--
 indra/newview/llvoicechannel.cpp | 24 ++++++++++++-
 indra/newview/llvoicechannel.h   |  7 ++++
 6 files changed, 145 insertions(+), 14 deletions(-)

diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index ff7dfccc0af..771419f60ac 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -240,6 +240,9 @@ void LLAvatarList::addAvalineItem(const LLUUID& item_id, const LLUUID& session_i
 	LLAvalineListItem* item = new LLAvalineListItem(/*hide_number=*/false);
 	item->setAvatarId(item_id, session_id, true, false);
 	item->setName(item_name);
+	item->showLastInteractionTime(mShowLastInteractionTime);
+	item->showSpeakingIndicator(mShowSpeakingIndicator);
+	item->setOnline(false);
 
 	addItem(item, item_id);
 	mIDs.push_back(item_id);
@@ -286,9 +289,18 @@ void LLAvatarList::refresh()
 			{
 				// *NOTE: If you change the UI to show a different string,
 				// be sure to change the filter code below.
-				addNewItem(buddy_id, 
-					       av_name.mDisplayName.empty() ? waiting_str : av_name.mDisplayName, 
-						   LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+				if (LLRecentPeople::instance().isAvalineCaller(buddy_id))
+				{
+					const LLSD& call_data = LLRecentPeople::instance().getData(buddy_id);
+					addAvalineItem(buddy_id, call_data["session_id"].asUUID(), call_data["call_number"].asString());
+				}
+				else
+				{
+					addNewItem(buddy_id, 
+						av_name.mDisplayName.empty() ? waiting_str : av_name.mDisplayName, 
+						LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+				}
+				
 				modified = true;
 				nadded++;
 			}
@@ -440,7 +452,7 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is
 BOOL LLAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
 	BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
-	if ( mContextMenu )
+	if ( mContextMenu && !isAvalineItemSelected())
 	{
 		uuid_vec_t selected_uuids;
 		getSelectedUUIDs(selected_uuids);
@@ -449,6 +461,21 @@ BOOL LLAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask)
 	return handled;
 }
 
+bool LLAvatarList::isAvalineItemSelected()
+{
+	std::vector<LLPanel*> selected_items;
+	getSelectedItems(selected_items);
+	std::vector<LLPanel*>::iterator it = selected_items.begin();
+	
+	for(; it != selected_items.end(); ++it)
+	{
+		if (dynamic_cast<LLAvalineListItem*>(*it))
+			return true;
+	}
+
+	return false;
+}
+
 void LLAvatarList::setVisible(BOOL visible)
 {
 	if ( visible == FALSE && mContextMenu )
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index cacbcf72444..4814a88a797 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -112,6 +112,8 @@ class LLAvatarList : public LLFlatListViewEx
 
 private:
 
+	bool isAvalineItemSelected();
+
 	bool mIgnoreOnlineStatus;
 	bool mShowLastInteractionTime;
 	bool mDirty;
diff --git a/indra/newview/llrecentpeople.cpp b/indra/newview/llrecentpeople.cpp
index 959fd51bbfd..7689cd1a525 100644
--- a/indra/newview/llrecentpeople.cpp
+++ b/indra/newview/llrecentpeople.cpp
@@ -33,7 +33,7 @@
 
 using namespace LLOldEvents;
 
-bool LLRecentPeople::add(const LLUUID& id)
+bool LLRecentPeople::add(const LLUUID& id, const LLSD& userdata)
 {
 	if (id == gAgent.getID())
 		return false;
@@ -42,10 +42,16 @@ bool LLRecentPeople::add(const LLUUID& id)
 
 	if (is_not_group_id)
 	{
-		LLDate date_added = LLDate::now();
+		// For each avaline call the id of caller is different even if
+		// the phone number is the same.
+		// To avoid duplication of avaline list items in the recent list
+		// of panel People, deleting id's with similar phone number.
+		const LLUUID& caller_id = getIDByPhoneNumber(userdata);
+		if (caller_id.notNull())
+			mPeople.erase(caller_id);
 
-		//[] instead of insert to replace existing id->date with new date value
-		mPeople[id] = date_added;
+		//[] instead of insert to replace existing id->llsd["date"] with new date value
+		mPeople[id] = userdata;
 		mChangedSignal();
 	}
 
@@ -64,15 +70,55 @@ void LLRecentPeople::get(uuid_vec_t& result) const
 		result.push_back((*pos).first);
 }
 
-const LLDate& LLRecentPeople::getDate(const LLUUID& id) const
+const LLDate LLRecentPeople::getDate(const LLUUID& id) const
 {
 	recent_people_t::const_iterator it = mPeople.find(id);
-	if (it!= mPeople.end()) return (*it).second;
+	if (it!= mPeople.end()) return it->second["date"].asDate();
 
 	static LLDate no_date = LLDate();
 	return no_date;
 }
 
+const LLSD& LLRecentPeople::getData(const LLUUID& id) const
+{
+	recent_people_t::const_iterator it = mPeople.find(id);
+
+	if (it != mPeople.end())
+		return it->second;
+
+	static LLSD no_data = LLSD();
+	return no_data;
+}
+
+bool LLRecentPeople::isAvalineCaller(const LLUUID& id) const
+{
+	recent_people_t::const_iterator it = mPeople.find(id);
+
+	if (it != mPeople.end())
+	{
+		const LLSD& user = it->second;		
+		return user["avaline_call"].asBoolean();
+	}
+
+	return false;
+}
+
+const LLUUID& LLRecentPeople::getIDByPhoneNumber(const LLSD& userdata)
+{
+	if (!userdata["avaline_call"].asBoolean())
+		return LLUUID::null;
+
+	for (recent_people_t::const_iterator it = mPeople.begin(); it != mPeople.end(); ++it)
+	{
+		const LLSD& user_info = it->second;
+		
+		if (user_info["call_number"].asString() == userdata["call_number"].asString())
+			return it->first;
+	}
+	
+	return LLUUID::null;
+}
+
 // virtual
 bool LLRecentPeople::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
 {
diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h
index 852a92ff807..d0d63768674 100644
--- a/indra/newview/llrecentpeople.h
+++ b/indra/newview/llrecentpeople.h
@@ -58,9 +58,15 @@ class LLRecentPeople: public LLSingleton<LLRecentPeople>, public LLOldEvents::LL
 	 * Add specified avatar to the list if it's not there already.
 	 *
 	 * @param id avatar to add.
+	 *
+	 * @param userdata additional information about last interaction party.
+	 *				   For example when last interaction party is not an avatar
+	 *				   but an avaline caller, additional info (such as phone
+	 *				   number, session id and etc.) should be added.
+	 *
 	 * @return false if the avatar is in the list already, true otherwise
 	 */
-	bool add(const LLUUID& id);
+	bool add(const LLUUID& id, const LLSD& userdata = LLSD().with("date", LLDate::now()));
 
 	/**
 	 * @param id avatar to search.
@@ -75,7 +81,25 @@ class LLRecentPeople: public LLSingleton<LLRecentPeople>, public LLOldEvents::LL
 	 */
 	void get(uuid_vec_t& result) const;
 
-	const LLDate& getDate(const LLUUID& id) const;
+	/**
+	 * Returns last interaction time with specified participant
+	 *
+	 */
+	const LLDate getDate(const LLUUID& id) const;
+
+	/**
+	 * Returns data about specified participant
+	 *
+	 * @param id identifier of specific participant
+	 */
+	const LLSD& getData(const LLUUID& id) const;
+
+	/**
+	 * Checks whether specific participant is an avaline caller
+	 *
+	 * @param id identifier of specific participant
+	 */
+	bool isAvalineCaller(const LLUUID& id) const;
 
 	/**
 	 * Set callback to be called when the list changed.
@@ -92,7 +116,10 @@ class LLRecentPeople: public LLSingleton<LLRecentPeople>, public LLOldEvents::LL
 	/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 
 private:
-	typedef std::map<LLUUID, LLDate> recent_people_t;
+
+	const LLUUID& getIDByPhoneNumber(const LLSD& userdata);
+
+	typedef std::map<LLUUID, LLSD> recent_people_t;
 	recent_people_t		mPeople;
 	signal_t			mChangedSignal;
 };
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index b692093fb9b..a71539266d6 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -853,7 +853,7 @@ void LLVoiceChannelP2P::activate()
 		}
 
 		// Add the party to the list of people with which we've recently interacted.
-		LLRecentPeople::instance().add(mOtherUserID);
+		addToTheRecentPeopleList();
 
 		//Default mic is ON on initiating/joining P2P calls
 		if (!LLVoiceClient::getInstance()->getUserPTTState() && LLVoiceClient::getInstance()->getPTTIsToggle())
@@ -938,3 +938,25 @@ void LLVoiceChannelP2P::setState(EState state)
 
 	LLVoiceChannel::setState(state);
 }
+
+void LLVoiceChannelP2P::addToTheRecentPeopleList()
+{
+	bool avaline_call = LLIMModel::getInstance()->findIMSession(mSessionID)->isAvalineSessionType();
+	
+	if (avaline_call)
+	{
+		LLSD call_data;
+		std::string call_number = LLVoiceChannel::getSessionName();
+		
+		call_data["avaline_call"]	= true;
+		call_data["session_id"]		= mSessionID;
+		call_data["call_number"]	= call_number;
+		call_data["date"]			= LLDate::now();
+		
+		LLRecentPeople::instance().add(mOtherUserID, call_data);
+	}
+	else
+	{
+		LLRecentPeople::instance().add(mOtherUserID);
+	}
+}
diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h
index 7cef3c13d1d..b8597ee5cb3 100644
--- a/indra/newview/llvoicechannel.h
+++ b/indra/newview/llvoicechannel.h
@@ -191,6 +191,13 @@ class LLVoiceChannelP2P : public LLVoiceChannelGroup
 	virtual void setState(EState state);
 
 private:
+
+	/**
+	* Add the caller to the list of people with which we've recently interacted
+	*
+	**/
+	void addToTheRecentPeopleList();
+
 	std::string	mSessionHandle;
 	LLUUID		mOtherUserID;
 	BOOL		mReceivedCall;
-- 
GitLab