Changeset View
Changeset View
Standalone View
Standalone View
lib/hooks/search-sidebars.js
// @flow | // @flow | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { sidebarInfoSelector } from '../selectors/thread-selectors'; | import { sidebarInfoSelector } from '../selectors/thread-selectors'; | ||||
import SearchIndex from '../shared/search-index'; | import SearchIndex from '../shared/search-index'; | ||||
import { threadSearchText } from '../shared/thread-utils'; | import { threadSearchText } from '../shared/thread-utils'; | ||||
import type { SetState } from '../types/hook-types'; | import type { SetState } from '../types/hook-types'; | ||||
import type { SidebarInfo, ThreadInfo } from '../types/thread-types'; | import type { SidebarInfo, ThreadInfo } from '../types/thread-types'; | ||||
import { useSelector } from '../utils/redux-utils'; | import { useSelector } from '../utils/redux-utils'; | ||||
function useSearchSidebars( | function useSearchSidebars( | ||||
threadInfo: ThreadInfo, | threadInfo: ThreadInfo, | ||||
text: string, | text: string, | ||||
setTextSearchText: SetState<string>, | setSearchText?: SetState<string>, | ||||
): { | ): { | ||||
+listData: $ReadOnlyArray<SidebarInfo>, | +listData: $ReadOnlyArray<SidebarInfo>, | ||||
+setSearchState: SetState<$ReadOnlySet<string>>, | +setSearchState: SetState<$ReadOnlySet<string>>, | ||||
+onChangeSearchText: ( | +onChangeSearchText: ( | ||||
text: SyntheticEvent<HTMLInputElement> | string, | text: SyntheticEvent<HTMLInputElement> | string, | ||||
) => mixed, | ) => mixed, | ||||
+clearQuery: (event: SyntheticEvent<HTMLAnchorElement>) => void, | |||||
} { | } { | ||||
const [searchState, setSearchState] = React.useState(new Set<string>()); | const [searchState, setSearchState] = React.useState(new Set<string>()); | ||||
const userInfos = useSelector(state => state.userStore.userInfos); | const userInfos = useSelector(state => state.userStore.userInfos); | ||||
const sidebarInfos = useSelector( | const sidebarInfos = useSelector( | ||||
state => sidebarInfoSelector(state)[threadInfo.id] ?? [], | state => sidebarInfoSelector(state)[threadInfo.id] ?? [], | ||||
); | ); | ||||
Show All 27 Lines | (event: SyntheticEvent<HTMLInputElement> | string) => { | ||||
let onChangeText; | let onChangeText; | ||||
if (typeof event === 'string') { | if (typeof event === 'string') { | ||||
onChangeText = event; | onChangeText = event; | ||||
} else { | } else { | ||||
onChangeText = event.currentTarget.value; | onChangeText = event.currentTarget.value; | ||||
} | } | ||||
setSearchState(new Set(searchIndex.getSearchResults(onChangeText))); | setSearchState(new Set(searchIndex.getSearchResults(onChangeText))); | ||||
setTextSearchText(onChangeText); | setSearchText?.(onChangeText); | ||||
}, | }, | ||||
[searchIndex, setSearchState, setTextSearchText], | [searchIndex, setSearchState, setSearchText], | ||||
); | |||||
const clearQuery = React.useCallback( | |||||
(event: SyntheticEvent<HTMLAnchorElement>) => { | |||||
event.preventDefault(); | |||||
setSearchState(new Set()); | |||||
setTextSearchText(''); | |||||
}, | |||||
[setSearchState, setTextSearchText], | |||||
); | ); | ||||
React.useEffect(() => { | React.useEffect(() => { | ||||
setSearchState(new Set(searchIndex.getSearchResults(text))); | setSearchState(new Set(searchIndex.getSearchResults(text))); | ||||
}, [searchIndex, setSearchState, text]); | setSearchText?.(text); | ||||
}, [searchIndex, setSearchState, setSearchText, text]); | |||||
return React.useMemo( | return React.useMemo( | ||||
() => ({ | () => ({ | ||||
listData, | listData, | ||||
setSearchState, | setSearchState, | ||||
onChangeSearchText, | onChangeSearchText, | ||||
clearQuery, | |||||
}), | }), | ||||
[listData, setSearchState, onChangeSearchText, clearQuery], | [listData, setSearchState, onChangeSearchText], | ||||
); | ); | ||||
} | } | ||||
export { useSearchSidebars }; | export { useSearchSidebars }; |