diff options
| author | Paul ProductEngine <pguslisty@productengine.com> | 2012-09-11 17:45:49 +0300 | 
|---|---|---|
| committer | Paul ProductEngine <pguslisty@productengine.com> | 2012-09-11 17:45:49 +0300 | 
| commit | 1e2dcbfb3fbc8717ea594365ff165115b29df83a (patch) | |
| tree | 5f84d41dfa78d9eef7f9d258e92b95da9c47b22e | |
| parent | 20b95f6ac0a63ce36cb1a7f51505bbf9ef8015c2 (diff) | |
CHUI-326 FIXED (One entry per conversation with a user in conversation log timestamped with most recent utterance/activity.)
- Modified LLConversationLog to show only one entry per conversation with user. I.e. there can't be two conversations with the same session_id in LLConversationLog.
- Got rid of processing voice sessions
- Refactored creation of conversation in LLConversationLog
- Refactored a little bit LLConversation and LLConversationLog: function names and made some functions private
| -rw-r--r-- | indra/newview/llconversationlog.cpp | 141 | ||||
| -rw-r--r-- | indra/newview/llconversationlog.h | 44 | ||||
| -rw-r--r-- | indra/newview/llconversationloglist.cpp | 57 | ||||
| -rw-r--r-- | indra/newview/llconversationloglist.h | 9 | ||||
| -rw-r--r-- | indra/newview/llconversationloglistitem.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/llconversationloglistitem.h | 8 | ||||
| -rw-r--r-- | indra/newview/llfloaterconversationlog.cpp | 12 | ||||
| -rw-r--r-- | indra/newview/llfloaterconversationlog.h | 5 | 
8 files changed, 187 insertions, 99 deletions
| diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp index cc02e18698..239a89015f 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -37,7 +37,7 @@ struct Conversation_params  	Conversation_params(time_t time)  	:	mTime(time),  		mTimestamp(LLConversation::createTimestamp(time)), -		mIsConversationPast(true) +		mIsVoice(false)  	{}  	time_t		mTime; @@ -48,7 +48,6 @@ struct Conversation_params  	LLUUID		mSessionID;  	LLUUID		mParticipantID;  	bool		mIsVoice; -	bool		mIsConversationPast;  	bool		mHasOfflineIMs;  }; @@ -65,7 +64,6 @@ LLConversation::LLConversation(const Conversation_params& params)  	mSessionID(params.mSessionID),  	mParticipantID(params.mParticipantID),  	mIsVoice(params.mIsVoice), -	mIsConversationPast(params.mIsConversationPast),  	mHasOfflineIMs(params.mHasOfflineIMs)  {  	setListenIMFloaterOpened(); @@ -80,7 +78,6 @@ LLConversation::LLConversation(const LLIMModel::LLIMSession& session)  	mSessionID(session.mSessionID),  	mParticipantID(session.mOtherParticipantID),  	mIsVoice(session.mStartedAsIMCall), -	mIsConversationPast(false),  	mHasOfflineIMs(session.mHasOfflineMessage)  {  	setListenIMFloaterOpened(); @@ -96,7 +93,6 @@ LLConversation::LLConversation(const LLConversation& conversation)  	mSessionID			= conversation.getSessionID();  	mParticipantID		= conversation.getParticipantID();  	mIsVoice			= conversation.isVoice(); -	mIsConversationPast = conversation.isConversationPast();  	mHasOfflineIMs		= conversation.hasOfflineMessages();  	setListenIMFloaterOpened(); @@ -107,12 +103,10 @@ LLConversation::~LLConversation()  	mIMFloaterShowedConnection.disconnect();  } -void LLConversation::setIsVoice(bool is_voice) +void LLConversation::updateTimestamp()  { -	if (mIsConversationPast) -		return; - -	mIsVoice = is_voice; +	mTime = time_corrected(); +	mTimestamp = createTimestamp(mTime);  }  void LLConversation::onIMFloaterShown(const LLUUID& session_id) @@ -154,14 +148,18 @@ void LLConversation::setListenIMFloaterOpened()  	LLIMFloater* floater = LLIMFloater::findInstance(mSessionID);  	bool has_offline_ims = !mIsVoice && mHasOfflineIMs; -	bool ims_are_read = LLIMFloater::isVisible(floater) && floater->hasFocus(); +	bool offline_ims_visible = LLIMFloater::isVisible(floater) && floater->hasFocus();  	// we don't need to listen for im floater with this conversation is opened  	// if floater is already opened or this conversation doesn't have unread offline messages -	if (has_offline_ims && !ims_are_read) +	if (has_offline_ims && !offline_ims_visible)  	{  		mIMFloaterShowedConnection = LLIMFloater::setIMFloaterShowedCallback(boost::bind(&LLConversation::onIMFloaterShown, this, _1));  	} +	else +	{ +		mHasOfflineIMs = false; +	}  }  /************************************************************************/ @@ -205,6 +203,7 @@ LLConversationLog::LLConversationLog()  		if (ctrl->getValue().asBoolean())  		{  			LLIMMgr::instance().addSessionObserver(this); +			newMessageSignalConnection = LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));  		}  	} @@ -218,17 +217,80 @@ void LLConversationLog::observeIMSession()  	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))  	{  		LLIMMgr::instance().addSessionObserver(this); +		LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));  	}  	else  	{  		LLIMMgr::instance().removeSessionObserver(this); +		newMessageSignalConnection.disconnect();  	}  } -void LLConversationLog::logConversation(const LLConversation& conversation) +void LLConversationLog::logConversation(const LLUUID& session_id)  { -	mConversations.push_back(conversation); -	notifyObservers(); +	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id); +	LLConversation* conversation = findConversation(session_id); + +	if (session && conversation) +	{ +		updateConversationTimestamp(conversation); +	} +	else if (session && !conversation) +	{ +		createConversation(session_id); +	} +} + +void LLConversationLog::createConversation(const LLUUID& session_id) +{ +	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id); + +	if (session) +	{ +		LLConversation conversation(*session); +		mConversations.push_back(conversation); + +		if (LLIMModel::LLIMSession::P2P_SESSION == session->mSessionType) +		{ +			LLAvatarNameCache::get(session->mOtherParticipantID, boost::bind(&LLConversationLog::onAvatarNameCache, this, _1, _2, session)); +		} + +		notifyObservers(); +	} +} + +void LLConversationLog::updateConversationName(const LLUUID& session_id, const std::string& name) +{ +	LLConversation* conversation = findConversation(session_id); + +	if (conversation) +	{ +		conversation->setConverstionName(name); +		notifyPrticularConversationObservers(session_id, LLConversationLogObserver::CHANGED_NAME); +	} +} + +void LLConversationLog::updateConversationTimestamp(LLConversation* conversation) +{ +	if (conversation) +	{ +		conversation->updateTimestamp(); +		notifyPrticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_TIME); +	} +} + +LLConversation* LLConversationLog::findConversation(const LLUUID& session_id) +{ +	conversations_vec_t::iterator conv_it = mConversations.begin(); +	for(; conv_it != mConversations.end(); ++conv_it) +	{ +		if (conv_it->getSessionID() == session_id) +		{ +			return &*conv_it; +		} +	} + +	return NULL;  }  void LLConversationLog::removeConversation(const LLConversation& conversation) @@ -271,34 +333,7 @@ void LLConversationLog::removeObserver(LLConversationLogObserver* observer)  void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)  { -	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id); -	if (session) -	{ -		if (LLIMModel::LLIMSession::P2P_SESSION == session->mSessionType) -		{ -			LLAvatarNameCache::get(session->mOtherParticipantID, boost::bind(&LLConversationLog::onAvatarNameCache, this, _1, _2, session)); -		} -		else -		{ -			LLConversation conversation(*session); -			LLConversationLog::instance().logConversation(conversation); -			session->mVoiceChannel->setStateChangedCallback(boost::bind(&LLConversationLog::onVoiceChannelConnected, this, _5, _2)); -		} -	} -} - -void LLConversationLog::sessionRemoved(const LLUUID& session_id) -{ -	conversations_vec_t::reverse_iterator rev_iter = mConversations.rbegin(); - -	for (; rev_iter != mConversations.rend(); ++rev_iter) -	{ -		if (rev_iter->getSessionID() == session_id && !rev_iter->isConversationPast()) -		{ -			rev_iter->setIsPast(true); -			return; // return here because only one session with session_id may be active -		} -	} +	logConversation(session_id);  }  void LLConversationLog::cache() @@ -442,25 +477,13 @@ void LLConversationLog::notifyPrticularConversationObservers(const LLUUID& sessi  	}  } -void LLConversationLog::onVoiceChannelConnected(const LLUUID& session_id, const LLVoiceChannel::EState& state) +void LLConversationLog::onNewMessageReceived(const LLSD& data)  { -	conversations_vec_t::reverse_iterator rev_iter = mConversations.rbegin(); - -	for (; rev_iter != mConversations.rend(); ++rev_iter) -	{ -		if (rev_iter->getSessionID() == session_id && !rev_iter->isConversationPast() && LLVoiceChannel::STATE_CALL_STARTED == state) -		{ -			rev_iter->setIsVoice(true); -			notifyPrticularConversationObservers(session_id, LLConversationLogObserver::VOICE_STATE); -			return; // return here because only one session with session_id may be active -		} -	} +	const LLUUID session_id = data["session_id"].asUUID(); +	logConversation(session_id);  }  void LLConversationLog::onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, LLIMModel::LLIMSession* session)  { -	LLConversation conversation(*session); -	conversation.setConverstionName(av_name.getCompleteName()); -	LLConversationLog::instance().logConversation(conversation); -	session->mVoiceChannel->setStateChangedCallback(boost::bind(&LLConversationLog::onVoiceChannelConnected, this, _5, _2)); +	updateConversationName(session->mSessionID, av_name.getCompleteName());  } diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h index 16be37d67a..ffd27f7e20 100644 --- a/indra/newview/llconversationlog.h +++ b/indra/newview/llconversationlog.h @@ -57,16 +57,19 @@ public:  	const std::string&	getTimestamp()			const	{ return mTimestamp; }  	const time_t&		getTime()				const	{ return mTime; }  	bool				isVoice()				const	{ return mIsVoice; } -	bool				isConversationPast()	const	{ return mIsConversationPast; }  	bool				hasOfflineMessages()	const	{ return mHasOfflineIMs; }  	void	setIsVoice(bool is_voice); -	void	setIsPast (bool is_past) { mIsConversationPast = is_past; }  	void	setConverstionName(std::string conv_name) { mConversationName = conv_name; }  	bool isOlderThan(U32 days) const;  	/* +	 * updates last interaction time +	 */ +	void updateTimestamp(); + +	/*  	 * Resets flag of unread offline message to false when im floater with this conversation is opened.  	 */  	void onIMFloaterShown(const LLUUID& session_id); @@ -86,7 +89,7 @@ private:  	boost::signals2::connection mIMFloaterShowedConnection; -	time_t			mTime; // start time of conversation +	time_t			mTime; // last interaction time  	SessionType		mConversationType;  	std::string		mConversationName;  	std::string		mHistoryFileName; @@ -94,8 +97,7 @@ private:  	LLUUID			mParticipantID;  	bool			mIsVoice;  	bool			mHasOfflineIMs; -	bool			mIsConversationPast; // once session is finished conversation became past forever -	std::string		mTimestamp; // conversation start time in form of: mm/dd/yyyy hh:mm +	std::string		mTimestamp; // last interaction time in form of: mm/dd/yyyy hh:mm  };  /** @@ -112,32 +114,26 @@ class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObse  	friend class LLSingleton<LLConversationLog>;  public: -	/** -	 * adds conversation to the conversation list and notifies observers -	 */ -	void logConversation(const LLConversation& conversation);  	void removeConversation(const LLConversation& conversation);  	/**  	 * Returns first conversation with matched session_id  	 */ -	const LLConversation* getConversation(const LLUUID& session_id); +	const LLConversation*				getConversation(const LLUUID& session_id); +	const std::vector<LLConversation>&	getConversations() { return mConversations; }  	void addObserver(LLConversationLogObserver* observer);  	void removeObserver(LLConversationLogObserver* observer); -	const std::vector<LLConversation>& getConversations() { return mConversations; } -  	// LLIMSessionObserver triggers  	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id); -	virtual void sessionRemoved(const LLUUID& session_id); +	virtual void sessionRemoved(const LLUUID& session_id){}											// Stub  	virtual void sessionVoiceOrIMStarted(const LLUUID& session_id){};								// Stub  	virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id){};	// Stub  	void notifyObservers(); -	void notifyPrticularConversationObservers(const LLUUID& session_id, U32 mask); -	void onVoiceChannelConnected(const LLUUID& session_id, const LLVoiceChannel::EState& state); +	void onNewMessageReceived(const LLSD& data);  	/**  	 * public method which is called on viewer exit to save conversation log @@ -148,6 +144,13 @@ private:  	LLConversationLog(); +	/** +	 * adds conversation to the conversation list and notifies observers +	 */ +	void logConversation(const LLUUID& session_id); + +	void notifyPrticularConversationObservers(const LLUUID& session_id, U32 mask); +  	void observeIMSession();  	/** @@ -161,11 +164,19 @@ private:  	void onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, LLIMModel::LLIMSession* session); +	void createConversation(const LLUUID& session_id); +	void updateConversationTimestamp(LLConversation* conversation); +	void updateConversationName(const LLUUID& session_id, const std::string& name); + +	LLConversation* findConversation(const LLUUID& session_id); +  	typedef std::vector<LLConversation> conversations_vec_t;  	std::vector<LLConversation>				mConversations;  	std::set<LLConversationLogObserver*>	mObservers;  	LLFriendObserver* mFriendObserver;		// Observer of the LLAvatarTracker instance + +	boost::signals2::connection newMessageSignalConnection;  };  class LLConversationLogObserver @@ -174,7 +185,8 @@ public:  	enum EConversationChange  		{ -			VOICE_STATE = 1 +			CHANGED_TIME = 1, // last interaction time changed +			CHANGED_NAME = 2  // conversation name changed  		};  	virtual ~LLConversationLogObserver(){} diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp index d39e090c22..429e99f7ad 100644 --- a/indra/newview/llconversationloglist.cpp +++ b/indra/newview/llconversationloglist.cpp @@ -143,22 +143,32 @@ void LLConversationLogList::changed()  void LLConversationLogList::changed(const LLUUID& session_id, U32 mask)  { -	if (mask & LLConversationLogObserver::VOICE_STATE) +	LLConversationLogListItem* item = getConversationLogListItem(session_id); + +	if (!item)  	{ -		std::vector<LLPanel*> panels; -		LLFlatListViewEx::getItems(panels); +		return; +	} -		std::vector<LLPanel*>::iterator iter = panels.begin(); +	if (mask & LLConversationLogObserver::CHANGED_TIME) +	{ +		item->updateTimestamp(); -		for (; iter != panels.end(); ++iter) +		// if list is sorted by date and a date of some item has changed, +		// than the whole list should be rebuilt +		if (E_SORT_BY_DATE == getSortOrder())  		{ -			LLConversationLogListItem* item = dynamic_cast<LLConversationLogListItem*>(*iter); - -			if (item && session_id == item->getConversation()->getSessionID() && !item->getConversation()->isConversationPast()) -			{ -				item->initIcons(); -				return; -			} +			mIsDirty = true; +		} +	} +	else if (mask & LLConversationLogObserver::CHANGED_NAME) +	{ +		item->updateName(); +		// if list is sorted by name and a name of some item has changed, +		// than the whole list should be rebuilt +		if (E_SORT_BY_DATE == getSortOrder()) +		{ +			mIsDirty = true;  		}  	}  } @@ -401,6 +411,29 @@ const LLConversation* LLConversationLogList::getSelectedConversation()  	return NULL;  } +LLConversationLogListItem* LLConversationLogList::getConversationLogListItem(const LLUUID& session_id) +{ +	std::vector<LLPanel*> panels; +	LLFlatListViewEx::getItems(panels); +	std::vector<LLPanel*>::iterator iter = panels.begin(); + +	for (; iter != panels.end(); ++iter) +	{ +		LLConversationLogListItem* item = dynamic_cast<LLConversationLogListItem*>(*iter); +		if (item && session_id == item->getConversation()->getSessionID()) +		{ +			return item; +		} +	} + +	return NULL; +} + +LLConversationLogList::ESortOrder LLConversationLogList::getSortOrder() +{ +	return static_cast<ESortOrder>(gSavedSettings.getU32("CallLogSortOrder")); +} +  bool LLConversationLogListItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const  {  	const LLConversationLogListItem* conversation_item1 = dynamic_cast<const LLConversationLogListItem*>(item1); diff --git a/indra/newview/llconversationloglist.h b/indra/newview/llconversationloglist.h index 5e7fc0a9fb..62ec57e09e 100644 --- a/indra/newview/llconversationloglist.h +++ b/indra/newview/llconversationloglist.h @@ -43,6 +43,12 @@ class LLConversationLogList: public LLFlatListViewEx, public LLConversationLogOb  {  	LOG_CLASS(LLConversationLogList);  public: + +	typedef enum e_sort_oder{ +		E_SORT_BY_NAME = 0, +		E_SORT_BY_DATE = 1, +	} ESortOrder; +  	struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>  	{  		Params(){}; @@ -90,6 +96,9 @@ private:  	LLIMModel::LLIMSession::SType getSelectedSessionType();  	const LLConversationLogListItem* getSelectedConversationPanel();  	const LLConversation* getSelectedConversation(); +	LLConversationLogListItem* getConversationLogListItem(const LLUUID& session_id); + +	ESortOrder getSortOrder();  	LLHandle<LLToggleableMenu>	mContextMenu;  	bool mIsDirty; diff --git a/indra/newview/llconversationloglistitem.cpp b/indra/newview/llconversationloglistitem.cpp index dddf216592..fac6130371 100644 --- a/indra/newview/llconversationloglistitem.cpp +++ b/indra/newview/llconversationloglistitem.cpp @@ -117,6 +117,16 @@ void LLConversationLogListItem::initIcons()  	}  } +void LLConversationLogListItem::updateTimestamp() +{ +	mConversationDate->setValue(mConversation->getTimestamp()); +} + +void LLConversationLogListItem::updateName() +{ +	mConversationName->setValue(mConversation->getConversationName()); +} +  void LLConversationLogListItem::onMouseEnter(S32 x, S32 y, MASK mask)  {  	getChildView("hovered_icon")->setVisible(true); diff --git a/indra/newview/llconversationloglistitem.h b/indra/newview/llconversationloglistitem.h index 2aaafa0fba..1bf7a0ed93 100644 --- a/indra/newview/llconversationloglistitem.h +++ b/indra/newview/llconversationloglistitem.h @@ -64,10 +64,16 @@ public:  	void onDoubleClick(); -	void initIcons(); +	/** +	 * updates string value of last interaction time from conversation +	 */ +	void updateTimestamp(); +	void updateName();  private: +	void initIcons(); +  	const LLConversation* mConversation;  	LLTextBox*		mConversationName; diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp index 4375ce5726..7b4c999e52 100644 --- a/indra/newview/llfloaterconversationlog.cpp +++ b/indra/newview/llfloaterconversationlog.cpp @@ -45,11 +45,11 @@ BOOL LLFloaterConversationLog::postBuild()  	switch (gSavedSettings.getU32("CallLogSortOrder"))  	{ -	case E_SORT_BY_NAME: +	case LLConversationLogList::E_SORT_BY_NAME:  		mConversationLogList->sortByName();  		break; -	case E_SORT_BY_DATE: +	case LLConversationLogList::E_SORT_BY_DATE:  		mConversationLogList->sortByDate();  		break;  	} @@ -87,12 +87,12 @@ void LLFloaterConversationLog::onCustomAction (const LLSD& userdata)  	if ("sort_by_name" == command_name)  	{  		mConversationLogList->sortByName(); -		gSavedSettings.setU32("CallLogSortOrder", E_SORT_BY_NAME); +		gSavedSettings.setU32("CallLogSortOrder", LLConversationLogList::E_SORT_BY_NAME);  	}  	else if ("sort_by_date" == command_name)  	{  		mConversationLogList->sortByDate(); -		gSavedSettings.setU32("CallLogSortOrder", E_SORT_BY_DATE); +		gSavedSettings.setU32("CallLogSortOrder", LLConversationLogList::E_SORT_BY_DATE);  	}  	else if ("sort_friends_on_top" == command_name)  	{ @@ -117,11 +117,11 @@ bool LLFloaterConversationLog::isActionChecked(const LLSD& userdata)  	if ("sort_by_name" == command_name)  	{ -		return sort_order == E_SORT_BY_NAME; +		return sort_order == LLConversationLogList::E_SORT_BY_NAME;  	}  	else if ("sort_by_date" == command_name)  	{ -		return sort_order == E_SORT_BY_DATE; +		return sort_order == LLConversationLogList::E_SORT_BY_DATE;  	}  	else if ("sort_friends_on_top" == command_name)  	{ diff --git a/indra/newview/llfloaterconversationlog.h b/indra/newview/llfloaterconversationlog.h index 7d788c0290..e971330f3d 100644 --- a/indra/newview/llfloaterconversationlog.h +++ b/indra/newview/llfloaterconversationlog.h @@ -34,11 +34,6 @@ class LLFloaterConversationLog : public LLFloater  {  public: -	typedef enum e_sort_oder{ -		E_SORT_BY_NAME = 0, -		E_SORT_BY_DATE = 1, -	} ESortOrder; -  	LLFloaterConversationLog(const LLSD& key);  	virtual ~LLFloaterConversationLog(){}; | 
