diff options
author | Eugen Rochko <eugen@zeonfederated.com> | 2017-09-23 14:47:32 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-23 14:47:32 +0200 |
commit | 1e02ba111ae38ab758135b5b2b46f34c672ca02e (patch) | |
tree | 62c916782bf9340837a12fcb0c79bb9d481b4ce8 /app/javascript/mastodon/components/autosuggest_textarea.js | |
parent | 66126f302167d21e4bf247e660f595ff0beaaf20 (diff) |
Add emoji autosuggest (#5053)
* Add emoji autosuggest Some credit goes to glitch-soc/mastodon#149 * Remove server-side shortcode->unicode conversion * Insert shortcode when suggestion is custom emoji * Remove remnant of server-side emojis * Update style of autosuggestions * Fix wrong emoji filenames generated in autosuggest item * Do not lazy load emoji picker, as that no longer works * Fix custom emoji autosuggest * Fix multiple "Custom" categories getting added to emoji index, only add once
Diffstat (limited to 'app/javascript/mastodon/components/autosuggest_textarea.js')
-rw-r--r-- | app/javascript/mastodon/components/autosuggest_textarea.js | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/app/javascript/mastodon/components/autosuggest_textarea.js b/app/javascript/mastodon/components/autosuggest_textarea.js index 30e3049df..daeb6fd53 100644 --- a/app/javascript/mastodon/components/autosuggest_textarea.js +++ b/app/javascript/mastodon/components/autosuggest_textarea.js @@ -1,10 +1,12 @@ import React from 'react'; import AutosuggestAccountContainer from '../features/compose/containers/autosuggest_account_container'; +import AutosuggestEmoji from './autosuggest_emoji'; import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import { isRtl } from '../rtl'; import ImmutablePureComponent from 'react-immutable-pure-component'; import Textarea from 'react-textarea-autosize'; +import classNames from 'classnames'; const textAtCursorMatchesToken = (str, caretPosition) => { let word; @@ -18,11 +20,11 @@ const textAtCursorMatchesToken = (str, caretPosition) => { word = str.slice(left, right + caretPosition); } - if (!word || word.trim().length < 2 || word[0] !== '@') { + if (!word || word.trim().length < 2 || ['@', ':'].indexOf(word[0]) === -1) { return [null, null]; } - word = word.trim().toLowerCase().slice(1); + word = word.trim().toLowerCase(); if (word.length > 0) { return [left + 1, word]; @@ -128,7 +130,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { } onSuggestionClick = (e) => { - const suggestion = e.currentTarget.getAttribute('data-index'); + const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index')); e.preventDefault(); this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion); this.textarea.focus(); @@ -151,9 +153,28 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { } } + renderSuggestion = (suggestion, i) => { + const { selectedSuggestion } = this.state; + let inner, key; + + if (typeof suggestion === 'object') { + inner = <AutosuggestEmoji emoji={suggestion} />; + key = suggestion.id; + } else { + inner = <AutosuggestAccountContainer id={suggestion} />; + key = suggestion; + } + + return ( + <div role='button' tabIndex='0' key={key} data-index={i} className={classNames('autosuggest-textarea__suggestions__item', { selected: i === selectedSuggestion })} onMouseDown={this.onSuggestionClick}> + {inner} + </div> + ); + } + render () { const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus } = this.props; - const { suggestionsHidden, selectedSuggestion } = this.state; + const { suggestionsHidden } = this.state; const style = { direction: 'ltr' }; if (isRtl(value)) { @@ -164,6 +185,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { <div className='autosuggest-textarea'> <label> <span style={{ display: 'none' }}>{placeholder}</span> + <Textarea inputRef={this.setTextarea} className='autosuggest-textarea__textarea' @@ -181,18 +203,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { </label> <div className={`autosuggest-textarea__suggestions ${suggestionsHidden || suggestions.isEmpty() ? '' : 'autosuggest-textarea__suggestions--visible'}`}> - {suggestions.map((suggestion, i) => ( - <div - role='button' - tabIndex='0' - key={suggestion} - data-index={suggestion} - className={`autosuggest-textarea__suggestions__item ${i === selectedSuggestion ? 'selected' : ''}`} - onMouseDown={this.onSuggestionClick} - > - <AutosuggestAccountContainer id={suggestion} /> - </div> - ))} + {suggestions.map(this.renderSuggestion)} </div> </div> ); |