Merge
commit
05e063836a
|
|
@ -10215,7 +10215,7 @@
|
|||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>2</integer>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>CallLogSortOrder</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -1397,7 +1397,7 @@ void LLAgent::setDoNotDisturb(bool pIsDoNotDisturb)
|
|||
LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(pIsDoNotDisturb);
|
||||
if (isDoNotDisturbSwitchedOff)
|
||||
{
|
||||
LLDoNotDisturbNotificationStorage::getInstance()->loadNotifications();
|
||||
LLDoNotDisturbNotificationStorage::getInstance()->updateNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,13 +2619,7 @@ 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");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue