import classNames from 'classnames'; import { Map as ImmutableMap } from 'immutable'; import debounce from 'lodash/debounce'; import * as React from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { useDispatch } from 'react-redux'; import { useHistory } from 'react-router-dom'; import { changeSearch, clearSearch, submitSearch, showSearch, } from 'soapbox/actions/search'; import AutosuggestAccountInput from 'soapbox/components/autosuggest_account_input'; import SvgIcon from 'soapbox/components/ui/icon/svg-icon'; import { useAppSelector } from 'soapbox/hooks'; const messages = defineMessages({ placeholder: { id: 'search.placeholder', defaultMessage: 'Search' }, action: { id: 'search.action', defaultMessage: 'Search for “{query}”' }, }); function redirectToAccount(accountId: string, routerHistory: any) { return (_dispatch: any, getState: () => ImmutableMap) => { const acct = getState().getIn(['accounts', accountId, 'acct']); if (acct && routerHistory) { routerHistory.push(`/@${acct}`); } }; } interface ISearch { autoFocus?: boolean, autoSubmit?: boolean, autosuggest?: boolean, openInRoute?: boolean } const Search = (props: ISearch) => { const { autoFocus = false, autoSubmit = false, autosuggest = false, openInRoute = false, } = props; const dispatch = useDispatch(); const history = useHistory(); const intl = useIntl(); const value = useAppSelector((state) => state.search.value); const submitted = useAppSelector((state) => state.search.submitted); const debouncedSubmit = debounce(() => { dispatch(submitSearch()); }, 900); const handleChange = (event: React.ChangeEvent) => { const { value } = event.target; dispatch(changeSearch(value)); if (autoSubmit) { debouncedSubmit(); } }; const handleClear = (event: React.MouseEvent) => { event.preventDefault(); if (value.length > 0 || submitted) { dispatch(clearSearch()); } }; const handleSubmit = () => { dispatch(submitSearch()); if (openInRoute) { history.push('/search'); } }; const handleKeyDown = (event: React.KeyboardEvent) => { if (event.key === 'Enter') { event.preventDefault(); handleSubmit(); } else if (event.key === 'Escape') { document.querySelector('.ui')?.parentElement?.focus(); } }; const handleFocus = () => { dispatch(showSearch()); }; const handleSelected = (accountId: string) => { dispatch(clearSearch()); dispatch(redirectToAccount(accountId, history)); }; const makeMenu = () => [ { text: intl.formatMessage(messages.action, { query: value }), icon: require('@tabler/icons/icons/search.svg'), action: handleSubmit, }, ]; const hasValue = value.length > 0 || submitted; const Component = autosuggest ? AutosuggestAccountInput : 'input'; return (
); }; export default Search;