import { OrderedSet as ImmutableOrderedSet } from 'immutable'; import throttle from 'lodash/throttle'; import React, { useState, useRef, useCallback, useEffect } from 'react'; import { accountSearch } from 'soapbox/actions/accounts'; import AutosuggestInput, { AutoSuggestion } from 'soapbox/components/autosuggest-input'; import { useAppDispatch } from 'soapbox/hooks'; import type { Menu } from 'soapbox/components/dropdown-menu'; import type { InputThemes } from 'soapbox/components/ui/input/input'; const noOp = () => { }; interface IAutosuggestAccountInput { onChange: React.ChangeEventHandler, onSelected: (accountId: string) => void, autoFocus?: boolean, value: string, limit?: number, className?: string, autoSelect?: boolean, menu?: Menu, onKeyDown?: React.KeyboardEventHandler, theme?: InputThemes, } const AutosuggestAccountInput: React.FC = ({ onChange, onSelected, value = '', limit = 4, ...rest }) => { const dispatch = useAppDispatch(); const [accountIds, setAccountIds] = useState(ImmutableOrderedSet()); const controller = useRef(new AbortController()); const refreshCancelToken = () => { controller.current.abort(); controller.current = new AbortController(); }; const clearResults = () => { setAccountIds(ImmutableOrderedSet()); }; const handleAccountSearch = useCallback(throttle((q) => { const params = { q, limit, resolve: false }; dispatch(accountSearch(params, controller.current.signal)) .then((accounts: { id: string }[]) => { const accountIds = accounts.map(account => account.id); setAccountIds(ImmutableOrderedSet(accountIds)); }) .catch(noOp); }, 900, { leading: true, trailing: true }), [limit]); const handleChange: React.ChangeEventHandler = e => { refreshCancelToken(); handleAccountSearch(e.target.value); onChange(e); }; const handleSelected = (_tokenStart: number, _lastToken: string | null, suggestion: AutoSuggestion) => { if (typeof suggestion === 'string' && suggestion[0] !== '#') { onSelected(suggestion); } }; useEffect(() => { if (rest.autoFocus) { handleAccountSearch(''); } }, []); useEffect(() => { if (value === '') { clearResults(); } }, [value]); return ( ); }; export default AutosuggestAccountInput;