import React from 'react'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import Link from './Link'; import ArtistSentence from '../ArtistSentence'; import * as helpers from '../../helpers'; import * as coreActions from '../../services/core/actions'; import * as uiActions from '../../services/ui/actions'; import * as spotifyActions from '../../services/spotify/actions'; class AddSeedField extends React.Component { constructor(props) { super(props); this.state = { value: '', }; this.id = helpers.generateGuid(); this.timer = null; this.handleClick = this.handleClick.bind(this); } componentDidMount() { window.addEventListener('click', this.handleClick, false); if (!this.props.genres) { this.props.spotifyActions.getGenres(); } } componentWillUnmount() { window.removeEventListener('click', this.handleClick, false); } handleClick(e) { if ($(e.target).closest('.add-seed-field').length <= 0) { this.props.spotifyActions.clearAutocompleteResults(this.id); } } handleChange(e, value) { const self = this; // update our local state this.setState({ value }); // start a timer to perform the actual search // this provides a wee delay between key presses to avoid request spamming clearTimeout(this.timer); this.timer = setTimeout( () => { self.setState({ searching: true }); self.props.spotifyActions.getAutocompleteResults(self.id, value, ['artist', 'track', 'genre']); }, 500, ); } handleSelect(e, item) { this.setState({ value: '' }); this.props.onSelect(e, item.uri); this.props.spotifyActions.clearAutocompleteResults(this.id); // Add our selected item to our global index switch (helpers.uriType(item.uri)) { case 'artist': this.props.coreActions.artistsLoaded(item); break; case 'track': this.props.coreActions.tracksLoaded(item); break; } } results() { if (typeof (this.props.results) === 'undefined') { return null; } if (typeof (this.props.results[this.id]) === 'undefined') { return null; } return this.props.results[this.id]; } renderResults(type) { const results = this.results(); if (!results || typeof (results[type]) === 'undefined' || results[type].length <= 0) return null; // only show the first 3 const items = results[type].slice(0, 3); return (

{type}

{ items.map((item) => (
this.handleSelect(e, item)}> {item.name} {type == 'tracks' ? ( {' '} ) : null}
)) }
); } render() { let className = 'field autocomplete-field add-seed-field'; if (this.results() && this.results().loading) { className += ' loading'; } return (
this.handleChange(e, e.target.value)} placeholder={this.props.placeholder ? this.props.placeholder : 'Start typing...'} />
{this.renderResults('artists')} {this.renderResults('tracks')} {this.renderResults('genres')}
); } } const mapStateToProps = (state, ownProps) => ({ genres: (state.ui.genres ? state.ui.genres : null), results: (state.spotify.autocomplete_results ? state.spotify.autocomplete_results : {}), }); const mapDispatchToProps = (dispatch) => ({ coreActions: bindActionCreators(coreActions, dispatch), uiActions: bindActionCreators(uiActions, dispatch), spotifyActions: bindActionCreators(spotifyActions, dispatch), }); export default connect(mapStateToProps, mapDispatchToProps)(AddSeedField);