Page MenuHomePhabricator

D8945.id30622.diff
No OneTemporary

D8945.id30622.diff

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
@@ -17,6 +17,7 @@
getMentionTypeaheadUserSuggestions,
getTypeaheadRegexMatches,
getUserMentionsCandidates,
+ getMentionTypeaheadChatSuggestions,
type MentionTypeaheadSuggestionItem,
type TypeaheadMatchedStrings,
} from 'lib/shared/mention-utils.js';
@@ -27,6 +28,8 @@
threadFrozenDueToViewerBlock,
threadActualMembers,
checkIfDefaultMembersAreVoiced,
+ useThreadChatMentionCandidates,
+ useThreadChatMentionSearchIndex,
} from 'lib/shared/thread-utils.js';
import type { CalendarQuery } from 'lib/types/entry-types.js';
import type { LoadingStatus } from 'lib/types/loading-types.js';
@@ -578,6 +581,9 @@
const dispatchActionPromise = useDispatchActionPromise();
const callJoinThread = useServerCall(joinThread);
const userSearchIndex = useSelector(userStoreMentionSearchIndex);
+ const chatMentionSearchIndex = useThreadChatMentionSearchIndex(
+ props.threadInfo,
+ );
const { parentThreadID } = props.threadInfo;
const parentThreadInfo = useSelector(state =>
@@ -589,6 +595,10 @@
parentThreadInfo,
);
+ const chatMentionCandidates = useThreadChatMentionCandidates(
+ props.threadInfo,
+ );
+
const typeaheadRegexMatches = React.useMemo(
() =>
getTypeaheadRegexMatches(
@@ -619,29 +629,39 @@
const setter = props.inputState.setTypeaheadState;
setter({
frozenUserMentionsCandidates: userMentionsCandidates,
+ frozenChatMentionsCandidates: chatMentionCandidates,
});
}
}, [
userMentionsCandidates,
props.inputState.setTypeaheadState,
props.inputState.typeaheadState.keepUpdatingThreadMembers,
+ chatMentionCandidates,
]);
- const suggestedUsers = React.useMemo(() => {
+ const suggestions = React.useMemo(() => {
if (!typeaheadMatchedStrings) {
return [];
}
- return getMentionTypeaheadUserSuggestions(
+ const suggestedUsers = getMentionTypeaheadUserSuggestions(
userSearchIndex,
props.inputState.typeaheadState.frozenUserMentionsCandidates,
viewerID,
typeaheadMatchedStrings.textPrefix,
);
+ const suggestedChats = getMentionTypeaheadChatSuggestions(
+ chatMentionSearchIndex,
+ props.inputState.typeaheadState.frozenChatMentionsCandidates,
+ typeaheadMatchedStrings.textPrefix,
+ );
+ return [...suggestedUsers, ...suggestedChats];
}, [
+ typeaheadMatchedStrings,
userSearchIndex,
props.inputState.typeaheadState.frozenUserMentionsCandidates,
+ props.inputState.typeaheadState.frozenChatMentionsCandidates,
viewerID,
- typeaheadMatchedStrings,
+ chatMentionSearchIndex,
]);
return (
@@ -657,7 +677,7 @@
dispatchActionPromise={dispatchActionPromise}
joinThread={callJoinThread}
typeaheadMatchedStrings={typeaheadMatchedStrings}
- suggestions={suggestedUsers}
+ suggestions={suggestions}
parentThreadInfo={parentThreadInfo}
/>
);
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
@@ -176,6 +176,7 @@
canBeVisible: false,
keepUpdatingThreadMembers: true,
frozenUserMentionsCandidates: [],
+ frozenChatMentionsCandidates: {},
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
@@ -9,7 +9,11 @@
type MediaMissionStep,
} from 'lib/types/media-types.js';
import type { RawTextMessageInfo } from 'lib/types/messages/text.js';
-import type { ThreadInfo, RelativeMemberInfo } from 'lib/types/thread-types.js';
+import type {
+ ThreadInfo,
+ RelativeMemberInfo,
+ ChatMentionCandidates,
+} from 'lib/types/thread-types.js';
export type PendingMultimediaUpload = {
+localID: string,
@@ -43,6 +47,7 @@
+canBeVisible: boolean,
+keepUpdatingThreadMembers: boolean,
+frozenUserMentionsCandidates: $ReadOnlyArray<RelativeMemberInfo>,
+ +frozenChatMentionsCandidates: ChatMentionCandidates,
+moveChoiceUp: ?() => void,
+moveChoiceDown: ?() => void,
+close: ?() => void,
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
@@ -8,11 +8,13 @@
getNewTextAndSelection,
type MentionTypeaheadSuggestionItem,
type TypeaheadTooltipActionItem,
+ encodeChatMentionText,
} from 'lib/shared/mention-utils.js';
import { validChatNameRegexString } from 'lib/shared/thread-utils.js';
import { stringForUserExplicit } from 'lib/shared/user-utils.js';
import type { SetState } from 'lib/types/hook-types.js';
+import ThreadAvatar from '../avatars/thread-avatar.react.js';
import UserAvatar from '../avatars/user-avatar.react.js';
import { typeaheadStyle } from '../chat/chat-constants.js';
import css from '../chat/typeahead-tooltip.css';
@@ -120,6 +122,29 @@
userInfo: suggestedUser,
},
});
+ } else if (suggestion.type === 'chat') {
+ const suggestedChat = suggestion.threadInfo;
+ const mentionText = `@[[${suggestedChat.id}:${encodeChatMentionText(
+ suggestedChat.uiName,
+ )}]]`;
+ actions.push({
+ key: suggestedChat.id,
+ execute: () => {
+ const { newText, newSelectionStart } = getNewTextAndSelection(
+ textBeforeAtSymbol,
+ inputStateDraft,
+ textPrefix,
+ mentionText,
+ );
+
+ inputStateSetDraft(newText);
+ inputStateSetTextCursorPosition(newSelectionStart);
+ },
+ actionButtonContent: {
+ type: 'chat',
+ threadInfo: suggestedChat,
+ },
+ });
}
}
return actions;
@@ -155,6 +180,15 @@
<UserAvatar size="small" userID={actionButtonContent.userInfo.id} />
);
typeaheadButtonText = `@${stringForUserExplicit(suggestedUser)}`;
+ } else if (actionButtonContent.type === 'chat') {
+ const suggestedChat = actionButtonContent.threadInfo;
+ avatarComponent = (
+ <ThreadAvatar
+ size="small"
+ threadInfo={actionButtonContent.threadInfo}
+ />
+ );
+ typeaheadButtonText = `@${suggestedChat.uiName}`;
}
return (

File Metadata

Mime Type
text/plain
Expires
Wed, Dec 25, 10:40 PM (11 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2703344
Default Alt Text
D8945.id30622.diff (6 KB)

Event Timeline