summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llgrouplist.cpp5
-rw-r--r--indra/newview/llimfloater.cpp33
-rw-r--r--indra/newview/llimfloater.h1
-rw-r--r--indra/newview/llimview.cpp49
-rw-r--r--indra/newview/llimview.h4
-rw-r--r--indra/newview/llpanellandmarks.cpp5
-rw-r--r--indra/newview/llpanelpeople.cpp6
-rw-r--r--indra/newview/llparticipantlist.cpp98
-rw-r--r--indra/newview/llparticipantlist.h20
-rw-r--r--indra/newview/llspeakers.cpp23
-rw-r--r--indra/newview/llspeakers.h10
-rw-r--r--indra/newview/llviewerfloaterreg.cpp1
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_im_control_panel.xml2
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml4
15 files changed, 224 insertions, 39 deletions
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 2e2b2d5101..010ed23918 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -183,6 +183,11 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL
item->childSetVisible("info_btn", false);
item->setGroupIconVisible(mShowIcons);
+ if (id.isNull())
+ {
+ item->childSetVisible("profile_btn", false);
+ }
+
addItem(item, id, pos);
// setCommentVisible(false);
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 85863ed85b..a634a1b0fd 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -115,7 +115,7 @@ void LLIMFloater::onClose(bool app_quitting)
/* static */
void LLIMFloater::newIMCallback(const LLSD& data){
- if (data["num_unread"].asInteger() > 0)
+ if (data["num_unread"].asInteger() > 0 || data["from_id"].asUUID().isNull())
{
LLUUID session_id = data["session_id"].asUUID();
@@ -235,7 +235,7 @@ BOOL LLIMFloater::postBuild()
std::string session_name(LLIMModel::instance().getName(mSessionID));
- mInputEditor->setLabel(mInputEditor->getLabel() + " " + session_name);
+ mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + session_name);
LLStringUtil::toUpper(session_name);
setTitle(session_name);
@@ -498,7 +498,8 @@ void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void*
// Allow enabling the LLIMFloater input editor only if session can accept text
LLIMModel::LLIMSession* im_session =
LLIMModel::instance().findIMSession(self->mSessionID);
- if( im_session && im_session->mTextIMPossible )
+ //TODO: While disabled lllineeditor can receive focus we need to check if it is enabled (EK)
+ if( im_session && im_session->mTextIMPossible && !self->mInputEditor->getEnabled())
{
//in disconnected state IM input editor should be disabled
self->mInputEditor->setEnabled(!gDisconnected);
@@ -588,6 +589,32 @@ void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing)
}
}
+void LLIMFloater::processAgentListUpdates(const LLSD& body)
+{
+ if ( !body.isMap() ) return;
+
+ if ( body.has("agent_updates") && body["agent_updates"].isMap() )
+ {
+ LLSD agent_data = body["agent_updates"].get(gAgentID.asString());
+ if (agent_data.isMap() && agent_data.has("info"))
+ {
+ LLSD agent_info = agent_data["info"];
+
+ if (agent_info.has("mutes"))
+ {
+ BOOL moderator_muted_text = agent_info["mutes"]["text"].asBoolean();
+ mInputEditor->setEnabled(!moderator_muted_text);
+ std::string label;
+ if (moderator_muted_text)
+ label = LLTrans::getString("IM_muted_text_label");
+ else
+ label = LLTrans::getString("IM_to_label") + " " + LLIMModel::instance().getName(mSessionID);
+ mInputEditor->setLabel(label);
+ }
+ }
+ }
+}
+
void LLIMFloater::processSessionUpdate(const LLSD& session_update)
{
// *TODO : verify following code when moderated mode will be implemented
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index f5edb3188a..065441b188 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -90,6 +90,7 @@ public:
void onVisibilityChange(const LLSD& new_visibility);
void processIMTyping(const LLIMInfo* im_info, BOOL typing);
+ void processAgentListUpdates(const LLSD& body);
void processSessionUpdate(const LLSD& session_update);
BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 7e8701bf21..ac5bd719e2 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -134,7 +134,6 @@ void LLIMModel::setActiveSessionID(const LLUUID& session_id)
LLIMModel::LLIMModel()
{
addNewMsgCallback(LLIMFloater::newIMCallback);
- addNoUnreadMsgsCallback(LLIMFloater::newIMCallback);
addNewMsgCallback(toast_callback);
}
@@ -440,7 +439,8 @@ bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, co
addToHistory(session_id, from, from_id, utf8_text);
if (log2file) logToFile(session_id, from, from_id, utf8_text);
- session->mNumUnread++;
+ //we do not count system messages
+ if (from_id.notNull()) session->mNumUnread++;
// notify listeners
LLSD arg;
@@ -1350,13 +1350,6 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
LLIMMgr::LLIMMgr() :
mIMReceived(FALSE)
{
- static bool registered_dialog = false;
- if (!registered_dialog)
- {
- LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIncomingCallDialog>);
- registered_dialog = true;
- }
-
mPendingInvitations = LLSD::emptyMap();
mPendingAgentListUpdates = LLSD::emptyMap();
}
@@ -1848,6 +1841,29 @@ void LLIMMgr::clearPendingInvitation(const LLUUID& session_id)
}
}
+void LLIMMgr::processAgentListUpdates(const LLUUID& session_id, const LLSD& body)
+{
+ LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+ if ( im_floater )
+ {
+ im_floater->processAgentListUpdates(body);
+ }
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
+ if (speaker_mgr)
+ {
+ speaker_mgr->updateSpeakers(body);
+ }
+ else
+ {
+ //we don't have a speaker manager yet..something went wrong
+ //we are probably receiving an update here before
+ //a start or an acceptance of an invitation. Race condition.
+ gIMMgr->addPendingAgentListUpdates(
+ session_id,
+ body);
+ }
+}
+
LLSD LLIMMgr::getPendingAgentListUpdates(const LLUUID& session_id)
{
if ( mPendingAgentListUpdates.has(session_id.asString()) )
@@ -2232,20 +2248,7 @@ public:
const LLSD& input) const
{
const LLUUID& session_id = input["body"]["session_id"].asUUID();
- LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
- if (speaker_mgr)
- {
- speaker_mgr->updateSpeakers(input["body"]);
- }
- else
- {
- //we don't have a speaker manager yet..something went wrong
- //we are probably receiving an update here before
- //a start or an acceptance of an invitation. Race condition.
- gIMMgr->addPendingAgentListUpdates(
- input["body"]["session_id"].asUUID(),
- input["body"]);
- }
+ gIMMgr->processAgentListUpdates(session_id, input["body"]);
}
};
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index f986d9dcdb..bd55bd2c30 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -66,7 +66,10 @@ public:
EInstantMessage mType;
LLUUID mOtherParticipantID;
std::vector<LLUUID> mInitialTargetIDs;
+
+ //does NOT include system messages
S32 mNumUnread;
+
std::list<LLSD> mMsgs;
LLVoiceChannel* mVoiceChannel;
@@ -315,6 +318,7 @@ public:
void clearPendingInvitation(const LLUUID& session_id);
+ void processAgentListUpdates(const LLUUID& session_id, const LLSD& body);
LLSD getPendingAgentListUpdates(const LLUUID& session_id);
void addPendingAgentListUpdates(
const LLUUID& sessioN_id,
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index c516546282..62dc881738 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -829,17 +829,18 @@ bool LLLandmarksPanel::canSelectedBeModified(const std::string& command_name) co
// then ask LLFolderView permissions
if (can_be_modified)
{
+ LLFolderViewItem* selected = getCurSelectedItem();
if ("cut" == command_name)
{
can_be_modified = mCurrentSelectedList->getRootFolder()->canCut();
}
else if ("rename" == command_name)
{
- can_be_modified = getCurSelectedItem()->getListener()->isItemRenameable();
+ can_be_modified = selected? selected->getListener()->isItemRenameable() : false;
}
else if ("delete" == command_name)
{
- can_be_modified = getCurSelectedItem()->getListener()->isItemRemovable();
+ can_be_modified = selected? selected->getListener()->isItemRemovable(): false;
}
else if("paste" == command_name)
{
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 65a7b5322b..bb6cdd2f78 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -667,8 +667,10 @@ void LLPanelPeople::updateButtons()
buttonSetEnabled("im_btn", (selected_uuids.size() >= 1)); // allow starting the friends conference for multiple selection
buttonSetEnabled("call_btn", item_selected && false); // not implemented yet
buttonSetEnabled("share_btn", item_selected && false); // not implemented yet
- buttonSetEnabled("group_info_btn", item_selected);
- buttonSetEnabled("chat_btn", item_selected);
+
+ bool none_group_selected = item_selected && selected_id.isNull();
+ buttonSetEnabled("group_info_btn", !none_group_selected);
+ buttonSetEnabled("chat_btn", !none_group_selected);
}
std::string LLPanelPeople::getActiveTabName() const
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 32223e314e..2be0781487 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -53,13 +53,16 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* av
mSpeakerAddListener = new SpeakerAddListener(*this);
mSpeakerRemoveListener = new SpeakerRemoveListener(*this);
mSpeakerClearListener = new SpeakerClearListener(*this);
+ mSpeakerModeratorListener = new SpeakerModeratorUpdateListener(*this);
mSpeakerMgr->addListener(mSpeakerAddListener, "add");
mSpeakerMgr->addListener(mSpeakerRemoveListener, "remove");
mSpeakerMgr->addListener(mSpeakerClearListener, "clear");
+ mSpeakerMgr->addListener(mSpeakerModeratorListener, "update_moderator");
mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData"));
mAvatarList->setDoubleClickCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, mAvatarList));
+ mAvatarList->setRefreshCompleteCallback(boost::bind(&LLParticipantList::onAvatarListRefreshed, this, _1, _2));
//Lets fill avatarList with existing speakers
LLAvatarList::uuid_vector_t& group_members = mAvatarList->getIDs();
@@ -68,7 +71,12 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* av
mSpeakerMgr->getSpeakerList(&speaker_list, true);
for(LLSpeakerMgr::speaker_list_t::iterator it = speaker_list.begin(); it != speaker_list.end(); it++)
{
- group_members.push_back((*it)->mID);
+ const LLPointer<LLSpeaker>& speakerp = *it;
+ group_members.push_back(speakerp->mID);
+ if ( speakerp->mIsModerator )
+ {
+ mModeratorList.insert(speakerp->mID);
+ }
}
sort();
}
@@ -87,6 +95,56 @@ void LLParticipantList::onAvatarListDoubleClicked(LLAvatarList* list)
LLAvatarActions::startIM(clicked_id);
}
+void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param)
+{
+ LLAvatarList* list = dynamic_cast<LLAvatarList*>(ctrl);
+ if (list)
+ {
+ const std::string moderator_indicator(LLTrans::getString("IM_moderator_label"));
+ const std::size_t moderator_indicator_len = moderator_indicator.length();
+
+ // Firstly remove moderators indicator
+ std::set<LLUUID>::const_iterator
+ moderator_list_it = mModeratorToRemoveList.begin(),
+ moderator_list_end = mModeratorToRemoveList.end();
+ for (;moderator_list_it != moderator_list_end; ++moderator_list_it)
+ {
+ LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*> (list->getItemByValue(*moderator_list_it));
+ if ( item )
+ {
+ std::string name = item->getAvatarName();
+ size_t found = name.find(moderator_indicator);
+ if (found == std::string::npos)
+ {
+ name.erase(found, moderator_indicator_len);
+ item->setName(name);
+ }
+ }
+ }
+
+ mModeratorToRemoveList.clear();
+
+ // Add moderators indicator
+ moderator_list_it = mModeratorList.begin();
+ moderator_list_end = mModeratorList.end();
+ for (;moderator_list_it != moderator_list_end; ++moderator_list_it)
+ {
+ LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*> (list->getItemByValue(*moderator_list_it));
+ if ( item )
+ {
+ std::string name = item->getAvatarName();
+ size_t found = name.find(moderator_indicator);
+ if (found == std::string::npos)
+ {
+ name += " ";
+ name += moderator_indicator;
+ item->setName(name);
+ }
+ }
+ }
+ }
+}
+
void LLParticipantList::setSortOrder(EParticipantSortOrder order)
{
if ( mSortOrder != order )
@@ -109,6 +167,8 @@ bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, co
}
group_members.push_back(uu_id);
+ // Mark AvatarList as dirty one
+ mAvatarList->setDirty();
sort();
return true;
}
@@ -133,14 +193,36 @@ bool LLParticipantList::onClearListEvent(LLPointer<LLOldEvents::LLEvent> event,
return true;
}
+bool LLParticipantList::onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+ const LLSD& evt_data = event->getValue();
+ if ( evt_data.has("id") && evt_data.has("is_moderator") )
+ {
+ LLUUID id = evt_data["id"];
+ bool is_moderator = evt_data["is_moderator"];
+ if ( id.notNull() )
+ {
+ if ( is_moderator )
+ mModeratorList.insert(id);
+ else
+ {
+ std::set<LLUUID>::iterator it = mModeratorList.find (id);
+ if ( it != mModeratorList.end () )
+ {
+ mModeratorToRemoveList.insert(id);
+ mModeratorList.erase(id);
+ }
+ }
+ }
+ }
+ return true;
+}
+
void LLParticipantList::sort()
{
if ( !mAvatarList )
return;
- // Mark AvatarList as dirty one
- mAvatarList->setDirty();
-
// TODO: Implement more sorting orders after specs updating (EM)
switch ( mSortOrder ) {
case E_SORT_BY_NAME :
@@ -175,3 +257,11 @@ bool LLParticipantList::SpeakerClearListener::handleEvent(LLPointer<LLOldEvents:
{
return mParent.onClearListEvent(event, userdata);
}
+
+//
+// LLParticipantList::SpeakerModeratorListener
+//
+bool LLParticipantList::SpeakerModeratorUpdateListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+ return mParent.onModeratorUpdateEvent(event, userdata);
+}
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index 8c209c0b20..fc34dd308b 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -35,6 +35,7 @@
class LLSpeakerMgr;
class LLAvatarList;
+class LLUICtrl;
class LLParticipantList
{
@@ -59,6 +60,7 @@ class LLParticipantList
bool onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
bool onRemoveItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
bool onClearListEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
+ bool onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
/**
* Sorts the Avatarlist by stored order
@@ -97,15 +99,27 @@ class LLParticipantList
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
};
+ class SpeakerModeratorUpdateListener : public BaseSpeakerListner
+ {
+ public:
+ SpeakerModeratorUpdateListener(LLParticipantList& parent) : BaseSpeakerListner(parent) {}
+ /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
+ };
+
private:
void onAvatarListDoubleClicked(LLAvatarList* list);
+ void onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param);
LLSpeakerMgr* mSpeakerMgr;
LLAvatarList* mAvatarList;
- LLPointer<SpeakerAddListener> mSpeakerAddListener;
- LLPointer<SpeakerRemoveListener> mSpeakerRemoveListener;
- LLPointer<SpeakerClearListener> mSpeakerClearListener;
+ std::set<LLUUID> mModeratorList;
+ std::set<LLUUID> mModeratorToRemoveList;
+
+ LLPointer<SpeakerAddListener> mSpeakerAddListener;
+ LLPointer<SpeakerRemoveListener> mSpeakerRemoveListener;
+ LLPointer<SpeakerClearListener> mSpeakerClearListener;
+ LLPointer<SpeakerModeratorUpdateListener> mSpeakerModeratorListener;
EParticipantSortOrder mSortOrder;
};
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 2341fcfc6d..2ed82b7d62 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -87,6 +87,21 @@ void LLSpeaker::onAvatarNameLookup(const LLUUID& id, const std::string& first, c
mDisplayName = first + " " + last;
}
+LLSpeakerUpdateModeratorEvent::LLSpeakerUpdateModeratorEvent(LLSpeaker* source)
+: LLEvent(source, "Speaker add moderator event"),
+ mSpeakerID (source->mID),
+ mIsModerator (source->mIsModerator)
+{
+}
+
+LLSD LLSpeakerUpdateModeratorEvent::getValue()
+{
+ LLSD ret;
+ ret["id"] = mSpeakerID;
+ ret["is_moderator"] = mIsModerator;
+ return ret;
+}
+
LLSpeakerTextModerationEvent::LLSpeakerTextModerationEvent(LLSpeaker* source)
: LLEvent(source, "Speaker text moderation event")
{
@@ -437,9 +452,13 @@ void LLIMSpeakerMgr::setSpeakers(const LLSD& speakers)
if ( speaker_it->second.isMap() )
{
+ BOOL is_moderator = speakerp->mIsModerator;
speakerp->mIsModerator = speaker_it->second["is_moderator"];
speakerp->mModeratorMutedText =
speaker_it->second["mutes"]["text"];
+ // Fire event only if moderator changed
+ if ( is_moderator != speakerp->mIsModerator )
+ fireEvent(new LLSpeakerUpdateModeratorEvent(speakerp), "update_moderator");
}
}
}
@@ -507,7 +526,11 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
if (agent_info.has("is_moderator"))
{
+ BOOL is_moderator = speakerp->mIsModerator;
speakerp->mIsModerator = agent_info["is_moderator"];
+ // Fire event only if moderator changed
+ if ( is_moderator != speakerp->mIsModerator )
+ fireEvent(new LLSpeakerUpdateModeratorEvent(speakerp), "update_moderator");
}
if (agent_info.has("mutes"))
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index e0f22bff4f..04046a8587 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -84,6 +84,16 @@ public:
BOOL mModeratorMutedText;
};
+class LLSpeakerUpdateModeratorEvent : public LLOldEvents::LLEvent
+{
+public:
+ LLSpeakerUpdateModeratorEvent(LLSpeaker* source);
+ /*virtual*/ LLSD getValue();
+private:
+ const LLUUID& mSpeakerID;
+ BOOL mIsModerator;
+};
+
class LLSpeakerTextModerationEvent : public LLOldEvents::LLEvent
{
public:
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 9ca2d3f61d..edbac69e1b 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -170,6 +170,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>);
LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloater>);
+ LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIncomingCallDialog>);
LLFloaterReg::add("inventory", "floater_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInventory>);
LLFloaterReg::add("inspect", "floater_inspect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInspect>);
LLInspectAvatarUtil::registerFloater();
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 70af2f63b6..452d28d4ea 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -15,7 +15,7 @@
width="520"
can_resize="true"
min_width="350"
- min_height="350">
+ min_height="369">
<layout_stack follows="left|top|right|bottom"
height="354"
width="520"
diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
index c8b134cdf0..e81532ec3e 100644
--- a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
+++ b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
@@ -14,7 +14,7 @@
width="125"/>
<text
- follows="left|right"
+ follows="top|left|right"
font="SansSerifBig"
height="16"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index ec2673644f..c850dce141 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2845,6 +2845,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="Unnamed">(Unnamed)</string>
<string name="IM_moderated_chat_label">(Moderated: Voices off by default)</string>
<string name="IM_unavailable_text_label">Text chat is not available for this call.</string>
+ <string name="IM_muted_text_label">Your text chat has been disabled by a Group Moderator.</string>
+ <string name="IM_default_text_label">Click here to instant message.</string>
+ <string name="IM_to_label">To</string>
+ <string name="IM_moderator_label">(Moderator)</string>
<string name="ringing-im">