import clsx from 'clsx'; import { OrderedSet as ImmutableOrderedSet } from 'immutable'; import throttle from 'lodash/throttle'; import React, { useCallback, useEffect, useRef, useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { locationSearch } from 'soapbox/actions/events'; import AutosuggestInput, { AutoSuggestion } from 'soapbox/components/autosuggest-input'; import Icon from 'soapbox/components/icon'; import { useAppDispatch } from 'soapbox/hooks'; import AutosuggestLocation from './autosuggest-location'; const noOp = () => {}; const messages = defineMessages({ placeholder: { id: 'location_search.placeholder', defaultMessage: 'Find an address' }, }); interface ILocationSearch { onSelected: (locationId: string) => void } const LocationSearch: React.FC = ({ onSelected }) => { const intl = useIntl(); const dispatch = useAppDispatch(); const [locationIds, setLocationIds] = useState(ImmutableOrderedSet()); const controller = useRef(new AbortController()); const [value, setValue] = useState(''); const isEmpty = (): boolean => { return !(value.length > 0); }; const handleChange: React.ChangeEventHandler = ({ target }) => { refreshCancelToken(); handleLocationSearch(target.value); setValue(target.value); }; const handleSelected = (_tokenStart: number, _lastToken: string | null, suggestion: AutoSuggestion) => { if (typeof suggestion === 'string') { onSelected(suggestion); } }; const handleClear: React.MouseEventHandler = e => { e.preventDefault(); if (!isEmpty()) { setValue(''); } }; const handleKeyDown: React.KeyboardEventHandler = e => { if (e.key === 'Escape') { document.querySelector('.ui')?.parentElement?.focus(); } }; const refreshCancelToken = () => { controller.current.abort(); controller.current = new AbortController(); }; const clearResults = () => { setLocationIds(ImmutableOrderedSet()); }; const handleLocationSearch = useCallback(throttle(q => { dispatch(locationSearch(q, controller.current.signal)) .then((locations: { origin_id: string }[]) => { const locationIds = locations.map(location => location.origin_id); setLocationIds(ImmutableOrderedSet(locationIds)); }) .catch(noOp); }, 900, { leading: true, trailing: true }), []); useEffect(() => { if (value === '') { clearResults(); } }, [value]); return (
); }; export default LocationSearch;