summaryrefslogtreecommitdiff
path: root/indra/newview/llfloaterchatmentionpicker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llfloaterchatmentionpicker.cpp')
-rw-r--r--indra/newview/llfloaterchatmentionpicker.cpp184
1 files changed, 184 insertions, 0 deletions
diff --git a/indra/newview/llfloaterchatmentionpicker.cpp b/indra/newview/llfloaterchatmentionpicker.cpp
new file mode 100644
index 0000000000..1cfed122a9
--- /dev/null
+++ b/indra/newview/llfloaterchatmentionpicker.cpp
@@ -0,0 +1,184 @@
+/**
+ * @file llfloaterchatmentionpicker.cpp
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2025, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterchatmentionpicker.h"
+
+#include "llavatarlist.h"
+#include "llfloaterimcontainer.h"
+#include "llchatmentionhelper.h"
+#include "llparticipantlist.h"
+
+LLUUID LLFloaterChatMentionPicker::sSessionID(LLUUID::null);
+
+LLFloaterChatMentionPicker::LLFloaterChatMentionPicker(const LLSD& key)
+: LLFloater(key), mAvatarList(NULL)
+{
+ // This floater should hover on top of our dependent (with the dependent having the focus)
+ setFocusStealsFrontmost(false);
+ setBackgroundVisible(false);
+ setAutoFocus(false);
+}
+
+bool LLFloaterChatMentionPicker::postBuild()
+{
+ mAvatarList = getChild<LLAvatarList>("avatar_list");
+ mAvatarList->setShowCompleteName(true, true);
+ mAvatarList->setFocusOnItemClicked(false);
+ mAvatarList->setItemClickedCallback([this](LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
+ {
+ if (LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(ctrl))
+ {
+ selectResident(item->getAvatarId());
+ }
+ });
+ mAvatarList->setRefreshCompleteCallback([this](LLUICtrl* ctrl, const LLSD& param)
+ {
+ if (mAvatarList->numSelected() == 0)
+ {
+ mAvatarList->selectFirstItem();
+ }
+ });
+
+ return LLFloater::postBuild();
+}
+
+void LLFloaterChatMentionPicker::onOpen(const LLSD& key)
+{
+ buildAvatarList();
+ mAvatarList->setNameFilter(key.has("av_name") ? key["av_name"].asString() : "");
+
+ gFloaterView->adjustToFitScreen(this, false);
+}
+
+uuid_vec_t LLFloaterChatMentionPicker::getParticipantIds()
+{
+ LLParticipantList* item = dynamic_cast<LLParticipantList*>(LLFloaterIMContainer::getInstance()->getSessionModel(sSessionID));
+ if (!item)
+ {
+ LL_WARNS() << "Participant list is missing" << LL_ENDL;
+ return {};
+ }
+
+ uuid_vec_t avatar_ids;
+ LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
+ LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
+ while (current_participant_model != end_participant_model)
+ {
+ LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
+ if (participant_model)
+ {
+ avatar_ids.push_back(participant_model->getUUID());
+ }
+ current_participant_model++;
+ }
+ return avatar_ids;
+}
+
+void LLFloaterChatMentionPicker::buildAvatarList()
+{
+ uuid_vec_t& avatar_ids = mAvatarList->getIDs();
+ avatar_ids = getParticipantIds();
+ updateAvatarList(avatar_ids);
+ mAvatarList->setDirty();
+}
+
+void LLFloaterChatMentionPicker::selectResident(const LLUUID& id)
+{
+ if (id.isNull())
+ return;
+
+ setValue(stringize("secondlife:///app/agent/", id.asString(), "/mention "));
+ onCommit();
+ LLChatMentionHelper::instance().hideHelper();
+}
+
+void LLFloaterChatMentionPicker::onClose(bool app_quitting)
+{
+ if (!app_quitting)
+ {
+ LLChatMentionHelper::instance().hideHelper();
+ }
+}
+
+bool LLFloaterChatMentionPicker::handleKey(KEY key, MASK mask, bool called_from_parent)
+{
+ if (mask == MASK_NONE)
+ {
+ switch (key)
+ {
+ case KEY_UP:
+ case KEY_DOWN:
+ return mAvatarList->handleKey(key, mask, called_from_parent);
+ case KEY_RETURN:
+ case KEY_TAB:
+ selectResident(mAvatarList->getSelectedUUID());
+ return true;
+ case KEY_ESCAPE:
+ LLChatMentionHelper::instance().hideHelper();
+ return true;
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ return true;
+ default:
+ break;
+ }
+ }
+ return LLFloater::handleKey(key, mask, called_from_parent);
+}
+
+void LLFloaterChatMentionPicker::goneFromFront()
+{
+ LLChatMentionHelper::instance().hideHelper();
+}
+
+void LLFloaterChatMentionPicker::updateSessionID(LLUUID session_id)
+{
+ sSessionID = session_id;
+
+ LLParticipantList* item = dynamic_cast<LLParticipantList*>(LLFloaterIMContainer::getInstance()->getSessionModel(sSessionID));
+ if (!item)
+ {
+ LL_WARNS() << "Participant list is missing" << LL_ENDL;
+ return;
+ }
+
+ uuid_vec_t avatar_ids = getParticipantIds();
+ updateAvatarList(avatar_ids);
+}
+
+void LLFloaterChatMentionPicker::updateAvatarList(uuid_vec_t& avatar_ids)
+{
+ std::vector<std::string> av_names;
+ for (auto& id : avatar_ids)
+ {
+ LLAvatarName av_name;
+ LLAvatarNameCache::get(id, &av_name);
+ av_names.push_back(utf8str_tolower(av_name.getAccountName()));
+ av_names.push_back(utf8str_tolower(av_name.getDisplayName()));
+ }
+ LLChatMentionHelper::instance().updateAvatarList(av_names);
+}