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.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 +++++++++++++----------------------- indra/newview/llparticipantlist.h | 39 ++++++++++++ 2 files changed, 81 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 diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h index 388d0b4fee..a130edb553 100644 --- a/indra/newview/llparticipantlist.h +++ b/indra/newview/llparticipantlist.h @@ -130,9 +130,48 @@ class LLParticipantList void toggleMuteVoice(const LLSD& userdata); // Voice moderation support + /** + * Check whether specified by argument avatar is muted for group chat or not. + */ bool isMuted(const LLUUID& avatar_id); + + /** + * Processes Voice moderation menu items. + * + * It calls either moderateVoiceParticipant() or moderateVoiceParticipant() depend on + * passed parameter. + * + * @param userdata can be "selected" or "others". + * + * @see moderateVoiceParticipant() + * @see moderateVoiceOtherParticipants() + */ void moderateVoice(const LLSD& userdata); + + /** + * Mutes/Unmutes avatar for current group voice chat. + * + * It only marks avatar as muted for session and does not use local Agent's Block list. + * It does not mute Agent itself. + * + * @param[in] avatar_id UUID of avatar to be processed + * @param[in] unmute if true - specified avatar will be muted, otherwise - unmuted. + * + * @see moderateVoiceOtherParticipants() + */ void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute); + + /** + * Mutes/Unmutes all avatars except specified for current group voice chat. + * + * It only marks avatars as muted for session and does not use local Agent's Block list. + * It based call moderateVoiceParticipant() for each avatar should be muted/unmuted. + * + * @param[in] excluded_avatar_id UUID of avatar NOT to be processed + * @param[in] unmute if true - avatars will be muted, otherwise - unmuted. + * + * @see moderateVoiceParticipant() + */ void moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute); }; -- cgit v1.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 ++++++++++++++++++++++++++++++++----- indra/newview/llparticipantlist.h | 22 ++++++++++++++- 2 files changed, 70 insertions(+), 8 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) diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h index a130edb553..229769ec09 100644 --- a/indra/newview/llparticipantlist.h +++ b/indra/newview/llparticipantlist.h @@ -64,6 +64,7 @@ class LLParticipantList bool onRemoveItemEvent(LLPointer event, const LLSD& userdata); bool onClearListEvent(LLPointer event, const LLSD& userdata); bool onModeratorUpdateEvent(LLPointer event, const LLSD& userdata); + bool onSpeakerMuteEvent(LLPointer event, const LLSD& userdata); /** * Sorts the Avatarlist by stored order @@ -109,6 +110,14 @@ class LLParticipantList /*virtual*/ bool handleEvent(LLPointer event, const LLSD& userdata); }; + class SpeakerMuteListener : public BaseSpeakerListner + { + public: + SpeakerMuteListener(LLParticipantList& parent) : BaseSpeakerListner(parent) {} + + /*virtual*/ bool handleEvent(LLPointer event, const LLSD& userdata); + }; + /** * Menu used in the participant list. */ @@ -181,8 +190,18 @@ class LLParticipantList /** * Adds specified avatar ID to the existing list if it is not Agent's ID + * + * @param[in, out] existing_list - vector with avatars' UUIDs already in the list + * @param[in] avatar_id - Avatar UUID to be added into the list + */ + void addAvatarIDExceptAgent(std::vector& existing_list, const LLUUID& avatar_id); + + /** + * Adjusts passed participant to work properly. + * + * Adds SpeakerMuteListener to process moderation actions. */ - static void addAvatarIDExceptAgent(std::vector& existing_list, const LLUUID& avatar_id); + void adjustParticipant(const LLUUID& speaker_id); LLSpeakerMgr* mSpeakerMgr; LLAvatarList* mAvatarList; @@ -194,6 +213,7 @@ class LLParticipantList LLPointer mSpeakerRemoveListener; LLPointer mSpeakerClearListener; LLPointer mSpeakerModeratorListener; + LLPointer mSpeakerMuteListener; LLParticipantListMenu* mParticipantListMenu; -- cgit v1.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 ++++++++++++++++--- indra/newview/llparticipantlist.h | 5 +++++ .../skins/default/xui/en/menu_participant_list.xml | 5 +++++ 3 files changed, 26 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; } diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h index 229769ec09..9d7d3a0cbe 100644 --- a/indra/newview/llparticipantlist.h +++ b/indra/newview/llparticipantlist.h @@ -138,6 +138,11 @@ class LLParticipantList void toggleMuteText(const LLSD& userdata); void toggleMuteVoice(const LLSD& userdata); + /** + * Return true if Agent is group moderator(and moderator of group call). + */ + bool isGroupModerator(); + // Voice moderation support /** * Check whether specified by argument avatar is muted for group chat or not. diff --git a/indra/newview/skins/default/xui/en/menu_participant_list.xml b/indra/newview/skins/default/xui/en/menu_participant_list.xml index ffe5430c55..adf4bd70e1 100644 --- a/indra/newview/skins/default/xui/en/menu_participant_list.xml +++ b/indra/newview/skins/default/xui/en/menu_participant_list.xml @@ -76,6 +76,10 @@ function="ParticipantList.EnableItem" parameter="can_mute_text" /> + + -- cgit v1.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.3 From eca66a2aa6b507bad1e168bcfafb18e4d389caa1 Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Fri, 11 Dec 2009 17:00:49 +0200 Subject: Work on major task EXT-2808 (Add speakers moderation (both voice and text) to the Voice Control Panel (Active Speakers List)) -- added updating of participant list to display participants not in voice as disabled. Unfortunatly I have to perform refreshing in a draw to mad it workable till beta 0. --HG-- branch : product-engine --- indra/newview/llcallfloater.cpp | 29 +++++++++++++++++++++++++++++ indra/newview/llcallfloater.h | 11 ++++++++++- indra/newview/llparticipantlist.cpp | 21 +++++++++++++++++++++ indra/newview/llparticipantlist.h | 10 ++++++++-- 4 files changed, 68 insertions(+), 3 deletions(-) (limited to 'indra/newview/llparticipantlist.cpp') diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index 4ab5ea1812..e6a6910d6d 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -82,6 +82,7 @@ LLCallFloater::LLCallFloater(const LLSD& key) , mVoiceType(VC_LOCAL_CHAT) { mFactoryMap["non_avatar_caller"] = LLCallbackMap(create_non_avatar_caller, NULL); + LLVoiceClient::getInstance()->addObserver(this); } LLCallFloater::~LLCallFloater() @@ -89,6 +90,13 @@ LLCallFloater::~LLCallFloater() mChannelChangedConnection.disconnect(); delete mPaticipants; mPaticipants = NULL; + + // Don't use LLVoiceClient::getInstance() here + // singleton MAY have already been destroyed. + if(gVoiceClient) + { + gVoiceClient->removeObserver(this); + } } // virtual @@ -121,6 +129,26 @@ void LLCallFloater::onOpen(const LLSD& /*key*/) { } +// virtual +void LLCallFloater::draw() +{ + // we have to refresh participants to display ones not in voice as disabled. + // It should be done only when she joins or leaves voice chat. + // But seems that LLVoiceClientParticipantObserver is not enough to satisfy this requirement. + // *TODO: mantipov: remove from draw() + onChange(); + LLDockableFloater::draw(); +} + +// virtual +void LLCallFloater::onChange() +{ + if (NULL == mPaticipants) return; + + mPaticipants->refreshVoiceState(); +} + + ////////////////////////////////////////////////////////////////////////// /// PRIVATE SECTION ////////////////////////////////////////////////////////////////////////// @@ -231,6 +259,7 @@ void LLCallFloater::refreshPartisipantList() { mAvatarList->setNoItemsCommentText(getString("no_one_near")); } + mPaticipants->refreshVoiceState(); } } diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h index b615f57d5b..52f9595435 100644 --- a/indra/newview/llcallfloater.h +++ b/indra/newview/llcallfloater.h @@ -35,6 +35,7 @@ #define LL_LLCALLFLOATER_H #include "lldockablefloater.h" +#include "llvoiceclient.h" class LLAvatarList; class LLNonAvatarCaller; @@ -52,7 +53,7 @@ class LLSpeakerMgr; * When the Resident is engaged in any chat except Nearby Chat, the Voice Control Panel also provides an * 'Leave Call' button to allow the Resident to leave that voice channel. */ -class LLCallFloater : public LLDockableFloater +class LLCallFloater : public LLDockableFloater, LLVoiceClientParticipantObserver { public: LLCallFloater(const LLSD& key); @@ -60,6 +61,14 @@ public: /*virtual*/ BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void draw(); + + /** + * Is called by LLVoiceClient::notifyParticipantObservers when voice participant list is changed. + * + * Refreshes list to display participants not in voice as disabled. + */ + /*virtual*/ void onChange(); private: typedef enum e_voice_controls_type diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index b787699a66..6b3f468ff1 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -224,6 +224,27 @@ void LLParticipantList::setSortOrder(EParticipantSortOrder order) } } +void LLParticipantList::refreshVoiceState() +{ + LLSpeakerMgr::speaker_list_t speakers; + mSpeakerMgr->getSpeakerList(&speakers, TRUE); + + for (LLSpeakerMgr::speaker_list_t::iterator iter = speakers.begin(); + iter != speakers.end(); ++iter) + { + LLSpeaker* speakerp = (*iter).get(); + const LLUUID& speaker_id = speakerp->mID; + LLAvatarListItem* item = dynamic_cast (mAvatarList->getItemByValue(speaker_id)); + if ( item ) + { + // if voice is disabled for this speaker show non voice speakers as disabled + bool is_in_voice = speakerp->mStatus > LLSpeaker::STATUS_VOICE_ACTIVE + && speakerp->mStatus != LLSpeaker::STATUS_MUTED; + item->setOnline(!is_in_voice); + } + } +} + bool LLParticipantList::onAddItemEvent(LLPointer event, const LLSD& userdata) { LLAvatarList::uuid_vector_t& group_members = mAvatarList->getIDs(); diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h index 9d7d3a0cbe..bc6c6c2b50 100644 --- a/indra/newview/llparticipantlist.h +++ b/indra/newview/llparticipantlist.h @@ -52,10 +52,16 @@ class LLParticipantList } EParticipantSortOrder; /** - * Set and sort Avatarlist by given order - */ + * Set and sort Avatarlist by given order + */ void setSortOrder(EParticipantSortOrder order = E_SORT_BY_NAME); + /** + * Refreshes participants to display ones not in voice as disabled. + * TODO: mantipov: probably should be moved into derived class for LLFloaterCall + */ + void refreshVoiceState(); + protected: /** * LLSpeakerMgr event handlers -- cgit v1.3 From fd99f8701cfe4cbcd95f847b77e985703937a581 Mon Sep 17 00:00:00 2001 From: Paul Guslisty Date: Fri, 11 Dec 2009 21:44:48 +0200 Subject: Fixed normal bug EXT - 2863 (Group Chat List Names right click do not contain view profile or send private message) --HG-- branch : product-engine --- indra/newview/llparticipantlist.cpp | 61 ++++++++++++++++++---- .../skins/default/xui/en/menu_participant_list.xml | 15 +++--- 2 files changed, 61 insertions(+), 15 deletions(-) (limited to 'indra/newview/llparticipantlist.cpp') diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 6b3f468ff1..47b9f29b48 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -42,6 +42,7 @@ #include "llavatarlist.h" #include "llspeakers.h" #include "llviewermenu.h" +#include "llvoiceclient.h" //LLParticipantList retrieves add, clear and remove events and updates view accordingly #if LL_MSVC @@ -416,6 +417,14 @@ LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu() registrar.add("ParticipantList.ToggleAllowTextChat", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleAllowTextChat, this, _2)); registrar.add("ParticipantList.ToggleMuteText", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleMuteText, this, _2)); + registrar.add("Avatar.Profile", boost::bind(&LLAvatarActions::showProfile, mUUIDs.front())); + registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startIM, mUUIDs.front())); + registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, mUUIDs.front())); + registrar.add("Avatar.BlockUnblock", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleMuteVoice, this, _2)); + registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::share, mUUIDs.front())); + registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, mUUIDs.front())); + registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startCall, mUUIDs.front())); + registrar.add("ParticipantList.ModerateVoice", boost::bind(&LLParticipantList::LLParticipantListMenu::moderateVoice, this, _2)); enable_registrar.add("ParticipantList.EnableItem", boost::bind(&LLParticipantList::LLParticipantListMenu::enableContextMenuItem, this, _2)); @@ -604,6 +613,33 @@ bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD& { return isGroupModerator(); } + else if (item == std::string("can_add")) + { + // We can add friends if: + // - there are selected people + // - and there are no friends among selection yet. + + bool result = (mUUIDs.size() > 0); + + std::vector::const_iterator + id = mUUIDs.begin(), + uuids_end = mUUIDs.end(); + + for (;id != uuids_end; ++id) + { + if ( LLAvatarActions::isFriend(*id) ) + { + result = false; + break; + } + } + return result; + } + else if (item == "can_call") + { + return LLVoiceClient::voiceEnabled(); + } + return true; } @@ -611,18 +647,25 @@ bool LLParticipantList::LLParticipantListMenu::checkContextMenuItem(const LLSD& { std::string item = userdata.asString(); const LLUUID& id = mUUIDs.front(); + if (item == "is_muted") - return LLMuteList::getInstance()->isMuted(id, LLMute::flagTextChat); - else - if (item == "is_allowed_text_chat") - { - LLPointer selected_speakerp = mParent.mSpeakerMgr->findSpeaker(id); + { + return LLMuteList::getInstance()->isMuted(id, LLMute::flagTextChat); + } + else if (item == "is_allowed_text_chat") + { + LLPointer selected_speakerp = mParent.mSpeakerMgr->findSpeaker(id); - if (selected_speakerp.notNull()) - { - return !selected_speakerp->mModeratorMutedText; - } + if (selected_speakerp.notNull()) + { + return !selected_speakerp->mModeratorMutedText; } + } + else if(item == "is_blocked") + { + return LLMuteList::getInstance()->isMuted(id, LLMute::flagVoiceChat); + } + return false; } diff --git a/indra/newview/skins/default/xui/en/menu_participant_list.xml b/indra/newview/skins/default/xui/en/menu_participant_list.xml index adf4bd70e1..449202aaaa 100644 --- a/indra/newview/skins/default/xui/en/menu_participant_list.xml +++ b/indra/newview/skins/default/xui/en/menu_participant_list.xml @@ -16,7 +16,7 @@ - + @@ -49,16 +52,16 @@ function="Avatar.Pay" /> Date: Mon, 14 Dec 2009 19:14:16 +0200 Subject: Update for critical bug EXT-3427 - Viewer chashes if select Moderator Options submenu in Voice controls quickly. Added code to hide menu before destroying it. Added aditional checks. Added comments --HG-- branch : product-engine --- indra/newview/llcallfloater.cpp | 6 +++++- indra/newview/llpanelpeoplemenus.cpp | 8 ++++++++ indra/newview/llpanelpeoplemenus.h | 2 ++ indra/newview/llparticipantlist.cpp | 8 ++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) (limited to 'indra/newview/llparticipantlist.cpp') diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index 4f1164788d..2f5523e04d 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -280,7 +280,11 @@ void LLCallFloater::refreshPartisipantList() void LLCallFloater::onCurrentChannelChanged(const LLUUID& /*session_id*/) { - if(LLVoiceChannel::STATE_NO_CHANNEL_INFO == LLVoiceChannel::getCurrentVoiceChannel()->getState()) + // Don't update participant list if no channel info is available. + // Fix for ticket EXT-3427 + // @see LLParticipantList::~LLParticipantList() + if(LLVoiceChannel::getCurrentVoiceChannel() && + LLVoiceChannel::STATE_NO_CHANNEL_INFO == LLVoiceChannel::getCurrentVoiceChannel()->getState()) { return; } diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp index 04fe42de9f..573de1e51c 100644 --- a/indra/newview/llpanelpeoplemenus.cpp +++ b/indra/newview/llpanelpeoplemenus.cpp @@ -81,6 +81,14 @@ void ContextMenu::show(LLView* spawning_view, const std::vector& uuids, LLMenuGL::showPopup(spawning_view, mMenu, x, y); } +void ContextMenu::hide() +{ + if(mMenu) + { + mMenu->hide(); + } +} + //== NearbyMenu =============================================================== LLContextMenu* NearbyMenu::createMenu() diff --git a/indra/newview/llpanelpeoplemenus.h b/indra/newview/llpanelpeoplemenus.h index ed0f8208f6..14ae2985f0 100644 --- a/indra/newview/llpanelpeoplemenus.h +++ b/indra/newview/llpanelpeoplemenus.h @@ -54,6 +54,8 @@ public: */ /*virtual*/ void show(LLView* spawning_view, const std::vector& uuids, S32 x, S32 y); + virtual void hide(); + protected: virtual LLContextMenu* createMenu() = 0; diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 47b9f29b48..2c5f1b094e 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -144,6 +144,14 @@ LLParticipantList::~LLParticipantList() mAvatarListRefreshConnection.disconnect(); mAvatarListReturnConnection.disconnect(); + // It is possible Participant List will be re-created from LLCallFloater::onCurrentChannelChanged() + // See ticket EXT-3427 + // hide menu before deleting it to stop enable and check handlers from triggering. + if(mParticipantListMenu) + { + mParticipantListMenu->hide(); + } + delete mParticipantListMenu; mParticipantListMenu = NULL; } -- cgit v1.3