diff --git a/web/calendar/thread-picker.react.js b/web/calendar/thread-picker.react.js --- a/web/calendar/thread-picker.react.js +++ b/web/calendar/thread-picker.react.js @@ -2,8 +2,11 @@ import invariant from 'invariant'; import * as React from 'react'; +import { createSelector } from 'reselect'; +import { threadSearchIndex } from 'lib/selectors/nav-selectors'; import { onScreenEntryEditableThreadInfos } from 'lib/selectors/thread-selectors'; +import SearchIndex from 'lib/shared/search-index'; import type { ThreadInfo } from 'lib/types/thread-types'; import { useSelector } from '../redux/redux-utils'; @@ -39,13 +42,23 @@ type Props = { ...BaseProps, +onScreenThreadInfos: $ReadOnlyArray, + +searchIndex: SearchIndex, }; +type State = { + +searchText: string, + +searchResults: Set, +}; +type PropsAndState = { ...Props, ...State }; -class ThreadPicker extends React.PureComponent { +class ThreadPicker extends React.PureComponent { pickerDiv: ?HTMLDivElement; constructor(props: Props) { super(props); + this.state = { + searchText: '', + searchResults: new Set(), + }; invariant( props.onScreenThreadInfos.length > 0, "ThreadPicker can't be open when onScreenThreadInfos is empty", @@ -57,6 +70,24 @@ this.pickerDiv.focus(); } + listDataSelector = createSelector( + (propsAndState: PropsAndState) => propsAndState.onScreenThreadInfos, + (propsAndState: PropsAndState) => propsAndState.searchText, + (propsAndState: PropsAndState) => propsAndState.searchResults, + ( + threadInfos: $ReadOnlyArray, + text: string, + searchResults: Set, + ) => + text + ? threadInfos.filter(threadInfo => searchResults.has(threadInfo.id)) + : [...threadInfos], + ); + + get getListData() { + return this.listDataSelector({ ...this.props, ...this.state }); + } + render() { const length = this.props.onScreenThreadInfos.length; invariant( @@ -64,7 +95,7 @@ "ThreadPicker can't be open when onScreenThreadInfos is empty", ); - const options = this.props.onScreenThreadInfos.map(threadInfo => ( + const options = this.getListData.map(threadInfo => ( { + const results = this.props.searchIndex.getSearchResults(searchText); + this.setState({ searchText, searchResults: new Set(results) }); + }; } const ConnectedThreadPicker: React.ComponentType = React.memo( function ConnectedThreadPicker(props) { const onScreenThreadInfos = useSelector(onScreenEntryEditableThreadInfos); + const index = useSelector(state => threadSearchIndex(state)); return ( - + ); }, );