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 @@ -8,6 +8,7 @@ import { type ThreadInfo, type RelativeMemberInfo, + type ResolvedThreadInfo, } from '../types/thread-types.js'; import { idSchemaRegex } from '../utils/validation-utils.js'; @@ -26,7 +27,14 @@ +userInfo: RelativeMemberInfo, }; -export type MentionTypeaheadSuggestionItem = MentionTypeaheadUserSuggestionItem; +type MentionTypeaheadChatSuggestionItem = { + +type: 'chat', + +threadInfo: ResolvedThreadInfo, +}; + +export type MentionTypeaheadSuggestionItem = + | MentionTypeaheadUserSuggestionItem + | MentionTypeaheadChatSuggestionItem; export type TypeaheadTooltipActionItem = { +key: string, @@ -60,6 +68,10 @@ return text.replace(/\\]/g, ']'); } +function getRawChatMention(threadInfo: ResolvedThreadInfo): string { + return `@[[${threadInfo.id}:${encodeChatMentionText(threadInfo.uiName)}]]`; +} + function extractUserMentionsFromText(text: string): string[] { const iterator = text.matchAll(userMentionsExtractionRegex); return [...iterator].map(matches => matches[2]); @@ -144,4 +156,5 @@ chatMentionRegex, encodeChatMentionText, decodeChatMentionText, + getRawChatMention, }; diff --git a/native/chat/chat-input-bar.react.js b/native/chat/chat-input-bar.react.js --- a/native/chat/chat-input-bar.react.js +++ b/native/chat/chat-input-bar.react.js @@ -69,11 +69,11 @@ } from 'lib/types/message-types.js'; import type { Dispatch } from 'lib/types/redux-types.js'; import { threadPermissions } from 'lib/types/thread-permission-types.js'; -import { - type ThreadInfo, - type ClientThreadJoinRequest, - type ThreadJoinPayload, - type RelativeMemberInfo, +import type { + ThreadInfo, + ClientThreadJoinRequest, + ThreadJoinPayload, + RelativeMemberInfo, } from 'lib/types/thread-types.js'; import { type UserInfos } from 'lib/types/user-types.js'; import { diff --git a/native/utils/typeahead-utils.js b/native/utils/typeahead-utils.js --- a/native/utils/typeahead-utils.js +++ b/native/utils/typeahead-utils.js @@ -5,6 +5,7 @@ import { oldValidUsernameRegexString } from 'lib/shared/account-utils.js'; import { getNewTextAndSelection, + getRawChatMention, type Selection, type TypeaheadTooltipActionItem, type MentionTypeaheadSuggestionItem, @@ -24,6 +25,24 @@ +query: string, +focusAndUpdateTextAndSelection: (text: string, selection: Selection) => void, }; +function mentionTypeaheadTooltipActionExecuteHandler({ + textBeforeAtSymbol, + text, + query, + mentionText, + focusAndUpdateTextAndSelection, +}) { + const { newText, newSelectionStart } = getNewTextAndSelection( + textBeforeAtSymbol, + text, + query, + mentionText, + ); + focusAndUpdateTextAndSelection(newText, { + start: newSelectionStart, + end: newSelectionStart, + }); +} function mentionTypeaheadTooltipActions({ suggestions, textBeforeAtSymbol, @@ -44,23 +63,37 @@ const mentionText = `@${resolvedUsername}`; actions.push({ key: userInfo.id, - execute: () => { - const { newText, newSelectionStart } = getNewTextAndSelection( + execute: () => + mentionTypeaheadTooltipActionExecuteHandler({ textBeforeAtSymbol, text, query, mentionText, - ); - focusAndUpdateTextAndSelection(newText, { - start: newSelectionStart, - end: newSelectionStart, - }); - }, + focusAndUpdateTextAndSelection, + }), actionButtonContent: { type: 'user', userInfo, }, }); + } else if (suggestion.type === 'chat') { + const { threadInfo } = suggestion; + const mentionText = getRawChatMention(threadInfo); + actions.push({ + key: threadInfo.id, + execute: () => + mentionTypeaheadTooltipActionExecuteHandler({ + textBeforeAtSymbol, + text, + query, + mentionText, + focusAndUpdateTextAndSelection, + }), + actionButtonContent: { + type: 'chat', + threadInfo, + }, + }); } } return actions;