diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index 8be5b939f9..a63894a989 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -1,5 +1,6 @@ import api from '../api'; import { emojiIndex } from 'emoji-mart'; +import { throttle } from 'lodash'; import { updateTimeline, @@ -247,23 +248,30 @@ export function clearComposeSuggestions() { }; }; +const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, token) => { + api(getState).get('/api/v1/accounts/search', { + params: { + q: token.slice(1), + resolve: false, + limit: 4, + }, + }).then(response => { + dispatch(readyComposeSuggestionsAccounts(token, response.data)); + }); +}, 200, { leading: true, trailing: true }); + +const fetchComposeSuggestionsEmojis = (dispatch, getState, token) => { + const results = emojiIndex.search(token.replace(':', ''), { maxResults: 5 }); + dispatch(readyComposeSuggestionsEmojis(token, results)); +}; + export function fetchComposeSuggestions(token) { return (dispatch, getState) => { if (token[0] === ':') { - const results = emojiIndex.search(token.replace(':', ''), { maxResults: 3 }); - dispatch(readyComposeSuggestionsEmojis(token, results)); - return; + fetchComposeSuggestionsEmojis(dispatch, getState, token); + } else { + fetchComposeSuggestionsAccounts(dispatch, getState, token); } - - api(getState).get('/api/v1/accounts/search', { - params: { - q: token.slice(1), - resolve: false, - limit: 4, - }, - }).then(response => { - dispatch(readyComposeSuggestionsAccounts(token, response.data)); - }); }; }; diff --git a/app/javascript/mastodon/components/autosuggest_emoji.js b/app/javascript/mastodon/components/autosuggest_emoji.js index e2866e8e47..31dc1dbb17 100644 --- a/app/javascript/mastodon/components/autosuggest_emoji.js +++ b/app/javascript/mastodon/components/autosuggest_emoji.js @@ -17,8 +17,13 @@ export default class AutosuggestEmoji extends React.PureComponent { if (emoji.custom) { url = emoji.imageUrl; } else { - const [ filename ] = unicodeMapping[emoji.native]; - url = `${assetHost}/emoji/${filename}.svg`; + const mapping = unicodeMapping[emoji.native] || unicodeMapping[emoji.native.replace(/\uFE0F$/, '')]; + + if (!mapping) { + return null; + } + + url = `${assetHost}/emoji/${mapping[0]}.svg`; } return ( diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js index d310410611..7d175a912d 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.js +++ b/app/javascript/mastodon/features/compose/components/compose_form.js @@ -5,7 +5,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import ReplyIndicatorContainer from '../containers/reply_indicator_container'; import AutosuggestTextarea from '../../../components/autosuggest_textarea'; -import { debounce } from 'lodash'; import UploadButtonContainer from '../containers/upload_button_container'; import { defineMessages, injectIntl } from 'react-intl'; import Collapsable from '../../../components/collapsable'; @@ -82,9 +81,9 @@ export default class ComposeForm extends ImmutablePureComponent { this.props.onClearSuggestions(); } - onSuggestionsFetchRequested = debounce((token) => { + onSuggestionsFetchRequested = (token) => { this.props.onFetchSuggestions(token); - }, 500, { trailing: true }) + } onSuggestionSelected = (tokenStart, token, value) => { this._restoreCaret = null;