diff options
-rw-r--r-- | indra/llui/lldockablefloater.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llavatarlistitem.cpp | 31 | ||||
-rw-r--r-- | indra/newview/llchathistory.cpp | 17 | ||||
-rw-r--r-- | indra/newview/llfloatergodtools.cpp | 6 | ||||
-rw-r--r-- | indra/newview/llfloaterworldmap.cpp | 7 | ||||
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 21 | ||||
-rw-r--r-- | indra/newview/lllocationinputctrl.cpp | 11 | ||||
-rw-r--r-- | indra/newview/llpanelavatar.cpp | 34 | ||||
-rw-r--r-- | indra/newview/llpanelavatar.h | 4 | ||||
-rw-r--r-- | indra/newview/llpanelmaininventory.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llpanelpeoplemenus.cpp | 24 | ||||
-rw-r--r-- | indra/newview/llpreviewscript.cpp | 6 | ||||
-rw-r--r-- | indra/newview/llprogressview.cpp | 5 | ||||
-rw-r--r-- | indra/newview/lltoolpie.cpp | 3 | ||||
-rw-r--r-- | indra/newview/llviewermenu.cpp | 13 | ||||
-rw-r--r-- | indra/newview/llvoiceclient.cpp | 23 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/menu_people_nearby.xml | 10 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml | 10 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/menu_profile_overflow.xml | 29 |
19 files changed, 179 insertions, 82 deletions
diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp index a94f0206a6..0492ab0f25 100644 --- a/indra/llui/lldockablefloater.cpp +++ b/indra/llui/lldockablefloater.cpp @@ -95,7 +95,7 @@ void LLDockableFloater::toggleInstance(const LLSD& sdname) LLDockableFloater* instance = dynamic_cast<LLDockableFloater*> (LLFloaterReg::findInstance(name)); // if floater closed or docked - if (instance == NULL || instance != NULL && instance->isDocked()) + if (instance == NULL || (instance && instance->isDocked())) { LLFloaterReg::toggleInstance(name, key); // restore button toggle state diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 846b2843dd..5011b191f4 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -526,21 +526,30 @@ void LLAvatarListItem::updateChildren() LLView* LLAvatarListItem::getItemChildView(EAvatarListItemChildIndex child_view_index) { LLView* child_view = mAvatarName; - if (child_view_index < 0 || ALIC_COUNT <= child_view_index) - { - LL_WARNS("AvatarItemReshape") << "Child view index is out of range: " << child_view_index << LL_ENDL; - return child_view; - } + switch (child_view_index) { - case ALIC_ICON: child_view = mAvatarIcon; break; - case ALIC_NAME: child_view = mAvatarName; break; - case ALIC_INTERACTION_TIME: child_view = mLastInteractionTime; break; - case ALIC_SPEAKER_INDICATOR: child_view = mSpeakingIndicator; break; - case ALIC_INFO_BUTTON: child_view = mInfoBtn; break; - case ALIC_PROFILE_BUTTON: child_view = mProfileBtn; break; + case ALIC_ICON: + child_view = mAvatarIcon; + break; + case ALIC_NAME: + child_view = mAvatarName; + break; + case ALIC_INTERACTION_TIME: + child_view = mLastInteractionTime; + break; + case ALIC_SPEAKER_INDICATOR: + child_view = mSpeakingIndicator; + break; + case ALIC_INFO_BUTTON: + child_view = mInfoBtn; + break; + case ALIC_PROFILE_BUTTON: + child_view = mProfileBtn; + break; default: LL_WARNS("AvatarItemReshape") << "Unexpected child view index is passed: " << child_view_index << LL_ENDL; + // leave child_view untouched } return child_view; diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 9368d9cb7c..81cc52528c 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -68,6 +68,9 @@ const static std::string NEW_LINE(rawstr_to_utf8("\n")); const static U32 LENGTH_OF_TIME_STR = std::string("12:00").length(); +const static std::string SLURL_APP_AGENT = "secondlife:///app/agent/"; +const static std::string SLURL_ABOUT = "/about"; + // support for secondlife:///app/objectim/{UUID}/ SLapps class LLObjectIMHandler : public LLCommandHandler { @@ -779,6 +782,20 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL else { std::string message = irc_me ? chat.mText.substr(3) : chat.mText; + + + //MESSAGE TEXT PROCESSING + //*HACK getting rid of redundant sender names in system notifications sent using sender name (see EXT-5010) + if (use_plain_text_chat_history && gAgentID != chat.mFromID && chat.mFromID.notNull()) + { + std::string slurl_about = SLURL_APP_AGENT + chat.mFromID.asString() + SLURL_ABOUT; + if (message.length() > slurl_about.length() && + message.compare(0, slurl_about.length(), slurl_about) == 0) + { + message = message.substr(slurl_about.length(), message.length()-1); + } + } + mEditor->appendText(message, FALSE, style_params); } mEditor->blockUndo(); diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp index 5294f09e64..eb56f387cd 100644 --- a/indra/newview/llfloatergodtools.cpp +++ b/indra/newview/llfloatergodtools.cpp @@ -213,6 +213,9 @@ void LLFloaterGodTools::showPanel(const std::string& panel_name) // static void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg) { + llassert(msg); + if (!msg) return; + LLHost host = msg->getSender(); if (host != gAgent.getRegionHost()) { @@ -270,8 +273,7 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg) if ( gAgent.isGodlike() && LLFloaterReg::instanceVisible("god_tools") && god_tools->mPanelRegionTools - && god_tools->mPanelObjectTools - && msg ) + && god_tools->mPanelObjectTools) { LLPanelRegionTools* rtool = god_tools->mPanelRegionTools; god_tools->mCurrentHost = host; diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index f4d4ea3553..b6de409611 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -788,8 +788,11 @@ void LLFloaterWorldMap::friendsChanged() if(avatar_id.notNull()) { LLCtrlSelectionInterface *iface = childGetSelectionInterface("friend combo"); - if(!iface || !iface->setCurrentByID(avatar_id) || - !t.getBuddyInfo(avatar_id)->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION) || gAgent.isGodlike()) + const LLRelationship* buddy_info = t.getBuddyInfo(avatar_id); + if(!iface || + !iface->setCurrentByID(avatar_id) || + (buddy_info && !buddy_info->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)) || + gAgent.isGodlike()) { LLTracker::stopTracking(NULL); } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 7b80d00c2c..75dc227c53 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -295,12 +295,27 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener* LLMessageSystem* msg = gMessageSystem; const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); LLViewerInventoryItem* item = NULL; - LLViewerInventoryCategory* cat = NULL; std::vector<LLUUID> move_ids; LLInventoryModel::update_map_t update; bool start_new_message = true; S32 count = batch.count(); S32 i; + + // first, hide any 'preview' floaters that correspond to the items + // being deleted. + for(i = 0; i < count; ++i) + { + bridge = (LLInvFVBridge*)(batch.get(i)); + if(!bridge || !bridge->isItemRemovable()) continue; + item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID()); + if(item) + { + LLPreview::hide(item->getUUID()); + } + } + + // do the inventory move to trash + for(i = 0; i < count; ++i) { bridge = (LLInvFVBridge*)(batch.get(i)); @@ -310,7 +325,6 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener* { if(item->getParentUUID() == trash_id) continue; move_ids.push_back(item->getUUID()); - LLPreview::hide(item->getUUID()); --update[item->getParentUUID()]; ++update[trash_id]; if(start_new_message) @@ -342,11 +356,12 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener* gInventory.accountForUpdate(update); update.clear(); } + for(i = 0; i < count; ++i) { bridge = (LLInvFVBridge*)(batch.get(i)); if(!bridge || !bridge->isItemRemovable()) continue; - cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID()); + LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID()); if(cat) { if(cat->getParentUUID() == trash_id) continue; diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index f48c96190f..c66d067779 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -833,10 +833,13 @@ void LLLocationInputCtrl::refreshParcelIcons() mDamageText->setVisible(false); } - S32 left_pad, right_pad; - mTextEntry->getTextPadding(&left_pad, &right_pad); - right_pad = mTextEntry->getRect().mRight - x; - mTextEntry->setTextPadding(left_pad, right_pad); + if (mTextEntry) + { + S32 left_pad, right_pad; + mTextEntry->getTextPadding(&left_pad, &right_pad); + right_pad = mTextEntry->getRect().mRight - x; + mTextEntry->setTextPadding(left_pad, right_pad); + } } void LLLocationInputCtrl::refreshHealth() diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index d7c558d188..91eab9f4f1 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -507,8 +507,8 @@ BOOL LLPanelAvatarProfile::postBuild() LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable; enable.add("Profile.EnableGod", boost::bind(&enable_god)); - enable.add("Profile.CheckItem", boost::bind(&LLPanelAvatarProfile::checkOverflowMenuItem, this, _2)); - enable.add("Profile.EnableItem", boost::bind(&LLPanelAvatarProfile::enableOverflowMenuItem, this, _2)); + enable.add("Profile.EnableBlock", boost::bind(&LLPanelAvatarProfile::enableBlock, this)); + enable.add("Profile.EnableUnblock", boost::bind(&LLPanelAvatarProfile::enableUnblock, this)); mProfileMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_profile_overflow.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); @@ -685,26 +685,6 @@ void LLPanelAvatarProfile::fillAccountStatus(const LLAvatarData* avatar_data) childSetValue("acc_status_text", caption_text); } -bool LLPanelAvatarProfile::checkOverflowMenuItem(const LLSD& param) -{ - std::string item = param.asString(); - - if (item == "is_blocked") - return LLAvatarActions::isBlocked(getAvatarId()); - - return false; -} - -bool LLPanelAvatarProfile::enableOverflowMenuItem(const LLSD& param) -{ - std::string item = param.asString(); - - if (item == "can_block") - return LLAvatarActions::canBlock(getAvatarId()); - - return false; -} - void LLPanelAvatarProfile::pay() { LLAvatarActions::pay(getAvatarId()); @@ -720,6 +700,16 @@ void LLPanelAvatarProfile::toggleBlock() LLAvatarActions::toggleBlock(getAvatarId()); } +bool LLPanelAvatarProfile::enableBlock() +{ + return LLAvatarActions::canBlock(getAvatarId()) && !LLAvatarActions::isBlocked(getAvatarId()); +} + +bool LLPanelAvatarProfile::enableUnblock() +{ + return LLAvatarActions::isBlocked(getAvatarId()); +} + void LLPanelAvatarProfile::kick() { LLAvatarActions::kick(getAvatarId()); diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index 52b4255e34..babbe534b4 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -202,8 +202,8 @@ protected: void unfreeze(); void csr(); - bool checkOverflowMenuItem(const LLSD& param); - bool enableOverflowMenuItem(const LLSD& param); + bool enableBlock(); + bool enableUnblock(); bool enableGod(); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 1895993a8e..2d3401966b 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -1003,7 +1003,10 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata) } const LLUUID item_id = current_item->getListener()->getUUID(); LLViewerInventoryItem *item = gInventory.getItem(item_id); - item->regenerateLink(); + if (item) + { + item->regenerateLink(); + } active_panel->setSelection(item_id, TAKE_FOCUS_NO); } if (command_name == "find_original") diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp index 7e184c78a8..900d28adca 100644 --- a/indra/newview/llpanelpeoplemenus.cpp +++ b/indra/newview/llpanelpeoplemenus.cpp @@ -121,6 +121,7 @@ LLContextMenu* NearbyMenu::createMenu() const LLUUID& id = mUUIDs.front(); registrar.add("Avatar.Profile", boost::bind(&LLAvatarActions::showProfile, id)); registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, id)); + registrar.add("Avatar.RemoveFriend", boost::bind(&LLAvatarActions::removeFriendDialog, id)); registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startIM, id)); registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startCall, id)); registrar.add("Avatar.OfferTeleport", boost::bind(&NearbyMenu::offerTeleport, this)); @@ -143,6 +144,7 @@ LLContextMenu* NearbyMenu::createMenu() // registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, mUUIDs)); // *TODO: unimplemented registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startConference, mUUIDs)); registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startAdhocCall, mUUIDs)); + registrar.add("Avatar.RemoveFriend",boost::bind(&LLAvatarActions::removeFriendsDialog, mUUIDs)); // registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::startIM, mUUIDs)); // *TODO: unimplemented // registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, mUUIDs)); // *TODO: unimplemented enable_registrar.add("Avatar.EnableItem", boost::bind(&NearbyMenu::enableContextMenuItem, this, _2)); @@ -191,8 +193,26 @@ bool NearbyMenu::enableContextMenuItem(const LLSD& userdata) } else if (item == std::string("can_delete")) { - const LLUUID& id = mUUIDs.front(); - return LLAvatarActions::isFriend(id); + // We can remove friends if: + // - there are selected people + // - and there are only friends among selection. + + bool result = (mUUIDs.size() > 0); + + std::vector<LLUUID>::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 == std::string("can_call")) { diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 3221745fa3..f5a9f82d50 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -955,8 +955,12 @@ BOOL LLPreviewLSL::postBuild() { const LLInventoryItem* item = getItem(); + llassert(item); + if (item) + { + childSetText("desc", item->getDescription()); + } childSetCommitCallback("desc", LLPreview::onText, this); - childSetText("desc", item->getDescription()); childSetPrevalidate("desc", &LLTextValidate::validateASCIIPrintableNoPipe); return LLPreview::postBuild(); diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index 7a48f890e0..0476e785a5 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -223,7 +223,10 @@ void LLProgressView::setCancelButtonVisible(BOOL b, const std::string& label) // static void LLProgressView::onCancelButtonClicked(void*) { - if (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE) + // Quitting viewer here should happen only when "Quit" button is pressed while starting up. + // Check for startup state is used here instead of teleport state to avoid quitting when + // cancel is pressed while teleporting inside region (EXT-4911) + if (LLStartUp::getStartupState() < STATE_STARTED) { LLAppViewer::instance()->requestQuit(); } diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index fdf9e1df2e..fb78b6a415 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -1263,11 +1263,10 @@ bool LLToolPie::handleMediaClick(const LLPickInfo& pick) return false; LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL; - if(!mep) return false; - viewer_media_t media_impl = mep ? LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()) : NULL; + viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()); if (gSavedSettings.getBOOL("MediaOnAPrimUI")) { diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index c18628d6f0..8108eae7b9 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3554,9 +3554,15 @@ bool LLHaveCallingcard::operator()(LLInventoryCategory* cat, BOOL is_agent_mappable(const LLUUID& agent_id) { - return (LLAvatarActions::isFriend(agent_id) && - LLAvatarTracker::instance().getBuddyInfo(agent_id)->isOnline() && - LLAvatarTracker::instance().getBuddyInfo(agent_id)->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION) + const LLRelationship* buddy_info = NULL; + bool is_friend = LLAvatarActions::isFriend(agent_id); + + if (is_friend) + buddy_info = LLAvatarTracker::instance().getBuddyInfo(agent_id); + + return (buddy_info && + buddy_info->isOnline() && + buddy_info->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION) ); } @@ -6402,7 +6408,6 @@ class LLToolsSelectedScriptAction : public view_listener_t else { llwarns << "Failed to generate LLFloaterScriptQueue with action: " << action << llendl; - delete queue; } return true; } diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index f3bfc2e86c..3d153db733 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -5377,24 +5377,25 @@ LLVoiceClient::sessionState* LLVoiceClient::startUserIMSession(const LLUUID &uui // No session with user, need to start one. std::string uri = sipURIFromID(uuid); session = addSession(uri); + + llassert(session); + if (!session) return NULL; + session->mIsSpatial = false; session->mReconnect = false; session->mIsP2P = true; session->mCallerID = uuid; } - if(session) + if(session->mHandle.empty()) { - if(session->mHandle.empty()) - { - // Session isn't active -- start it up. - sessionCreateSendMessage(session, false, true); - } - else - { - // Session is already active -- start up text. - sessionTextConnectSendMessage(session); - } + // Session isn't active -- start it up. + sessionCreateSendMessage(session, false, true); + } + else + { + // Session is already active -- start up text. + sessionTextConnectSendMessage(session); } return session; diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby.xml b/indra/newview/skins/default/xui/en/menu_people_nearby.xml index c4da1df017..9d2ccba4da 100644 --- a/indra/newview/skins/default/xui/en/menu_people_nearby.xml +++ b/indra/newview/skins/default/xui/en/menu_people_nearby.xml @@ -20,6 +20,16 @@ parameter="can_add" /> </menu_item_call> <menu_item_call + label="Remove Friend" + layout="topleft" + name="Remove Friend"> + <menu_item_call.on_click + function="Avatar.RemoveFriend" /> + <menu_item_call.on_enable + function="Avatar.EnableItem" + parameter="can_delete" /> + </menu_item_call> + <menu_item_call label="IM" layout="topleft" name="IM"> diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml index 0d3dd3366d..588342595e 100644 --- a/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml +++ b/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml @@ -14,6 +14,16 @@ parameter="can_add" /> </menu_item_call> <menu_item_call + label="Remove Friends" + layout="topleft" + name="Remove Friend"> + <menu_item_call.on_click + function="Avatar.RemoveFriend" /> + <menu_item_call.on_enable + function="Avatar.EnableItem" + parameter="can_delete" /> + </menu_item_call> + <menu_item_call label="IM" layout="topleft" name="IM"> diff --git a/indra/newview/skins/default/xui/en/menu_profile_overflow.xml b/indra/newview/skins/default/xui/en/menu_profile_overflow.xml index 407ce14e81..5162a4902f 100644 --- a/indra/newview/skins/default/xui/en/menu_profile_overflow.xml +++ b/indra/newview/skins/default/xui/en/menu_profile_overflow.xml @@ -19,19 +19,22 @@ <menu_item_call.on_click function="Profile.Share" /> </menu_item_call> - <menu_item_check - label="Block/Unblock" - layout="topleft" - name="block_unblock"> - <menu_item_check.on_click - function="Profile.BlockUnblock" /> - <menu_item_check.on_check - function="Profile.CheckItem" - parameter="is_blocked" /> - <menu_item_check.on_enable - function="Profile.EnableItem" - parameter="can_block" /> - </menu_item_check> + <menu_item_call + label="Block" + name="block"> + <menu_item_call.on_click + function="Profile.BlockUnblock"/> + <menu_item_call.on_visible + function="Profile.EnableBlock" /> + </menu_item_call> + <menu_item_call + label="Unblock" + name="unblock"> + <menu_item_call.on_click + function="Profile.BlockUnblock"/> + <menu_item_call.on_visible + function="Profile.EnableUnblock" /> + </menu_item_call> <menu_item_call label="Kick" layout="topleft" |