diff --git a/src/AutoCompleteListView.js b/src/AutoCompleteListView.js index a95b734..4f0a79c 100644 --- a/src/AutoCompleteListView.js +++ b/src/AutoCompleteListView.js @@ -1,181 +1,124 @@ import React from 'react'; -import PropTypes from 'prop-types'; -import { TextInput, View, StyleSheet, Animated, TouchableOpacity } from 'react-native'; -import MaterialIcons from 'react-native-vector-icons/MaterialIcons'; -import AutoCompleteListView from './AutoCompleteListView'; -import axios, { CancelToken } from 'axios'; +import { + FlatList, Text, View, StyleSheet, TouchableOpacity, LayoutAnimation, Platform, + TouchableNativeFeedback, +} from 'react-native'; import Events from 'react-native-simple-events'; -import debounce from '../utils/debounce'; - -const AUTOCOMPLETE_URL = 'https://maps.googleapis.com/maps/api/place/autocomplete/json'; -const REVRSE_GEO_CODE_URL = 'https://maps.googleapis.com/maps/api/geocode/json'; +import PropTypes from 'prop-types'; -export default class AutoCompleteInput extends React.Component { +export default class AutoCompleteListView extends React.Component { static propTypes = { - apiKey: PropTypes.string.isRequired, - language: PropTypes.string, - debounceDuration: PropTypes.number.isRequired, - components: PropTypes.arrayOf(PropTypes.string), + predictions: PropTypes.array.isRequired, + onSelectPlace: PropTypes.func, }; - static defaultProps = { - language: 'en', - components: [], + state = { + inFocus: false, }; - constructor(props) { - super(props); - this._request = debounce(this._request.bind(this), this.props.debounceDuration); + componentDidMount() { + Events.listen('InputBlur', 'ListViewID', this._onTextBlur); + Events.listen('InputFocus', 'ListViewID', this._onTextFocus); } componentWillUnmount() { - this._abortRequest(); + Events.rm('InputBlur', 'ListViewID'); + Events.rm('InputFocus', 'ListViewID'); } - state = { - predictions: [], - loading: false, - inFocus: false, - }; - - _abortRequest = () => { - if (this.source) { - this.source.cancel('Operation canceled by the user.'); - } - }; - - fetchAddressForLocation = location => { - this.setState({ loading: true, predictions: [] }); - let { latitude, longitude } = location; - this.source = CancelToken.source(); - axios - .get(`${REVRSE_GEO_CODE_URL}?key=${this.props.apiKey}&latlng=${latitude},${longitude}`, { - cancelToken: this.source.token, - }) - .then(({ data }) => { - this.setState({ loading: false }); - let { results } = data; - if (results.length > 0) { - let { formatted_address } = results[0]; - this.setState({ text: formatted_address }); - } - }); - }; - - _request = text => { - this._abortRequest(); - if (text.length >= 3) { - this.source = CancelToken.source(); - axios - .get(AUTOCOMPLETE_URL, { - cancelToken: this.source.token, - params: { - input: text, - key: this.props.apiKey, - language: this.props.language, - components: this.props.components.join('|'), - }, - }) - .then(({ data }) => { - let { predictions } = data; - this.setState({ predictions }); - }); - } else { - this.setState({ predictions: [] }); - } - }; - - _onChangeText = text => { - this._request(text); - this.setState({ text }); - }; - - _onFocus = () => { - this._abortRequest(); - this.setState({ loading: false, inFocus: true }); - Events.trigger('InputFocus'); + _onTextFocus = () => { + this.setState({ inFocus: true }); }; - _onBlur = () => { + _onTextBlur = () => { this.setState({ inFocus: false }); - Events.trigger('InputBlur'); }; - blur = () => { - this._input.blur(); - }; - - _onPressClear = () => { - this.setState({ text: '', predictions: [] }); - }; + componentDidUpdate() { + LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); + } - _getClearButton = () => - this.state.inFocus ? ( - - - - ) : null; + _renderItem({ item }) { + const TouchableControl = Platform.OS === 'ios' ? TouchableOpacity : TouchableNativeFeedback; + const { structured_formatting } = item; + return ( + Events.trigger('PlaceSelected', item.place_id)}> + + + {structured_formatting.main_text} + + + {structured_formatting.secondary_text} + + + + ); + } - getAddress = () => (this.state.loading ? '' : this.state.text); + _getFlatList = () => { + const style = this.state.inFocus ? null : { height: 0 }; + return ( + } + keyboardShouldPersistTaps={'handled'} + keyExtractor={item => item.id} + /> + ); + }; render() { return ( - - - (this._input = input)} - value={this.state.loading ? 'Loading...' : this.state.text} - style={styles.textInput} - underlineColorAndroid={'transparent'} - placeholder={'Search'} - onFocus={this._onFocus} - onBlur={this._onBlur} - onChangeText={this._onChangeText} - outlineProvider="bounds" - autoCorrect={false} - spellCheck={false} - /> - {this._getClearButton()} - - - - - + Platform.OS === 'android' ? this._getFlatList() : {this._getFlatList()} ); } } const styles = StyleSheet.create({ - textInputContainer: { - flexDirection: 'row', - height: 40, - zIndex: 99, - paddingLeft: 10, - borderRadius: 5, + row: { + width: '100%', + height: 50, + justifyContent: 'center', + paddingLeft: 8, + paddingRight: 5, + }, + list: { backgroundColor: 'white', + borderBottomRightRadius: 10, + borderBottomLeftRadius: 10, + maxHeight: 220, + }, + listContainer: { shadowOffset: { width: 0, height: 2, }, shadowRadius: 2, shadowOpacity: 0.24, - alignItems: 'center', + backgroundColor: 'transparent', + borderBottomRightRadius: 10, + borderBottomLeftRadius: 10, }, - textInput: { - flex: 1, - fontSize: 17, - color: '#404752', + separator: { + height: StyleSheet.hairlineWidth, + backgroundColor: 'rgba(0,0,0,0.3)', }, - btn: { - width: 30, - height: 30, - padding: 5, - justifyContent: 'center', - alignItems: 'center', + primaryText: { + color: '#545961', + fontSize: 14, }, - listViewContainer: { - paddingLeft: 3, - paddingRight: 3, - paddingBottom: 3, + secondaryText: { + color: '#A1A1A9', + fontSize: 13, }, });