diff --git a/lib/shared/mention-utils.js b/lib/shared/mention-utils.js --- a/lib/shared/mention-utils.js +++ b/lib/shared/mention-utils.js @@ -5,6 +5,7 @@ import { threadOtherMembers, validChatNameRegexString, + extractThreadID, } from './thread-utils.js'; import { stringForUserExplicit } from './user-utils.js'; import { threadTypes } from '../types/thread-types-enum.js'; @@ -14,6 +15,7 @@ ResolvedThreadInfo, ChatMentionCandidates, } from '../types/thread-types.js'; +import { ET, entityTextToRawString } from '../utils/entity-text.js'; export type TypeaheadMatchedStrings = { +textBeforeAtSymbol: string, @@ -60,8 +62,54 @@ 'g', ); -const chatMentionRegexString = `^(? { + const matches = text.matchAll(globalChatMentionRegex); + if (!matches) { + return []; + } + const result = []; + for (const match of matches) { + result.push({ + threadID: match[2], + defaultText: match[3], + }); + } + return result; +} + +function renderChatMentions( + text: string, + threadInfos: { +[idWithoutKeyserverPrefix: string]: ThreadInfo }, + mentionableThreadIDs: $ReadOnlySet, +): string { + const matches = text.matchAll(globalChatMentionRegex); + if (!matches) { + return text; + } + let newText = text; + for (const match of matches) { + const threadID = extractThreadID(match[2]); + if (mentionableThreadIDs.has(threadID) && threadInfos[threadID]) { + const mentionedThreadInfo = threadInfos[threadID]; + const thread = ET.thread({ + display: 'uiName', + threadInfo: mentionedThreadInfo, + }); + const threadName = entityTextToRawString(ET`${thread}`); + newText = newText.replace(match[0], `@${threadName}`); + } else { + newText = newText.replace(match[0], `@${match[3]}`); + } + } + return newText; +} function encodeChatMentionText(text: string): string { return text.replace(/]/g, '\\]'); @@ -174,4 +222,6 @@ chatMentionRegex, encodeChatMentionText, decodeChatMentionText, + extractChatMentions, + renderChatMentions, }; diff --git a/lib/shared/thread-utils.js b/lib/shared/thread-utils.js --- a/lib/shared/thread-utils.js +++ b/lib/shared/thread-utils.js @@ -1798,6 +1798,10 @@ return chatMentionCandidatesSearchIndex[threadInfo.id]; } +function extractThreadID(threadID: string): string { + return threadID.slice(threadID.indexOf('|') + 1); +} + export { threadHasPermission, viewerIsMember, @@ -1870,4 +1874,5 @@ useChatMentionCandidatesObj, useThreadChatMentionCandidates, useThreadChatMentionSearchIndex, + extractThreadID, };