From e2685ccc81f04e1a63a97af80686bf85027418a6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 14 Jul 2017 19:47:53 +0200 Subject: Fix #4149, fix #1199 - Store emojis as unicode (#4189) - Use unicode when selecting emoji through picker - Convert shortcodes to unicode when storing text input server-side - Do not convert shortcodes in JS anymore --- app/javascript/mastodon/actions/compose.js | 7 ++++--- app/javascript/mastodon/emoji.js | 24 +++------------------- .../features/compose/components/compose_form.js | 3 ++- .../compose/components/emoji_picker_dropdown.js | 5 +++-- app/javascript/mastodon/reducers/compose.js | 2 +- app/javascript/styles/components.scss | 1 + 6 files changed, 14 insertions(+), 28 deletions(-) (limited to 'app/javascript') diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index 647a52b93..9f05a53e9 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -2,8 +2,6 @@ import api from '../api'; import { updateTimeline } from './timelines'; -import * as emojione from 'emojione'; - export const COMPOSE_CHANGE = 'COMPOSE_CHANGE'; export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST'; export const COMPOSE_SUBMIT_SUCCESS = 'COMPOSE_SUBMIT_SUCCESS'; @@ -73,11 +71,14 @@ export function mentionCompose(account, router) { export function submitCompose() { return function (dispatch, getState) { - const status = emojione.shortnameToUnicode(getState().getIn(['compose', 'text'], '')); + const status = getState().getIn(['compose', 'text'], ''); + if (!status || !status.length) { return; } + dispatch(submitComposeRequest()); + api(getState).post('/api/v1/statuses', { status, in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null), diff --git a/app/javascript/mastodon/emoji.js b/app/javascript/mastodon/emoji.js index 7043d5f3a..ed2180cd1 100644 --- a/app/javascript/mastodon/emoji.js +++ b/app/javascript/mastodon/emoji.js @@ -6,36 +6,18 @@ const trie = new Trie(Object.keys(emojione.jsEscapeMap)); function emojify(str) { // This walks through the string from start to end, ignoring any tags (

,
, etc.) - // and replacing valid shortnames like :smile: and :wink: as well as unicode strings + // and replacing valid unicode strings // that _aren't_ within tags with an version. - // The goal is to be the same as an emojione.regShortNames/regUnicode replacement, but faster. + // The goal is to be the same as an emojione.regUnicode replacement, but faster. let i = -1; let insideTag = false; - let insideShortname = false; - let shortnameStartIndex = -1; let match; while (++i < str.length) { const char = str.charAt(i); - if (insideShortname && char === ':') { - const shortname = str.substring(shortnameStartIndex, i + 1); - if (shortname in emojione.emojioneList) { - const unicode = emojione.emojioneList[shortname].unicode[emojione.emojioneList[shortname].unicode.length - 1]; - const alt = emojione.convert(unicode.toUpperCase()); - const replacement = `${alt}`; - str = str.substring(0, shortnameStartIndex) + replacement + str.substring(i + 1); - i += (replacement.length - shortname.length - 1); // jump ahead the length we've added to the string - } else { - i--; // stray colon, try again - } - insideShortname = false; - } else if (insideTag && char === '>') { + if (insideTag && char === '>') { insideTag = false; } else if (char === '<') { insideTag = true; - insideShortname = false; - } else if (!insideTag && char === ':') { - insideShortname = true; - shortnameStartIndex = i; } else if (!insideTag && (match = trie.search(str.substring(i)))) { const unicodeStr = match; if (unicodeStr in emojione.jsEscapeMap) { diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js index f7eeedc69..f07552947 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.js +++ b/app/javascript/mastodon/features/compose/components/compose_form.js @@ -136,7 +136,8 @@ export default class ComposeForm extends ImmutablePureComponent { handleEmojiPick = (data) => { const position = this.autosuggestTextarea.textarea.selectionStart; - this._restoreCaret = position + data.shortname.length + 1; + const emojiChar = String.fromCodePoint(parseInt(data.unicode, 16)); + this._restoreCaret = position + emojiChar.length + 1; this.props.onPickEmoji(position, data); } diff --git a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js index 83c66a5d5..acc584f20 100644 --- a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js +++ b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js @@ -109,11 +109,12 @@ export default class EmojiPickerDropdown extends React.PureComponent { 🙂 + { this.state.active && !this.state.loading && diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index a92b5aa23..ea3b78b67 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -118,7 +118,7 @@ const insertSuggestion = (state, position, token, completion) => { }; const insertEmoji = (state, position, emojiData) => { - const emoji = emojiData.shortname; + const emoji = String.fromCodePoint(parseInt(emojiData.unicode, 16)); return state.withMutations(map => { map.update('text', oldText => `${oldText.slice(0, position)}${emoji} ${oldText.slice(position)}`); diff --git a/app/javascript/styles/components.scss b/app/javascript/styles/components.scss index 0face646d..0420a2bed 100644 --- a/app/javascript/styles/components.scss +++ b/app/javascript/styles/components.scss @@ -2708,6 +2708,7 @@ button.icon-button.active i.fa-retweet { margin-left: 2px; width: 24px; outline: 0; + cursor: pointer; &:active, &:focus { -- cgit