CHUI-668: Not fully complete but as of this commit, have functionality to use the user's most intrusive chat notification upon exiting from DND mode with IM's. Also if in DND mode, clicking on a conversation line item or floater, will flush the DND notifications system of storing that conversation. This way upon existing DND mode already responded conversations won't be notified to the user.

master
Gilbert Gonzales 2013-01-11 18:20:29 -08:00
parent 16082462a4
commit 69497e645b
8 changed files with 142 additions and 4 deletions

View File

@ -67,12 +67,18 @@ void LLCommunicationChannel::clearHistory()
mHistory.clear();
}
void LLCommunicationChannel::removeItem(history_list_t::const_iterator itemToRemove)
{
mHistory.erase(itemToRemove);
}
void LLCommunicationChannel::onFilterFail(LLNotificationPtr pNotificationPtr)
{
std::string notificationType = pNotificationPtr->getType();
if ((notificationType == "groupnotify")
|| (notificationType == "offer")
|| (notificationType == "notifytoast"))
|| (notificationType == "notifytoast")
&& !pNotificationPtr->isCancelled())
{
mHistory.insert(std::make_pair<LLDate, LLNotificationPtr>(pNotificationPtr->getDate(), pNotificationPtr));
}

View File

@ -48,6 +48,7 @@ public:
history_list_t::const_iterator endHistory() const;
void clearHistory();
void removeItem(history_list_t::const_iterator itemToRemove);
protected:
virtual void onFilterFail(LLNotificationPtr pNotificationPtr);

View File

@ -41,6 +41,8 @@
#include "llsingleton.h"
#include "lluuid.h"
extern void useMostItrusiveIMNotification();
LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage()
: LLSingleton<LLDoNotDisturbNotificationStorage>()
, LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"))
@ -103,15 +105,22 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
}
LLNotifications& instance = LLNotifications::instance();
bool imToastExists = false;
for (LLSD::array_const_iterator notification_it = data.beginArray();
notification_it != data.endArray();
++notification_it)
{
LLSD notification_params = *notification_it;
const std::string notificationName = notification_params["name"].asString();
const LLUUID& notificationID = notification_params["id"];
LLNotificationPtr notification = instance.find(notificationID);
if(notificationName == "IMToast")
{
imToastExists = true;
}
//Notification already exists in notification pipeline (same instance of app running)
if (notification)
{
@ -138,6 +147,11 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
}
}
if(imToastExists)
{
useMostItrusiveIMNotification();
}
// Clear the communication channel history and rewrite the save file to empty it as well
LLNotificationChannelPtr channelPtr = getCommunicationChannel();
LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
@ -154,6 +168,45 @@ LLNotificationChannelPtr LLDoNotDisturbNotificationStorage::getCommunicationChan
return channelPtr;
}
void LLDoNotDisturbNotificationStorage::removeIMNotification(const LLUUID& session_id)
{
LLNotifications& instance = LLNotifications::instance();
LLNotificationChannelPtr channelPtr = getCommunicationChannel();
LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
LLNotificationPtr notification;
LLSD substitutions;
LLUUID notificationSessionID;
LLCommunicationChannel::history_list_t::const_iterator it;
std::vector<LLCommunicationChannel::history_list_t::const_iterator> itemsToRemove;
//Find notification with the matching session id
for (it = commChannel->beginHistory();
it != commChannel->endHistory();
++it)
{
notification = it->second;
substitutions = notification->getSubstitutions();
notificationSessionID = substitutions["SESSION_ID"].asUUID();
if(session_id == notificationSessionID)
{
itemsToRemove.push_back(it);
}
}
//Remove the notification
while(itemsToRemove.size())
{
it = itemsToRemove.back();
notification = it->second;
commChannel->removeItem(it);
//instance.cancel triggers onChannelChanged to be called within LLNotificationChannelBase::updateItem (which save changes to the .xml file)
//but this means that saveNotifications write a file each time as well, BAD! Will find a way to prevent this.
instance.cancel(notification);
itemsToRemove.pop_back();
}
}
bool LLDoNotDisturbNotificationStorage::onChannelChanged(const LLSD& pPayload)
{

View File

@ -45,6 +45,7 @@ public:
void saveNotifications();
void loadNotifications();
void removeIMNotification(const LLUUID& session_id);
protected:

View File

@ -39,6 +39,7 @@
#include "llavatariconctrl.h"
#include "llavatarnamecache.h"
#include "llcallbacklist.h"
#include "lldonotdisturbnotificationstorage.h"
#include "llgroupactions.h"
#include "llgroupiconctrl.h"
#include "llflashtimer.h"
@ -1291,6 +1292,10 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
if (widget && widget->getParentFolder())
{
widget->getParentFolder()->setSelection(widget, FALSE, FALSE);
if(gAgent.isDoNotDisturb())
{
LLDoNotDisturbNotificationStorage::getInstance()->removeIMNotification(session_id);
}
}
}
@ -1312,6 +1317,11 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
// Switch to the conversation floater that is being selected
selectFloater(session_floater);
}
if(gAgent.isDoNotDisturb())
{
LLDoNotDisturbNotificationStorage::getInstance()->removeIMNotification(session_id);
}
}
// Set the focus on the selected floater

