summaryrefslogtreecommitdiff
path: root/indra/newview/llimview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llimview.cpp')
-rw-r--r--indra/newview/llimview.cpp822
1 files changed, 508 insertions, 314 deletions
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 5a6cbb045d..d8643ab9c1 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -1,5 +1,5 @@
/**
- * @file llimview.cpp
+ * @file LLIMMgr.cpp
* @brief Container for Instant Messaging
*
* Copyright (c) 2001-$CurrentYear$, Linden Research, Inc.
@@ -12,9 +12,9 @@
#include "llfontgl.h"
#include "llrect.h"
-#include "lldbstrings.h"
#include "llerror.h"
#include "llbutton.h"
+#include "llhttpclient.h"
#include "llsdutil.h"
#include "llstring.h"
#include "linked_lists.h"
@@ -26,8 +26,8 @@
#include "llviewerwindow.h"
#include "llresmgr.h"
#include "llfloaterchat.h"
+#include "llfloaterchatterbox.h"
#include "llfloaternewim.h"
-#include "llhttpclient.h"
#include "llhttpnode.h"
#include "llimpanel.h"
#include "llresizebar.h"
@@ -42,40 +42,48 @@
#include "llcallingcard.h"
#include "lltoolbar.h"
#include "llviewermessage.h"
+#include "llnotify.h"
#include "llviewerregion.h"
+#include "llfirstuse.h"
+
const EInstantMessage GROUP_DIALOG = IM_SESSION_GROUP_START;
const EInstantMessage DEFAULT_DIALOG = IM_NOTHING_SPECIAL;
//
// Globals
//
-LLIMView* gIMView = NULL;
+LLIMMgr* gIMMgr = NULL;
//
// Statics
//
+//*FIXME: make these all either UIStrings or Strings
static LLString sOnlyUserMessage;
-static LLString sOfflineMessage;
+static LLUIString sOfflineMessage;
static std::map<std::string,LLString> sEventStringsMap;
static std::map<std::string,LLString> sErrorStringsMap;
static std::map<std::string,LLString> sForceCloseSessionMap;
+static LLUIString sInviteMessage;
//
// Helper Functions
//
// returns true if a should appear before b
-static BOOL group_dictionary_sort( LLGroupData* a, LLGroupData* b )
-{
- return (LLString::compareDict( a->mName, b->mName ) < 0);
-}
+//static BOOL group_dictionary_sort( LLGroupData* a, LLGroupData* b )
+//{
+// return (LLString::compareDict( a->mName, b->mName ) < 0);
+//}
// the other_participant_id is either an agent_id, a group_id, or an inventory
// folder item_id (collection of calling cards)
-static LLUUID compute_session_id(EInstantMessage dialog,
- const LLUUID& other_participant_id)
+
+// static
+LLUUID LLIMMgr::computeSessionID(
+ EInstantMessage dialog,
+ const LLUUID& other_participant_id)
{
LLUUID session_id;
if (IM_SESSION_GROUP_START == dialog)
@@ -87,6 +95,11 @@ static LLUUID compute_session_id(EInstantMessage dialog,
{
session_id.generate();
}
+ else if (IM_SESSION_INVITE == dialog)
+ {
+ // use provided session id for invites
+ session_id = other_participant_id;
+ }
else
{
LLUUID agent_id = gAgent.getID();
@@ -121,87 +134,25 @@ LLFloaterIM::LLFloaterIM()
BOOL LLFloaterIM::postBuild()
{
- requires("only_user_message", WIDGET_TYPE_TEXT_BOX);
- requires("offline_message", WIDGET_TYPE_TEXT_BOX);
- requires("generic_request_error", WIDGET_TYPE_TEXT_BOX);
- requires("insufficient_perms_error", WIDGET_TYPE_TEXT_BOX);
- requires("generic_request_error", WIDGET_TYPE_TEXT_BOX);
- requires("add_session_event", WIDGET_TYPE_TEXT_BOX);
- requires("message_session_event", WIDGET_TYPE_TEXT_BOX);
- requires("removed_from_group", WIDGET_TYPE_TEXT_BOX);
-
- if (checkRequirements())
- {
- sOnlyUserMessage = childGetText("only_user_message");
- sOfflineMessage = childGetText("offline_message");
-
- sErrorStringsMap["generic"] =
- childGetText("generic_request_error");
- sErrorStringsMap["unverified"] =
- childGetText("insufficient_perms_error");
- sErrorStringsMap["no_user_911"] =
- childGetText("user_no_help");
+ sOnlyUserMessage = getFormattedUIString("only_user_message");
+ sOfflineMessage = getUIString("offline_message");
- sEventStringsMap["add"] = childGetText("add_session_event");
- sEventStringsMap["message"] =
- childGetText("message_session_event");
+ sErrorStringsMap["generic"] =
+ getFormattedUIString("generic_request_error");
+ sErrorStringsMap["unverified"] =
+ getFormattedUIString("insufficient_perms_error");
+ sErrorStringsMap["no_user_911"] =
+ getFormattedUIString("user_no_help");
- sForceCloseSessionMap["removed"] =
- childGetText("removed_from_group");
+ sEventStringsMap["add"] = childGetText("add_session_event");
+ sEventStringsMap["message"] =
+ getFormattedUIString("message_session_event");
- return TRUE;
- }
- return FALSE;
-}
-
-//// virtual
-//BOOL LLFloaterIM::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
-//{
-// BOOL handled = FALSE;
-// if (getEnabled()
-// && mask == (MASK_CONTROL|MASK_SHIFT))
-// {
-// if (key == 'W')
-// {
-// LLFloater* floater = getActiveFloater();
-// if (floater)
-// {
-// if (mTabContainer->getTabCount() == 1)
-// {
-// // trying to close last tab, close
-// // entire window.
-// close();
-// handled = TRUE;
-// }
-// }
-// }
-// }
-// return handled || LLMultiFloater::handleKeyHere(key, mask, called_from_parent);
-//}
+ sForceCloseSessionMap["removed"] =
+ getFormattedUIString("removed_from_group");
-void LLFloaterIM::onClose(bool app_quitting)
-{
- if (!app_quitting)
- {
- gSavedSettings.setBOOL("ShowIM", FALSE);
- }
- setVisible(FALSE);
-}
-
-//virtual
-void LLFloaterIM::addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point)
-{
-/*
- Code removed via patch from VWR-1626
-
- // this code is needed to fix the bug where new IMs received will resize the IM floater.
- // SL-29075, SL-24556, and others
- LLRect parent_rect = getRect();
- S32 dheight = LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT;
- LLRect rect(0, parent_rect.getHeight()-dheight, parent_rect.getWidth(), 0);
- floaterp->reshape(rect.getWidth(), rect.getHeight(), TRUE);
-*/
- LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
+ sInviteMessage = getUIString("invite_message");
+ return TRUE;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -213,7 +164,7 @@ void LLFloaterIM::addFloater(LLFloater* floaterp, BOOL select_added_floater, LLT
class LLIMViewFriendObserver : public LLFriendObserver
{
public:
- LLIMViewFriendObserver(LLIMView* tv) : mTV(tv) {}
+ LLIMViewFriendObserver(LLIMMgr* tv) : mTV(tv) {}
virtual ~LLIMViewFriendObserver() {}
virtual void changed(U32 mask)
{
@@ -223,7 +174,30 @@ public:
}
}
protected:
- LLIMView* mTV;
+ LLIMMgr* mTV;
+};
+
+
+class LLIMMgr::LLIMSessionInvite
+{
+public:
+ LLIMSessionInvite(const LLUUID& session_id, const LLString& session_name, const LLUUID& caller_id,const LLString& caller_name, EInstantMessage type, const LLString& session_handle, const LLString& notify_box) :
+ mSessionID(session_id),
+ mSessionName(session_name),
+ mCallerID(caller_id),
+ mCallerName(caller_name),
+ mType(type),
+ mSessionHandle(session_handle),
+ mNotifyBox(notify_box)
+ {};
+
+ LLUUID mSessionID;
+ LLString mSessionName;
+ LLUUID mCallerID;
+ LLString mCallerName;
+ EInstantMessage mType;
+ LLString mSessionHandle;
+ LLString mNotifyBox;
};
@@ -234,7 +208,7 @@ protected:
// This is a helper function to determine what kind of im session
// should be used for the given agent.
// static
-EInstantMessage LLIMView::defaultIMTypeForAgent(const LLUUID& agent_id)
+EInstantMessage LLIMMgr::defaultIMTypeForAgent(const LLUUID& agent_id)
{
EInstantMessage type = IM_NOTHING_SPECIAL;
if(is_agent_friend(agent_id))
@@ -248,20 +222,20 @@ EInstantMessage LLIMView::defaultIMTypeForAgent(const LLUUID& agent_id)
}
// static
-//void LLIMView::onPinButton(void*)
+//void LLIMMgr::onPinButton(void*)
//{
// BOOL state = gSavedSettings.getBOOL( "PinTalkViewOpen" );
// gSavedSettings.setBOOL( "PinTalkViewOpen", !state );
//}
// static
-void LLIMView::toggle(void*)
+void LLIMMgr::toggle(void*)
{
static BOOL return_to_mouselook = FALSE;
// Hide the button and show the floater or vice versa.
- llassert( gIMView );
- BOOL old_state = gIMView->getFloaterOpen();
+ llassert( gIMMgr );
+ BOOL old_state = gIMMgr->getFloaterOpen();
// If we're in mouselook and we triggered the Talk View, we want to talk.
if( gAgent.cameraMouselook() && old_state )
@@ -292,53 +266,39 @@ void LLIMView::toggle(void*)
return_to_mouselook = FALSE;
}
- gIMView->setFloaterOpen( new_state );
+ gIMMgr->setFloaterOpen( new_state );
}
//
// Member Functions
//
-LLIMView::LLIMView(const std::string& name, const LLRect& rect) :
- LLView(name, rect, FALSE),
+LLIMMgr::LLIMMgr() :
mFriendObserver(NULL),
mIMReceived(FALSE)
{
- gIMView = this;
mFriendObserver = new LLIMViewFriendObserver(this);
LLAvatarTracker::instance().addObserver(mFriendObserver);
- mTalkFloater = new LLFloaterIM();
+ //*HACK: use floater to initialize string constants from xml file
+ // then delete it right away
+ LLFloaterIM* dummy_floater = new LLFloaterIM();
+ delete dummy_floater;
- // New IM Panel
- mNewIMFloater = new LLFloaterNewIM();
- mTalkFloater->addFloater(mNewIMFloater, TRUE);
-
- // Tabs sometimes overlap resize handle
- mTalkFloater->moveResizeHandleToFront();
+ mPendingVoiceInvitations = LLSD::emptyMap();
}
-LLIMView::~LLIMView()
+LLIMMgr::~LLIMMgr()
{
LLAvatarTracker::instance().removeObserver(mFriendObserver);
delete mFriendObserver;
// Children all cleaned up by default view destructor.
}
-EWidgetType LLIMView::getWidgetType() const
-{
- return WIDGET_TYPE_TALK_VIEW;
-}
-
-LLString LLIMView::getWidgetTag() const
-{
- return LL_TALK_VIEW_TAG;
-}
-
// Add a message to a session.
-void LLIMView::addMessage(
+void LLIMMgr::addMessage(
const LLUUID& session_id,
- const LLUUID& other_participant_id,
+ const LLUUID& target_id,
const char* from,
const char* msg,
const char* session_name,
@@ -347,11 +307,30 @@ void LLIMView::addMessage(
const LLUUID& region_id,
const LLVector3& position)
{
+ LLUUID other_participant_id = target_id;
+ bool is_from_system = target_id.isNull();
+
+ // don't process muted IMs
+ if (gMuteListp->isMuted(
+ other_participant_id,
+ LLMute::flagTextChat) && !gMuteListp->isLinden(from))
+ {
+ return;
+ }
+
+ //not sure why...but if it is from ourselves we set the target_id
+ //to be NULL
+ if( other_participant_id == gAgent.getID() )
+ {
+ other_participant_id = LLUUID::null;
+ }
+
LLFloaterIMPanel* floater;
LLUUID new_session_id = session_id;
if (new_session_id.isNull())
{
- new_session_id = compute_session_id(dialog, other_participant_id);
+ //no session ID...compute new one
+ new_session_id = computeSessionID(dialog, other_participant_id);
}
floater = findFloaterBySession(new_session_id);
if (!floater)
@@ -363,20 +342,10 @@ void LLIMView::addMessage(
<< " by participant " << other_participant_id << llendl;
}
}
- if(floater)
- {
- floater->addHistoryLine(msg);
- }
- else
- {
- //if we have recently requsted to be dropped from a session
- //but are still receiving messages from the session, don't make
- //a new floater
- if ( mSessionsDropRequested.has(session_id.asString()) )
- {
- return ;
- }
+ // create IM window as necessary
+ if(!floater)
+ {
const char* name = from;
if(session_name && (strlen(session_name)>1))
{
@@ -384,7 +353,12 @@ void LLIMView::addMessage(
}
- floater = createFloater(new_session_id, other_participant_id, name, dialog, FALSE);
+ floater = createFloater(
+ new_session_id,
+ other_participant_id,
+ name,
+ dialog,
+ FALSE);
// When we get a new IM, and if you are a god, display a bit
// of information about the source. This is to help liaisons
@@ -404,27 +378,41 @@ void LLIMView::addMessage(
//<< "*** region_id: " << region_id << std::endl
//<< "*** position: " << position << std::endl;
- floater->addHistoryLine(bonus_info.str());
+ floater->addHistoryLine(bonus_info.str(), gSavedSettings.getColor4("SystemChatColor"));
}
- floater->addHistoryLine(msg);
make_ui_sound("UISndNewIncomingIMSession");
}
- if( !mTalkFloater->getVisible() && !floater->getVisible())
+ // now add message to floater
+ if ( is_from_system ) // chat came from system
+ {
+ floater->addHistoryLine(
+ other_participant_id,
+ msg,
+ gSavedSettings.getColor4("SystemChatColor"));
+ }
+ else
+ {
+ floater->addHistoryLine(other_participant_id, msg);
+ }
+
+ LLFloaterChatterBox* chat_floater = LLFloaterChatterBox::getInstance(LLSD());
+
+ if( !chat_floater->getVisible() && !floater->getVisible())
{
//if the IM window is not open and the floater is not visible (i.e. not torn off)
- LLFloater* previouslyActiveFloater = mTalkFloater->getActiveFloater();
+ LLFloater* previouslyActiveFloater = chat_floater->getActiveFloater();
// select the newly added floater (or the floater with the new line added to it).
// it should be there.
- mTalkFloater->selectFloater(floater);
+ chat_floater->selectFloater(floater);
//there was a previously unseen IM, make that old tab flashing
//it is assumed that the most recently unseen IM tab is the one current selected/active
if ( previouslyActiveFloater && getIMReceived() )
{
- mTalkFloater->setFloaterFlashing(previouslyActiveFloater, TRUE);
+ chat_floater->setFloaterFlashing(previouslyActiveFloater, TRUE);
}
//notify of a new IM
@@ -432,37 +420,87 @@ void LLIMView::addMessage(
}
}
-void LLIMView::notifyNewIM()
+void LLIMMgr::addSystemMessage(const LLUUID& session_id, const LLString& message_name, const LLString::format_map_t& args)
+{
+ LLUIString message;
+
+ // null session id means near me (chat history)
+ if (session_id.isNull())
+ {
+ LLFloaterChat* floaterp = LLFloaterChat::getInstance();
+
+ message = floaterp->getUIString(message_name);
+ message.setArgList(args);
+
+ LLChat chat(message);
+ chat.mSourceType = CHAT_SOURCE_SYSTEM;
+ LLFloaterChat::getInstance()->addChatHistory(chat);
+ }
+ else // going to IM session
+ {
+ LLFloaterIMPanel* floaterp = findFloaterBySession(session_id);
+ if (floaterp)
+ {
+ message = floaterp->getUIString(message_name);
+ message.setArgList(args);
+
+ gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString().c_str());
+ }
+ }
+}
+
+void LLIMMgr::notifyNewIM()
{
- if(!gIMView->getFloaterOpen())
+ if(!gIMMgr->getFloaterOpen())
{
mIMReceived = TRUE;
}
}
-BOOL LLIMView::getIMReceived() const
+void LLIMMgr::clearNewIMNotification()
+{
+ mIMReceived = FALSE;
+}
+
+BOOL LLIMMgr::getIMReceived() const
{
return mIMReceived;
}
// This method returns TRUE if the local viewer has a session
// currently open keyed to the uuid.
-BOOL LLIMView::isIMSessionOpen(const LLUUID& uuid)
+BOOL LLIMMgr::isIMSessionOpen(const LLUUID& uuid)
{
LLFloaterIMPanel* floater = findFloaterBySession(uuid);
if(floater) return TRUE;
return FALSE;
}
+LLUUID LLIMMgr::addP2PSession(const std::string& name,
+ const LLUUID& other_participant_id,
+ const LLString& voice_session_handle)
+{
+ LLUUID session_id = addSession(name, IM_NOTHING_SPECIAL, other_participant_id);
+
+ LLFloaterIMPanel* floater = findFloaterBySession(session_id);
+ if(floater)
+ {
+ LLVoiceChannelP2P* voice_channelp = (LLVoiceChannelP2P*)floater->getVoiceChannel();
+ voice_channelp->setSessionHandle(voice_session_handle);
+ }
+
+ return session_id;
+}
+
// This adds a session to the talk view. The name is the local name of
// the session, dialog specifies the type of session. If the session
// exists, it is brought forward. Specifying id = NULL results in an
// im session to everyone. Returns the uuid of the session.
-LLUUID LLIMView::addSession(const std::string& name,
+LLUUID LLIMMgr::addSession(const std::string& name,
EInstantMessage dialog,
const LLUUID& other_participant_id)
{
- LLUUID session_id = compute_session_id(dialog, other_participant_id);
+ LLUUID session_id = computeSessionID(dialog, other_participant_id);
LLFloaterIMPanel* floater = findFloaterBySession(session_id);
if(!floater)
@@ -478,7 +516,7 @@ LLUUID LLIMView::addSession(const std::string& name,
TRUE);
noteOfflineUsers(floater, ids);
- mTalkFloater->showFloater(floater);
+ LLFloaterChatterBox::getInstance(LLSD())->showFloater(floater);
}
else
{
@@ -491,7 +529,7 @@ LLUUID LLIMView::addSession(const std::string& name,
// Adds a session using the given session_id. If the session already exists
// the dialog type is assumed correct. Returns the uuid of the session.
-LLUUID LLIMView::addSession(const std::string& name,
+LLUUID LLIMMgr::addSession(const std::string& name,
EInstantMessage dialog,
const LLUUID& other_participant_id,
const LLDynamicArray<LLUUID>& ids)
@@ -501,7 +539,7 @@ LLUUID LLIMView::addSession(const std::string& name,
return LLUUID::null;
}
- LLUUID session_id = compute_session_id(dialog,
+ LLUUID session_id = computeSessionID(dialog,
other_participant_id);
LLFloaterIMPanel* floater = findFloaterBySession(session_id);
@@ -520,7 +558,7 @@ LLUUID LLIMView::addSession(const std::string& name,
noteOfflineUsers(floater, ids);
}
- mTalkFloater->showFloater(floater);
+ LLFloaterChatterBox::getInstance(LLSD())->showFloater(floater);
//mTabContainer->selectTabPanel(panel);
floater->setInputFocus(TRUE);
return floater->getSessionID();
@@ -528,134 +566,272 @@ LLUUID LLIMView::addSession(const std::string& name,
// This removes the panel referenced by the uuid, and then restores
// internal consistency. The internal pointer is not deleted.
-void LLIMView::removeSession(const LLUUID& session_id)
+void LLIMMgr::removeSession(const LLUUID& session_id)
{
LLFloaterIMPanel* floater = findFloaterBySession(session_id);
if(floater)
{
mFloaters.erase(floater->getHandle());
- mTalkFloater->removeFloater(floater);
+ LLFloaterChatterBox::getInstance(LLSD())->removeFloater(floater);
//mTabContainer->removeTabPanel(floater);
- if(session_id.notNull()
- && (floater->getDialogType() != IM_NOTHING_SPECIAL))
- {
- mSessionsDropRequested[session_id.asString()] = LLSD();
- }
}
}
-void LLIMView::refresh()
+void LLIMMgr::inviteToSession(
+ const LLUUID& session_id,
+ const LLString& session_name,
+ const LLUUID& caller_id,
+ const LLString& caller_name,
+ EInstantMessage type,
+ const LLString& session_handle)
{
- S32 old_scroll_pos = mNewIMFloater->getScrollPos();
- mNewIMFloater->clearAllTargets();
+ //ignore voice invites from voice-muted residents
+ if (gMuteListp->isMuted(caller_id))
+ {
+ return;
+ }
- // build a list of groups.
- LLLinkedList<LLGroupData> group_list( group_dictionary_sort );
+ LLString notify_box_type;
- LLGroupData* group;
- S32 count = gAgent.mGroups.count();
- S32 i;
- // read/sort groups on the first pass.
- for(i = 0; i < count; ++i)
+ BOOL ad_hoc_invite = FALSE;
+ if(type == IM_SESSION_P2P_INVITE)
{
- group = &(gAgent.mGroups.get(i));
- group_list.addDataSorted( group );
+ notify_box_type = "VoiceInviteP2P";
}
-
- // add groups to the floater on the second pass.
- for(group = group_list.getFirstData();
- group;
- group = group_list.getNextData())
+ else if (gAgent.isInGroup(session_id))
{
- mNewIMFloater->addGroup(group->mID, (void*)(&GROUP_DIALOG), TRUE, FALSE);
+ notify_box_type = "VoiceInviteGroup";
+ }
+ else
+ {
+ notify_box_type = "VoiceInviteAdHoc";
+ ad_hoc_invite = TRUE;
}
- // build a set of buddies in the current buddy list.
- LLCollectAllBuddies collector;
- LLAvatarTracker::instance().applyFunctor(collector);
- LLCollectAllBuddies::buddy_map_t::iterator it;
- LLCollectAllBuddies::buddy_map_t::iterator end;
- it = collector.mOnline.begin();
- end = collector.mOnline.end();
- for( ; it != end; ++it)
+ LLIMSessionInvite* invite = new LLIMSessionInvite(
+ session_id,
+ session_name,
+ caller_id,
+ caller_name,
+ type,
+ session_handle,
+ notify_box_type);
+
+ LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(session_id);
+ if (channelp && channelp->callStarted())
{
- mNewIMFloater->addAgent((*it).second, (void*)(&DEFAULT_DIALOG), TRUE);
+ // you have already started a call to the other user, so just accept the invite
+ inviteUserResponse(0, invite);
+ return;
}
- it = collector.mOffline.begin();
- end = collector.mOffline.end();
- for( ; it != end; ++it)
+
+ if (type == IM_SESSION_P2P_INVITE || ad_hoc_invite)
{
- mNewIMFloater->addAgent((*it).second, (void*)(&DEFAULT_DIALOG), FALSE);
+ // is the inviter a friend?
+ if (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL)
+ {
+ // if not, and we are ignoring voice invites from non-friends
+ // then silently decline
+ if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly"))
+ {
+ // invite not from a friend, so decline
+ inviteUserResponse(1, invite);
+ return;
+ }
+ }
}
- mNewIMFloater->setScrollPos( old_scroll_pos );
+ if ( !mPendingVoiceInvitations.has(session_id.asString()) )
+ {
+ if (caller_name.empty())
+ {
+ gCacheName->getName(caller_id, onInviteNameLookup, invite);
+ }
+ else
+ {
+ LLString::format_map_t args;
+ args["[NAME]"] = caller_name;
+ args["[GROUP]"] = session_name;
+
+ LLNotifyBox::showXml(notify_box_type,
+ args,
+ inviteUserResponse,
+ (void*)invite);
+
+ }
+ mPendingVoiceInvitations[session_id.asString()] = LLSD();
+ }
}
-// JC - This used to set console visibility. It doesn't any more.
-void LLIMView::setFloaterOpen(BOOL set_open)
+//static
+void LLIMMgr::onInviteNameLookup(const LLUUID& id, const char* first, const char* last, BOOL is_group, void* userdata)
{
- gSavedSettings.setBOOL("ShowIM", set_open);
+ LLIMSessionInvite* invite = (LLIMSessionInvite*)userdata;
- //RN "visible" and "open" are considered synonomous for now
- if (set_open)
+ invite->mCallerName = llformat("%s %s", first, last);
+ invite->mSessionName = invite->mCallerName;
+
+ LLString::format_map_t args;
+ args["[NAME]"] = invite->mCallerName;
+
+ LLNotifyBox::showXml(invite->mNotifyBox,
+ args,
+ inviteUserResponse,
+ (void*)invite);
+}
+
+class LLViewerChatterBoxInvitationAcceptResponder :
+ public LLHTTPClient::Responder
+{
+public:
+ LLViewerChatterBoxInvitationAcceptResponder(
+ const LLUUID& session_id,
+ bool is_voice_invitation)
{
- mTalkFloater->open(); /*Flawfinder: ignore*/
+ mSessionID = session_id;
+ mIsVoiceInvitiation = is_voice_invitation;
}
- else
+
+ void result(const LLSD& content)
{
- mTalkFloater->close();
+ if ( gIMMgr)
+ {
+ LLFloaterIMPanel* floaterp =
+ gIMMgr->findFloaterBySession(mSessionID);
+
+ if (floaterp)
+ {
+ floaterp->setSpeakersList(content["agents"]);
+
+ if ( mIsVoiceInvitiation )
+ {
+ floaterp->requestAutoConnect();
+ LLFloaterIMPanel::onClickStartCall(floaterp);
+ }
+ }
+
+ if ( mIsVoiceInvitiation )
+ {
+ gIMMgr->clearPendingVoiceInviation(mSessionID);
+ }
+ }
}
- if( set_open )
+ void error(U32 statusNum, const std::string& reason)
{
- // notifyNewIM();
-
- // We're showing the IM, so mark view as non-pending
- mIMReceived = FALSE;
+ //throw something back to the viewer here?
+ if ( gIMMgr && mIsVoiceInvitiation )
+ {
+ gIMMgr->clearPendingVoiceInviation(mSessionID);
+ }
}
-}
+private:
+ LLUUID mSessionID;
+ bool mIsVoiceInvitiation;
+};
-BOOL LLIMView::getFloaterOpen()
+//static
+void LLIMMgr::inviteUserResponse(S32 option, void* user_data)
{
- return mTalkFloater->getVisible();
-}
-
-void LLIMView::pruneSessions()
-{
- if(mNewIMFloater)
+ LLIMSessionInvite* invitep = (LLIMSessionInvite*)user_data;
+
+ switch(option)
{
- BOOL removed = TRUE;
- LLFloaterIMPanel* floater = NULL;
- while(removed)
+ case 0: // accept
+ {
+ if (invitep->mType == IM_SESSION_P2P_INVITE)
+ {
+ // create a normal IM session
+ invitep->mSessionID = gIMMgr->addP2PSession(
+ invitep->mSessionName,
+ invitep->mCallerID,
+ invitep->mSessionHandle);
+
+ LLFloaterIMPanel* im_floater =
+ gIMMgr->findFloaterBySession(
+ invitep->mSessionID);
+ if (im_floater)
+ {
+ im_floater->requestAutoConnect();
+ LLFloaterIMPanel::onClickStartCall(im_floater);
+ }
+
+ gIMMgr->clearPendingVoiceInviation(invitep->mSessionID);
+ }
+ else
+ {
+ gIMMgr->addSession(
+ invitep->mSessionName,
+ invitep->mType,
+ invitep->mSessionID);
+
+ std::string url = gAgent.getRegion()->getCapability(
+ "ChatSessionRequest");
+
+ LLSD data;
+ data["method"] = "accept invitation";
+ data["session-id"] = invitep->mSessionID;
+ LLHTTPClient::post(
+ url,
+ data,
+ new LLViewerChatterBoxInvitationAcceptResponder(
+ invitep->mSessionID,
+ true));
+ }
+ }
+ break;
+ case 2: // mute (also implies ignore, so this falls through to the "ignore" case below)
+ {
+ // mute the sender of this invite
+ if (!gMuteListp->isMuted(invitep->mCallerID))
+ {
+ LLMute mute(invitep->mCallerID, invitep->mCallerName, LLMute::AGENT);
+ gMuteListp->add(mute);
+ }
+ }
+ /* FALLTHROUGH */
+
+ case 1: // ignore
{
- removed = FALSE;
- std::set<LLViewHandle>::iterator handle_it;
- for(handle_it = mFloaters.begin();
- handle_it != mFloaters.end();
- ++handle_it)
+ if (invitep->mType == IM_SESSION_P2P_INVITE)
{
- floater = (LLFloaterIMPanel*)LLFloater::getFloaterByHandle(*handle_it);
- if(floater && !mNewIMFloater->isUUIDAvailable(floater->getOtherParticipantID()))
+ if(gVoiceClient)
{
- // remove this floater
- removed = TRUE;
- mFloaters.erase(handle_it++);
- floater->close();
- break;
+ gVoiceClient->declineInvite(invitep->mSessionHandle);
}
}
}
+ break;
}
+
+ delete invitep;
}
+void LLIMMgr::refresh()
+{
+}
-void LLIMView::disconnectAllSessions()
+void LLIMMgr::setFloaterOpen(BOOL set_open)
{
- if(mNewIMFloater)
+ if (set_open)
{
- mNewIMFloater->setEnabled(FALSE);
+ LLFloaterChatterBox::showInstance(LLSD());
}
+ else
+ {
+ LLFloaterChatterBox::hideInstance(LLSD());
+ }
+}
+
+
+BOOL LLIMMgr::getFloaterOpen()
+{
+ return LLFloaterChatterBox::instanceVisible(LLSD());
+}
+
+void LLIMMgr::disconnectAllSessions()
+{
LLFloaterIMPanel* floater = NULL;
std::set<LLViewHandle>::iterator handle_it;
for(handle_it = mFloaters.begin();
@@ -670,7 +846,7 @@ void LLIMView::disconnectAllSessions()
if (floater)
{
floater->setEnabled(FALSE);
- floater->onClose(TRUE);
+ floater->close(TRUE);
}
}
}
@@ -679,7 +855,7 @@ void LLIMView::disconnectAllSessions()
// This method returns the im panel corresponding to the uuid
// provided. The uuid can either be a session id or an agent
// id. Returns NULL if there is no matching panel.
-LLFloaterIMPanel* LLIMView::findFloaterBySession(const LLUUID& session_id)
+LLFloaterIMPanel* LLIMMgr::findFloaterBySession(const LLUUID& session_id)
{
LLFloaterIMPanel* rv = NULL;
std::set<LLViewHandle>::iterator handle_it;
@@ -698,17 +874,25 @@ LLFloaterIMPanel* LLIMView::findFloaterBySession(const LLUUID& session_id)
}
-BOOL LLIMView::hasSession(const LLUUID& session_id)
+BOOL LLIMMgr::hasSession(const LLUUID& session_id)
{
return (findFloaterBySession(session_id) != NULL);
}
+void LLIMMgr::clearPendingVoiceInviation(const LLUUID& session_id)
+{
+ if ( mPendingVoiceInvitations.has(session_id.asString()) )
+ {
+ mPendingVoiceInvitations.erase(session_id.asString());
+ }
+}
+
// create a floater and update internal representation for
// consistency. Returns the pointer, caller (the class instance since
// it is a private method) is not responsible for deleting the
// pointer. Add the floater to this but do not select it.
-LLFloaterIMPanel* LLIMView::createFloater(
+LLFloaterIMPanel* LLIMMgr::createFloater(
const LLUUID& session_id,
const LLUUID& other_participant_id,
const std::string& session_label,
@@ -720,7 +904,7 @@ LLFloaterIMPanel* LLIMView::createFloater(
llwarns << "Creating LLFloaterIMPanel with null session ID" << llendl;
}
- llinfos << "LLIMView::createFloater: from " << other_participant_id
+ llinfos << "LLIMMgr::createFloater: from " << other_participant_id
<< " in session " << session_id << llendl;
LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label,
LLRect(),
@@ -729,12 +913,12 @@ LLFloaterIMPanel* LLIMView::createFloater(
other_participant_id,
dialog);
LLTabContainerCommon::eInsertionPoint i_pt = user_initiated ? LLTabContainerCommon::RIGHT_OF_CURRENT : LLTabContainerCommon::END;
- mTalkFloater->addFloater(floater, FALSE, i_pt);
+ LLFloaterChatterBox::getInstance(LLSD())->addFloater(floater, FALSE, i_pt);
mFloaters.insert(floater->getHandle());
return floater;
}
-LLFloaterIMPanel* LLIMView::createFloater(
+LLFloaterIMPanel* LLIMMgr::createFloater(
const LLUUID& session_id,
const LLUUID& other_participant_id,
const std::string& session_label,
@@ -747,7 +931,7 @@ LLFloaterIMPanel* LLIMView::createFloater(
llwarns << "Creating LLFloaterIMPanel with null session ID" << llendl;
}
- llinfos << "LLIMView::createFloater: from " << other_participant_id
+ llinfos << "LLIMMgr::createFloater: from " << other_participant_id
<< " in session " << session_id << llendl;
LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label,
LLRect(),
@@ -757,18 +941,18 @@ LLFloaterIMPanel* LLIMView::createFloater(
ids,
dialog);
LLTabContainerCommon::eInsertionPoint i_pt = user_initiated ? LLTabContainerCommon::RIGHT_OF_CURRENT : LLTabContainerCommon::END;
- mTalkFloater->addFloater(floater, FALSE, i_pt);
+ LLFloaterChatterBox::getInstance(LLSD())->addFloater(floater, FALSE, i_pt);
mFloaters.insert(floater->getHandle());
return floater;
}
-void LLIMView::noteOfflineUsers(LLFloaterIMPanel* floater,
+void LLIMMgr::noteOfflineUsers(LLFloaterIMPanel* floater,
const LLDynamicArray<LLUUID>& ids)
{
S32 count = ids.count();
if(count == 0)
{
- floater->addHistoryLine(sOnlyUserMessage);
+ floater->addHistoryLine(sOnlyUserMessage, gSavedSettings.getColor4("SystemChatColor"));
}
else
{
@@ -785,25 +969,25 @@ void LLIMView::noteOfflineUsers(LLFloaterIMPanel* floater,
LLUIString offline = sOfflineMessage;
offline.setArg("[FIRST]", first);
offline.setArg("[LAST]", last);
- floater->addHistoryLine(offline);
+ floater->addHistoryLine(offline, gSavedSettings.getColor4("SystemChatColor"));
}
}
}
}
-void LLIMView::processIMTypingStart(const LLIMInfo* im_info)
+void LLIMMgr::processIMTypingStart(const LLIMInfo* im_info)
{
processIMTypingCore(im_info, TRUE);
}
-void LLIMView::processIMTypingStop(const LLIMInfo* im_info)
+void LLIMMgr::processIMTypingStop(const LLIMInfo* im_info)
{
processIMTypingCore(im_info, FALSE);
}
-void LLIMView::processIMTypingCore(const LLIMInfo* im_info, BOOL typing)
+void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing)
{
- LLUUID session_id = compute_session_id(im_info->mIMType, im_info->mFromID);
+ LLUUID session_id = computeSessionID(im_info->mIMType, im_info->mFromID);
LLFloaterIMPanel* floater = findFloaterBySession(session_id);
if (floater)
{
@@ -811,8 +995,9 @@ void LLIMView::processIMTypingCore(const LLIMInfo* im_info, BOOL typing)
}
}
-void LLIMView::updateFloaterSessionID(const LLUUID& old_session_id,
- const LLUUID& new_session_id)
+void LLIMMgr::updateFloaterSessionID(
+ const LLUUID& old_session_id,
+ const LLUUID& new_session_id)
{
LLFloaterIMPanel* floater = findFloaterBySession(old_session_id);
if (floater)
@@ -821,9 +1006,9 @@ void LLIMView::updateFloaterSessionID(const LLUUID& old_session_id,
}
}
-void LLIMView::onDropRequestReplyReceived(const LLUUID& session_id)
-{
- mSessionsDropRequested.erase(session_id.asString());
+LLFloaterChatterBox* LLIMMgr::getFloater()
+{
+ return LLFloaterChatterBox::getInstance(LLSD());
}
void onConfirmForceCloseError(S32 option, void* data)
@@ -831,25 +1016,24 @@ void onConfirmForceCloseError(S32 option, void* data)
//only 1 option really
LLFloaterIMPanel* floater = ((LLFloaterIMPanel*) data);
- if ( floater ) floater->onClose(FALSE);
+ if ( floater ) floater->close(FALSE);
}
-class LLViewerIMSessionStartReply : public LLHTTPNode
+class LLViewerChatterBoxSessionStartReply : public LLHTTPNode
{
public:
virtual void describe(Description& desc) const
{
- desc.shortInfo("Used for receiving a reply to a request to initialize an IM session");
+ desc.shortInfo("Used for receiving a reply to a request to initialize an ChatterBox session");
desc.postAPI();
desc.input(
"{\"client_session_id\": UUID, \"session_id\": UUID, \"success\" boolean, \"reason\": string");
desc.source(__FILE__, __LINE__);
}
- virtual void post(
- ResponsePtr response,
- const LLSD& context,
- const LLSD& input) const
+ virtual void post(ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
{
LLSD body;
LLUUID temp_session_id;
@@ -863,16 +1047,21 @@ public:
if ( success )
{
session_id = body["session_id"].asUUID();
- gIMView->updateFloaterSessionID(
+ gIMMgr->updateFloaterSessionID(
temp_session_id,
session_id);
+ LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id);
+ if (floaterp)
+ {
+ floaterp->setSpeakersList(body["agents"]);
+ }
}
else
{
//throw an error dialog and close the temp session's
//floater
LLFloaterIMPanel* floater =
- gIMView->findFloaterBySession(temp_session_id);
+ gIMMgr->findFloaterBySession(temp_session_id);
if (floater)
{
LLString::format_map_t args;
@@ -880,22 +1069,22 @@ public:
sErrorStringsMap[body["error"].asString()];
args["[RECIPIENT]"] = floater->getTitle();
- gViewerWindow->alertXml(
- "IMSessionStartError",
- args,
- onConfirmForceCloseError,
- floater);
+ gViewerWindow->alertXml("ChatterBoxSessionStartError",
+ args,
+ onConfirmForceCloseError,
+ floater);
+
}
}
}
};
-class LLViewerIMSessionEventReply : public LLHTTPNode
+class LLViewerChatterBoxSessionEventReply : public LLHTTPNode
{
public:
virtual void describe(Description& desc) const
{
- desc.shortInfo("Used for receiving a reply to a IM session event");
+ desc.shortInfo("Used for receiving a reply to a ChatterBox session event");
desc.postAPI();
desc.input(
"{\"event\": string, \"reason\": string, \"success\": boolean, \"session_id\": UUID");
@@ -917,7 +1106,7 @@ public:
{
//throw an error dialog
LLFloaterIMPanel* floater =
- gIMView->findFloaterBySession(session_id);
+ gIMMgr->findFloaterBySession(session_id);
if (floater)
{
LLString::format_map_t args;
@@ -927,14 +1116,14 @@ public:
sEventStringsMap[body["event"].asString()];
args["[RECIPIENT]"] = floater->getTitle();
- gViewerWindow->alertXml("IMSessionEventError",
+ gViewerWindow->alertXml("ChatterBoxSessionEventError",
args);
}
}
}
};
-class LLViewerForceCloseIMSession: public LLHTTPNode
+class LLViewerForceCloseChatterBoxSession: public LLHTTPNode
{
public:
virtual void post(ResponsePtr response,
@@ -948,7 +1137,7 @@ public:
reason = input["body"]["reason"].asString();
LLFloaterIMPanel* floater =
- gIMView ->findFloaterBySession(session_id);
+ gIMMgr ->findFloaterBySession(session_id);
if ( floater )
{
@@ -957,7 +1146,7 @@ public:
args["[NAME]"] = floater->getTitle();
args["[REASON]"] = sForceCloseSessionMap[reason];
- gViewerWindow->alertXml("ForceCloseIMSession",
+ gViewerWindow->alertXml("ForceCloseChatterBoxSession",
args,
onConfirmForceCloseError,
floater);
@@ -965,28 +1154,6 @@ public:
}
};
-class LLViewerIMSessionDropReply : public LLHTTPNode
-{
-public:
- virtual void post(ResponsePtr response,
- const LLSD& context,
- const LLSD& input) const
- {
- LLUUID session_id;
- bool success;
-
- success = input["body"]["success"].asBoolean();
- session_id = input["body"]["session_id"].asUUID();
-
- if ( !success )
- {
- //throw an error alert?
- }
-
- gIMView->onDropRequestReplyReceived(session_id);
- }
-};
-
class LLViewerChatterBoxSessionAgentListUpdates : public LLHTTPNode
{
public:
@@ -995,29 +1162,38 @@ public:
const LLSD& context,
const LLSD& input) const
{
+ LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(input["body"]["session_id"].asUUID());
+ if (floaterp)
+ {
+ floaterp->updateSpeakersList(input["body"]["updates"]);
+ }
}
};
class LLViewerChatterBoxInvitation : public LLHTTPNode
{
public:
+
virtual void post(
- ResponsePtr responder,
+ ResponsePtr response,
const LLSD& context,
const LLSD& input) const
{
if ( input["body"].has("instantmessage") )
{
+ LLString capability = input["body"]["capabilities"]["call"].asString();
+
LLSD message_params =
input["body"]["instantmessage"]["message_params"];
+ //do something here to have the IM invite behave
+ //just like a normal IM
//this is just replicated code from process_improved_im
//and should really go in it's own function -jwolk
if (gNoRender)
{
return;
}
-
char buffer[DB_IM_MSG_BUF_SIZE * 2]; /* Flawfinder: ignore */
LLChat chat;
@@ -1032,7 +1208,11 @@ public:
(time_t) message_params["timestamp"].asInteger();
BOOL is_busy = gAgent.getBusy();
- BOOL is_muted = gMuteListp->isMuted(from_id, name);
+ BOOL is_muted = gMuteListp->isMuted(
+ from_id,
+ name.c_str(),
+ LLMute::flagTextChat);
+
BOOL is_linden = gMuteListp->isLinden(
name.c_str());
char separator_string[3]=": "; /* Flawfinder: ignore */
@@ -1049,7 +1229,8 @@ public:
chat.mMuted = is_muted && !is_linden;
chat.mFromID = from_id;
chat.mFromName = name;
- if (!is_linden && is_busy)
+
+ if (!is_linden && (is_busy || is_muted))
{
return;
}
@@ -1077,10 +1258,9 @@ public:
BOOL is_this_agent = FALSE;
if(from_id == gAgentID)
{
- from_id = LLUUID::null;
is_this_agent = TRUE;
}
- gIMView->addMessage(
+ gIMMgr->addMessage(
session_id,
from_id,
name.c_str(),
@@ -1102,11 +1282,7 @@ public:
chat.mText = buffer;
LLFloaterChat::addChat(chat, TRUE, is_this_agent);
- //if we succesfully accepted the invitation
- //send a message back down
-
- //TODO - When availble, have this response just be part
- //of an automatic response system
+ //K now we want to accept the invitation
std::string url = gAgent.getRegion()->getCapability(
"ChatSessionRequest");
@@ -1118,28 +1294,46 @@ public:
LLHTTPClient::post(
url,
data,
- NULL);
+ new LLViewerChatterBoxInvitationAcceptResponder(
+ input["body"]["session_id"],
+ false));
}
} //end if invitation has instant message
+ else if ( input["body"].has("voice") )
+ {
+ if (gNoRender)
+ {
+ return;
+ }
+
+ if(!LLVoiceClient::voiceEnabled())
+ {
+ // Don't display voice invites unless the user has voice enabled.
+ return;
+ }
+
+ gIMMgr->inviteToSession(
+ input["body"]["session_id"].asUUID(),
+ input["body"]["session_name"].asString(),
+ input["body"]["from_id"].asUUID(),
+ input["body"]["from_name"].asString(),
+ IM_SESSION_INVITE);
+ }
}
};
-LLHTTPRegistration<LLViewerIMSessionStartReply>
- gHTTPRegistrationMessageImsessionstartreply(
+LLHTTPRegistration<LLViewerChatterBoxSessionStartReply>
+ gHTTPRegistrationMessageChatterboxsessionstartreply(
"/message/ChatterBoxSessionStartReply");
-LLHTTPRegistration<LLViewerIMSessionEventReply>
- gHTTPRegistrationMessageImsessioneventreply(
+LLHTTPRegistration<LLViewerChatterBoxSessionEventReply>
+ gHTTPRegistrationMessageChatterboxsessioneventreply(
"/message/ChatterBoxSessionEventReply");
-LLHTTPRegistration<LLViewerForceCloseIMSession>
- gHTTPRegistrationMessageForceCloseImSession(
+LLHTTPRegistration<LLViewerForceCloseChatterBoxSession>
+ gHTTPRegistrationMessageForceclosechatterboxsession(
"/message/ForceCloseChatterBoxSession");
-LLHTTPRegistration<LLViewerIMSessionDropReply>
- gHTTPRegistrationMessageImSessionDropReply(
- "/message/ChatterBoxSessionLeaveReply");
-
LLHTTPRegistration<LLViewerChatterBoxSessionAgentListUpdates>
gHTTPRegistrationMessageChatterboxsessionagentlistupdates(
"/message/ChatterBoxSessionAgentListUpdates");