From 08c0d3876bcddb2beeabb6fb2cd1a620eeb02576 Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Thu, 10 Dec 2009 14:45:41 +0200 Subject: Work on major task EXT-2808 (Add speakers moderation (both voice and text) to the Voice Control Panel (Active Speakers List)) -- Implemented Actions to Mute/Unmute Participants without using Agent's Block List -- Updated missing strings to show error while moderating --HG-- branch : product-engine --- indra/newview/llparticipantlist.cpp | 101 ++++++++++++++++++++++++++++++------ 1 file changed, 84 insertions(+), 17 deletions(-) (limited to 'indra/newview/llparticipantlist.cpp') diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 48a7a32a3b..a42b5e48cc 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -341,7 +341,7 @@ void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const if (uuids.size() == 0) return; const LLUUID speaker_id = mUUIDs.front(); - BOOL is_muted = LLMuteList::getInstance()->isMuted(speaker_id, LLMute::flagVoiceChat); + BOOL is_muted = isMuted(speaker_id); if (is_muted) { @@ -353,7 +353,6 @@ void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const LLMenuGL::sMenuContainer->childSetVisible("ModerateVoiceUnMuteSelected", false); LLMenuGL::sMenuContainer->childSetVisible("ModerateVoiceUnMuteOthers", false); } - } void LLParticipantList::LLParticipantListMenu::toggleAllowTextChat(const LLSD& userdata) @@ -390,14 +389,14 @@ void LLParticipantList::LLParticipantListMenu::toggleAllowTextChat(const LLSD& u { gIMMgr->showSessionEventError( "mute", - "not_a_moderator", + "not_a_mod_error", mSessionID); } else { gIMMgr->showSessionEventError( "mute", - "generic", + "generic_request_error", mSessionID); } } @@ -450,34 +449,102 @@ void LLParticipantList::LLParticipantListMenu::toggleMuteVoice(const LLSD& userd toggleMute(userdata, LLMute::flagVoiceChat); } +bool LLParticipantList::LLParticipantListMenu::isMuted(const LLUUID& avatar_id) +{ + LLPointer selected_speakerp = mParent.mSpeakerMgr->findSpeaker(avatar_id); + if (!selected_speakerp) return true; + + return selected_speakerp->mStatus == LLSpeaker::STATUS_MUTED; +} + void LLParticipantList::LLParticipantListMenu::moderateVoice(const LLSD& userdata) { + if (!gAgent.getRegion()) return; + bool moderate_selected = userdata.asString() == "selected"; + const LLUUID& selected_avatar_id = mUUIDs.front(); + bool is_muted = isMuted(selected_avatar_id); + + if (moderate_selected) + { + moderateVoiceParticipant(selected_avatar_id, is_muted); + } + else + { + moderateVoiceOtherParticipants(selected_avatar_id, is_muted); + } } -void LLParticipantList::LLParticipantListMenu::moderateVoiceOtherParticipants(const LLSD& userdata) + +void LLParticipantList::LLParticipantListMenu::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute) +{ + if (gAgentID == avatar_id) return; // do not process myself + + std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest"); + LLSD data; + data["method"] = "mute update"; + data["session-id"] = mParent.mSpeakerMgr->getSessionID(); + data["params"] = LLSD::emptyMap(); + data["params"]["agent_id"] = avatar_id; + data["params"]["mute_info"] = LLSD::emptyMap(); + data["params"]["mute_info"]["voice"] = !unmute; + + class MuteVoiceResponder : public LLHTTPClient::Responder + { + public: + MuteVoiceResponder(const LLUUID& session_id) + { + mSessionID = session_id; + } + + virtual void error(U32 status, const std::string& reason) + { + llwarns << status << ": " << reason << llendl; + + if ( gIMMgr ) + { + //403 == you're not a mod + //should be disabled if you're not a moderator + if ( 403 == status ) + { + gIMMgr->showSessionEventError( + "mute", + "not_a_mod_error", + mSessionID); + } + else + { + gIMMgr->showSessionEventError( + "mute", + "generic_request_error", + mSessionID); + } + } + } + + private: + LLUUID mSessionID; + }; + + LLHTTPClient::post( + url, + data, + new MuteVoiceResponder(mParent.mSpeakerMgr->getSessionID())); +} + +void LLParticipantList::LLParticipantListMenu::moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute) { LLSpeakerMgr::speaker_list_t speakers; mParent.mSpeakerMgr->getSpeakerList(&speakers, true); - const LLUUID& excluded_avatar_id = mUUIDs.front(); - bool should_mute = userdata.asString() == "mute"; for (LLSpeakerMgr::speaker_list_t::iterator iter = speakers.begin(); iter != speakers.end(); ++iter) { LLSpeaker* speakerp = (*iter).get(); LLUUID speaker_id = speakerp->mID; - if (excluded_avatar_id == speaker_id) continue; - LLMute mute(speaker_id, speakerp->mDisplayName, speakerp->mType == LLSpeaker::SPEAKER_AGENT ? LLMute::AGENT : LLMute::OBJECT); + if (excluded_avatar_id == speaker_id) continue; - if (should_mute) - { - LLMuteList::getInstance()->add(mute, LLMute::flagVoiceChat); - } - else - { - LLMuteList::getInstance()->remove(mute, LLMute::flagVoiceChat); - } + moderateVoiceParticipant(speaker_id, unmute); } } -- cgit v1.2.3 From e8d3afc99c3914a060384ee9eb6d2b673e76e36f Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Thu, 10 Dec 2009 15:15:45 +0200 Subject: Work on major task EXT-2808 (Add speakers moderation (both voice and text) to the Voice Control Panel (Active Speakers List)) -- Refactored moderating of text & voice chats to use the only LLHTTPClient::Responder class -- added doxygen comments for voice moderation functions --HG-- branch : product-engine --- indra/newview/llparticipantlist.cpp | 118 +++++++++++++----------------------- 1 file changed, 42 insertions(+), 76 deletions(-) (limited to 'indra/newview/llparticipantlist.cpp') diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index a42b5e48cc..9a6cafe0de 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -47,6 +47,44 @@ #if LL_MSVC #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally #endif + +class ModerationResponder : public LLHTTPClient::Responder +{ +public: + ModerationResponder(const LLUUID& session_id) + { + mSessionID = session_id; + } + + virtual void error(U32 status, const std::string& reason) + { + llwarns << status << ": " << reason << llendl; + + if ( gIMMgr ) + { + //403 == you're not a mod + //should be disabled if you're not a moderator + if ( 403 == status ) + { + gIMMgr->showSessionEventError( + "mute", + "not_a_mod_error", + mSessionID); + } + else + { + gIMMgr->showSessionEventError( + "mute", + "generic_request_error", + mSessionID); + } + } + } + +private: + LLUUID mSessionID; +}; + LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list, bool use_context_menu/* = true*/): mSpeakerMgr(data_source), mAvatarList(avatar_list), @@ -369,47 +407,10 @@ void LLParticipantList::LLParticipantListMenu::toggleAllowTextChat(const LLSD& u //current value represents ability to type, so invert data["params"]["mute_info"]["text"] = !mParent.mSpeakerMgr->findSpeaker(speaker_id)->mModeratorMutedText; - class MuteTextResponder : public LLHTTPClient::Responder - { - public: - MuteTextResponder(const LLUUID& session_id) - { - mSessionID = session_id; - } - - virtual void error(U32 status, const std::string& reason) - { - llwarns << status << ": " << reason << llendl; - - if ( gIMMgr ) - { - //403 == you're not a mod - //should be disabled if you're not a moderator - if ( 403 == status ) - { - gIMMgr->showSessionEventError( - "mute", - "not_a_mod_error", - mSessionID); - } - else - { - gIMMgr->showSessionEventError( - "mute", - "generic_request_error", - mSessionID); - } - } - } - - private: - LLUUID mSessionID; - }; - LLHTTPClient::post( url, data, - new MuteTextResponder(mParent.mSpeakerMgr->getSessionID())); + new ModerationResponder(mParent.mSpeakerMgr->getSessionID())); } void LLParticipantList::LLParticipantListMenu::toggleMute(const LLSD& userdata, U32 flags) @@ -488,47 +489,10 @@ void LLParticipantList::LLParticipantListMenu::moderateVoiceParticipant(const LL data["params"]["mute_info"] = LLSD::emptyMap(); data["params"]["mute_info"]["voice"] = !unmute; - class MuteVoiceResponder : public LLHTTPClient::Responder - { - public: - MuteVoiceResponder(const LLUUID& session_id) - { - mSessionID = session_id; - } - - virtual void error(U32 status, const std::string& reason) - { - llwarns << status << ": " << reason << llendl; - - if ( gIMMgr ) - { - //403 == you're not a mod - //should be disabled if you're not a moderator - if ( 403 == status ) - { - gIMMgr->showSessionEventError( - "mute", - "not_a_mod_error", - mSessionID); - } - else - { - gIMMgr->showSessionEventError( - "mute", - "generic_request_error", - mSessionID); - } - } - } - - private: - LLUUID mSessionID; - }; - LLHTTPClient::post( url, data, - new MuteVoiceResponder(mParent.mSpeakerMgr->getSessionID())); + new ModerationResponder(mParent.mSpeakerMgr->getSessionID())); } void LLParticipantList::LLParticipantListMenu::moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute) @@ -583,3 +547,5 @@ bool LLParticipantList::LLParticipantListMenu::checkContextMenuItem(const LLSD& } return false; } + +//EOF -- cgit v1.2.3 From ce621eafd8a115cc6c13a124453bbbda1bc43e13 Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Fri, 11 Dec 2009 13:31:43 +0200 Subject: Work on major task EXT-2808 (Add speakers moderation (both voice and text) to the Voice Control Panel (Active Speakers List)) -- initial implementation of the speacker listener to handle moderation mute -- added doxygen comments for voice moderation functions --HG-- branch : product-engine --- indra/newview/llparticipantlist.cpp | 56 ++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 7 deletions(-) (limited to 'indra/newview/llparticipantlist.cpp') diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 9a6cafe0de..e99a9a5d12 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -95,6 +95,7 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* av mSpeakerRemoveListener = new SpeakerRemoveListener(*this); mSpeakerClearListener = new SpeakerClearListener(*this); mSpeakerModeratorListener = new SpeakerModeratorUpdateListener(*this); + mSpeakerMuteListener = new SpeakerMuteListener(*this); mSpeakerMgr->addListener(mSpeakerAddListener, "add"); mSpeakerMgr->addListener(mSpeakerRemoveListener, "remove"); @@ -125,6 +126,7 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* av for(LLSpeakerMgr::speaker_list_t::iterator it = speaker_list.begin(); it != speaker_list.end(); it++) { const LLPointer& speakerp = *it; + addAvatarIDExceptAgent(group_members, speakerp->mID); if ( speakerp->mIsModerator ) { @@ -286,6 +288,24 @@ bool LLParticipantList::onModeratorUpdateEvent(LLPointer e return true; } +bool LLParticipantList::onSpeakerMuteEvent(LLPointer event, const LLSD& userdata) +{ + LLPointer speakerp = (LLSpeaker*)event->getSource(); + if (speakerp.isNull()) return false; + + // update UI on confirmation of moderator mutes + if (event->getValue().asString() == "voice") + { + LLAvatarListItem* item = dynamic_cast(mAvatarList->getItemByValue(speakerp->mID)); + if (item) + { + LLOutputMonitorCtrl* indicator = item->getChild("speaking_indicator"); + indicator->setIsMuted(speakerp->mModeratorMutedVoice); + } + } + return true; +} + void LLParticipantList::sort() { if ( !mAvatarList ) @@ -302,13 +322,21 @@ void LLParticipantList::sort() } } -// static void LLParticipantList::addAvatarIDExceptAgent(std::vector& existing_list, const LLUUID& avatar_id) { - if (gAgent.getID() != avatar_id) - { - existing_list.push_back(avatar_id); - } + if (gAgent.getID() == avatar_id) return; + + existing_list.push_back(avatar_id); + adjustParticipant(avatar_id); +} + +void LLParticipantList::adjustParticipant(const LLUUID& speaker_id) +{ + LLPointer speakerp = mSpeakerMgr->findSpeaker(speaker_id); + if (speakerp.isNull()) return; + + // add listener to process moderation changes + speakerp->addListener(mSpeakerMuteListener); } // @@ -353,6 +381,11 @@ bool LLParticipantList::SpeakerModeratorUpdateListener::handleEvent(LLPointer event, const LLSD& userdata) +{ + return mParent.onSpeakerMuteEvent(event, userdata); +} + LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu() { // set up the callbacks for all of the avatar menu items @@ -480,6 +513,16 @@ void LLParticipantList::LLParticipantListMenu::moderateVoiceParticipant(const LL { if (gAgentID == avatar_id) return; // do not process myself + LLPointer speakerp = mParent.mSpeakerMgr->findSpeaker(avatar_id); + if (!speakerp) return; + + // *NOTE: mantipov: probably this condition will be incorrect when avatar will be blocked for + // text chat via moderation (LLSpeaker::mModeratorMutedText == TRUE) + bool is_in_voice = speakerp->mStatus <= LLSpeaker::STATUS_VOICE_ACTIVE || speakerp->mStatus == LLSpeaker::STATUS_MUTED; + + // do not send voice moderation changes for avatars not in voice channel + if (!is_in_voice) return; + std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest"); LLSD data; data["method"] = "mute update"; @@ -498,7 +541,7 @@ void LLParticipantList::LLParticipantListMenu::moderateVoiceParticipant(const LL void LLParticipantList::LLParticipantListMenu::moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute) { LLSpeakerMgr::speaker_list_t speakers; - mParent.mSpeakerMgr->getSpeakerList(&speakers, true); + mParent.mSpeakerMgr->getSpeakerList(&speakers, FALSE); for (LLSpeakerMgr::speaker_list_t::iterator iter = speakers.begin(); iter != speakers.end(); ++iter) @@ -510,7 +553,6 @@ void LLParticipantList::LLParticipantListMenu::moderateVoiceOtherParticipants(co moderateVoiceParticipant(speaker_id, unmute); } - } bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD& userdata) -- cgit v1.2.3 From 77b5ee1b4d7fb03f757efdaa4169ab38fb754b25 Mon Sep 17 00:00:00 2001 From: Dmitry Zaporozhan Date: Fri, 11 Dec 2009 18:33:37 +0200 Subject: Implemented major task EXT-3390 - Move Moderation options into submenu. --HG-- branch : product-engine --- indra/newview/llparticipantlist.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'indra/newview/llparticipantlist.cpp') diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index e99a9a5d12..1986a98fb7 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -401,8 +401,13 @@ LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu() enable_registrar.add("ParticipantList.CheckItem", boost::bind(&LLParticipantList::LLParticipantListMenu::checkContextMenuItem, this, _2)); // create the context menu from the XUI - return LLUICtrlFactory::getInstance()->createFromFile( + LLContextMenu* main_menu = LLUICtrlFactory::getInstance()->createFromFile( "menu_participant_list.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); + + main_menu->setItemVisible("Moderator Options", isGroupModerator()); + main_menu->arrangeAndClear(); + + return main_menu; } void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const std::vector& uuids, S32 x, S32 y) @@ -483,6 +488,15 @@ void LLParticipantList::LLParticipantListMenu::toggleMuteVoice(const LLSD& userd toggleMute(userdata, LLMute::flagVoiceChat); } +bool LLParticipantList::LLParticipantListMenu::isGroupModerator() +{ + // Agent is in Group Call + bool is_in_group = gAgent.isInGroup(mParent.mSpeakerMgr->getSessionID()); + // Agent is Moderator + bool is_moderator = mParent.mSpeakerMgr->findSpeaker(gAgentID)->mIsModerator; + return is_in_group && is_moderator; +} + bool LLParticipantList::LLParticipantListMenu::isMuted(const LLUUID& avatar_id) { LLPointer selected_speakerp = mParent.mSpeakerMgr->findSpeaker(avatar_id); @@ -565,8 +579,7 @@ bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD& else if (item == "can_allow_text_chat" || "can_moderate_voice" == item) { - LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(mParent.mSpeakerMgr->getSessionID()); - return im_session->mType == IM_SESSION_GROUP_START && mParent.mSpeakerMgr->findSpeaker(gAgentID)->mIsModerator; + return isGroupModerator(); } return true; } -- cgit v1.2.3 From 5f0b2624bc40c6c7580fa7c02f137c3dee330b94 Mon Sep 17 00:00:00 2001 From: Dmitry Zaporozhan Date: Fri, 11 Dec 2009 18:53:55 +0200 Subject: Update for major task EXT-3390 - Move Moderation options into submenu. Minor code change. --HG-- branch : product-engine --- indra/newview/llparticipantlist.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'indra/newview/llparticipantlist.cpp') diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 1986a98fb7..b787699a66 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -491,10 +491,12 @@ void LLParticipantList::LLParticipantListMenu::toggleMuteVoice(const LLSD& userd bool LLParticipantList::LLParticipantListMenu::isGroupModerator() { // Agent is in Group Call - bool is_in_group = gAgent.isInGroup(mParent.mSpeakerMgr->getSessionID()); - // Agent is Moderator - bool is_moderator = mParent.mSpeakerMgr->findSpeaker(gAgentID)->mIsModerator; - return is_in_group && is_moderator; + if(gAgent.isInGroup(mParent.mSpeakerMgr->getSessionID())) + { + // Agent is Moderator + return mParent.mSpeakerMgr->findSpeaker(gAgentID)->mIsModerator; + } + return false; } bool LLParticipantList::LLParticipantListMenu::isMuted(const LLUUID& avatar_id) -- cgit v1.2.3