From 70956fb2dbc42501d27a474e3f80003d591ee646 Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Sat, 14 Oct 2023 00:11:06 +0200 Subject: SL-20163 Allow residents to hide exact join date on profiles --- indra/newview/llavatarpropertiesprocessor.h | 1 + indra/newview/llpanelavatar.cpp | 42 ++++ indra/newview/llpanelavatar.h | 4 +- indra/newview/llpanelprofile.cpp | 225 ++++++++------------- indra/newview/llpanelprofile.h | 5 +- .../default/xui/en/panel_profile_secondlife.xml | 37 +++- 6 files changed, 165 insertions(+), 149 deletions(-) diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h index f4e4252e61..c2347b9e35 100644 --- a/indra/newview/llavatarpropertiesprocessor.h +++ b/indra/newview/llavatarpropertiesprocessor.h @@ -86,6 +86,7 @@ struct LLAvatarData U8 caption_index; std::string caption_text; std::string customer_type; + bool hide_sl_age; U32 flags; }; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index ff33efe4aa..626978f9fb 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -127,6 +127,48 @@ void LLPanelProfileTab::setApplyProgress(bool started) } } +static void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t httpHeaders; + + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + httpOpts->setFollowRedirects(true); + + std::string finalUrl = cap_url + "/" + agent_id.asString(); + + LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS("AvatarProperties") << "Failed to put agent information " << data << " for id " << agent_id << LL_ENDL; + return; + } + + LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Data: " << data << " Result: " << httpResults << LL_ENDL; +} + +bool LLPanelProfileTab::saveAgentUserInfoCoro(std::string name, LLSD value) const +{ + std::string cap_url = gAgent.getRegionCapability("AgentProfile"); + if (cap_url.empty()) + { + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; + return false; + } + + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with(name, value))); + + return true; +} + LLPanelProfilePropertiesProcessorTab::LLPanelProfilePropertiesProcessorTab() : LLPanelProfileTab() { diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index f182660c8e..572e1eb029 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -92,7 +92,7 @@ public: /** * Returns avatar ID. */ - virtual const LLUUID& getAvatarId() { return mAvatarId; } + virtual const LLUUID& getAvatarId() const { return mAvatarId; } /** * Sends update data request to server. @@ -133,6 +133,8 @@ protected: const bool getSelfProfile() const { return mSelfProfile; } + bool saveAgentUserInfoCoro(std::string name, LLSD value) const; + public: void setIsLoading() { mLoadingState = PROFILE_LOADING; } void resetLoading() { mLoadingState = PROFILE_INIT; } diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 3333c832d2..1d81586c15 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -191,6 +191,8 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) avatar_data->caption_text = result["caption"].asString(); } + avatar_data->hide_sl_age = result["hide_sl_age"].asBoolean(); + panel = floater_profile->findChild(PANEL_SECONDLIFE, TRUE); LLPanelProfileSecondLife *panel_sl = dynamic_cast(panel); if (panel_sl) @@ -274,38 +276,6 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) } } -//TODO: changes take two minutes to propagate! -// Add some storage that holds updated data for two minutes -// for new instances to reuse the data -// Profile data is only relevant to won avatar, but notes -// are for everybody -void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLCore::HttpHeaders::ptr_t httpHeaders; - - LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); - httpOpts->setFollowRedirects(true); - - std::string finalUrl = cap_url + "/" + agent_id.asString(); - - LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - if (!status) - { - LL_WARNS("AvatarProperties") << "Failed to put agent information " << data << " for id " << agent_id << LL_ENDL; - return; - } - - LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Data: " << data << " Result: " << httpResults << LL_ENDL; -} - LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::string path_to_image, LLHandle *handle) { LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); @@ -889,6 +859,7 @@ LLPanelProfileSecondLife::LLPanelProfileSecondLife() , mHasUnsavedDescriptionChanges(false) , mWaitingForImageUpload(false) , mAllowPublish(false) + , mHideSLAge(false) { } @@ -914,6 +885,7 @@ BOOL LLPanelProfileSecondLife::postBuild() { mGroupList = getChild("group_list"); mShowInSearchCombo = getChild("show_in_search"); + mHideSLAgeCombo = getChild("hide_sl_age"); mSecondLifePic = getChild("2nd_life_pic"); mSecondLifePicLayout = getChild("image_panel"); mDescriptionEdit = getChild("sl_description_edit"); @@ -928,6 +900,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mCantEditObjectsIcon = getChild("cant_edit_objects"); mShowInSearchCombo->setCommitCallback([this](LLUICtrl*, void*) { onShowInSearchCallback(); }, nullptr); + mHideSLAgeCombo->setCommitCallback([this](LLUICtrl*, void*) { onHideSLAgeCallback(); }, nullptr); mGroupList->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { LLPanelProfileSecondLife::openGroupProfile(); }); mGroupList->setReturnCallback([this](LLUICtrl*, const LLSD&) { LLPanelProfileSecondLife::openGroupProfile(); }); mSaveDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr); @@ -1202,7 +1175,7 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) // and to make sure icons in text will be up to date LLAvatarIconIDCache::getInstance()->add(avatar_data->avatar_id, avatar_data->image_id); - fillAgeData(avatar_data->born_on); + fillAgeData(avatar_data); setDescriptionText(avatar_data->about_text); @@ -1237,7 +1210,7 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) if (getSelfProfile()) { mAllowPublish = avatar_data->flags & AVATAR_ALLOW_PUBLISH; - mShowInSearchCombo->setValue((BOOL)mAllowPublish); + mShowInSearchCombo->setValue(mAllowPublish ? TRUE : FALSE); } } @@ -1362,21 +1335,44 @@ void LLPanelProfileSecondLife::fillRightsData() } } -void LLPanelProfileSecondLife::fillAgeData(const LLDate &born_on) +void LLPanelProfileSecondLife::fillAgeData(const LLAvatarData* avatar_data) { // Date from server comes already converted to stl timezone, // so display it as an UTC + 0 - std::string name_and_date = getString("date_format"); + std::string name_and_date = getString(avatar_data->hide_sl_age ? "date_format_short" : "date_format_full"); LLSD args_name; - args_name["datetime"] = (S32)born_on.secondsSinceEpoch(); + args_name["datetime"] = (S32)avatar_data->born_on.secondsSinceEpoch(); LLStringUtil::format(name_and_date, args_name); getChild("sl_birth_date")->setValue(name_and_date); - std::string register_date = getString("age_format"); - LLSD args_age; - args_age["[AGE]"] = LLDateUtil::ageFromDate(born_on, LLDate::now()); - LLStringUtil::format(register_date, args_age); - getChild("user_age")->setValue(register_date); + LLUICtrl* userAgeCtrl = getChild("user_age"); + if (avatar_data->hide_sl_age) + { + userAgeCtrl->setVisible(FALSE); + } + else + { + std::string register_date = getString("age_format"); + LLSD args_age; + args_age["[AGE]"] = LLDateUtil::ageFromDate(avatar_data->born_on, LLDate::now()); + LLStringUtil::format(register_date, args_age); + userAgeCtrl->setValue(register_date); + } + + if (getSelfProfile()) + { + F64 birth = avatar_data->born_on.secondsSinceEpoch(); + F64 now = LLDate::now().secondsSinceEpoch(); + if (now - birth > 365 * 24 * 60 * 60) + { + mHideSLAge = avatar_data->hide_sl_age; + mHideSLAgeCombo->setValue(mHideSLAge ? TRUE : FALSE); + } + else + { + mHideSLAgeCombo->setVisible(FALSE); + } + } } void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep) @@ -1493,6 +1489,10 @@ void LLPanelProfileSecondLife::setLoaded() if (getSelfProfile()) { mShowInSearchCombo->setEnabled(TRUE); + if (mHideSLAgeCombo->getVisible()) + { + mHideSLAgeCombo->setEnabled(TRUE); + } mDescriptionEdit->setEnabled(TRUE); } } @@ -1820,39 +1820,28 @@ void LLPanelProfileSecondLife::onSetDescriptionDirty() void LLPanelProfileSecondLife::onShowInSearchCallback() { - S32 value = mShowInSearchCombo->getValue().asInteger(); - if (mAllowPublish == (bool)value) - { + bool value = mShowInSearchCombo->getValue().asInteger(); + if (value == mAllowPublish) return; - } - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) - { - mAllowPublish = value; - LLSD data; - data["allow_publish"] = mAllowPublish; - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), data)); - } - else - { - LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; - } + + mAllowPublish = value; + saveAgentUserInfoCoro("allow_publish", value); +} + +void LLPanelProfileSecondLife::onHideSLAgeCallback() +{ + bool value = mHideSLAgeCombo->getValue().asInteger(); + if (value == mHideSLAge) + return; + + mHideSLAge = value; + saveAgentUserInfoCoro("hide_sl_age", value); } void LLPanelProfileSecondLife::onSaveDescriptionChanges() { mDescriptionText = mDescriptionEdit->getValue().asString(); - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) - { - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("sl_about_text", mDescriptionText))); - } - else - { - LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; - } + saveAgentUserInfoCoro("sl_about_text", mDescriptionText); mSaveDescriptionChanges->setEnabled(FALSE); mDiscardDescriptionChanges->setEnabled(FALSE); @@ -1987,46 +1976,34 @@ void LLPanelProfileSecondLife::onShowTexturePicker() void LLPanelProfileSecondLife::onCommitProfileImage(const LLUUID& id) { if (mImageId == id) - { return; - } - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) + if (!saveAgentUserInfoCoro("sl_image_id", id)) + return; + + mImageId = id; + if (mImageId == LLUUID::null) + { + mSecondLifePic->setValue("Generic_Person_Large"); + } + else { - LLSD params; - params["sl_image_id"] = id; - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); + mSecondLifePic->setValue(mImageId); + } - mImageId = id; + LLFloater *floater = mFloaterProfileTextureHandle.get(); + if (floater) + { + LLFloaterProfileTexture * texture_view = dynamic_cast(floater); if (mImageId == LLUUID::null) { - mSecondLifePic->setValue("Generic_Person_Large"); + texture_view->resetAsset(); } else { - mSecondLifePic->setValue(mImageId); - } - - LLFloater *floater = mFloaterProfileTextureHandle.get(); - if (floater) - { - LLFloaterProfileTexture * texture_view = dynamic_cast(floater); - if (mImageId == LLUUID::null) - { - texture_view->resetAsset(); - } - else - { - texture_view->loadAsset(mImageId); - } + texture_view->loadAsset(mImageId); } } - else - { - LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; - } } ////////////////////////////////////////////////////////////////////////// @@ -2324,34 +2301,22 @@ void LLPanelProfileFirstLife::onRemovePhoto() void LLPanelProfileFirstLife::onCommitPhoto(const LLUUID& id) { if (mImageId == id) - { return; - } - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) - { - LLSD params; - params["fl_image_id"] = id; - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); - - mImageId = id; - if (mImageId.notNull()) - { - mPicture->setValue(mImageId); - } - else - { - mPicture->setValue("Generic_Person_Large"); - } + if (!saveAgentUserInfoCoro("fl_image_id", id)) + return; - mRemovePhoto->setEnabled(mImageId.notNull()); + mImageId = id; + if (mImageId.notNull()) + { + mPicture->setValue(mImageId); } else { - LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; + mPicture->setValue("Generic_Person_Large"); } + + mRemovePhoto->setEnabled(mImageId.notNull()); } void LLPanelProfileFirstLife::setDescriptionText(const std::string &text) @@ -2374,16 +2339,7 @@ void LLPanelProfileFirstLife::onSetDescriptionDirty() void LLPanelProfileFirstLife::onSaveDescriptionChanges() { mCurrentDescription = mDescriptionEdit->getValue().asString(); - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) - { - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("fl_about_text", mCurrentDescription))); - } - else - { - LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; - } + saveAgentUserInfoCoro("fl_about_text", mCurrentDescription); mSaveChanges->setEnabled(FALSE); mDiscardChanges->setEnabled(FALSE); @@ -2517,16 +2473,7 @@ void LLPanelProfileNotes::onSetNotesDirty() void LLPanelProfileNotes::onSaveNotesChanges() { mCurrentNotes = mNotesEditor->getValue().asString(); - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) - { - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", mCurrentNotes))); - } - else - { - LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; - } + saveAgentUserInfoCoro("notes", mCurrentNotes); mSaveChanges->setEnabled(FALSE); mDiscardChanges->setEnabled(FALSE); diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index 11632a10ae..61ced27db5 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -143,7 +143,7 @@ protected: /** * Fills user name, display name, age. */ - void fillAgeData(const LLDate &born_on); + void fillAgeData(const LLAvatarData* avatar_data); void onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep); static void onImageLoaded(BOOL success, @@ -179,6 +179,7 @@ private: void setDescriptionText(const std::string &text); void onSetDescriptionDirty(); void onShowInSearchCallback(); + void onHideSLAgeCallback(); void onSaveDescriptionChanges(); void onDiscardDescriptionChanges(); void onShowAgentPermissionsDialog(); @@ -193,6 +194,7 @@ private: LLGroupList* mGroupList; LLComboBox* mShowInSearchCombo; + LLComboBox* mHideSLAgeCombo; LLThumbnailCtrl* mSecondLifePic; LLPanel* mSecondLifePicLayout; LLTextEditor* mDescriptionEdit; @@ -214,6 +216,7 @@ private: bool mVoiceStatus; bool mWaitingForImageUpload; bool mAllowPublish; + bool mHideSLAge; std::string mDescriptionText; LLUUID mImageId; diff --git a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml index d50a223dd0..26cc04e6af 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml @@ -5,7 +5,7 @@ top="0" left="0" height="480" - width="420" + width="440" follows="all" layout="topleft" > @@ -14,8 +14,11 @@ so display it as an UTC+0 --> + @@ -53,7 +56,7 @@ Account: [ACCTTYPE] top="8" left="6" bottom="-1" - width="160" + width="180" border_size="0" follows="left|top|bottom" layout="topleft" @@ -335,7 +338,7 @@ Account: [ACCTTYPE] left="1" top="25" height="25" - width="140" + width="176" label="Actions" halign="left" image_unselected="DropDown_Off" @@ -349,7 +352,7 @@ Account: [ACCTTYPE] name="settings_panel" follows="all" layout="topleft" - height="50" + height="80" auto_resize="false" user_resize="false"> @@ -359,10 +362,9 @@ Account: [ACCTTYPE] left="1" top="18" height="23" - width="140" + width="176" follows="left|top" layout="topleft" - visible="true" enabled="false"> + + + +