diff options
-rw-r--r-- | indra/newview/llavataractions.cpp | 12 | ||||
-rw-r--r-- | indra/newview/llavataractions.h | 5 | ||||
-rw-r--r-- | indra/newview/llchathistory.cpp | 264 | ||||
-rw-r--r-- | indra/newview/llfloaterimcontainer.cpp | 22 | ||||
-rw-r--r-- | indra/newview/llfloaterimcontainer.h | 1 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/menu_avatar_icon.xml | 44 |
6 files changed, 306 insertions, 42 deletions
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 219d9da01f..8fe684ad79 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -1005,7 +1005,7 @@ void LLAvatarActions::toggleBlock(const LLUUID& id) } // static -void LLAvatarActions::toggleMuteVoice(const LLUUID& id) +void LLAvatarActions::toggleMute(const LLUUID& id, U32 flags) { LLAvatarName av_name; LLAvatarNameCache::get(id, &av_name); @@ -1016,15 +1016,21 @@ void LLAvatarActions::toggleMuteVoice(const LLUUID& id) LLMute mute(id, av_name.getUserName(), LLMute::AGENT); if (!is_muted) { - mute_list->add(mute, LLMute::flagVoiceChat); + mute_list->add(mute, flags); } else { - mute_list->remove(mute, LLMute::flagVoiceChat); + mute_list->remove(mute, flags); } } // static +void LLAvatarActions::toggleMuteVoice(const LLUUID& id) +{ + toggleMute(id, LLMute::flagVoiceChat); +} + +// static bool LLAvatarActions::canOfferTeleport(const LLUUID& id) { // First use LLAvatarTracker::isBuddy() diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 256d44d820..b56d5b0fb9 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -131,6 +131,11 @@ public: static void toggleBlock(const LLUUID& id); /** + * Mute/unmute avatar. + */ + static void toggleMute(const LLUUID& id, U32 flags); + + /** * Block/unblock the avatar voice. */ static void toggleMuteVoice(const LLUUID& id); diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 9798ef3529..5748eeec47 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -38,10 +38,14 @@ #include "llpanel.h" #include "lluictrlfactory.h" #include "llscrollcontainer.h" -#include "llavatariconctrl.h" -#include "llcallingcard.h" //for LLAvatarTracker +#include "llagent.h" #include "llagentdata.h" #include "llavataractions.h" +#include "llavatariconctrl.h" +#include "llcallingcard.h" //for LLAvatarTracker +#include "llgroupactions.h" +#include "llgroupmgr.h" +#include "llspeakers.h" //for LLIMSpeakerMgr #include "lltrans.h" #include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" @@ -49,7 +53,6 @@ #include "llstylemap.h" #include "llslurl.h" #include "lllayoutstack.h" -#include "llagent.h" #include "llnotificationsutil.h" #include "lltoastnotifypanel.h" #include "lltooltip.h" @@ -61,7 +64,6 @@ #include "llurlaction.h" #include "llviewercontrol.h" #include "llviewerobjectlist.h" -#include "llmutelist.h" static LLDefaultChildRegistry::Register<LLChatHistory> r("chat_history"); @@ -187,6 +189,161 @@ public: return false; } + void banGroupMember(const LLUUID& participant_uuid) + { + LLUUID group_uuid = mSessionID; + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_uuid); + if (!gdatap) + { + // Not a group + return; + } + + gdatap->banMemberById(participant_uuid); + } + + bool canBanInGroup() + { + LLUUID group_uuid = mSessionID; + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_uuid); + if (!gdatap) + { + // Not a group + return false; + } + + if (gAgent.hasPowerInGroup(group_uuid, GP_ROLE_REMOVE_MEMBER) + && gAgent.hasPowerInGroup(group_uuid, GP_GROUP_BAN_ACCESS)) + { + return true; + } + + return false; + } + + bool canBanGroupMember(const LLUUID& participant_uuid) + { + LLUUID group_uuid = mSessionID; + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_uuid); + if (!gdatap) + { + // Not a group + return false; + } + + if (gdatap->mPendingBanRequest) + { + return false; + } + + if (gAgentID == getAvatarId()) + { + //Don't ban self + return false; + } + + if (gdatap->isRoleMemberDataComplete()) + { + if (gdatap->mMembers.size()) + { + LLGroupMgrGroupData::member_list_t::iterator mi = gdatap->mMembers.find(participant_uuid); + if (mi != gdatap->mMembers.end()) + { + LLGroupMemberData* member_data = (*mi).second; + // Is the member an owner? + if (member_data && member_data->isInRole(gdatap->mOwnerRole)) + { + return false; + } + + if (gAgent.hasPowerInGroup(group_uuid, GP_ROLE_REMOVE_MEMBER) + && gAgent.hasPowerInGroup(group_uuid, GP_GROUP_BAN_ACCESS)) + { + return true; + } + } + } + } + + LLSpeakerMgr * speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + { + LLSpeaker * speakerp = speaker_mgr->findSpeaker(participant_uuid).get(); + + if (speakerp + && gAgent.hasPowerInGroup(group_uuid, GP_ROLE_REMOVE_MEMBER) + && gAgent.hasPowerInGroup(group_uuid, GP_GROUP_BAN_ACCESS)) + { + return true; + } + } + + return false; + } + + bool isGroupModerator() + { + LLSpeakerMgr * speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (!speaker_mgr) + { + LL_WARNS() << "Speaker manager is missing" << LL_ENDL; + return false; + } + + // Is session a group call/chat? + if(gAgent.isInGroup(mSessionID)) + { + LLSpeaker * speakerp = speaker_mgr->findSpeaker(gAgentID).get(); + + // Is agent a moderator? + return speakerp && speakerp->mIsModerator; + } + + return false; + } + + bool canModerate(const std::string& userdata) + { + // only group moderators can perform actions related to this "enable callback" + if (!isGroupModerator() || gAgentID == getAvatarId()) + { + return false; + } + + LLSpeakerMgr * speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (!speaker_mgr) + { + return false; + } + + LLSpeaker * speakerp = speaker_mgr->findSpeaker(getAvatarId()).get(); + if (!speakerp) + { + return false; + } + + bool voice_channel = speakerp->isInVoiceChannel(); + + if ("can_moderate_voice" == userdata) + { + return voice_channel; + } + else if ("can_mute" == userdata) + { + return voice_channel && (speakerp->mStatus != LLSpeaker::STATUS_MUTED); + } + else if ("can_unmute" == userdata) + { + return speakerp->mStatus == LLSpeaker::STATUS_MUTED; + } + else if ("can_allow_text_chat" == userdata) + { + return true; + } + + return false; + } + void onAvatarIconContextMenuItemClicked(const LLSD& userdata) { std::string level = userdata.asString(); @@ -245,11 +402,36 @@ public: } else if(level == "block_unblock") { - mute(getAvatarId(), LLMute::flagVoiceChat); + LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagVoiceChat); } else if(level == "mute_unmute") { - mute(getAvatarId(), LLMute::flagTextChat); + LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagTextChat); + } + else if(level == "toggle_allow_text_chat") + { + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + speaker_mgr->toggleAllowTextChat(getAvatarId()); + } + else if(level == "group_mute") + { + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + { + speaker_mgr->moderateVoiceParticipant(getAvatarId(), false); + } + } + else if(level == "group_unmute") + { + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + { + speaker_mgr->moderateVoiceParticipant(getAvatarId(), true); + } + } + else if(level == "ban_member") + { + banGroupMember(getAvatarId()); } } @@ -265,24 +447,69 @@ public: { return LLMuteList::getInstance()->isMuted(getAvatarId(), LLMute::flagTextChat); } + else if (level == "is_allowed_text_chat") + { + if (gAgent.isInGroup(mSessionID)) + { + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + const LLSpeaker * speakerp = speaker_mgr->findSpeaker(getAvatarId()); + + if (NULL != speakerp) + { + return !speakerp->mModeratorMutedText; + } + } + return false; + } return false; } - void mute(const LLUUID& participant_id, U32 flags) + bool onAvatarIconContextMenuItemEnabled(const LLSD& userdata) { - BOOL is_muted = LLMuteList::getInstance()->isMuted(participant_id, flags); - LLAvatarName av_name; - LLAvatarNameCache::get(participant_id, &av_name); - LLMute mute(participant_id, av_name.getUserName(), LLMute::AGENT); + std::string level = userdata.asString(); - if (!is_muted) + if (level == "can_allow_text_chat" || level == "can_mute" || level == "can_unmute") { - LLMuteList::getInstance()->add(mute, flags); + return canModerate(userdata); } - else + else if (level == "can_ban_member") { - LLMuteList::getInstance()->remove(mute, flags); + return canBanGroupMember(getAvatarId()); } + return false; + } + + bool onAvatarIconContextMenuItemVisible(const LLSD& userdata) + { + std::string level = userdata.asString(); + + if (level == "show_mute") + { + LLSpeakerMgr * speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + { + LLSpeaker * speakerp = speaker_mgr->findSpeaker(getAvatarId()).get(); + if (speakerp) + { + return speakerp->isInVoiceChannel() && speakerp->mStatus != LLSpeaker::STATUS_MUTED; + } + } + return false; + } + else if (level == "show_unmute") + { + LLSpeakerMgr * speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + { + LLSpeaker * speakerp = speaker_mgr->findSpeaker(getAvatarId()).get(); + if (speakerp) + { + return speakerp->mStatus == LLSpeaker::STATUS_MUTED; + } + } + return false; + } + return false; } BOOL postBuild() @@ -292,6 +519,8 @@ public: registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2)); registrar_enable.add("AvatarIcon.Check", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemChecked, this, _2)); + registrar_enable.add("AvatarIcon.Enable", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemEnabled, this, _2)); + registrar_enable.add("AvatarIcon.Visible", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemVisible, this, _2)); registrar.add("ObjectIcon.Action", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2)); registrar_enable.add("ObjectIcon.Visible", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemVisible, this, _2)); @@ -567,9 +796,14 @@ protected: if(menu) { bool is_friend = LLAvatarActions::isFriend(mAvatarID); + bool is_group_session = gAgent.isInGroup(mSessionID); menu->setItemEnabled("Add Friend", !is_friend); menu->setItemEnabled("Remove Friend", is_friend); + menu->setItemVisible("Moderator Options Separator", is_group_session && isGroupModerator()); + menu->setItemVisible("Moderator Options", is_group_session && isGroupModerator()); + menu->setItemVisible("Group Ban Separator", is_group_session && canBanInGroup()); + menu->setItemVisible("BanMember", is_group_session && canBanInGroup()); if(gAgentID == mAvatarID) { diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 3522932d03..333765f99f 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -1150,11 +1150,11 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec } else if ("block_unblock" == command) { - toggleMute(userID, LLMute::flagVoiceChat); + LLAvatarActions::toggleMute(userID, LLMute::flagVoiceChat); } else if ("mute_unmute" == command) { - toggleMute(userID, LLMute::flagTextChat); + LLAvatarActions::toggleMute(userID, LLMute::flagTextChat); } else if ("selected" == command || "mute_all" == command || "unmute_all" == command) { @@ -2096,24 +2096,6 @@ void LLFloaterIMContainer::toggleAllowTextChat(const LLUUID& participant_uuid) } } -void LLFloaterIMContainer::toggleMute(const LLUUID& participant_id, U32 flags) -{ - BOOL is_muted = LLMuteList::getInstance()->isMuted(participant_id, flags); - - LLAvatarName av_name; - LLAvatarNameCache::get(participant_id, &av_name); - LLMute mute(participant_id, av_name.getUserName(), LLMute::AGENT); - - if (!is_muted) - { - LLMuteList::getInstance()->add(mute, flags); - } - else - { - LLMuteList::getInstance()->remove(mute, flags); - } -} - void LLFloaterIMContainer::openNearbyChat() { // If there's only one conversation in the container and that conversation is the nearby chat diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index 60cef83d9a..90fc0c2bdd 100644 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -176,7 +176,6 @@ private: void moderateVoiceAllParticipants(bool unmute); void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute); void toggleAllowTextChat(const LLUUID& participant_uuid); - void toggleMute(const LLUUID& participant_id, U32 flags); void banSelectedMember(const LLUUID& participant_uuid); void openNearbyChat(); bool isParticipantListExpanded(); 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 410caa7290..05ab4d35a0 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu +<toggleable_menu height="101" layout="topleft" left="100" @@ -109,5 +109,43 @@ name="Mute Text"> <on_click function="AvatarIcon.Action" parameter="mute_unmute" /> <on_check function="AvatarIcon.Check" parameter="is_muted" /> - </menu_item_check> -</menu> + </menu_item_check> + <menu_item_separator layout="topleft" name="Moderator Options Separator"/> + <context_menu + label="Moderator Options" + layout="topleft" + name="Moderator Options"> + <menu_item_check + label="Allow text chat" + layout="topleft" + name="AllowTextChat"> + <on_check function="AvatarIcon.Check" parameter="is_allowed_text_chat" /> + <on_click function="AvatarIcon.Action" parameter="toggle_allow_text_chat" /> + <on_enable function="AvatarIcon.Enable" parameter="can_allow_text_chat" /> + </menu_item_check> + <menu_item_call + label="Mute this participant" + layout="topleft" + name="ModerateVoiceMuteSelected"> + <on_click function="AvatarIcon.Action" parameter="group_mute" /> + <on_enable function="AvatarIcon.Enable" parameter="can_mute" /> + <on_visible function="AvatarIcon.Visible" parameter="show_mute" /> + </menu_item_call> + <menu_item_call + label="Unmute this participant" + layout="topleft" + name="ModerateVoiceUnMuteSelected"> + <on_click function="AvatarIcon.Action" parameter="group_unmute" /> + <on_enable function="AvatarIcon.Enable" parameter="can_unmute" /> + <on_visible function="AvatarIcon.Visible" parameter="show_unmute" /> + </menu_item_call> + </context_menu> + <menu_item_separator layout="topleft" name="Group Ban Separator"/> + <menu_item_call + label="Ban member" + layout="topleft" + name="BanMember"> + <on_click function="AvatarIcon.Action" parameter="ban_member" /> + <on_enable function="AvatarIcon.Enable" parameter="can_ban_member" /> + </menu_item_call> +</toggleable_menu> |