diff --git a/web/modals/threads/thread-picker-modal.react.js b/web/modals/threads/thread-picker-modal.react.js index 0370ef35b..bd5ffadee 100644 --- a/web/modals/threads/thread-picker-modal.react.js +++ b/web/modals/threads/thread-picker-modal.react.js @@ -1,140 +1,125 @@ // @flow import invariant from 'invariant'; import * as React from 'react'; -import { createSelector } from 'reselect'; import { useGlobalThreadSearchIndex } from 'lib/selectors/nav-selectors.js'; import { onScreenEntryEditableThreadInfos } from 'lib/selectors/thread-selectors.js'; import type { ThreadInfo } from 'lib/types/thread-types.js'; import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js'; import css from './thread-picker-modal.css'; import ThreadAvatar from '../../avatars/thread-avatar.react.js'; import Button from '../../components/button.react.js'; import Search from '../../components/search.react.js'; import { useSelector } from '../../redux/redux-utils.js'; import Modal, { type ModalOverridableProps } from '../modal.react.js'; type OptionProps = { +threadInfo: ThreadInfo, +createNewEntry: (threadID: string) => void, +onCloseModal: () => void, }; function ThreadPickerOption(props: OptionProps) { const { threadInfo, createNewEntry, onCloseModal } = props; const onClickThreadOption = React.useCallback(() => { createNewEntry(threadInfo.id); onCloseModal(); }, [threadInfo.id, createNewEntry, onCloseModal]); const { uiName } = useResolvedThreadInfo(threadInfo); return (
); } type Props = { ...ModalOverridableProps, +createNewEntry: (threadID: string) => void, }; function ThreadPickerModal(props: Props): React.Node { const { createNewEntry, ...modalProps } = props; const onScreenThreadInfos = useSelector(onScreenEntryEditableThreadInfos); const searchIndex = useGlobalThreadSearchIndex(); invariant( onScreenThreadInfos.length > 0, "ThreadPicker can't be open when onScreenThreadInfos is empty", ); const [searchText, setSearchText] = React.useState(''); const [searchResults, setSearchResults] = React.useState>( new Set(), ); const searchRef = React.useRef(); React.useEffect(() => { searchRef.current?.focus(); }, []); const onChangeSearchText = React.useCallback( (text: string) => { const results = searchIndex.getSearchResults(text); setSearchText(text); setSearchResults(new Set(results)); }, [searchIndex], ); - const listDataSelector = createSelector( - state => state.onScreenThreadInfos, - state => state.searchText, - state => state.searchResults, - ( - threadInfos: $ReadOnlyArray, - text: string, - results: Set, - ) => - text - ? threadInfos.filter(threadInfo => results.has(threadInfo.id)) - : [...threadInfos], - ); - - const threads = useSelector(() => - listDataSelector({ - onScreenThreadInfos, - searchText, - searchResults, - }), + const threads = React.useMemo( + () => + searchText + ? onScreenThreadInfos.filter(thread => searchResults.has(thread.id)) + : onScreenThreadInfos, + [searchText, onScreenThreadInfos, searchResults], ); const threadPickerContent = React.useMemo(() => { const options = threads.map(threadInfo => ( )); if (options.length === 0 && searchText.length > 0) { return (
No results for {searchText}
); } else { return options; } }, [threads, createNewEntry, modalProps.onClose, searchText]); return (
{threadPickerContent}
); } export default ThreadPickerModal;