summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rwxr-xr-xindra/newview/app_settings/settings.xml2
-rwxr-xr-xindra/newview/llagent.cpp2
-rw-r--r--indra/newview/llcommunicationchannel.cpp36
-rw-r--r--indra/newview/llcommunicationchannel.h7
-rw-r--r--indra/newview/lldonotdisturbnotificationstorage.cpp150
-rw-r--r--indra/newview/lldonotdisturbnotificationstorage.h22
-rw-r--r--indra/newview/llfloaterimcontainer.cpp10
-rw-r--r--indra/newview/llimview.cpp45
-rw-r--r--indra/newview/llpanelblockedlist.cpp3
-rw-r--r--indra/newview/lltoastnotifypanel.cpp15
10 files changed, 247 insertions, 45 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 126df69519..fd4d1df894 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -10215,7 +10215,7 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <integer>2</integer>
+ <integer>0</integer>
</map>
<key>CallLogSortOrder</key>
<map>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index d28af3eff9..094d502078 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -1397,7 +1397,7 @@ void LLAgent::setDoNotDisturb(bool pIsDoNotDisturb)
LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(pIsDoNotDisturb);
if (isDoNotDisturbSwitchedOff)
{
- LLDoNotDisturbNotificationStorage::getInstance()->loadNotifications();
+ LLDoNotDisturbNotificationStorage::getInstance()->updateNotifications();
}
}
diff --git a/indra/newview/llcommunicationchannel.cpp b/indra/newview/llcommunicationchannel.cpp
index 4b0a70ffd8..0821510645 100644
--- a/indra/newview/llcommunicationchannel.cpp
+++ b/indra/newview/llcommunicationchannel.cpp
@@ -52,6 +52,11 @@ bool LLCommunicationChannel::filterByDoNotDisturbStatus(LLNotificationPtr)
return !gAgent.isDoNotDisturb();
}
+S32 LLCommunicationChannel::getHistorySize() const
+{
+ return mHistory.size();
+}
+
LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::beginHistory() const
{
return mHistory.begin();
@@ -62,17 +67,46 @@ LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::e
return mHistory.end();
}
+LLCommunicationChannel::history_list_t::iterator LLCommunicationChannel::beginHistory()
+{
+ return mHistory.begin();
+}
+
+LLCommunicationChannel::history_list_t::iterator LLCommunicationChannel::endHistory()
+{
+ return mHistory.end();
+}
+
void LLCommunicationChannel::clearHistory()
{
mHistory.clear();
}
+void LLCommunicationChannel::removeItemFromHistory(LLNotificationPtr p)
+{
+ //Find the notification and removes it from mHistory
+ for(history_list_t::iterator it = beginHistory(); it != endHistory(); ++it)
+ {
+ if(it->second == p)
+ {
+ mHistory.erase(it);
+ break;
+ }
+ }
+}
+
+void LLCommunicationChannel::onDelete(LLNotificationPtr p)
+{
+ removeItemFromHistory(p);
+}
+
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));
}
diff --git a/indra/newview/llcommunicationchannel.h b/indra/newview/llcommunicationchannel.h
index 0e15e1cd15..0d8f7f4387 100644
--- a/indra/newview/llcommunicationchannel.h
+++ b/indra/newview/llcommunicationchannel.h
@@ -44,12 +44,17 @@ public:
static bool filterByDoNotDisturbStatus(LLNotificationPtr);
typedef std::multimap<LLDate, LLNotificationPtr> history_list_t;
+ S32 getHistorySize() const;
history_list_t::const_iterator beginHistory() const;
history_list_t::const_iterator endHistory() const;
-
+ history_list_t::iterator beginHistory();
+ history_list_t::iterator endHistory();
+
void clearHistory();
+ void removeItemFromHistory(LLNotificationPtr p);
protected:
+ virtual void onDelete(LLNotificationPtr p);
virtual void onFilterFail(LLNotificationPtr pNotificationPtr);
private:
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index ac41a3804f..42b455c1ce 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -33,6 +33,7 @@
#include "lldir.h"
#include "llerror.h"
#include "llfasttimer_class.h"
+#include "llfloaterreg.h"
#include "llnotifications.h"
#include "llnotificationhandler.h"
#include "llnotificationstorage.h"
@@ -41,9 +42,34 @@
#include "llsingleton.h"
#include "lluuid.h"
+static const F32 DND_TIMER = 3.0;
+
+LLDoNotDisturbNotificationStorageTimer::LLDoNotDisturbNotificationStorageTimer() : LLEventTimer(DND_TIMER)
+{
+ mEventTimer.start();
+}
+
+LLDoNotDisturbNotificationStorageTimer::~LLDoNotDisturbNotificationStorageTimer()
+{
+ mEventTimer.stop();
+}
+
+BOOL LLDoNotDisturbNotificationStorageTimer::tick()
+{
+ LLDoNotDisturbNotificationStorage * doNotDisturbNotificationStorage = LLDoNotDisturbNotificationStorage::getInstance();
+
+ if(doNotDisturbNotificationStorage
+ && doNotDisturbNotificationStorage->getDirty())
+ {
+ doNotDisturbNotificationStorage->saveNotifications();
+ }
+ return FALSE;
+}
+
LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage()
: LLSingleton<LLDoNotDisturbNotificationStorage>()
, LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"))
+ , mDirty(false)
{
}
@@ -56,6 +82,16 @@ void LLDoNotDisturbNotificationStorage::initialize()
getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1));
}
+bool LLDoNotDisturbNotificationStorage::getDirty()
+{
+ return mDirty;
+}
+
+void LLDoNotDisturbNotificationStorage::resetDirty()
+{
+ mDirty = false;
+}
+
static LLFastTimer::DeclareTimer FTM_SAVE_DND_NOTIFICATIONS("Save DND Notifications");
void LLDoNotDisturbNotificationStorage::saveNotifications()
@@ -82,6 +118,8 @@ void LLDoNotDisturbNotificationStorage::saveNotifications()
}
writeNotifications(output);
+
+ resetDirty();
}
static LLFastTimer::DeclareTimer FTM_LOAD_DND_NOTIFICATIONS("Load DND Notifications");
@@ -103,6 +141,7 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
}
LLNotifications& instance = LLNotifications::instance();
+ bool imToastExists = false;
for (LLSD::array_const_iterator notification_it = data.beginArray();
notification_it != data.endArray();
@@ -110,17 +149,15 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
{
LLSD notification_params = *notification_it;
const LLUUID& notificationID = notification_params["id"];
+ std::string notificationName = notification_params["name"];
LLNotificationPtr notification = instance.find(notificationID);
-
- //Notification already exists in notification pipeline (same instance of app running)
- if (notification)
- {
- notification->setDND(true);
- instance.update(notification);
- }
- //Notification doesn't exist (different instance since restarted app while in DND mode)
- else
- {
+
+ if(notificationName == "IMToast")
+ {
+ imToastExists = true;
+ }
+
+ //New notification needs to be added
notification = (LLNotificationPtr) new LLNotification(notification_params.with("is_dnd", true));
LLNotificationResponderInterface* responder = createResponder(notification_params["responder_sd"]["responder_type"], notification_params["responder_sd"]);
if (responder == NULL)
@@ -136,16 +173,58 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
instance.add(notification);
}
- }
- // Clear the communication channel history and rewrite the save file to empty it as well
+ if(imToastExists)
+ {
+ LLFloaterReg::showInstance("im_container");
+ }
+
+ //writes out empty .xml file (since LLCommunicationChannel::mHistory is empty)
+ saveNotifications();
+}
+
+void LLDoNotDisturbNotificationStorage::updateNotifications()
+{
+
LLNotificationChannelPtr channelPtr = getCommunicationChannel();
LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
llassert(commChannel != NULL);
+
+ LLNotifications& instance = LLNotifications::instance();
+ bool imToastExists = false;
+
+ for (LLCommunicationChannel::history_list_t::const_iterator it = commChannel->beginHistory();
+ it != commChannel->endHistory();
+ ++it)
+ {
+ LLNotificationPtr notification = it->second;
+ std::string notificationName = notification->getName();
+
+ if(notificationName == "IMToast")
+ {
+ imToastExists = true;
+ }
+
+ //Notification already exists in notification pipeline (same instance of app running)
+ if (notification)
+ {
+ notification->setDND(true);
+ instance.update(notification);
+ }
+ }
+
+ if(imToastExists)
+ {
+ LLFloaterReg::showInstance("im_container");
+ }
+
+ //When exit DND mode, write empty notifications file
+ if(commChannel->getHistorySize())
+ {
commChannel->clearHistory();
-
saveNotifications();
}
+}
LLNotificationChannelPtr LLDoNotDisturbNotificationStorage::getCommunicationChannel() const
{
@@ -154,12 +233,55 @@ 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::iterator it;
+ std::vector<LLCommunicationChannel::history_list_t::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 notifications
+ if(itemsToRemove.size())
+ {
+ while(itemsToRemove.size())
+ {
+ it = itemsToRemove.back();
+ notification = it->second;
+ commChannel->removeItemFromHistory(notification);
+ instance.cancel(notification);
+ itemsToRemove.pop_back();
+ }
+ //Trigger saving of notifications to xml once all have been removed
+ saveNotifications();
+ }
+}
+
bool LLDoNotDisturbNotificationStorage::onChannelChanged(const LLSD& pPayload)
{
if (pPayload["sigtype"].asString() != "load")
{
- saveNotifications();
+ mDirty = true;
}
return false;
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
index 60bcd89ec3..fd03b71357 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.h
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -28,12 +28,26 @@
#define LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
#include "llerror.h"
+#include "lleventtimer.h"
#include "llnotifications.h"
#include "llnotificationstorage.h"
#include "llsingleton.h"
class LLSD;
+class LLDoNotDisturbNotificationStorageTimer : public LLEventTimer
+{
+public:
+ LLDoNotDisturbNotificationStorageTimer();
+ ~LLDoNotDisturbNotificationStorageTimer();
+
+public:
+ void startTimer();
+ void stopTimer();
+ bool isRunning();
+ BOOL tick();
+};
+
class LLDoNotDisturbNotificationStorage : public LLSingleton<LLDoNotDisturbNotificationStorage>, public LLNotificationStorage
{
LOG_CLASS(LLDoNotDisturbNotificationStorage);
@@ -42,13 +56,19 @@ public:
~LLDoNotDisturbNotificationStorage();
void initialize();
-
+ bool getDirty();
+ void resetDirty();
void saveNotifications();
void loadNotifications();
+ void updateNotifications();
+ void removeIMNotification(const LLUUID& session_id);
protected:
private:
+ bool mDirty;
+ LLDoNotDisturbNotificationStorageTimer mTimer;
+
LLNotificationChannelPtr getCommunicationChannel() const;
bool onChannelChanged(const LLSD& pPayload);
};
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index ac5ecc4b80..062a92b520 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -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"
@@ -1298,6 +1299,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);
+ }
}
}
@@ -1319,6 +1324,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
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index da811535e5..d0a8dfc0c8 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -128,18 +128,11 @@ void process_dnd_im(const LLSD& notification)
false,
false); //will need slight refactor to retrieve whether offline message or not (assume online for now)
}
-
- // open conversation floater
- LLFloaterIMContainer* container_floater =
- LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
- if (container_floater && !(container_floater->isFrontmost()))
- {
- container_floater->openFloater();
- container_floater->setFrontmost(TRUE);
- }
}
+
+
static void on_avatar_name_cache_toast(const LLUUID& agent_id,
const LLAvatarName& av_name,
LLSD msg)
@@ -254,13 +247,22 @@ void on_new_message(const LLSD& msg)
{
if (conversation_floater_not_focused)
{
- if(session_floater_not_focused)
+ if(session_floater_not_focused && !gAgent.isDoNotDisturb())
{
//User is not focused on conversation containing the message
gToolBarView->flashCommand(LLCommandId("chat"), true);
}
im_box->flashConversationItemWidget(session_id, true);
+
+ //If a DND message, allow notification to be stored so upon DND exit
+ //useMostItrusiveIMNotification will be called to notify user a message exists
+ if(session_id.notNull()
+ && participant_id.notNull()
+ && gAgent.isDoNotDisturb())
+ {
+ LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
+ }
}
}
@@ -272,9 +274,21 @@ void on_new_message(const LLSD& msg)
//Flash line item
im_box->flashConversationItemWidget(session_id, true);
+ if(!gAgent.isDoNotDisturb())
+ {
//Surface conversations floater
LLFloaterReg::showInstance("im_container");
}
+
+ //If in DND mode, allow notification to be stored so upon DND exit
+ //useMostItrusiveIMNotification will be called to notify user a message exists
+ if(session_id.notNull()
+ && participant_id.notNull()
+ && gAgent.isDoNotDisturb())
+ {
+ LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
+ }
+}
}
}
@@ -2605,15 +2619,10 @@ void LLIMMgr::addMessage(
// Open conversation floater if offline messages are present
if (is_offline_msg)
{
- LLFloaterIMContainer* container_floater =
- LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
- if (container_floater && !(container_floater->isFrontmost()))
- {
- container_floater->openFloater();
- container_floater->setFrontmost(TRUE);
- }
+ LLFloaterReg::showInstance("im_container");
+ LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->
+ flashConversationItemWidget(session_id, true);
}
-
}
void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args)
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index df1ccdd9fc..115114bb53 100644
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -89,6 +89,9 @@ BOOL LLPanelBlockedList::postBuild()
case E_SORT_BY_TYPE:
mBlockedList->sortByType();
break;
+ default:
+ llwarns << "Unrecognized sort order for blocked list" << llendl;
+ break;
}
// Use the context menu of the Block list for the Block tab gear menu.
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index d494d12903..268b68b539 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -356,9 +356,8 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
if(rect != LLRect::null)
{
this->setShape(rect);
- }
+ }
mInfoPanel = getChild<LLPanel>("info_panel");
- mInfoPanel->setFollowsAll();
mControlPanel = getChild<LLPanel>("control_panel");
BUTTON_WIDTH = gSavedSettings.getS32("ToastButtonWidth");
@@ -453,10 +452,10 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
if(h_pad < 2*HPAD)
{
/*
- * Probably it is a scriptdialog toast
- * for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons.
- * In last case set default h_pad to avoid heaping of buttons
- */
+ * Probably it is a scriptdialog toast
+ * for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons.
+ * In last case set default h_pad to avoid heaping of buttons
+ */
S32 button_per_row = button_panel_width / BUTTON_WIDTH;
h_pad = (button_panel_width % BUTTON_WIDTH) / (button_per_row - 1);// -1 because we do not need space after last button in a row
if(h_pad < 2*HPAD) // still not enough space between buttons ?
@@ -491,10 +490,10 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
//mButtons.assign(buttons.begin(), buttons.end());
}
}
+
// adjust panel's height to the text size
+ mInfoPanel->setFollowsAll();
snapToMessageHeight(mTextBox, MAX_LENGTH);
-
-
}