diff --git a/web/search/message-search-state-provider.react.js b/web/search/message-search-state-provider.react.js new file mode 100644 --- /dev/null +++ b/web/search/message-search-state-provider.react.js @@ -0,0 +1,67 @@ +// @flow + +import invariant from 'invariant'; +import * as React from 'react'; + +type MessageSearchState = { + +getQuery: (threadID: string) => string, + +setQuery: (query: string, threadID: string) => void, + +clearQuery: (threadID: string) => void, +}; + +const MessageSearchContext: React.Context = + React.createContext(null); + +type Props = { + +children: React.Node, +}; + +function MessageSearchStateProvider(props: Props): React.Node { + const [queries, setQueries] = React.useState<{ + [threadID: string]: string, + }>({}); + + const setQuery = React.useCallback( + (query: string, threadID: string) => + setQueries(prevQueries => ({ ...prevQueries, [threadID]: query })), + [], + ); + + const clearQuery = React.useCallback( + (threadID: string) => + setQueries(prevQueries => { + const { [threadID]: deleted, ...newState } = prevQueries; + return newState; + }), + [], + ); + + const getQuery = React.useCallback( + (threadID: string) => queries[threadID] ?? '', + [queries], + ); + + const state = React.useMemo( + () => ({ + getQuery, + setQuery, + clearQuery, + }), + [getQuery, setQuery, clearQuery], + ); + + return ( + + {props.children} + + ); +} + +function useMessageSearchContext(): MessageSearchState { + const context = React.useContext(MessageSearchContext); + invariant(context, 'MessageSearchContext not found'); + + return context; +} + +export { MessageSearchStateProvider, useMessageSearchContext };