View File

@ -1624,6 +1624,36 @@ void LLFloaterPreference::selectChatPanel()
selectPanel("chat");
}
S32 LLFloaterPreference::getHighestNotificationIndex() //change this name
{
static const S32 comboBoxNamesLength = 5;
static std::string comboBoxNames[comboBoxNamesLength] = {"NearbyChatOptions",
"FriendIMOptions",
"NonFriendIMOptions",
"ConferenceIMOptions",
"GroupChatOptions"};
S32 selectedIndex;
S32 priorityindex = 3;
LLComboBox * comboBox;
for(S32 i = 0; i < comboBoxNamesLength; ++i)
{
comboBox = getChild<LLComboBox>(comboBoxNames[i]);
if(comboBox)
{
selectedIndex = comboBox->getCurrentIndex();
if(selectedIndex < priorityindex)
{
priorityindex = selectedIndex;
}
}
}
return priorityindex;
}
//------------------------------Updater---------------------------------------
static bool handleBandwidthChanged(const LLSD& newvalue)

View File

@ -86,6 +86,7 @@ public:
void saveAvatarProperties( void );
void selectPrivacyPanel();
void selectChatPanel();
S32 getHighestNotificationIndex();
protected:
void onBtnOK();

View File

@ -52,6 +52,7 @@
#include "llchat.h"
#include "llfloaterimsession.h"
#include "llfloaterimcontainer.h"
#include "llfloaterpreference.h"
#include "llgroupiconctrl.h"
#include "llmd5.h"
#include "llmutelist.h"
@ -128,11 +129,46 @@ void process_dnd_im(const LLSD& notification)
false,
false); //will need slight refactor to retrieve whether offline message or not (assume online for now)
}
//Flash toolbar button for now, eventually the user's preference will be taken into account
gToolBarView->flashCommand(LLCommandId("chat"), true);
}
void useMostItrusiveIMNotification()
{
LLFloaterPreference * instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
if (instance)
{
LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
//conv. floater is closed
bool conversation_floater_is_closed =
!( im_box
&& im_box->isInVisibleChain()
&& !im_box->isMinimized());
//conversation floater not focused (visible or not)
bool conversation_floater_not_focused =
conversation_floater_is_closed || !im_box->hasFocus();
switch(instance->getHighestNotificationIndex())
{
//Highest priority to lowest (cases correspond to options in drop down box inside Preferences->Chat)
//open conversation floater
case 0:
LLFloaterReg::showInstance("im_container");
break;
//pop up message
case 1:
//flash toolbar button
case 2:
if(conversation_floater_not_focused)
{
gToolBarView->flashCommand(LLCommandId("chat"), true);
}
break;
}
}
}
static void on_avatar_name_cache_toast(const LLUUID& agent_id,
const LLAvatarName& av_name,