diff options
6 files changed, 17 insertions, 135 deletions
diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index c86184046..5f265a750 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -1,5 +1,4 @@ import api from '../api'; -import emojione from 'emojione'; import { updateTimeline, @@ -23,7 +22,6 @@ export const COMPOSE_UPLOAD_UNDO = 'COMPOSE_UPLOAD_UNDO'; export const COMPOSE_SUGGESTIONS_CLEAR = 'COMPOSE_SUGGESTIONS_CLEAR'; export const COMPOSE_SUGGESTIONS_READY = 'COMPOSE_SUGGESTIONS_READY'; -export const COMPOSE_SUGGESTIONS_READY_TXT = 'COMPOSE_SUGGESTIONS_READY_TXT'; export const COMPOSE_SUGGESTION_SELECT = 'COMPOSE_SUGGESTION_SELECT'; export const COMPOSE_MOUNT = 'COMPOSE_MOUNT'; @@ -213,56 +211,18 @@ export function clearComposeSuggestions() { }; }; -let allShortcodes = null; // cached list of all shortcodes for suggestions - export function fetchComposeSuggestions(token) { - let leading = token[0]; - - if (leading === '@') { - // handle search - return (dispatch, getState) => { - api(getState).get('/api/v1/accounts/search', { - params: { - q: token.slice(1), // remove the '@' - resolve: false, - limit: 4, - }, - }).then(response => { - dispatch(readyComposeSuggestions(token, response.data)); - }); - }; - } else if (leading === ':') { - // shortcode - if (!allShortcodes) { - allShortcodes = Object.keys(emojione.emojioneList); - // TODO when we have custom emojons merged, add them to this shortcode list - } - return (dispatch) => { - const innertxt = token.slice(1); - if (innertxt.length > 1) { // prevent searching single letter, causes lag - dispatch(readyComposeSuggestionsTxt(token, allShortcodes.filter((sc) => { - return sc.indexOf(innertxt) !== -1; - }).sort((a, b) => { - if (a.indexOf(token) === 0 && b.indexOf(token) === 0) return a.localeCompare(b); - if (a.indexOf(token) === 0) return -1; - if (b.indexOf(token) === 0) return 1; - return a.localeCompare(b); - }))); - } - }; - } else { - // hashtag - return (dispatch, getState) => { - api(getState).get('/api/v1/search', { - params: { - q: token, - resolve: true, - }, - }).then(response => { - dispatch(readyComposeSuggestionsTxt(token, response.data.hashtags.map((ht) => `#${ht}`))); - }); - }; - } + return (dispatch, getState) => { + api(getState).get('/api/v1/accounts/search', { + params: { + q: token, + resolve: false, + limit: 4, + }, + }).then(response => { + dispatch(readyComposeSuggestions(token, response.data)); + }); + }; }; export function readyComposeSuggestions(token, accounts) { @@ -273,19 +233,9 @@ export function readyComposeSuggestions(token, accounts) { }; }; -export function readyComposeSuggestionsTxt(token, items) { - return { - type: COMPOSE_SUGGESTIONS_READY_TXT, - token, - items, - }; -}; - export function selectComposeSuggestion(position, token, accountId) { return (dispatch, getState) => { - const completion = (typeof accountId === 'string') ? - accountId.slice(1) : // text suggestion: discard the leading : or # - the replacing code replaces only what follows - getState().getIn(['accounts', accountId, 'acct']); + const completion = getState().getIn(['accounts', accountId, 'acct']); dispatch({ type: COMPOSE_SUGGESTION_SELECT, diff --git a/app/javascript/mastodon/components/autosuggest_textarea.js b/app/javascript/mastodon/components/autosuggest_textarea.js index 1c7ffe196..82a10687f 100644 --- a/app/javascript/mastodon/components/autosuggest_textarea.js +++ b/app/javascript/mastodon/components/autosuggest_textarea.js @@ -1,6 +1,5 @@ import React from 'react'; import AutosuggestAccountContainer from '../features/compose/containers/autosuggest_account_container'; -import AutosuggestShortcode from '../features/compose/components/autosuggest_shortcode'; import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import { isRtl } from '../rtl'; @@ -19,12 +18,11 @@ const textAtCursorMatchesToken = (str, caretPosition) => { word = str.slice(left, right + caretPosition); } - if (!word || word.trim().length < 2 || ['@', ':', '#'].indexOf(word[0]) === -1) { + if (!word || word.trim().length < 2 || word[0] !== '@') { return [null, null]; } - word = word.trim().toLowerCase(); - // was: .slice(1); - we leave the leading char there, handler can decide what to do based on it + word = word.trim().toLowerCase().slice(1); if (word.length > 0) { return [left + 1, word]; @@ -43,7 +41,6 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { onSuggestionSelected: PropTypes.func.isRequired, onSuggestionsClearRequested: PropTypes.func.isRequired, onSuggestionsFetchRequested: PropTypes.func.isRequired, - onLocalSuggestionsFetchRequested: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired, onKeyUp: PropTypes.func, onKeyDown: PropTypes.func, @@ -67,13 +64,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { if (token !== null && this.state.lastToken !== token) { this.setState({ lastToken: token, selectedSuggestion: 0, tokenStart }); - if (token[0] === ':') { - // faster debounce for shortcodes. - // hashtags have long debounce because they're fetched from server. - this.props.onLocalSuggestionsFetchRequested(token); - } else { - this.props.onSuggestionsFetchRequested(token); - } + this.props.onSuggestionsFetchRequested(token); } else if (token === null) { this.setState({ lastToken: null }); this.props.onSuggestionsClearRequested(); @@ -137,9 +128,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { } onSuggestionClick = (e) => { - // leave suggestion string unchanged if it's a hash / shortcode suggestion. convert account number to int. - const suggestionStr = e.currentTarget.getAttribute('data-index'); - const suggestion = [':', '#'].indexOf(suggestionStr[0]) !== -1 ? suggestionStr : Number(suggestionStr); + const suggestion = Number(e.currentTarget.getAttribute('data-index')); e.preventDefault(); this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion); this.textarea.focus(); @@ -180,14 +169,6 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { style.direction = 'rtl'; } - let makeItem = (suggestion) => { - if (suggestion[0] === ':') return <AutosuggestShortcode shortcode={suggestion} />; - if (suggestion[0] === '#') return suggestion; // hashtag - - // else - accounts are always returned as IDs with no prefix - return <AutosuggestAccountContainer id={suggestion} />; - }; - return ( <div className='autosuggest-textarea'> <label> @@ -219,7 +200,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { className={`autosuggest-textarea__suggestions__item ${i === selectedSuggestion ? 'selected' : ''}`} onMouseDown={this.onSuggestionClick} > - {makeItem(suggestion)} + <AutosuggestAccountContainer id={suggestion} /> </div> ))} </div> diff --git a/app/javascript/mastodon/features/compose/components/autosuggest_shortcode.js b/app/javascript/mastodon/features/compose/components/autosuggest_shortcode.js deleted file mode 100644 index 4a0ef96b3..000000000 --- a/app/javascript/mastodon/features/compose/components/autosuggest_shortcode.js +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import PropTypes from 'prop-types'; -import emojione from 'emojione'; - -// This is bad, but I don't know how to make it work without importing the entirety of emojione. -// taken from some old version of mastodon before they gutted emojione to "emojione_light" -const shortnameToImage = str => str.replace(emojione.regShortNames, shortname => { - if (typeof shortname === 'undefined' || shortname === '' || !(shortname in emojione.emojioneList)) { - return shortname; - } - - const unicode = emojione.emojioneList[shortname].unicode[emojione.emojioneList[shortname].unicode.length - 1]; - const alt = emojione.convert(unicode.toUpperCase()); - - return `<img draggable="false" class="emojione" alt="${alt}" src="/emoji/${unicode}.svg" />`; -}); - -export default class AutosuggestShortcode extends ImmutablePureComponent { - - static propTypes = { - shortcode: PropTypes.string.isRequired, - }; - - render () { - const { shortcode } = this.props; - - let emoji = shortnameToImage(shortcode); - - return ( - <div className='autosuggest-account'> - <div className='autosuggest-account-icon' dangerouslySetInnerHTML={{ __html: emoji }} /> - {shortcode} - </div> - ); - } - -} diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js index 5befd0337..8fbcf6a3d 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.js +++ b/app/javascript/mastodon/features/compose/components/compose_form.js @@ -98,10 +98,6 @@ export default class ComposeForm extends ImmutablePureComponent { this.props.onFetchSuggestions(token); }, 500, { trailing: true }) - onLocalSuggestionsFetchRequested = debounce((token) => { - this.props.onFetchSuggestions(token); - }, 100, { trailing: true }) - onSuggestionSelected = (tokenStart, token, value) => { this._restoreCaret = null; this.props.onSuggestionSelected(tokenStart, token, value); @@ -238,7 +234,6 @@ export default class ComposeForm extends ImmutablePureComponent { suggestions={this.props.suggestions} onKeyDown={this.handleKeyDown} onSuggestionsFetchRequested={this.onSuggestionsFetchRequested} - onLocalSuggestionsFetchRequested={this.onLocalSuggestionsFetchRequested} onSuggestionsClearRequested={this.onSuggestionsClearRequested} onSuggestionSelected={this.onSuggestionSelected} onPaste={onPaste} diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index d2b29721f..e7a3567b4 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -15,7 +15,6 @@ import { COMPOSE_UPLOAD_PROGRESS, COMPOSE_SUGGESTIONS_CLEAR, COMPOSE_SUGGESTIONS_READY, - COMPOSE_SUGGESTIONS_READY_TXT, COMPOSE_SUGGESTION_SELECT, COMPOSE_ADVANCED_OPTIONS_CHANGE, COMPOSE_SENSITIVITY_CHANGE, @@ -264,9 +263,6 @@ export default function compose(state = initialState, action) { return state.update('suggestions', ImmutableList(), list => list.clear()).set('suggestion_token', null); case COMPOSE_SUGGESTIONS_READY: return state.set('suggestions', ImmutableList(action.accounts.map(item => item.id))).set('suggestion_token', action.token); - case COMPOSE_SUGGESTIONS_READY_TXT: - // suggestion received that is not an account - hashtag or emojo - return state.set('suggestions', ImmutableList(action.items.map(item => item))).set('suggestion_token', action.token); case COMPOSE_SUGGESTION_SELECT: return insertSuggestion(state, action.position, action.token, action.completion); case TIMELINE_DELETE: diff --git a/app/javascript/styles/components.scss b/app/javascript/styles/components.scss index af85b6b50..3cbfb7d3a 100644 --- a/app/javascript/styles/components.scss +++ b/app/javascript/styles/components.scss @@ -2040,8 +2040,6 @@ .autosuggest-textarea__suggestions { display: none; position: absolute; - max-height: 300px; - overflow-y: auto; top: 100%; width: 100%; z-index: 99; |