Add emoji suggestion to poll options

This commit is contained in:
Thibaut Girka 2019-04-11 17:59:38 +02:00 committed by ThibG
parent b35b38f4ea
commit 4155a1556a
3 changed files with 51 additions and 5 deletions

View file

@ -50,6 +50,7 @@ export default class AutosuggestInput extends ImmutablePureComponent {
className: PropTypes.string, className: PropTypes.string,
id: PropTypes.string, id: PropTypes.string,
searchTokens: PropTypes.list, searchTokens: PropTypes.list,
maxLength: PropTypes.number,
}; };
static defaultProps = { static defaultProps = {
@ -185,7 +186,7 @@ export default class AutosuggestInput extends ImmutablePureComponent {
} }
render () { render () {
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, className, id } = this.props; const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, className, id, maxLength } = this.props;
const { suggestionsHidden } = this.state; const { suggestionsHidden } = this.state;
const style = { direction: 'ltr' }; const style = { direction: 'ltr' };
@ -214,6 +215,7 @@ export default class AutosuggestInput extends ImmutablePureComponent {
aria-autocomplete='list' aria-autocomplete='list'
id={id} id={id}
className={className} className={className}
maxLength={maxLength}
/> />
</label> </label>

View file

@ -5,6 +5,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import IconButton from 'flavours/glitch/components/icon_button'; import IconButton from 'flavours/glitch/components/icon_button';
import Icon from 'flavours/glitch/components/icon'; import Icon from 'flavours/glitch/components/icon';
import AutosuggestInput from 'flavours/glitch/components/autosuggest_input';
import classNames from 'classnames'; import classNames from 'classnames';
import { pollLimits } from 'flavours/glitch/util/initial_state'; import { pollLimits } from 'flavours/glitch/util/initial_state';
@ -29,6 +30,10 @@ class Option extends React.PureComponent {
isPollMultiple: PropTypes.bool, isPollMultiple: PropTypes.bool,
onChange: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired,
onRemove: PropTypes.func.isRequired, onRemove: PropTypes.func.isRequired,
suggestions: ImmutablePropTypes.list,
onClearSuggestions: PropTypes.func.isRequired,
onFetchSuggestions: PropTypes.func.isRequired,
onSuggestionSelected: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
}; };
@ -40,6 +45,18 @@ class Option extends React.PureComponent {
this.props.onRemove(this.props.index); this.props.onRemove(this.props.index);
}; };
onSuggestionsClearRequested = () => {
this.props.onClearSuggestions();
}
onSuggestionsFetchRequested = (token) => {
this.props.onFetchSuggestions(token);
}
onSuggestionSelected = (tokenStart, token, value) => {
this.props.onSuggestionSelected(tokenStart, token, value, ['poll', 'options', this.props.index]);
}
render () { render () {
const { isPollMultiple, title, index, intl } = this.props; const { isPollMultiple, title, index, intl } = this.props;
@ -48,12 +65,16 @@ class Option extends React.PureComponent {
<label className='poll__text editable'> <label className='poll__text editable'>
<span className={classNames('poll__input', { checkbox: isPollMultiple })} /> <span className={classNames('poll__input', { checkbox: isPollMultiple })} />
<input <AutosuggestInput
type='text'
placeholder={intl.formatMessage(messages.option_placeholder, { number: index + 1 })} placeholder={intl.formatMessage(messages.option_placeholder, { number: index + 1 })}
maxLength={pollLimits.max_option_chars} maxLength={pollLimits.max_option_chars}
value={title} value={title}
onChange={this.handleOptionTitleChange} onChange={this.handleOptionTitleChange}
suggestions={this.props.suggestions}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
onSuggestionSelected={this.onSuggestionSelected}
searchTokens={[':']}
/> />
</label> </label>
@ -78,6 +99,10 @@ class PollForm extends ImmutablePureComponent {
onAddOption: PropTypes.func.isRequired, onAddOption: PropTypes.func.isRequired,
onRemoveOption: PropTypes.func.isRequired, onRemoveOption: PropTypes.func.isRequired,
onChangeSettings: PropTypes.func.isRequired, onChangeSettings: PropTypes.func.isRequired,
suggestions: ImmutablePropTypes.list,
onClearSuggestions: PropTypes.func.isRequired,
onFetchSuggestions: PropTypes.func.isRequired,
onSuggestionSelected: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
}; };
@ -94,7 +119,7 @@ class PollForm extends ImmutablePureComponent {
}; };
render () { render () {
const { options, expiresIn, isMultiple, onChangeOption, onRemoveOption, intl } = this.props; const { options, expiresIn, isMultiple, onChangeOption, onRemoveOption, intl, ...other } = this.props;
if (!options) { if (!options) {
return null; return null;
@ -103,7 +128,7 @@ class PollForm extends ImmutablePureComponent {
return ( return (
<div className='compose-form__poll-wrapper'> <div className='compose-form__poll-wrapper'>
<ul> <ul>
{options.map((title, i) => <Option title={title} key={i} index={i} onChange={onChangeOption} onRemove={onRemoveOption} isPollMultiple={isMultiple} />)} {options.map((title, i) => <Option title={title} key={i} index={i} onChange={onChangeOption} onRemove={onRemoveOption} isPollMultiple={isMultiple} {...other} />)}
{options.size < pollLimits.max_options && ( {options.size < pollLimits.max_options && (
<label className='poll__text editable'> <label className='poll__text editable'>
<span className={classNames('poll__input')} style={{ opacity: 0 }} /> <span className={classNames('poll__input')} style={{ opacity: 0 }} />

View file

@ -1,8 +1,14 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import PollForm from '../components/poll_form'; import PollForm from '../components/poll_form';
import { addPollOption, removePollOption, changePollOption, changePollSettings } from 'flavours/glitch/actions/compose'; import { addPollOption, removePollOption, changePollOption, changePollSettings } from 'flavours/glitch/actions/compose';
import {
clearComposeSuggestions,
fetchComposeSuggestions,
selectComposeSuggestion,
} from 'flavours/glitch/actions/compose';
const mapStateToProps = state => ({ const mapStateToProps = state => ({
suggestions: state.getIn(['compose', 'suggestions']),
options: state.getIn(['compose', 'poll', 'options']), options: state.getIn(['compose', 'poll', 'options']),
expiresIn: state.getIn(['compose', 'poll', 'expires_in']), expiresIn: state.getIn(['compose', 'poll', 'expires_in']),
isMultiple: state.getIn(['compose', 'poll', 'multiple']), isMultiple: state.getIn(['compose', 'poll', 'multiple']),
@ -24,6 +30,19 @@ const mapDispatchToProps = dispatch => ({
onChangeSettings(expiresIn, isMultiple) { onChangeSettings(expiresIn, isMultiple) {
dispatch(changePollSettings(expiresIn, isMultiple)); dispatch(changePollSettings(expiresIn, isMultiple));
}, },
onClearSuggestions () {
dispatch(clearComposeSuggestions());
},
onFetchSuggestions (token) {
dispatch(fetchComposeSuggestions(token));
},
onSuggestionSelected (position, token, accountId, path) {
dispatch(selectComposeSuggestion(position, token, accountId, path));
},
}); });
export default connect(mapStateToProps, mapDispatchToProps)(PollForm); export default connect(mapStateToProps, mapDispatchToProps)(PollForm);