diff --git a/lib/selectors/chat-selectors.js b/lib/selectors/chat-selectors.js --- a/lib/selectors/chat-selectors.js +++ b/lib/selectors/chat-selectors.js @@ -592,7 +592,7 @@ ); }, ); -type MessageListData = ?(ChatMessageItem[]); +export type MessageListData = ?(ChatMessageItem[]); const messageListData: ( threadID: ?string, additionalMessages: $ReadOnlyArray, diff --git a/lib/shared/search-utils.js b/lib/shared/search-utils.js --- a/lib/shared/search-utils.js +++ b/lib/shared/search-utils.js @@ -18,7 +18,12 @@ searchUsersActionTypes, } from '../actions/user-actions.js'; import genesis from '../facts/genesis.js'; -import type { RawMessageInfo } from '../types/message-types.js'; +import type { + ChatMessageInfoItem, + MessageListData, +} from '../selectors/chat-selectors'; +import type { MessageInfo, RawMessageInfo } from '../types/message-types'; +import { isComposableMessageType } from '../types/message-types.js'; import { userRelationshipStatus } from '../types/relationship-types.js'; import { threadPermissions } from '../types/thread-permission-types.js'; import { type ThreadType, threadTypes } from '../types/thread-types-enum.js'; @@ -297,9 +302,45 @@ return serverSearchResults; } +function filterChatMessageInfosForSearch( + chatMessageInfos: MessageListData, + translatedSearchResults: $ReadOnlyArray, +): ?(ChatMessageInfoItem[]) { + if (!chatMessageInfos) { + return null; + } + + const idSet = new Set(translatedSearchResults.map(item => item.id)); + + const chatMessageInfoItems = chatMessageInfos.filter( + item => + item.messageInfo && + idSet.has(item.messageInfo.id) && + isComposableMessageType(item.messageInfo.type), + ); + + const uniqueChatMessageInfoItemsMap = new Map(); + chatMessageInfoItems.forEach( + item => + item.messageInfo && + item.messageInfo.id && + uniqueChatMessageInfoItemsMap.set(item.messageInfo.id, item), + ); + + const sortedChatMessageInfoItems = []; + for (let i = 0; i < translatedSearchResults.length; i++) { + sortedChatMessageInfoItems.push( + uniqueChatMessageInfoItemsMap.get(translatedSearchResults[i].id), + ); + } + + return sortedChatMessageInfoItems.filter(Boolean); +} + export { getPotentialMemberItems, notFriendNotice, useSearchMessages, useSearchUsers, + filterChatMessageInfosForSearch, }; diff --git a/native/search/message-search.react.js b/native/search/message-search.react.js --- a/native/search/message-search.react.js +++ b/native/search/message-search.react.js @@ -7,7 +7,10 @@ import { messageListData } from 'lib/selectors/chat-selectors.js'; import { createMessageInfo } from 'lib/shared/message-utils.js'; -import { useSearchMessages } from 'lib/shared/search-utils.js'; +import { + useSearchMessages, + filterChatMessageInfosForSearch, +} from 'lib/shared/search-utils.js'; import type { RawMessageInfo } from 'lib/types/message-types.js'; import type { ThreadInfo } from 'lib/types/thread-types.js'; @@ -98,35 +101,14 @@ ); const filteredChatMessageInfos = React.useMemo(() => { - if (!chatMessageInfos) { - return null; - } - - const idSet = new Set(translatedSearchResults.map(item => item.id)); - - const chatMessageInfoItems = chatMessageInfos.filter( - item => item.messageInfo && idSet.has(item.messageInfo.id), - ); - - const uniqueChatMessageInfoItemsMap = new Map(); - chatMessageInfoItems.forEach( - item => - item.messageInfo && - item.messageInfo.id && - uniqueChatMessageInfoItemsMap.set(item.messageInfo.id, item), + const result = filterChatMessageInfosForSearch( + chatMessageInfos, + translatedSearchResults, ); - - const sortedChatMessageInfoItems = []; - for (let i = 0; i < translatedSearchResults.length; i++) { - sortedChatMessageInfoItems.push( - uniqueChatMessageInfoItemsMap.get(translatedSearchResults[i].id), - ); + if (result && !endReached) { + return [...result, { itemType: 'loader' }]; } - if (!endReached) { - sortedChatMessageInfoItems.push({ itemType: 'loader' }); - } - - return sortedChatMessageInfoItems.filter(Boolean); + return result; }, [chatMessageInfos, endReached, translatedSearchResults]); const [measuredMessages, setMeasuredMessages] = React.useState([]); diff --git a/web/modals/search/message-search-utils.react.js b/web/modals/search/message-search-utils.react.js --- a/web/modals/search/message-search-utils.react.js +++ b/web/modals/search/message-search-utils.react.js @@ -8,6 +8,7 @@ createMessageInfo, modifyItemForResultScreen, } from 'lib/shared/message-utils.js'; +import { filterChatMessageInfosForSearch } from 'lib/shared/search-utils.js'; import type { RawMessageInfo } from 'lib/types/message-types.js'; import type { ThreadInfo } from 'lib/types/thread-types.js'; @@ -32,34 +33,14 @@ messageListData(threadInfo.id, translatedSearchResults), ); - const filteredChatMessageInfos = React.useMemo(() => { - if (!chatMessageInfos) { - return []; - } - - const idSet = new Set(translatedSearchResults.map(item => item.id)); - - const chatMessageInfoItems = chatMessageInfos.filter( - item => item.messageInfo && idSet.has(item.messageInfo.id), - ); - - const uniqueChatMessageInfoItemsMap = new Map(); - chatMessageInfoItems.forEach( - item => - item.messageInfo && - item.messageInfo.id && - uniqueChatMessageInfoItemsMap.set(item.messageInfo.id, item), - ); - - const sortedChatMessageInfoItems = []; - for (let i = 0; i < translatedSearchResults.length; i++) { - sortedChatMessageInfoItems.push( - uniqueChatMessageInfoItemsMap.get(translatedSearchResults[i].id), - ); - } - - return sortedChatMessageInfoItems.filter(Boolean); - }, [chatMessageInfos, translatedSearchResults]); + const filteredChatMessageInfos = React.useMemo( + () => + filterChatMessageInfosForSearch( + chatMessageInfos, + translatedSearchResults, + ) ?? [], + [chatMessageInfos, translatedSearchResults], + ); return React.useMemo( () => filteredChatMessageInfos.map(item => modifyItemForResultScreen(item)),