From d97de4d57667a2cf4dff4bfe7803080e2ca54098 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 13 Jul 2017 17:37:43 +0100 Subject: [PATCH] Implement disabled-by-default setting for auto-replacement of plaintext emojis FTR a list of plaintexts and their unicode equivalents can be found here - https://github.com/vector-im/riot-web/issues/4554#issuecomment-314374303 Pressing space after a matching emoji will replace the plaintext emoji with the equivalent unicode emoji. --- src/components/structures/UserSettings.js | 4 +++ .../views/rooms/MessageComposerInput.js | 31 +++++++++++++++++++ src/i18n/strings/en_EN.json | 3 +- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index a172ca4dbf..45c52c7f1d 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -93,6 +93,10 @@ const SETTINGS_LABELS = [ id: 'enableSyntaxHighlightLanguageDetection', label: 'Enable automatic language detection for syntax highlighting', }, + { + id: 'MessageComposerInput.autoReplaceEmoji', + label: 'Automatically replace plain text Emoji', + }, /* { id: 'useFixedWidthFont', diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index abe63ad491..acd49f6fb4 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -43,6 +43,11 @@ import Markdown from '../../../Markdown'; import ComposerHistoryManager from '../../../ComposerHistoryManager'; import MessageComposerStore from '../../../stores/MessageComposerStore'; +import {asciiRegexp, shortnameToUnicode, emojioneList, asciiList, mapUnicodeToShort} from 'emojione'; +const EMOJI_SHORTNAMES = Object.keys(emojioneList); +const EMOJI_UNICODE_TO_SHORTNAME = mapUnicodeToShort(); +const REGEX_EMOJI_WHITESPACE = new RegExp('(' + asciiRegexp + ')\\s$'); + const TYPING_USER_TIMEOUT = 10000, TYPING_SERVER_TIMEOUT = 30000; const ZWS_CODE = 8203; @@ -369,6 +374,32 @@ export default class MessageComposerInput extends React.Component { editorState = EditorState.forceSelection(editorState, currentSelection); } + // Automatic replacement of plaintext emoji to Unicode emoji + if (UserSettingsStore.getSyncedSetting('MessageComposerInput.autoReplaceEmoji', false)) { + // The first matched group includes just the matched plaintext emoji + const emojiMatch = REGEX_EMOJI_WHITESPACE.exec(text.slice(0, currentStartOffset)); + if(emojiMatch) { + // plaintext -> hex unicode + const emojiUc = asciiList[emojiMatch[1]]; + // hex unicode -> shortname -> actual unicode + const unicodeEmoji = shortnameToUnicode(EMOJI_UNICODE_TO_SHORTNAME[emojiUc]); + const newContentState = Modifier.replaceText( + editorState.getCurrentContent(), + currentSelection.merge({ + anchorOffset: currentStartOffset - emojiMatch[0].length, + focusOffset: currentStartOffset, + }), + unicodeEmoji, + ); + editorState = EditorState.push( + editorState, + newContentState, + 'insert-characters', + ); + editorState = EditorState.forceSelection(editorState, newContentState.getSelectionAfter()); + } + } + /* Since a modification was made, set originalEditorState to null, since newState is now our original */ this.setState({ editorState, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index e041649906..4841f2f0de 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -955,5 +955,6 @@ "To join an exisitng group you'll have to know its group identifier; this will look something like +example:matrix.org.": "To join an exisitng group you'll have to know its group identifier; this will look something like +example:matrix.org.", "Featured Rooms:": "Featured Rooms:", "Error whilst fetching joined groups": "Error whilst fetching joined groups", - "Featured Users:": "Featured Users:" + "Featured Users:": "Featured Users:", + "Automatically replace plain text Emoji": "Automatically replace plain text Emoji" }