diff --git a/src/components/common/pickers/ChatOrUserPicker.tsx b/src/components/common/pickers/ChatOrUserPicker.tsx index d1d0308bd..e4b0277c1 100644 --- a/src/components/common/pickers/ChatOrUserPicker.tsx +++ b/src/components/common/pickers/ChatOrUserPicker.tsx @@ -4,13 +4,12 @@ import { } from '../../../lib/teact/teact'; import { getActions, getGlobal, withGlobal } from '../../../global'; -import type { ApiTopic } from '../../../api/types'; import type { GlobalState } from '../../../global/types'; import type { AnimationLevel, ThreadId } from '../../../types'; import { PEER_PICKER_ITEM_HEIGHT_PX } from '../../../config'; import { - getCanPostInChat, getGroupStatus, getUserStatus, isUserOnline, + getCanPostInChat, getGroupStatus, getOrderedTopics, getUserStatus, isUserOnline, } from '../../../global/helpers'; import { isApiPeerChat } from '../../../global/helpers/peers'; import { @@ -21,7 +20,9 @@ import { selectUserStatus, } from '../../../global/selectors'; import { selectAnimationLevel } from '../../../global/selectors/sharedState'; +import { selectThread } from '../../../global/selectors/threads'; import buildClassName from '../../../util/buildClassName'; +import { mapTruthyValues, mapValues } from '../../../util/iteratees'; import { buildChatSelectionKey, type ChatSelectionKey, @@ -31,7 +32,7 @@ import { resolveTransitionName } from '../../../util/resolveTransitionName'; import { REM } from '../helpers/mediaDimensions'; import renderText from '../helpers/renderText'; -import useSelector from '../../../hooks/data/useSelector'; +import useSelector, { useShallowSelector } from '../../../hooks/data/useSelector'; import useInfiniteScroll from '../../../hooks/useInfiniteScroll'; import useInputFocusOnOpen from '../../../hooks/useInputFocusOnOpen'; import useKeyboardListNavigation from '../../../hooks/useKeyboardListNavigation'; @@ -144,7 +145,16 @@ const ChatOrUserPicker = ({ }, [forumId]); const topicsInfo = useSelector(selectForumTopicsInfo); - const forumTopicsById = topicsInfo?.topicsById; + + const selectTopicThreads = useCallback((global: GlobalState) => { + if (!forumId) { + return undefined; + } + + return mapTruthyValues(topicsInfo?.topicsById || {}, (topic) => selectThread(global, forumId, topic.id)); + }, [forumId, topicsInfo?.topicsById]); + + const topicThreads = useShallowSelector(selectTopicThreads); const [topicIds, topics] = useMemo(() => { const global = getGlobal(); @@ -153,27 +163,25 @@ const ChatOrUserPicker = ({ const chat = chatsById[forumId!]; - if (!chat || !forumTopicsById) { + if (!chat || !topicsInfo) { return [undefined, undefined]; } const searchTitle = topicSearch.toLowerCase(); - const result = forumTopicsById - ? Object.values(forumTopicsById).reduce((acc, topic) => { - if ( - getCanPostInChat(chat, topic, undefined, chatFullInfoById[forumId!]) - && (!searchTitle || topic.title.toLowerCase().includes(searchTitle)) - ) { - acc[topic.id] = topic; - } + const filteredTopics = Object.values(topicsInfo.topicsById).filter((topic) => ( + getCanPostInChat(chat, topic, undefined, chatFullInfoById[forumId!]) + && (!searchTitle || topic.title.toLowerCase().includes(searchTitle)) + )); + const topicThreadInfos = topicThreads && mapValues(topicThreads, (topicThread) => topicThread.threadInfo); + const orderedTopics = getOrderedTopics( + filteredTopics, + topicThreadInfos, + topicsInfo.orderedPinnedTopicIds, + ); - return acc; - }, {} as Record) - : forumTopicsById; - - return [Object.keys(result).map(Number), result]; - }, [forumId, topicSearch, forumTopicsById]); + return [orderedTopics.map(({ id }) => id), topicsInfo.topicsById]; + }, [forumId, topicSearch, topicsInfo, topicThreads]); const handleHeaderBackClick = useLastCallback(() => { setForumId(undefined);