fixed EXT-5904 “Offers embedding into IM windows”,

made all type offers be embedded to the IM floater;
made showing offer toast if IM floater isn't visible;
corrected IM message counter on showing offer toast;

--HG--
branch : product-engine
master
Alexei Arabadji 2010-03-04 11:35:34 +02:00
parent e84e440adc
commit f54bf2a1ea
8 changed files with 145 additions and 22 deletions

View File

@ -320,7 +320,6 @@ LLNotificationChiclet::LLNotificationChiclet(const Params& p)
// connect counter handlers to the signals
connectCounterUpdatersToSignal("notify");
connectCounterUpdatersToSignal("groupnotify");
connectCounterUpdatersToSignal("offer");
// ensure that notification well window exists, to synchronously
// handle toast add/delete events.

View File

@ -648,6 +648,15 @@ void LLIMFloater::updateMessages()
if (msg.has("notification_id"))
{
chat.mNotifId = msg["notification_id"].asUUID();
// remove embedded notification from channel
LLNotificationsUI::LLScreenChannel* channel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>
(LLNotificationsUI::LLChannelManager::getInstance()->
findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
if (getVisible())
{
// toast will be automatically closed since it is not storable toast
channel->hideToast(chat.mNotifId);
}
}
//process text message
else
@ -657,6 +666,19 @@ void LLIMFloater::updateMessages()
mChatHistory->appendMessage(chat, chat_args);
mLastMessageIndex = msg["index"].asInteger();
// if it is a notification - next message is a notification history log, so skip it
if (chat.mNotifId.notNull() && LLNotificationsUtil::find(chat.mNotifId) != NULL)
{
if (++iter == iter_end)
{
break;
}
else
{
mLastMessageIndex++;
}
}
}
}
}

View File

@ -297,6 +297,11 @@ public:
*/
static bool canSpawnSessionAndLogToIM(const LLNotificationPtr& notification);
/**
* Determines whether IM floater is opened.
*/
static bool isIMFloaterOpened(const LLNotificationPtr& notification);
/**
* Writes notification message to IM session.
*/
@ -343,6 +348,16 @@ public:
* Adds notification panel to the IM floater.
*/
static void addNotifPanelToIM(const LLNotificationPtr& notification);
/**
* Updates messages of visible IM floater.
*/
static void updateVisibleIMFLoaterMesages(const LLNotificationPtr& notification);
/**
* Decrements counter of IM messages.
*/
static void decIMMesageCounter(const LLNotificationPtr& notification);
};
}

View File

@ -127,7 +127,9 @@ const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"),
FRIENDSHIP_DECLINED_BYME("FriendshipDeclinedByMe"),
FRIEND_ONLINE("FriendOnline"), FRIEND_OFFLINE("FriendOffline"),
SERVER_OBJECT_MESSAGE("ServerObjectMessage"),
TELEPORT_OFFERED("TeleportOffered");
TELEPORT_OFFERED("TeleportOffered"),
TELEPORT_OFFER_SENT("TeleportOfferSent");
// static
bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification)
@ -141,7 +143,10 @@ bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification)
|| FRIENDSHIP_DECLINED_BYME == notification->getName()
|| SERVER_OBJECT_MESSAGE == notification->getName()
|| INVENTORY_ACCEPTED == notification->getName()
|| INVENTORY_DECLINED == notification->getName();
|| INVENTORY_DECLINED == notification->getName()
|| USER_GIVE_ITEM == notification->getName()
|| TELEPORT_OFFERED == notification->getName()
|| TELEPORT_OFFER_SENT == notification->getName();
}
// static
@ -161,23 +166,43 @@ bool LLHandlerUtil::canSpawnIMSession(const LLNotificationPtr& notification)
|| FRIENDSHIP_ACCEPTED == notification->getName()
|| USER_GIVE_ITEM == notification->getName()
|| INVENTORY_ACCEPTED == notification->getName()
|| INVENTORY_DECLINED == notification->getName();
|| INVENTORY_DECLINED == notification->getName()
|| TELEPORT_OFFERED == notification->getName();
}
// static
bool LLHandlerUtil::canAddNotifPanelToIM(const LLNotificationPtr& notification)
{
return OFFER_FRIENDSHIP == notification->getName()
|| USER_GIVE_ITEM == notification->getName();
|| USER_GIVE_ITEM == notification->getName()
|| TELEPORT_OFFERED == notification->getName();
}
// static
bool LLHandlerUtil::canSpawnSessionAndLogToIM(const LLNotificationPtr& notification)
{
return canLogToIM(notification) && canSpawnIMSession(notification);
}
// static
bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
{
bool res = false;
LLUUID from_id = notification->getPayload()["from_id"];
LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL,
from_id);
LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>(
"impanel", session_id);
if (im_floater != NULL)
{
res = im_floater->getVisible() == TRUE;
}
return res;
}
// static
void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
const std::string& session_name, const std::string& from_name,
@ -348,6 +373,42 @@ void LLHandlerUtil::addNotifPanelToIM(const LLNotificationPtr& notification)
offer["time"] = LLLogChat::timestamp(true);
offer["index"] = (LLSD::Integer)session->mMsgs.size();
session->mMsgs.push_front(offer);
LLIMFloater::show(session_id);
}
// static
void LLHandlerUtil::updateVisibleIMFLoaterMesages(const LLNotificationPtr& notification)
{
const std::string name = LLHandlerUtil::getSubstitutionName(notification);
LLUUID from_id = notification->getPayload()["from_id"];
LLUUID session_id = spawnIMSession(name, from_id);
LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
if (im_floater != NULL && im_floater->getVisible())
{
im_floater->updateMessages();
}
}
// static
void LLHandlerUtil::decIMMesageCounter(const LLNotificationPtr& notification)
{
const std::string name = LLHandlerUtil::getSubstitutionName(notification);
LLUUID from_id = notification->getPayload()["from_id"];
LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id);
LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession(
session_id);
if (session == NULL)
{
return;
}
LLSD arg;
arg["session_id"] = session_id;
session->mNumUnread--;
arg["num_unread"] = session->mNumUnread;
session->mParticipantUnreadMessageCount--;
arg["participant_unread"] = session->mParticipantUnreadMessageCount;
LLIMModel::getInstance()->mNewMsgSignal(arg);
}

