From 41c3b459f2fa381bdc3e79864ef917f833257274 Mon Sep 17 00:00:00 2001
From: Alexei Arabadji <aarabadji@productengine.com>
Date: Wed, 3 Mar 2010 19:48:16 +0200
Subject: [PATCH] =?UTF-8?q?fixed=20EXT-5685=20=E2=80=9CDuplicated=20'user?=
 =?UTF-8?q?=20online/offline'=20toasts=20after=20coming=20back=20to=20View?=
 =?UTF-8?q?er=E2=80=9D,=20implemented=20filtering=20of=20exclusive=20notif?=
 =?UTF-8?q?ications;?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

--HG--
branch : product-engine
---
 indra/newview/llnotificationhandler.h       |  9 +++
 indra/newview/llnotificationhandlerutil.cpp | 77 ++++++++++++++++++++-
 indra/newview/llnotificationtiphandler.cpp  | 17 +++++
 indra/newview/llscreenchannel.cpp           |  5 +-
 4 files changed, 106 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 0d5c431d752..a163b6fd625 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -122,9 +122,17 @@ class LLEventHandler
 class LLSysHandler : public LLEventHandler
 {
 public:
+	LLSysHandler();
 	virtual ~LLSysHandler() {};
 
 	virtual bool processNotification(const LLSD& notify)=0;
+
+protected :
+	static void init();
+	void removeExclusiveNotifications(const LLNotificationPtr& notif);
+
+	typedef std::list< std::set<std::string> > exclusive_notif_sets;
+	static exclusive_notif_sets sExclusiveNotificationGroups;
 };
 
 /**
@@ -171,6 +179,7 @@ class LLTipHandler : public LLSysHandler
 
 protected:
 	virtual void onDeleteToast(LLToast* toast);
+	virtual void onRejectToast(const LLUUID& id);
 	virtual void initChannel();
 };
 
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 9de9998cbdd..546017f0286 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -43,6 +43,75 @@
 
 using namespace LLNotificationsUI;
 
+// static
+std::list< std::set<std::string> > LLSysHandler::sExclusiveNotificationGroups;
+
+// static
+void LLSysHandler::init()
+{
+	std::set<std::string> online_offline_group;
+	online_offline_group.insert("FriendOnline");
+	online_offline_group.insert("FriendOffline");
+
+	sExclusiveNotificationGroups.push_back(online_offline_group);
+}
+
+LLSysHandler::LLSysHandler()
+{
+	if(sExclusiveNotificationGroups.empty())
+	{
+		init();
+	}
+}
+
+void LLSysHandler::removeExclusiveNotifications(const LLNotificationPtr& notif)
+{
+	LLScreenChannel* channel = dynamic_cast<LLScreenChannel *>(mChannel);
+	if (channel == NULL)
+	{
+		return;
+	}
+
+	class ExclusiveMatcher: public LLScreenChannel::Matcher
+	{
+	public:
+		ExclusiveMatcher(const std::set<std::string>& excl_group,
+				const std::string& from_name) :
+			mExclGroup(excl_group), mFromName(from_name)
+		{
+		}
+		bool matches(const LLNotificationPtr notification) const
+		{
+			for (std::set<std::string>::iterator it = mExclGroup.begin(); it
+					!= mExclGroup.end(); it++)
+			{
+				std::string from_name = LLHandlerUtil::getSubstitutionName(notification);
+				if (notification->getName() == *it && from_name == mFromName)
+				{
+					return true;
+				}
+			}
+			return false;
+		}
+	private:
+		const std::set<std::string>& mExclGroup;
+		const std::string& mFromName;
+	};
+
+
+	for (exclusive_notif_sets::iterator it = sExclusiveNotificationGroups.begin(); it
+			!= sExclusiveNotificationGroups.end(); it++)
+	{
+		std::set<std::string> group = *it;
+		std::set<std::string>::iterator g_it = group.find(notif->getName());
+		if (g_it != group.end())
+		{
+			channel->killMatchedToasts(ExclusiveMatcher(group,
+					LLHandlerUtil::getSubstitutionName(notif)));
+		}
+	}
+}
+
 const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"),
 		REVOKED_MODIFY_RIGHTS("RevokedModifyRights"), OBJECT_GIVE_ITEM(
 				"ObjectGiveItem"), OBJECT_GIVE_ITEM_UNKNOWN_USER(
@@ -249,9 +318,15 @@ LLUUID LLHandlerUtil::spawnIMSession(const std::string& name, const LLUUID& from
 // static
 std::string LLHandlerUtil::getSubstitutionName(const LLNotificationPtr& notification)
 {
-	return notification->getSubstitutions().has("NAME")
+	std::string res = notification->getSubstitutions().has("NAME")
 		? notification->getSubstitutions()["NAME"]
 		: notification->getSubstitutions()["[NAME]"];
+	if (res.empty())
+	{
+		LLUUID from_id = notification->getPayload()["FROM_ID"];
+		gCacheName->getFullName(from_id, res);
+	}
+	return res;
 }
 
 // static
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index be76959d07e..4e2c5085ed3 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -40,6 +40,7 @@
 #include "lltoastnotifypanel.h"
 #include "llviewercontrol.h"
 #include "llviewerwindow.h"
+#include "llnotificationmanager.h"
 
 using namespace LLNotificationsUI;
 
@@ -82,6 +83,10 @@ LLTipHandler::LLTipHandler(e_notification_type type, const LLSD& id)
 
 	// Getting a Channel for our notifications
 	mChannel = LLChannelManager::getInstance()->createNotificationChannel();
+
+	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+	if(channel)
+		channel->setOnRejectToastCallback(boost::bind(&LLTipHandler::onRejectToast, this, _1));
 }
 
 //--------------------------------------------------------------------------
@@ -167,6 +172,8 @@ bool LLTipHandler::processNotification(const LLSD& notify)
 		p.is_tip = true;
 		p.can_be_stored = false;
 		
+		removeExclusiveNotifications(notification);
+
 		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
 		if(channel)
 			channel->addToast(p);
@@ -185,4 +192,14 @@ void LLTipHandler::onDeleteToast(LLToast* toast)
 
 //--------------------------------------------------------------------------
 
+void LLTipHandler::onRejectToast(const LLUUID& id)
+{
+	LLNotificationPtr notification = LLNotifications::instance().find(id);
 
+	if (notification
+			&& LLNotificationManager::getInstance()->getHandlerForNotification(
+					notification->getType()) == this)
+	{
+		LLNotifications::instance().cancel(notification);
+	}
+}
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index c75d90be6f3..a4426b370e1 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -687,7 +687,10 @@ void LLNotificationsUI::LLScreenChannel::startFadingToasts()
 	while (it != mToastList.end())
 	{
 		ToastElem& elem = *it;
-		elem.toast->startFading();
+		if (elem.toast->getVisible())
+		{
+			elem.toast->startFading();
+		}
 		++it;
 	}
 }
-- 
GitLab