From c40d3351d511b19f4468f7467be38499bf16588f Mon Sep 17 00:00:00 2001
From: Kitty Barnett <develop@catznip.com>
Date: Wed, 2 Nov 2022 19:05:24 +0100
Subject: [PATCH] Commit immediately if the user already typed a full shortcode

---
 indra/llui/llemojidictionary.cpp | 17 +++++++++++++----
 indra/llui/llemojidictionary.h   |  6 ++++--
 indra/llui/llemojihelper.cpp     |  8 ++++++++
 indra/llui/lltextbase.cpp        |  1 +
 4 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/indra/llui/llemojidictionary.cpp b/indra/llui/llemojidictionary.cpp
index eefa4047a20..c31638b0bf2 100644
--- a/indra/llui/llemojidictionary.cpp
+++ b/indra/llui/llemojidictionary.cpp
@@ -175,17 +175,26 @@ LLWString LLEmojiDictionary::findMatchingEmojis(const std::string& needle) const
 	return result;
 }
 
-std::string LLEmojiDictionary::getNameFromEmoji(llwchar ch)
+const LLEmojiDescriptor* LLEmojiDictionary::getDescriptorFromShortCode(const std::string& short_code) const
+{
+	const auto it = mShortCode2Descr.find(short_code);
+	return (mShortCode2Descr.end() != it) ? &it->second : nullptr;
+}
+
+std::string LLEmojiDictionary::getNameFromEmoji(llwchar ch) const
 {
 	const auto it = mEmoji2Descr.find(ch);
-	return (mEmoji2Descr.end() != it) ? it->second->Name : LLStringUtil::null;
+	return (mEmoji2Descr.end() != it) ? it->second.Name : LLStringUtil::null;
 }
 
 void LLEmojiDictionary::addEmoji(LLEmojiDescriptor&& descr)
 {
 	mEmojis.push_back(descr);
-	const LLEmojiDescriptor& back = mEmojis.back();
-	mEmoji2Descr.insert(std::make_pair(descr.Character, &back));
+	mEmoji2Descr.insert(std::make_pair(descr.Character, mEmojis.back()));
+	for (const std::string& shortCode : descr.ShortCodes)
+	{
+		mShortCode2Descr.insert(std::make_pair(shortCode, mEmojis.back()));
+	}
 }
 
 // ============================================================================
diff --git a/indra/llui/llemojidictionary.h b/indra/llui/llemojidictionary.h
index 3fa55cd4172..0cde6637196 100644
--- a/indra/llui/llemojidictionary.h
+++ b/indra/llui/llemojidictionary.h
@@ -58,14 +58,16 @@ class LLEmojiDictionary : public LLParamSingleton<LLEmojiDictionary>, public LLI
 public:
 	static void initClass();
 	LLWString   findMatchingEmojis(const std::string& needle) const;
-	std::string getNameFromEmoji(llwchar ch);
+	const LLEmojiDescriptor* getDescriptorFromShortCode(const std::string& short_code) const;
+	std::string getNameFromEmoji(llwchar ch) const;
 
 private:
 	void addEmoji(LLEmojiDescriptor&& descr);
 
 private:
 	std::list<LLEmojiDescriptor> mEmojis;
-	std::map<llwchar, const LLEmojiDescriptor*> mEmoji2Descr;
+	std::map<llwchar, const LLEmojiDescriptor&> mEmoji2Descr;
+	std::map<std::string, const LLEmojiDescriptor&> mShortCode2Descr;
 };
 
 // ============================================================================
diff --git a/indra/llui/llemojihelper.cpp b/indra/llui/llemojihelper.cpp
index 551f0331e79..32471e59a84 100644
--- a/indra/llui/llemojihelper.cpp
+++ b/indra/llui/llemojihelper.cpp
@@ -83,6 +83,14 @@ bool LLEmojiHelper::isCursorInEmojiCode(const LLWString& wtext, S32 cursorPos, S
 
 void LLEmojiHelper::showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, const std::string& short_code, std::function<void(LLWString)> cb)
 {
+	// Commit immediately if the user already typed a full shortcode
+	if (const auto* emojiDescrp = LLEmojiDictionary::instance().getDescriptorFromShortCode(short_code))
+	{
+		cb(LLWString(1, emojiDescrp->Character));
+		hideHelper();
+		return;
+	}
+
 	if (mHelperHandle.isDead())
 	{
 		LLFloater* pHelperFloater = LLFloaterReg::getInstance(DEFAULT_EMOJI_HELPER_FLOATER);
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 693dcb7b8da..b88c7ced40a 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -29,6 +29,7 @@
 
 #include "lltextbase.h"
 
+#include "llemojihelper.h"
 #include "lllocalcliprect.h"
 #include "llmenugl.h"
 #include "llscrollcontainer.h"
-- 
GitLab