diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 122597ecb7..3b46cdf95a 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -2153,6 +2153,14 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
registrar.add("FS.LeaveGroup", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/groupleave", true));
registrar.add("FS.ActivateGroup", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/groupactivate", true));
+ // hook up moderation tools
+ // if someone knows how to pass a parameter to these, let me know! - Zi
+ // also, I wish I could pass the group session id through these calls, but LLTextBase does not know it - Zi
+ registrar.add("FS.AllowGroupChat", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/groupchatallow", true));
+ registrar.add("FS.ForbidGroupChat", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/groupchatforbid", true));
+ registrar.add("FS.EjectGroupMember", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/groupeject", true));
+ registrar.add("FS.BanGroupMember", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/groupban", true));
+
enable_registrar.add("FS.WaitingForGroupData", boost::bind(&FSRegistrarUtils::checkIsEnabled, gFSRegistrarUtils, target_id, FS_RGSTR_CHK_WAITING_FOR_GROUP_DATA));
enable_registrar.add("FS.HaveGroupData", boost::bind(&FSRegistrarUtils::checkIsEnabled, gFSRegistrarUtils, target_id, FS_RGSTR_CHK_HAVE_GROUP_DATA));
enable_registrar.add("FS.EnableJoinGroup", boost::bind(&FSRegistrarUtils::checkIsEnabled, gFSRegistrarUtils, target_id, FS_RGSTR_CHK_CAN_JOIN_GROUP));
@@ -2200,6 +2208,16 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
unblockButton->setVisible(is_blocked);
}
}
+
+ // hide the moderation tools in the context menu unless we are in a group IM floater
+ LLFloater* parent_floater = getParentByType();
+ if (!parent_floater || parent_floater->getName() != "panel_im")
+ {
+ menu->getChild("GroupModerationSubmenu")->setVisible(false);
+ menu->getChild("GroupModerationSeparator")->setVisible(false);
+ }
+ //
+
menu->show(x, y);
LLMenuGL::showPopup(this, menu, x, y);
}
diff --git a/indra/newview/fschathistory.cpp b/indra/newview/fschathistory.cpp
index b154ac17ef..bcd2a9377c 100644
--- a/indra/newview/fschathistory.cpp
+++ b/indra/newview/fschathistory.cpp
@@ -459,10 +459,15 @@ public:
{
LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagTextChat);
}
- else if (param == "toggle_allow_text_chat")
+ else if (param == "allow_text_chat")
{
LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
- speaker_mgr->toggleAllowTextChat(getAvatarId());
+ speaker_mgr->allowTextChat(getAvatarId(), true);
+ }
+ else if (param == "forbid_text_chat")
+ {
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ speaker_mgr->allowTextChat(getAvatarId(), false);
}
else if (param == "group_mute")
{
@@ -482,7 +487,15 @@ public:
}
else if (param == "ban_member")
{
- banGroupMember(getAvatarId());
+ // don't do safety checks as participant list is broken, just ban
+ // banGroupMember(getAvatarId());
+ std::vector ids;
+ ids.push_back(getAvatarId());
+
+ LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, mSessionID, LLGroupMgr::BAN_CREATE, ids);
+ LLGroupMgr::getInstance()->sendGroupMemberEjects(mSessionID, ids);
+ LLGroupMgr::getInstance()->sendGroupMembersRequest(mSessionID);
+ //
}
}
diff --git a/indra/newview/fsparticipantlist.cpp b/indra/newview/fsparticipantlist.cpp
index b4b6c20caa..e292d67a11 100644
--- a/indra/newview/fsparticipantlist.cpp
+++ b/indra/newview/fsparticipantlist.cpp
@@ -703,7 +703,7 @@ LLContextMenu* FSParticipantList::FSParticipantListMenu::createMenu()
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
registrar.add("ParticipantList.Sort", boost::bind(&FSParticipantList::FSParticipantListMenu::sortParticipantList, this, _2));
- registrar.add("ParticipantList.ToggleAllowTextChat", boost::bind(&FSParticipantList::FSParticipantListMenu::toggleAllowTextChat, this, _2));
+ registrar.add("ParticipantList.AllowTextChat", boost::bind(&FSParticipantList::FSParticipantListMenu::allowTextChat, this, _2));
registrar.add("ParticipantList.ToggleMuteText", boost::bind(&FSParticipantList::FSParticipantListMenu::toggleMuteText, this, _2));
// [SL:KB] - Patch: Chat-GroupSessionEject | Checked: 2012-02-04 (Catznip-3.2.1) | Added: Catznip-3.2.1
registrar.add("ParticipantList.Eject", boost::bind(&LLGroupActions::ejectFromGroup, mParent.mSpeakerMgr->getSessionID(), mUUIDs.front()));
@@ -780,14 +780,13 @@ void FSParticipantList::FSParticipantListMenu::sortParticipantList(const LLSD& u
}
}
-void FSParticipantList::FSParticipantListMenu::toggleAllowTextChat(const LLSD& userdata)
+void FSParticipantList::FSParticipantListMenu::allowTextChat(const LLSD& userdata)
{
-
LLIMSpeakerMgr* mgr = dynamic_cast(mParent.mSpeakerMgr);
if (mgr)
{
const LLUUID speaker_id = mUUIDs.front();
- mgr->toggleAllowTextChat(speaker_id);
+ mgr->allowTextChat(speaker_id, userdata.asString() == "allow");
}
}
diff --git a/indra/newview/fsparticipantlist.h b/indra/newview/fsparticipantlist.h
index 5f7f9c0b91..c5221c2e02 100644
--- a/indra/newview/fsparticipantlist.h
+++ b/indra/newview/fsparticipantlist.h
@@ -179,7 +179,7 @@ protected:
bool checkContextMenuItem(const LLSD& userdata);
void sortParticipantList(const LLSD& userdata);
- void toggleAllowTextChat(const LLSD& userdata);
+ void allowTextChat(const LLSD& userdata);
void toggleMute(const LLSD& userdata, U32 flags);
void toggleMuteText(const LLSD& userdata);
void toggleMuteVoice(const LLSD& userdata);
diff --git a/indra/newview/fsslurlcommand.cpp b/indra/newview/fsslurlcommand.cpp
index b53041d829..f0a8427c00 100644
--- a/indra/newview/fsslurlcommand.cpp
+++ b/indra/newview/fsslurlcommand.cpp
@@ -32,9 +32,13 @@
#include "llcommandhandler.h"
#include "llfloatersettingsdebug.h"
#include "llgroupactions.h"
+#include "llgroupmgr.h"
#include "lllogchat.h"
#include "llnotificationsutil.h"
+#include "llspeakers.h"
+#include "fsfloaterimcontainer.h"
+#include "fsfloaterim.h"
class FSSlurlCommandHandler : public LLCommandHandler
{
@@ -138,19 +142,101 @@ public:
if (verb == "groupjoin")
{
- LLGroupActions::join(LLUUID(target_id));
+ LLGroupActions::join(target_id);
return true;
}
if (verb == "groupleave")
{
- LLGroupActions::leave(LLUUID(target_id));
+ LLGroupActions::leave(target_id);
return true;
}
if (verb == "groupactivate")
{
- LLGroupActions::activate(LLUUID(target_id));
+ LLGroupActions::activate(target_id);
+ return true;
+ }
+
+ // please someone tell me there is an easier way to get the group UUID of the
+ // currently focused group, or transfer the UUID through the context menu somehow - Zi
+ LLFloater* focused_floater = gFloaterView->getFocusedFloater();
+
+ FSFloaterIM* floater_im;
+
+ // let's guess that the user has tabbed IMs
+ FSFloaterIMContainer* floater_container = dynamic_cast(focused_floater);
+
+ if (floater_container)
+ {
+ // get the active sub-floater inside the tabbed IMs
+ floater_im = dynamic_cast(floater_container->getActiveFloater());
+ }
+ else
+ {
+ // no tabbed IMs or torn-off group floater, try if this is already what we wanted
+ floater_im = dynamic_cast(focused_floater);
+ }
+
+ // still not an IM floater, give up
+ if (!floater_im)
+ {
+ return true;
+ }
+
+ // get the group's UUID
+ LLUUID group_id = floater_im->getKey();
+
+ // is this actually a valid IM session?
+ LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(group_id);
+ if (!session)
+ {
+ return true;
+ }
+
+ // is this actually a valid group IM session?
+ if (!session->isGroupSessionType())
+ {
+ return true;
+ }
+
+ // finally! let's see what we came here to do
+
+ if (verb == "groupchatallow")
+ {
+ // no safety checks, just allow
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(group_id);
+ speaker_mgr->allowTextChat(target_id, true);
+
+ return true;
+ }
+
+ if (verb == "groupchatforbid")
+ {
+ // no safety checks, just mute
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(group_id);
+ speaker_mgr->allowTextChat(target_id, false);
+
+ return true;
+ }
+
+ if (verb == "groupeject")
+ {
+ // no safety checks, just eject
+ LLGroupActions::ejectFromGroup(group_id, target_id);
+ return true;
+ }
+
+ if (verb == "groupban")
+ {
+ std::vector ids;
+ ids.push_back(target_id);
+
+ // no safety checks, just ban
+ LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, group_id, LLGroupMgr::BAN_CREATE, ids);
+ LLGroupMgr::getInstance()->sendGroupMemberEjects(group_id, ids);
+ LLGroupMgr::getInstance()->sendGroupMembersRequest(group_id);
+
return true;
}
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 62e2658044..b56979da76 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -819,10 +819,15 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
}
}
-void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id)
+// make text chat block in groups not a toggle to prevent accidental unmuting
+// void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id)
+void LLIMSpeakerMgr::allowTextChat(const LLUUID& speaker_id, bool allow)
{
- LLPointer speakerp = findSpeaker(speaker_id);
- if (!speakerp) return;
+ // Don't test for presence in the group participants list, as the list
+ // is unreliable and this leads to situations where people can't be
+ // chat muted at all anymore
+ // LLPointer speakerp = findSpeaker(speaker_id);
+ // if (!speakerp) return;
std::string url = gAgent.getRegionCapability("ChatSessionRequest");
LLSD data;
@@ -831,8 +836,10 @@ void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id)
data["params"] = LLSD::emptyMap();
data["params"]["agent_id"] = speaker_id;
data["params"]["mute_info"] = LLSD::emptyMap();
+ // make text chat block in groups not a toggle to prevent accidental unmuting
//current value represents ability to type, so invert
- data["params"]["mute_info"]["text"] = !speakerp->mModeratorMutedText;
+ // data["params"]["mute_info"]["text"] = !speakerp->mModeratorMutedText;
+ data["params"]["mute_info"]["text"] = !allow;
LLCoros::instance().launch("LLIMSpeakerMgr::moderationActionCoro",
boost::bind(&LLIMSpeakerMgr::moderationActionCoro, this, url, data));
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index d1dbf72fe9..0d19bf9fcf 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -297,7 +297,9 @@ public:
void updateSpeakers(const LLSD& update);
void setSpeakers(const LLSD& speakers);
- void toggleAllowTextChat(const LLUUID& speaker_id);
+ // make text chat block in groups not a toggle to prevent accidental unmuting
+ // void toggleAllowTextChat(const LLUUID& speaker_id);
+ void allowTextChat(const LLUUID& speaker_id, bool allow);
/**
* Mutes/Unmutes avatar for current group voice chat.
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
index edc8b22199..596cb4261d 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
@@ -149,14 +149,20 @@
label="Moderator Options"
layout="topleft"
name="Moderator Options">
-
-
-
+
-
+
+
+
+
+
-
-
+ function="ParticipantList.AllowTextChat"
+ parameter="allow" />
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+