diff options
author | Eugen Rochko <eugen@zeonfederated.com> | 2016-11-12 14:33:21 +0100 |
---|---|---|
committer | Eugen Rochko <eugen@zeonfederated.com> | 2016-11-12 14:36:10 +0100 |
commit | 09218d4c0152013750dd1c127d3c8267dc45f880 (patch) | |
tree | 7cd9975b84a28de92403c80f483d08e471b10155 /app/assets/javascripts/components/features/ui | |
parent | cd765f26a9610e160ffd347637fca40d7b80164e (diff) |
Use full-text search for autosuggestions
Diffstat (limited to 'app/assets/javascripts/components/features/ui')
-rw-r--r-- | app/assets/javascripts/components/features/ui/components/compose_form.jsx | 53 | ||||
-rw-r--r-- | app/assets/javascripts/components/features/ui/containers/compose_form_container.jsx | 10 |
2 files changed, 39 insertions, 24 deletions
diff --git a/app/assets/javascripts/components/features/ui/components/compose_form.jsx b/app/assets/javascripts/components/features/ui/components/compose_form.jsx index 0655a7c79..20dc32709 100644 --- a/app/assets/javascripts/components/features/ui/components/compose_form.jsx +++ b/app/assets/javascripts/components/features/ui/components/compose_form.jsx @@ -1,10 +1,11 @@ -import CharacterCounter from './character_counter'; -import Button from '../../../components/button'; -import PureRenderMixin from 'react-addons-pure-render-mixin'; +import CharacterCounter from './character_counter'; +import Button from '../../../components/button'; +import PureRenderMixin from 'react-addons-pure-render-mixin'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import ReplyIndicator from './reply_indicator'; -import UploadButton from './upload_button'; -import Autosuggest from 'react-autosuggest'; +import ReplyIndicator from './reply_indicator'; +import UploadButton from './upload_button'; +import Autosuggest from 'react-autosuggest'; +import AutosuggestAccountContainer from '../../compose/containers/autosuggest_account_container'; const getTokenForSuggestions = (str, caretPosition) => { let word; @@ -31,11 +32,8 @@ const getTokenForSuggestions = (str, caretPosition) => { } }; -const getSuggestionValue = suggestion => suggestion.completion; - -const renderSuggestion = suggestion => ( - <span>{suggestion.label}</span> -); +const getSuggestionValue = suggestionId => suggestionId; +const renderSuggestion = suggestionId => <AutosuggestAccountContainer id={suggestionId} />; const textareaStyle = { display: 'block', @@ -59,18 +57,26 @@ const ComposeForm = React.createClass({ propTypes: { text: React.PropTypes.string.isRequired, + suggestion_token: React.PropTypes.string, suggestions: React.PropTypes.array, is_submitting: React.PropTypes.bool, is_uploading: React.PropTypes.bool, in_reply_to: ImmutablePropTypes.map, onChange: React.PropTypes.func.isRequired, onSubmit: React.PropTypes.func.isRequired, - onCancelReply: React.PropTypes.func.isRequired + onCancelReply: React.PropTypes.func.isRequired, + onClearSuggestions: React.PropTypes.func.isRequired, + onFetchSuggestions: React.PropTypes.func.isRequired, + onSuggestionSelected: React.PropTypes.func.isRequired }, mixins: [PureRenderMixin], handleChange (e) { + if (typeof e.target.value === 'undefined' || typeof e.target.value === 'number') { + return; + } + this.props.onChange(e.target.value); }, @@ -86,8 +92,7 @@ const ComposeForm = React.createClass({ componentDidUpdate (prevProps) { if (prevProps.text !== this.props.text || prevProps.in_reply_to !== this.props.in_reply_to) { - const node = ReactDOM.findDOMNode(this.refs.autosuggest); - const textarea = node.querySelector('textarea'); + const textarea = this.autosuggest.input; if (textarea) { textarea.focus(); @@ -100,28 +105,31 @@ const ComposeForm = React.createClass({ }, onSuggestionsFetchRequested ({ value }) { - const node = ReactDOM.findDOMNode(this.refs.autosuggest); - const textarea = node.querySelector('textarea'); + const textarea = this.autosuggest.input; if (textarea) { const token = getTokenForSuggestions(value, textarea.selectionStart); if (token !== null) { this.props.onFetchSuggestions(token); + } else { + this.props.onClearSuggestions(); } } }, - onSuggestionSelected (e, { suggestionValue, method }) { - const node = ReactDOM.findDOMNode(this.refs.autosuggest); - const textarea = node.querySelector('textarea'); + onSuggestionSelected (e, { suggestionValue }) { + const textarea = this.autosuggest.input; if (textarea) { - const str = this.props.text; - this.props.onChange([str.slice(0, textarea.selectionStart), suggestionValue, str.slice(textarea.selectionStart)].join('')); + this.props.onSuggestionSelected(textarea.selectionStart, suggestionValue); } }, + setRef (c) { + this.autosuggest = c; + }, + render () { let replyArea = ''; const disabled = this.props.is_submitting || this.props.is_uploading; @@ -143,8 +151,9 @@ const ComposeForm = React.createClass({ {replyArea} <Autosuggest - ref='autosuggest' + ref={this.setRef} suggestions={this.props.suggestions} + focusFirstSuggestion={true} onSuggestionsFetchRequested={this.onSuggestionsFetchRequested} onSuggestionsClearRequested={this.onSuggestionsClearRequested} onSuggestionSelected={this.onSuggestionSelected} diff --git a/app/assets/javascripts/components/features/ui/containers/compose_form_container.jsx b/app/assets/javascripts/components/features/ui/containers/compose_form_container.jsx index dcfeef752..87bcd6b99 100644 --- a/app/assets/javascripts/components/features/ui/containers/compose_form_container.jsx +++ b/app/assets/javascripts/components/features/ui/containers/compose_form_container.jsx @@ -5,7 +5,8 @@ import { submitCompose, cancelReplyCompose, clearComposeSuggestions, - fetchComposeSuggestions + fetchComposeSuggestions, + selectComposeSuggestion } from '../../../actions/compose'; import { makeGetStatus } from '../../../selectors'; @@ -15,7 +16,8 @@ const makeMapStateToProps = () => { const mapStateToProps = function (state, props) { return { text: state.getIn(['compose', 'text']), - suggestions: state.getIn(['compose', 'suggestions']), + suggestion_token: state.getIn(['compose', 'suggestion_token']), + suggestions: state.getIn(['compose', 'suggestions']).toJS(), is_submitting: state.getIn(['compose', 'is_submitting']), is_uploading: state.getIn(['compose', 'is_uploading']), in_reply_to: getStatus(state, state.getIn(['compose', 'in_reply_to'])) @@ -45,6 +47,10 @@ const mapDispatchToProps = function (dispatch) { onFetchSuggestions (token) { dispatch(fetchComposeSuggestions(token)); + }, + + onSuggestionSelected (position, accountId) { + dispatch(selectComposeSuggestion(position, accountId)); } } }; |