summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan "Geenz" Goodman <geenz@lindenlab.com>2026-05-20 11:35:24 -0400
committerGitHub <noreply@github.com>2026-05-20 11:35:24 -0400
commit491b0b32c74e2186dd34f9be8513bb08d390dfe2 (patch)
treefdd37805842de5ba6f3db69c5699b727388ff50a
parentcd2dd394b95361a6a274670c7b7ee8c6f2cf8979 (diff)
parentd53041d9ea1687febf2d9e7c38ac5d4be3c8eae0 (diff)
Merge pull request #5842 from secondlife/release/2026.03
Release/2026.03
-rw-r--r--indra/llui/lluictrlfactory.cpp2
-rw-r--r--indra/llui/lluictrlfactory.h11
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/llappviewer.cpp2
-rw-r--r--indra/newview/llconversationloglist.cpp65
-rw-r--r--indra/newview/llconversationloglist.h10
-rw-r--r--indra/newview/llfloaterconversationlog.cpp8
-rw-r--r--indra/newview/llfloaterimcontainer.cpp2
-rw-r--r--indra/newview/skins/default/xui/en/menu_conversation_log_view.xml10
9 files changed, 111 insertions, 10 deletions
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index 33ffc3dfc6..740f187ed8 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -67,7 +67,7 @@ public:
static LLDefaultChildRegistry::Register<LLUICtrlLocate> r1("locate");
// Build time optimization, generate this once in .cpp file
-template class LLUICtrlFactory* LLSingleton<class LLUICtrlFactory>::getInstance();
+template class LLUICtrlFactory* LLSimpleton<class LLUICtrlFactory>::getInstance();
//-----------------------------------------------------------------------------
// LLUICtrlFactory()
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index f44b4ba4dc..75cee5f004 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -81,12 +81,13 @@ class LLWidgetNameRegistry
// Build time optimization, generate this once in .cpp file
#ifndef LLUICTRLFACTORY_CPP
-extern template class LLUICtrlFactory* LLSingleton<class LLUICtrlFactory>::getInstance();
+extern template class LLUICtrlFactory* LLSimpleton<class LLUICtrlFactory>::getInstance();
#endif
-class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
+class LLUICtrlFactory : public LLSimpleton<LLUICtrlFactory>
{
- LLSINGLETON(LLUICtrlFactory);
+public:
+ LLUICtrlFactory();
~LLUICtrlFactory();
// only partial specialization allowed in inner classes, so use extra dummy parameter
@@ -313,6 +314,10 @@ template<typename T>
LLChildRegistry<DERIVED>::Register<T>::Register(const char* tag, LLWidgetCreatorFunc func)
: LLChildRegistry<DERIVED>::StaticRegistrar(tag, func == nullptr ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder<T> : func)
{
+ if (!LLUICtrlFactory::instanceExists())
+ {
+ LLUICtrlFactory::createInstance();
+ }
// add this widget to various registries
LLUICtrlFactory::instance().registerWidget(typeid(T), typeid(typename T::Params), tag);
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index c41a1e5b88..931abeb7ab 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -11129,6 +11129,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>ShowBlockedConvHistory</key>
+ <map>
+ <key>Comment</key>
+ <string>Specifies whether blocked agents will be shown in Call Log</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>ShowMatureEvents</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 59b8ff5c70..bea275bf82 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2144,6 +2144,8 @@ bool LLAppViewer::cleanup()
// deleteSingleton() methods.
LLSingletonBase::deleteAll();
+ LLUICtrlFactory::deleteSingleton();
+
LLSplashScreen::hide();
LL_INFOS() << "Goodbye!" << LL_ENDL;
diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
index 65863f0a5e..e9c6df3ed8 100644
--- a/indra/newview/llconversationloglist.cpp
+++ b/indra/newview/llconversationloglist.cpp
@@ -45,6 +45,7 @@ LLConversationLogList::LLConversationLogList(const Params& p)
mIsDirty(true)
{
LLConversationLog::instance().addObserver(this);
+ LLMuteList::instance().addObserver(this);
// Set up context menu.
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
@@ -65,6 +66,15 @@ LLConversationLogList::LLConversationLogList(const Params& p)
}
mIsFriendsOnTop = gSavedSettings.getBOOL("SortFriendsFirst");
+ LLControlVariable* cntrl_ptr = gSavedSettings.getControl("ShowBlockedConvHistory");
+ if (cntrl_ptr)
+ {
+ mShowBlockedSignal = cntrl_ptr->getCommitSignal()->connect(
+ [this](LLControlVariable* control, const LLSD& value, const LLSD& previous)
+ {
+ setDirty(true);
+ });
+ }
}
LLConversationLogList::~LLConversationLogList()
@@ -74,6 +84,7 @@ LLConversationLogList::~LLConversationLogList()
mContextMenu.get()->die();
}
+ LLMuteList::getInstance()->removeObserver(this);
LLConversationLog::instance().removeObserver(this);
}
@@ -178,6 +189,44 @@ void LLConversationLogList::changed(const LLUUID& session_id, U32 mask)
}
}
+// inherited from LLMuteListObserver
+void LLConversationLogList::onChange()
+{
+}
+
+// inherited from LLMuteListObserver
+void LLConversationLogList::onChangeDetailed(const LLMute& mute)
+{
+ if (isDirty())
+ {
+ // Going to refresh either way.
+ return;
+ }
+
+ static LLCachedControl<bool> show_blocked(gSavedSettings, "ShowBlockedConvHistory", false);
+ if (!show_blocked())
+ {
+ // Check if any conversation in the log has this participant
+ const std::vector<LLConversation>& conversations = LLConversationLog::instance().getConversations();
+
+ // Note sure if actually need this update. List can be rather large
+ // and rebuilding it on every event can be expensive.
+ // But 'mute' events are also rare, so maybe not a problem.
+ // There also might be a way to react only to relevant changes,
+ // instead of reacting to everything, like ignoring voice only mutes,
+ // which are not relevant for this log by themselves.
+ for (const LLConversation& conversation : conversations)
+ {
+ if (conversation.getParticipantID() == mute.mID)
+ {
+ setDirty(true);
+ break;
+ }
+ }
+ }
+ // else don't need to hide anything
+}
+
void LLConversationLogList::addNewItem(const LLConversation* conversation)
{
LLConversationLogListItem* item = new LLConversationLogListItem(&*conversation);
@@ -207,6 +256,9 @@ void LLConversationLogList::rebuildList()
const std::vector<LLConversation>& conversations = log_instance.getConversations();
std::vector<LLConversation>::const_iterator iter = conversations.begin();
+ LLMuteList* mutes = LLMuteList::getInstance();
+
+ static LLCachedControl<bool> show_blocked(gSavedSettings, "ShowBlockedConvHistory", false);
for (; iter != conversations.end(); ++iter)
{
@@ -214,6 +266,11 @@ void LLConversationLogList::rebuildList()
if (not_found)
continue;
+ if (!show_blocked() && mutes->isMuted(iter->getParticipantID()))
+ {
+ continue;
+ }
+
addNewItem(&*iter);
}
@@ -517,8 +574,8 @@ bool LLConversationLogListNameComparator::doCompare(const LLConversationLogListI
LLStringUtil::toUpper(name1);
LLStringUtil::toUpper(name2);
- bool friends_first = gSavedSettings.getBOOL("SortFriendsFirst");
- if (friends_first && (LLAvatarActions::isFriend(id1) ^ LLAvatarActions::isFriend(id2)))
+ static LLCachedControl<bool> sort_friends_first(gSavedSettings, "SortFriendsFirst", true);
+ if (sort_friends_first() && (LLAvatarActions::isFriend(id1) ^ LLAvatarActions::isFriend(id2)))
{
return LLAvatarActions::isFriend(id1);
}
@@ -533,8 +590,8 @@ bool LLConversationLogListDateComparator::doCompare(const LLConversationLogListI
const LLUUID& id1 = conversation1->getConversation()->getParticipantID();
const LLUUID& id2 = conversation2->getConversation()->getParticipantID();
- bool friends_first = gSavedSettings.getBOOL("SortFriendsFirst");
- if (friends_first && (LLAvatarActions::isFriend(id1) ^ LLAvatarActions::isFriend(id2)))
+ static LLCachedControl<bool> sort_friends_first(gSavedSettings, "SortFriendsFirst", true);
+ if (sort_friends_first() && (LLAvatarActions::isFriend(id1) ^ LLAvatarActions::isFriend(id2)))
{
return LLAvatarActions::isFriend(id1);
}
diff --git a/indra/newview/llconversationloglist.h b/indra/newview/llconversationloglist.h
index 6372f6c9a3..39f129c9f1 100644
--- a/indra/newview/llconversationloglist.h
+++ b/indra/newview/llconversationloglist.h
@@ -39,7 +39,7 @@ class LLConversationLogListItem;
* it's always in actual state.
*/
-class LLConversationLogList: public LLFlatListViewEx, public LLConversationLogObserver
+class LLConversationLogList: public LLFlatListViewEx, public LLConversationLogObserver, public LLMuteListObserver
{
LOG_CLASS(LLConversationLogList);
public:
@@ -76,6 +76,12 @@ public:
virtual void changed();
virtual void changed(const LLUUID& session_id, U32 mask);
+ /**
+ * Changes from LLMuteListObserver
+ */
+ virtual void onChange();
+ virtual void onChangeDetailed(const LLMute& mute);
+
private:
void setDirty(bool dirty = true) { mIsDirty = dirty; }
@@ -104,6 +110,8 @@ private:
bool mIsDirty;
bool mIsFriendsOnTop;
std::string mNameFilter;
+
+ boost::signals2::scoped_connection mShowBlockedSignal;
};
/**
diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp
index 97399c9cf7..40e2d2bf1e 100644
--- a/indra/newview/llfloaterconversationlog.cpp
+++ b/indra/newview/llfloaterconversationlog.cpp
@@ -100,6 +100,10 @@ void LLFloaterConversationLog::onCustomAction (const LLSD& userdata)
{
mConversationLogList->toggleSortFriendsOnTop();
}
+ else if ("show_blocked" == command_name)
+ {
+ gSavedSettings.setBOOL("ShowBlockedConvHistory", !gSavedSettings.getBOOL("ShowBlockedConvHistory"));
+ }
else if ("view_nearby_chat_history" == command_name)
{
LLFloaterReg::showInstance("preview_conversation", LLSD(LLUUID::null), true);
@@ -129,6 +133,10 @@ bool LLFloaterConversationLog::isActionChecked(const LLSD& userdata)
{
return gSavedSettings.getBOOL("SortFriendsFirst");
}
+ else if ("show_blocked" == command_name)
+ {
+ return gSavedSettings.getBOOL("ShowBlockedConvHistory");
+ }
return false;
}
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index a0f2dbe197..e80133f93c 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1948,7 +1948,7 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
mConversationEventQueue.erase(uuid);
// Don't let the focus fall IW, select and refocus on the first conversation in the list
- if (change_focus && isInVisibleChain())
+ if (change_focus && is_widget_selected && isInVisibleChain())
{
setFocus(true);
if (new_selection)
diff --git a/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml
index 864bec5d9a..1e10a984da 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml
@@ -34,6 +34,16 @@
function="CallLog.Check"
parameter="sort_friends_on_top" />
</menu_item_check>
+ <menu_item_check
+ label="Show muted"
+ name="show_muted">
+ <on_click
+ function="CallLog.Action"
+ parameter="show_blocked" />
+ <on_check
+ function="CallLog.Check"
+ parameter="show_blocked" />
+ </menu_item_check>
<menu_item_separator />
<menu_item_call
label="View Nearby chat history..."