View File

@ -113,36 +113,53 @@ bool LLOfferHandler::processNotification(const LLSD& notify)
session_id = LLHandlerUtil::spawnIMSession(name, from_id);
}
if (LLHandlerUtil::canAddNotifPanelToIM(notification))
bool show_toast = true;
bool add_notid_to_im = LLHandlerUtil::canAddNotifPanelToIM(notification);
if (add_notid_to_im)
{
LLHandlerUtil::addNotifPanelToIM(notification);
LLHandlerUtil::logToIMP2P(notification, true);
if (LLHandlerUtil::isIMFloaterOpened(notification))
{
show_toast = false;
}
}
else if (notification->getPayload().has("SUPPRESS_TOAST")
if (notification->getPayload().has("SUPPRESS_TOAST")
&& notification->getPayload()["SUPPRESS_TOAST"])
{
LLHandlerUtil::logToIMP2P(notification);
LLNotificationsUtil::cancel(notification);
}
else
else if(show_toast)
{
LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
// don't close notification on panel destroy since it will be used by IM floater
notify_box->setCloseNotificationOnDestroy(!add_notid_to_im);
LLToast::Params p;
p.notif_id = notification->getID();
p.notification = notification;
p.panel = notify_box;
p.on_delete_toast = boost::bind(&LLOfferHandler::onDeleteToast, this, _1);
// we not save offer notifications to the syswell floater that should be added to the IM floater
p.can_be_stored = !add_notid_to_im;
LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
if(channel)
channel->addToast(p);
LLHandlerUtil::logToIMP2P(notification);
// send a signal to the counter manager
mNewNotificationSignal();
}
if (LLHandlerUtil::canLogToIM(notification))
{
LLHandlerUtil::logToIMP2P(notification);
}
// update IM floater messages if need
if (add_notid_to_im)
{
LLHandlerUtil::updateVisibleIMFLoaterMesages(notification);
}
}
}
else if (notify["sigtype"].asString() == "delete")
@ -155,6 +172,11 @@ bool LLOfferHandler::processNotification(const LLSD& notify)
}
else
{
if (LLHandlerUtil::canAddNotifPanelToIM(notification)
&& !LLHandlerUtil::isIMFloaterOpened(notification))
{
LLHandlerUtil::decIMMesageCounter(notification);
}
mChannel->killToastByNotificationID(notification->getID());
}
}
@ -181,7 +203,9 @@ void LLOfferHandler::onRejectToast(LLUUID& id)
if (notification
&& LLNotificationManager::getInstance()->getHandlerForNotification(
notification->getType()) == this)
notification->getType()) == this
// don't delete notification since it may be used by IM floater
&& !LLHandlerUtil::canAddNotifPanelToIM(notification))
{
LLNotifications::instance().cancel(notification);
}

View File

@ -710,9 +710,7 @@ void LLScreenChannel::hideToast(const LLUUID& notification_id)
if(mToastList.end() != it)
{
ToastElem te = *it;
te.toast->setVisible(FALSE);
te.toast->stopTimer();
mToastList.erase(it);
te.toast->hide();
}
}

View File

@ -60,7 +60,8 @@ mInfoPanel(NULL),
mControlPanel(NULL),
mNumOptions(0),
mNumButtons(0),
mAddedDefaultBtn(false)
mAddedDefaultBtn(false),
mCloseNotificationOnDestroy(true)
{
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_notification.xml");
mInfoPanel = getChild<LLPanel>("info_panel");
@ -257,7 +258,7 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt
LLToastNotifyPanel::~LLToastNotifyPanel()
{
std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer());
if (LLNotificationsUtil::find(mNotification->getID()) != NULL)
if (mCloseNotificationOnDestroy && LLNotificationsUtil::find(mNotification->getID()) != NULL)
{
LLNotifications::getInstance()->cancel(mNotification);
}

View File

@ -57,6 +57,7 @@ public:
virtual ~LLToastNotifyPanel();
LLPanel * getControlPanel() { return mControlPanel; }
void setCloseNotificationOnDestroy(bool close) { mCloseNotificationOnDestroy = close; }
protected:
LLButton* createButton(const LLSD& form_element, BOOL is_option);
@ -68,6 +69,8 @@ protected:
};
std::vector<InstanceAndS32*> mBtnCallbackData;
bool mCloseNotificationOnDestroy;
private:
typedef std::pair<int,LLButton*> index_button_pair_t;