0
0
Fork 0

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
This commit is contained in:
Eugen Rochko 2017-07-14 19:47:53 +02:00 committed by GitHub
parent c42092ba7a
commit e2685ccc81
15 changed files with 69 additions and 71 deletions

View file

@ -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),

View file

@ -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 (<p>, <br>, 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 <img> 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 = `<img draggable="false" class="emojione" alt="${alt}" title="${shortname}" src="/emoji/${unicode}.svg" />`;
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) {

View file

@ -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);
}

View file

@ -109,11 +109,12 @@ export default class EmojiPickerDropdown extends React.PureComponent {
<Dropdown ref={this.setRef} className='emoji-picker__dropdown' onShow={this.onShowDropdown} onHide={this.onHideDropdown}>
<DropdownTrigger className='emoji-button' title={intl.formatMessage(messages.emoji)}>
<img
draggable='false'
className={`emojione ${active && loading ? 'pulse-loading' : ''}`}
alt='🙂' src='/emoji/1f602.svg'
alt='🙂'
src='/emoji/1f602.svg'
/>
</DropdownTrigger>
<DropdownContent className='dropdown__left'>
{
this.state.active && !this.state.loading &&

View file

@ -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)}`);