diff --git a/keyserver/src/push/send.js b/keyserver/src/push/send.js --- a/keyserver/src/push/send.js +++ b/keyserver/src/push/send.js @@ -11,7 +11,7 @@ import uuidv4 from 'uuid/v4.js'; import { oldValidUsernameRegex } from 'lib/shared/account-utils.js'; -import { isMentioned } from 'lib/shared/mention-utils.js'; +import { isUserMentioned } from 'lib/shared/mention-utils.js'; import { createMessageInfo, sortMessageInfoList, @@ -172,7 +172,7 @@ : newMessageInfo; return ( unwrappedMessageInfo.type === messageTypes.TEXT && - isMentioned(username, unwrappedMessageInfo.text) + isUserMentioned(username, unwrappedMessageInfo.text) ); }); if (!updateBadge && !displayBanner && !userWasMentioned) { diff --git a/lib/shared/markdown.js b/lib/shared/markdown.js --- a/lib/shared/markdown.js +++ b/lib/shared/markdown.js @@ -3,7 +3,7 @@ import invariant from 'invariant'; import { - markdownMentionRegex, + markdownUserMentionRegex, decodeChatMentionText, } from './mention-utils.js'; import type { @@ -197,7 +197,7 @@ }; } -function matchMentions( +function matchUserMentions( members: $ReadOnlyArray, ): MatchFunction { const memberSet = new Set( @@ -210,7 +210,7 @@ if (!state.inline) { return null; } - const result = markdownMentionRegex.exec(source); + const result = markdownUserMentionRegex.exec(source); if (!result) { return null; } @@ -221,7 +221,7 @@ } return result; }; - match.regex = markdownMentionRegex; + match.regex = markdownUserMentionRegex; return match; } @@ -339,7 +339,7 @@ jsonPrint, matchList, parseList, - matchMentions, + matchUserMentions, stripSpoilersFromNotifications, stripSpoilersFromMarkdownAST, parseChatMention, 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 @@ -23,12 +23,12 @@ +end: number, }; -type TypeaheadUserSuggestionItem = { +type MentionTypeaheadUserSuggestionItem = { +type: 'user', +userInfo: RelativeMemberInfo, }; -export type TypeaheadSuggestionItem = TypeaheadUserSuggestionItem; +export type MentionTypeaheadSuggestionItem = MentionTypeaheadUserSuggestionItem; export type TypeaheadTooltipActionItem = { +key: string, @@ -38,15 +38,15 @@ // The simple-markdown package already breaks words out for us, and we are // supposed to only match when the first word of the input matches -const markdownMentionRegex: RegExp = new RegExp( +const markdownUserMentionRegex: RegExp = new RegExp( `^(@(${oldValidUsernameRegexString}))\\b`, ); -function isMentioned(username: string, text: string): boolean { +function isUserMentioned(username: string, text: string): boolean { return new RegExp(`\\B@${username}\\b`, 'i').test(text); } -const mentionsExtractionRegex = new RegExp( +const userMentionsExtractionRegex = new RegExp( `\\B(@(${oldValidUsernameRegexString}))\\b`, 'g', ); @@ -58,8 +58,8 @@ return text.replace(/\\]/g, ']'); } -function extractMentionsFromText(text: string): string[] { - const iterator = text.matchAll(mentionsExtractionRegex); +function extractUserMentionsFromText(text: string): string[] { + const iterator = text.matchAll(userMentionsExtractionRegex); return [...iterator].map(matches => matches[2]); } @@ -77,12 +77,12 @@ return null; } -function getTypeaheadUserSuggestions( +function getMentionTypeaheadUserSuggestions( userSearchIndex: SearchIndex, threadMembers: $ReadOnlyArray, viewerID: ?string, usernamePrefix: string, -): $ReadOnlyArray { +): $ReadOnlyArray { const userIDs = userSearchIndex.getSearchResults(usernamePrefix); const usersInThread = threadOtherMembers(threadMembers, viewerID); @@ -115,7 +115,7 @@ return { newText, newSelectionStart }; } -function getMentionsCandidates( +function getUserMentionsCandidates( threadInfo: ThreadInfo, parentThreadInfo: ?ThreadInfo, ): $ReadOnlyArray { @@ -132,13 +132,13 @@ } export { - markdownMentionRegex, - isMentioned, - extractMentionsFromText, - getTypeaheadUserSuggestions, + markdownUserMentionRegex, + isUserMentioned, + extractUserMentionsFromText, + getMentionTypeaheadUserSuggestions, getNewTextAndSelection, getTypeaheadRegexMatches, - getMentionsCandidates, + getUserMentionsCandidates, chatMentionRegex, decodeChatMentionText, }; diff --git a/lib/shared/messages/text-message-spec.js b/lib/shared/messages/text-message-spec.js --- a/lib/shared/messages/text-message-spec.js +++ b/lib/shared/messages/text-message-spec.js @@ -40,7 +40,7 @@ stripSpoilersFromNotifications, stripSpoilersFromMarkdownAST, } from '../markdown.js'; -import { isMentioned } from '../mention-utils.js'; +import { isUserMentioned } from '../mention-utils.js'; import { notifTextsForSidebarCreation } from '../notif-utils.js'; import { threadIsGroupChat, @@ -213,7 +213,7 @@ if ( sourceMessage.type === messageTypes.TEXT && - isMentioned(username, sourceMessage.text) + isUserMentioned(username, sourceMessage.text) ) { // If the notif target was already mentioned in the source message, // there's no need to update the notif @@ -225,7 +225,7 @@ messageInfo.type === messageTypes.TEXT, 'messageInfo should be messageTypes.TEXT!', ); - if (!isMentioned(username, messageInfo.text)) { + if (!isUserMentioned(username, messageInfo.text)) { // We only need to update the notif if the notif target is mentioned return null; } diff --git a/lib/shared/notif-utils.js b/lib/shared/notif-utils.js --- a/lib/shared/notif-utils.js +++ b/lib/shared/notif-utils.js @@ -2,7 +2,7 @@ import invariant from 'invariant'; -import { isMentioned } from './mention-utils.js'; +import { isUserMentioned } from './mention-utils.js'; import { robotextForMessageInfo } from './message-utils.js'; import type { NotificationTextsParams } from './messages/message-spec.js'; import { messageSpecs } from './messages/message-specs.js'; @@ -177,13 +177,13 @@ username && sidebarSourceMessageInfo && sidebarSourceMessageInfo.sourceMessage.type === messageTypes.TEXT && - isMentioned(username, sidebarSourceMessageInfo.sourceMessage.text) + isUserMentioned(username, sidebarSourceMessageInfo.sourceMessage.text) ) { body = ET`${body} that tagged you`; } else if ( username && firstSidebarMessageInfo && - isMentioned(username, firstSidebarMessageInfo.text) + isUserMentioned(username, firstSidebarMessageInfo.text) ) { body = ET`${body} and tagged you`; } else if (initialName) { 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 @@ -9,7 +9,7 @@ import { generatePendingThreadColor } from './color-utils.js'; import { type ParserRules } from './markdown.js'; -import { extractMentionsFromText } from './mention-utils.js'; +import { extractUserMentionsFromText } from './mention-utils.js'; import { getMessageTitle } from './message-utils.js'; import { relationshipBlockedInEitherDirection } from './relationship-utils.js'; import threadWatcher from './thread-watcher.js'; @@ -447,7 +447,7 @@ threadInfo: ThreadInfo, ): Map { const memberMap = memberLowercaseUsernameMap(threadInfo.members); - const mentions = extractMentionsFromText(text); + const mentions = extractUserMentionsFromText(text); const mentionedMembers = new Map(); for (const mention of mentions) { 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 @@ -37,10 +37,10 @@ import { colorIsDark } from 'lib/shared/color-utils.js'; import { useEditMessage } from 'lib/shared/edit-messages-utils.js'; import { - getTypeaheadUserSuggestions, + getMentionTypeaheadUserSuggestions, getTypeaheadRegexMatches, type Selection, - getMentionsCandidates, + getUserMentionsCandidates, } from 'lib/shared/mention-utils.js'; import { localIDPrefix, @@ -130,7 +130,7 @@ import { runTiming } from '../utils/animation-utils.js'; import { exitEditAlert } from '../utils/edit-messages-utils.js'; import { - nativeTypeaheadRegex, + nativeMentionTypeaheadRegex, mentionTypeaheadTooltipActions, mentionTypeaheadTooltipButtonRenderer, } from '../utils/typeahead-utils.js'; @@ -172,7 +172,7 @@ +joinThread: (request: ClientThreadJoinRequest) => Promise, +inputState: ?InputState, +userSearchIndex: SearchIndex, - +mentionsCandidates: $ReadOnlyArray, + +userMentionsCandidates: $ReadOnlyArray, +parentThreadInfo: ?ThreadInfo, +editedMessagePreview: ?MessagePreviewResult, +editedMessageInfo: ?MessageInfo, @@ -548,7 +548,7 @@ const typeaheadRegexMatches = getTypeaheadRegexMatches( this.state.selectionState.text, this.state.selectionState.selection, - nativeTypeaheadRegex, + nativeMentionTypeaheadRegex, ); let typeaheadTooltip = null; @@ -559,9 +559,9 @@ textPrefix: typeaheadRegexMatches[4] ?? '', }; - const suggestedUsers = getTypeaheadUserSuggestions( + const suggestedUsers = getMentionTypeaheadUserSuggestions( this.props.userSearchIndex, - this.props.mentionsCandidates, + this.props.userMentionsCandidates, this.props.viewerID, typeaheadMatchedStrings.textPrefix, ); @@ -1260,7 +1260,7 @@ parentThreadID ? threadInfoSelector(state)[parentThreadID] : null, ); - const mentionsCandidates = getMentionsCandidates( + const userMentionsCandidates = getUserMentionsCandidates( props.threadInfo, parentThreadInfo, ); @@ -1298,7 +1298,7 @@ joinThread={callJoinThread} inputState={inputState} userSearchIndex={userSearchIndex} - mentionsCandidates={mentionsCandidates} + userMentionsCandidates={userMentionsCandidates} parentThreadInfo={parentThreadInfo} editedMessagePreview={editedMessagePreview} editedMessageInfo={editedMessageInfo} diff --git a/native/markdown/rules.react.js b/native/markdown/rules.react.js --- a/native/markdown/rules.react.js +++ b/native/markdown/rules.react.js @@ -382,9 +382,9 @@ ...baseRules, simpleMarkdownRules: { ...baseRules.simpleMarkdownRules, - mention: { + userMention: { ...SimpleMarkdown.defaultRules.strong, - match: SharedMarkdown.matchMentions(members), + match: SharedMarkdown.matchUserMentions(members), parse: (capture: SharedMarkdown.Capture) => ({ content: capture[0], }), 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 @@ -8,7 +8,7 @@ getNewTextAndSelection, type Selection, type TypeaheadTooltipActionItem, - type TypeaheadSuggestionItem, + type MentionTypeaheadSuggestionItem, } from 'lib/shared/mention-utils.js'; import { stringForUserExplicit } from 'lib/shared/user-utils.js'; @@ -17,7 +17,7 @@ // Native regex is a little bit different than web one as // there are no named capturing groups yet on native. -const nativeTypeaheadRegex: RegExp = new RegExp( +const nativeMentionTypeaheadRegex: RegExp = new RegExp( `((^(.|\n)*\\s+)|^)@(${oldValidUsernameRegexString})?$`, ); @@ -34,8 +34,8 @@ text, textPrefix, focusAndUpdateTextAndSelection, -}: TypeaheadTooltipActionsParams): $ReadOnlyArray< - TypeaheadTooltipActionItem, +}: TypeaheadTooltipActionsParams): $ReadOnlyArray< + TypeaheadTooltipActionItem, > { const actions = []; for (const suggestion of suggestions) { @@ -77,7 +77,7 @@ function mentionTypeaheadTooltipButtonRenderer({ item, styles, -}: TypeaheadTooltipButtonRendererParams): React.Node { +}: TypeaheadTooltipButtonRendererParams): React.Node { let avatarComponent = null; let typeaheadTooltipButtonText = null; if (item.actionButtonContent.type === 'user') { @@ -97,7 +97,7 @@ } export { - nativeTypeaheadRegex, + nativeMentionTypeaheadRegex, mentionTypeaheadTooltipActions, mentionTypeaheadTooltipButtonRenderer, }; diff --git a/web/chat/chat-input-bar.react.js b/web/chat/chat-input-bar.react.js --- a/web/chat/chat-input-bar.react.js +++ b/web/chat/chat-input-bar.react.js @@ -14,9 +14,9 @@ import { threadInfoSelector } from 'lib/selectors/thread-selectors.js'; import { userStoreSearchIndex } from 'lib/selectors/user-selectors.js'; import { - getTypeaheadUserSuggestions, + getMentionTypeaheadUserSuggestions, getTypeaheadRegexMatches, - getMentionsCandidates, + getUserMentionsCandidates, } from 'lib/shared/mention-utils.js'; import type { TypeaheadMatchedStrings } from 'lib/shared/mention-utils.js'; import { localIDPrefix, trimMessage } from 'lib/shared/message-utils.js'; @@ -56,7 +56,7 @@ import Multimedia from '../media/multimedia.react.js'; import { useSelector } from '../redux/redux-utils.js'; import { nonThreadCalendarQuery } from '../selectors/nav-selectors.js'; -import { webTypeaheadRegex } from '../utils/typeahead-utils.js'; +import { webMentionTypeaheadRegex } from '../utils/typeahead-utils.js'; type BaseProps = { +threadInfo: ThreadInfo, @@ -578,7 +578,7 @@ parentThreadID ? threadInfoSelector(state)[parentThreadID] : null, ); - const mentionsCandidates = getMentionsCandidates( + const userMentionsCandidates = getUserMentionsCandidates( props.threadInfo, parentThreadInfo, ); @@ -591,7 +591,7 @@ start: props.inputState.textCursorPosition, end: props.inputState.textCursorPosition, }, - webTypeaheadRegex, + webMentionTypeaheadRegex, ), [props.inputState.textCursorPosition, props.inputState.draft], ); @@ -612,11 +612,11 @@ if (props.inputState.typeaheadState.keepUpdatingThreadMembers) { const setter = props.inputState.setTypeaheadState; setter({ - frozenMentionsCandidates: mentionsCandidates, + frozenUserMentionsCandidates: userMentionsCandidates, }); } }, [ - mentionsCandidates, + userMentionsCandidates, props.inputState.setTypeaheadState, props.inputState.typeaheadState.keepUpdatingThreadMembers, ]); @@ -626,15 +626,15 @@ if (!typeaheadMatchedStrings) { return []; } - return getTypeaheadUserSuggestions( + return getMentionTypeaheadUserSuggestions( userSearchIndex, - props.inputState.typeaheadState.frozenMentionsCandidates, + props.inputState.typeaheadState.frozenUserMentionsCandidates, viewerID, typeaheadMatchedStrings.textPrefix, ).map(suggestion => suggestion.userInfo); }, [ userSearchIndex, - props.inputState.typeaheadState.frozenMentionsCandidates, + props.inputState.typeaheadState.frozenUserMentionsCandidates, viewerID, typeaheadMatchedStrings, ]); diff --git a/web/input/input-state-container.react.js b/web/input/input-state-container.react.js --- a/web/input/input-state-container.react.js +++ b/web/input/input-state-container.react.js @@ -175,7 +175,7 @@ typeaheadState: { canBeVisible: false, keepUpdatingThreadMembers: true, - frozenMentionsCandidates: [], + frozenUserMentionsCandidates: [], moveChoiceUp: null, moveChoiceDown: null, close: null, diff --git a/web/input/input-state.js b/web/input/input-state.js --- a/web/input/input-state.js +++ b/web/input/input-state.js @@ -42,7 +42,7 @@ export type TypeaheadState = { +canBeVisible: boolean, +keepUpdatingThreadMembers: boolean, - +frozenMentionsCandidates: $ReadOnlyArray, + +frozenUserMentionsCandidates: $ReadOnlyArray, +moveChoiceUp: ?() => void, +moveChoiceDown: ?() => void, +close: ?() => void, diff --git a/web/markdown/rules.react.js b/web/markdown/rules.react.js --- a/web/markdown/rules.react.js +++ b/web/markdown/rules.react.js @@ -187,9 +187,9 @@ ...baseRules, simpleMarkdownRules: { ...baseRules.simpleMarkdownRules, - mention: { + userMention: { ...SimpleMarkdown.defaultRules.strong, - match: SharedMarkdown.matchMentions(members), + match: SharedMarkdown.matchUserMentions(members), parse: (capture: SharedMarkdown.Capture) => ({ content: capture[0], }), diff --git a/web/utils/typeahead-utils.js b/web/utils/typeahead-utils.js --- a/web/utils/typeahead-utils.js +++ b/web/utils/typeahead-utils.js @@ -14,7 +14,7 @@ import css from '../chat/typeahead-tooltip.css'; import Button from '../components/button.react.js'; -const webTypeaheadRegex: RegExp = new RegExp( +const webMentionTypeaheadRegex: RegExp = new RegExp( `(?(?:^(?:.|\n)*\\s+)|^)@(?${oldValidUsernameRegexString})?$`, ); @@ -206,7 +206,7 @@ } export { - webTypeaheadRegex, + webMentionTypeaheadRegex, getCaretOffsets, getTypeaheadTooltipActions, getTypeaheadTooltipButtons,