diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js
index 2266522bfe..2b7384a5aa 100644
--- a/src/HtmlUtils.js
+++ b/src/HtmlUtils.js
@@ -53,7 +53,6 @@ const ZWJ_REGEX = new RegExp("\u200D|\u2003", "g");
const WHITESPACE_REGEX = new RegExp("\\s", "g");
const BIGEMOJI_REGEX = new RegExp(`^(${EMOJIBASE_REGEX.source})+$`, 'i');
-const SINGLE_EMOJI_REGEX = new RegExp(`^(${EMOJIBASE_REGEX.source})$`, 'i');
const COLOR_REGEX = /^#[0-9a-fA-F]{6}$/;
@@ -72,6 +71,21 @@ function mightContainEmoji(str) {
return SURROGATE_PAIR_PATTERN.test(str) || SYMBOL_PATTERN.test(str);
}
+/**
+ * Find emoji data in emojibase by character.
+ *
+ * @param {String} char The emoji character
+ * @return {Object} The emoji data
+ */
+export function findEmojiData(char) {
+ // Check against both the char and the char with an empty variation selector
+ // appended because that's how emojibase stores its base emojis which have
+ // variations.
+ // See also https://github.com/vector-im/riot-web/issues/9785.
+ const emptyVariation = char + VARIATION_SELECTOR;
+ return EMOJIBASE.find(e => e.unicode === char || e.unicode === emptyVariation);
+}
+
/**
* Returns the shortcode for an emoji character.
*
@@ -79,10 +93,7 @@ function mightContainEmoji(str) {
* @return {String} The shortcode (such as :thumbup:)
*/
export function unicodeToShortcode(char) {
- // Check against both the char and the char with an empty variation selector appended because that's how
- // emoji-base stores its base emojis which have variations. https://github.com/vector-im/riot-web/issues/9785
- const emptyVariation = char + VARIATION_SELECTOR;
- const data = EMOJIBASE.find(e => e.unicode === char || e.unicode === emptyVariation);
+ const data = findEmojiData(char);
return (data && data.shortcodes ? `:${data.shortcodes[0]}:` : '');
}
diff --git a/src/components/views/emojipicker/EmojiPicker.js b/src/components/views/emojipicker/EmojiPicker.js
index 48713b90d8..9fe8b4c81e 100644
--- a/src/components/views/emojipicker/EmojiPicker.js
+++ b/src/components/views/emojipicker/EmojiPicker.js
@@ -48,7 +48,14 @@ const DATA_BY_CATEGORY = {
};
const DATA_BY_EMOJI = {};
+const VARIATION_SELECTOR = String.fromCharCode(0xFE0F);
EMOJIBASE.forEach(emoji => {
+ if (emoji.unicode.includes(VARIATION_SELECTOR)) {
+ // Clone data into variation-less version
+ emoji = Object.assign({}, emoji, {
+ unicode: emoji.unicode.replace(VARIATION_SELECTOR, ""),
+ });
+ }
DATA_BY_EMOJI[emoji.unicode] = emoji;
const categoryId = EMOJIBASE_CATEGORY_IDS[emoji.group];
if (DATA_BY_CATEGORY.hasOwnProperty(categoryId)) {
@@ -82,7 +89,10 @@ class EmojiPicker extends React.Component {
viewportHeight: 280,
};
- this.recentlyUsed = recent.get().map(unicode => DATA_BY_EMOJI[unicode]);
+ // Convert recent emoji characters to emoji data, removing unknowns.
+ this.recentlyUsed = recent.get()
+ .map(unicode => DATA_BY_EMOJI[unicode])
+ .filter(data => !!data);
this.memoizedDataByCategory = {
recent: this.recentlyUsed,
...DATA_BY_CATEGORY,
diff --git a/src/components/views/emojipicker/QuickReactions.js b/src/components/views/emojipicker/QuickReactions.js
index 71a53984cc..8444fb2d9c 100644
--- a/src/components/views/emojipicker/QuickReactions.js
+++ b/src/components/views/emojipicker/QuickReactions.js
@@ -16,17 +16,19 @@ limitations under the License.
import React from 'react';
import PropTypes from 'prop-types';
-import EMOJIBASE from 'emojibase-data/en/compact.json';
import sdk from '../../../index';
import { _t } from '../../../languageHandler';
+import { findEmojiData } from '../../../HtmlUtils';
-const QUICK_REACTIONS = ["👍", "👎", "😄", "🎉", "😕", "❤️", "🚀", "👀"];
-EMOJIBASE.forEach(emoji => {
- const index = QUICK_REACTIONS.indexOf(emoji.unicode);
- if (index !== -1) {
- QUICK_REACTIONS[index] = emoji;
+const QUICK_REACTIONS = ["👍", "👎", "😄", "🎉", "😕", "❤️", "🚀", "👀"].map(emoji => {
+ const data = findEmojiData(emoji);
+ if (!data) {
+ throw new Error(`Emoji ${emoji} doesn't exist in emojibase`);
}
+ // Prefer our unicode value for quick reactions (which does not have
+ // variation selectors).
+ return Object.assign({}, data, { unicode: emoji });
});
class QuickReactions extends React.Component {