// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. import $ from 'jquery'; import ReactDOM from 'react-dom'; import client from 'utils/web_client.jsx'; import * as AsyncClient from 'utils/async_client.jsx'; import SearchStore from 'stores/search_store.jsx'; import AppDispatcher from '../dispatcher/app_dispatcher.jsx'; import SuggestionBox from './suggestion/suggestion_box.jsx'; import SearchChannelProvider from './suggestion/search_channel_provider.jsx'; import SearchSuggestionList from './suggestion/search_suggestion_list.jsx'; import SearchUserProvider from './suggestion/search_user_provider.jsx'; import * as utils from 'utils/utils.jsx'; import Constants from 'utils/constants.jsx'; import {intlShape, injectIntl, defineMessages, FormattedMessage, FormattedHTMLMessage} from 'react-intl'; var ActionTypes = Constants.ActionTypes; import {Popover} from 'react-bootstrap'; const holders = defineMessages({ search: { id: 'search_bar.search', defaultMessage: 'Search' } }); import React from 'react'; class SearchBar extends React.Component { constructor() { super(); this.mounted = false; this.onListenerChange = this.onListenerChange.bind(this); this.handleUserInput = this.handleUserInput.bind(this); this.handleUserFocus = this.handleUserFocus.bind(this); this.handleUserBlur = this.handleUserBlur.bind(this); this.performSearch = this.performSearch.bind(this); this.handleSubmit = this.handleSubmit.bind(this); const state = this.getSearchTermStateFromStores(); state.focused = false; this.state = state; this.suggestionProviders = [new SearchChannelProvider(), new SearchUserProvider()]; } getSearchTermStateFromStores() { var term = SearchStore.getSearchTerm() || ''; return { searchTerm: term }; } componentDidMount() { SearchStore.addSearchTermChangeListener(this.onListenerChange); this.mounted = true; } componentWillUnmount() { SearchStore.removeSearchTermChangeListener(this.onListenerChange); this.mounted = false; } onListenerChange(doSearch, isMentionSearch) { if (this.mounted) { var newState = this.getSearchTermStateFromStores(); if (!utils.areObjectsEqual(newState, this.state)) { this.setState(newState); } if (doSearch) { this.performSearch(newState.searchTerm, isMentionSearch); } } } clearFocus() { $('.search-bar__container').removeClass('focused'); } handleClose(e) { e.preventDefault(); AppDispatcher.handleServerAction({ type: ActionTypes.RECEIVED_SEARCH, results: null }); AppDispatcher.handleServerAction({ type: ActionTypes.RECEIVED_SEARCH_TERM, term: null, do_search: false, is_mention_search: false }); AppDispatcher.handleServerAction({ type: ActionTypes.RECEIVED_POST_SELECTED, postId: null }); } handleUserInput(text) { var term = text; SearchStore.storeSearchTerm(term); SearchStore.emitSearchTermChange(false); this.setState({searchTerm: term}); } handleUserBlur() { this.setState({focused: false}); } handleUserFocus() { $('.search-bar__container').addClass('focused'); this.setState({focused: true}); } performSearch(terms, isMentionSearch) { if (terms.length) { this.setState({isSearching: true}); client.search( terms, (data) => { this.setState({isSearching: false}); if (utils.isMobile()) { ReactDOM.findDOMNode(this.refs.search).value = ''; } AppDispatcher.handleServerAction({ type: ActionTypes.RECEIVED_SEARCH, results: data, is_mention_search: isMentionSearch }); }, (err) => { this.setState({isSearching: false}); AsyncClient.dispatchError(err, 'search'); } ); } } handleSubmit(e) { e.preventDefault(); this.performSearch(this.state.searchTerm.trim()); } render() { var isSearching = null; if (this.state.isSearching) { isSearching = ; } let helpClass = 'search-help-popover'; if (!this.state.searchTerm && this.state.focused) { helpClass += ' visible'; } return (
{isSearching}
); } } SearchBar.propTypes = { intl: intlShape.isRequired }; export default injectIntl(SearchBar);