From 7b8b7d97631682c3a929992cb16fe4cbda5756de Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Fri, 6 May 2022 15:47:29 +0300 Subject: [PATCH 01/12] Make emojis larger when multiple are sent at the same time --- src/CONST.js | 2 ++ src/libs/EmojiUtils.js | 25 +++++++++++++++++++ .../home/report/ReportActionItemFragment.js | 2 +- src/styles/styles.js | 2 +- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index 894cf295b27c..59b51b2d0b83 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -387,6 +387,8 @@ const CONST = { EMOJI_FREQUENT_ROW_COUNT: 3, + EMOJI_INVISIBLE_CODEPOINT: 'fe0f', + LOGIN_TYPE: { PHONE: 'phone', EMAIL: 'email', diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index 61684d37d0f9..044fedbab462 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -70,6 +70,30 @@ function isSingleEmoji(message) { return matchedUnicode === currentMessageUnicode; } +/** + * Validates that this string contains only emojis + * + * @param {String} message + * @returns {Boolean} + */ +function containsOnlyEmojis(message) { + const match = message.match(CONST.REGEX.EMOJIS); + if (match) { + const codes = []; + + _.map(match, emoji => _.map(getEmojiUnicode(emoji).split(' '), (code) => { + if (code !== CONST.EMOJI_INVISIBLE_CODEPOINT) { + codes.push(code); + } + return code; + })); + + const messageCodes = _.filter(_.map([...message], char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); + return codes.length === messageCodes.length; + } + return false; +} + /** * Get the header indices based on the max emojis per row * @param {Object[]} emojis @@ -176,4 +200,5 @@ export { getDynamicHeaderIndices, mergeEmojisWithFrequentlyUsedEmojis, addToFrequentlyUsedEmojis, + containsOnlyEmojis, }; diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index 194a865636f7..3d2ec24975dd 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -106,7 +106,7 @@ const ReportActionItemFragment = (props) => { ) : ( {Str.htmlDecode(props.fragment.text)} {props.fragment.isEdited && ( diff --git a/src/styles/styles.js b/src/styles/styles.js index d022567aa233..c11587ea9501 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1042,7 +1042,7 @@ const styles = { textDecorationLine: 'none', }, - singleEmojiText: { + multipleEmojisText: { fontSize: variables.fontSizeSingleEmoji, lineHeight: variables.fontSizeSingleEmojiHeight, }, From 10fc82e10c1f2b7bc57a8aa5f96807a170219262 Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Mon, 9 May 2022 20:29:20 +0300 Subject: [PATCH 02/12] Update comment --- src/libs/EmojiUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index 044fedbab462..ecb71de9362b 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -71,7 +71,7 @@ function isSingleEmoji(message) { } /** - * Validates that this string contains only emojis + * Validates that this message contains only emojis * * @param {String} message * @returns {Boolean} From 316d03082bbc571e60c13c671be85f3b12666301 Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Mon, 9 May 2022 20:38:03 +0300 Subject: [PATCH 03/12] Memoize getEmojiUnicode function --- src/libs/EmojiUtils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index ecb71de9362b..e72096992223 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -9,7 +9,7 @@ import * as User from './actions/User'; * @param {String} input * @returns {String} */ -function getEmojiUnicode(input) { +const getEmojiUnicode = _.memoize((input) => { if (input.length === 0) { return ''; } @@ -40,7 +40,7 @@ function getEmojiUnicode(input) { } } return _.map(pairs, val => parseInt(val, 10).toString(16)).join(' '); -} +}); /** * Function to remove Skin Tone and utf16 surrogates from Emoji From f89d249f5e7118027ecde47fb9a9728c462ab81d Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Mon, 9 May 2022 21:17:07 +0300 Subject: [PATCH 04/12] Return early in containsOnlyEmojis function --- src/libs/EmojiUtils.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index e72096992223..4e9d654e0ee0 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -78,20 +78,21 @@ function isSingleEmoji(message) { */ function containsOnlyEmojis(message) { const match = message.match(CONST.REGEX.EMOJIS); - if (match) { - const codes = []; - _.map(match, emoji => _.map(getEmojiUnicode(emoji).split(' '), (code) => { - if (code !== CONST.EMOJI_INVISIBLE_CODEPOINT) { - codes.push(code); - } - return code; - })); - - const messageCodes = _.filter(_.map([...message], char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); - return codes.length === messageCodes.length; + if (!match) { + return false; } - return false; + + const codes = []; + _.map(match, emoji => _.map(getEmojiUnicode(emoji).split(' '), (code) => { + if (code !== CONST.EMOJI_INVISIBLE_CODEPOINT) { + codes.push(code); + } + return code; + })); + + const messageCodes = _.filter(_.map([...message], char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); + return codes.length === messageCodes.length; } /** From d3ac4623eaf063114d6ab2c15038d72fa4d5b3af Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Tue, 10 May 2022 11:25:58 +0300 Subject: [PATCH 05/12] Update styles name --- src/pages/home/report/ReportActionItemFragment.js | 2 +- src/styles/styles.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index 3d2ec24975dd..76ab07500782 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -106,7 +106,7 @@ const ReportActionItemFragment = (props) => { ) : ( {Str.htmlDecode(props.fragment.text)} {props.fragment.isEdited && ( diff --git a/src/styles/styles.js b/src/styles/styles.js index c11587ea9501..11c67fd6819c 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1042,7 +1042,7 @@ const styles = { textDecorationLine: 'none', }, - multipleEmojisText: { + onlyEmojisText: { fontSize: variables.fontSizeSingleEmoji, lineHeight: variables.fontSizeSingleEmojiHeight, }, From e9945b39acb4aff6e0b3e205e6525d8fe22b892f Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Tue, 10 May 2022 20:17:08 +0300 Subject: [PATCH 06/12] Rename onlyEmojis style variables --- src/styles/styles.js | 4 ++-- src/styles/variables.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/styles/styles.js b/src/styles/styles.js index 11c67fd6819c..9a8b59f10bd1 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1043,8 +1043,8 @@ const styles = { }, onlyEmojisText: { - fontSize: variables.fontSizeSingleEmoji, - lineHeight: variables.fontSizeSingleEmojiHeight, + fontSize: variables.fontSizeOnlyEmojis, + lineHeight: variables.fontSizeOnlyEmojisHeight, }, createMenuPositionSidebar: { diff --git a/src/styles/variables.js b/src/styles/variables.js index 4302947ac879..506755712154 100644 --- a/src/styles/variables.js +++ b/src/styles/variables.js @@ -14,8 +14,8 @@ export default { avatarSizeSmall: 28, avatarSizeSubscript: 20, avatarSizeSmallSubscript: 14, - fontSizeSingleEmoji: 30, - fontSizeSingleEmojiHeight: 35, + fontSizeOnlyEmojis: 30, + fontSizeOnlyEmojisHeight: 35, fontSizeSmall: 11, fontSizeExtraSmall: 9, fontSizeLabel: 13, From 4a782667992828eca6b18238b002817b26e8f183 Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Tue, 10 May 2022 20:17:56 +0300 Subject: [PATCH 07/12] Ignore spaces in containsOnlyEmojis function --- src/libs/EmojiUtils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index 4e9d654e0ee0..2cbecbff5cd6 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -77,7 +77,7 @@ function isSingleEmoji(message) { * @returns {Boolean} */ function containsOnlyEmojis(message) { - const match = message.match(CONST.REGEX.EMOJIS); + const match = message.replace(/ /g, '').match(CONST.REGEX.EMOJIS); if (!match) { return false; @@ -91,7 +91,7 @@ function containsOnlyEmojis(message) { return code; })); - const messageCodes = _.filter(_.map([...message], char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); + const messageCodes = _.filter(_.map([...message.replace(/ /g, '')], char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); return codes.length === messageCodes.length; } From d7362250a3c86a71192c8a2016a5e4920225d518 Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Tue, 10 May 2022 23:33:57 +0300 Subject: [PATCH 08/12] Add support for multiple emojis with line breaks between them --- src/libs/EmojiUtils.js | 5 +++-- src/pages/home/report/ReportActionItemFragment.js | 10 +++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index 2cbecbff5cd6..b928f33fedbe 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -77,7 +77,7 @@ function isSingleEmoji(message) { * @returns {Boolean} */ function containsOnlyEmojis(message) { - const match = message.replace(/ /g, '').match(CONST.REGEX.EMOJIS); + const match = message.replace(/ /g, '').replaceAll('\n', '').match(CONST.REGEX.EMOJIS); if (!match) { return false; @@ -91,7 +91,8 @@ function containsOnlyEmojis(message) { return code; })); - const messageCodes = _.filter(_.map([...message.replace(/ /g, '')], char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); + const messageCodes = _.filter(_.map([...message.replace(/ /g, '').replaceAll('\n', '')], + char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); return codes.length === messageCodes.length; } diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index 76ab07500782..25a651929549 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -68,7 +68,7 @@ const defaultProps = { const ReportActionItemFragment = (props) => { switch (props.fragment.type) { - case 'COMMENT': + case 'COMMENT': { // If this is an attachment placeholder, return the placeholder component if (props.isAttachment && props.loading) { return ( @@ -97,6 +97,13 @@ const ReportActionItemFragment = (props) => { ); } + const differByLineBreaksOnly = props.fragment.html.replaceAll('
', ' ') === props.fragment.text; + if (differByLineBreaksOnly) { + const textWithLineBreaks = props.fragment.html.replaceAll('
', '\n'); + // eslint-disable-next-line no-param-reassign + props.fragment = {...props.fragment, text: textWithLineBreaks, html: textWithLineBreaks}; + } + // Only render HTML if we have html in the fragment return props.fragment.html !== props.fragment.text ? ( @@ -119,6 +126,7 @@ const ReportActionItemFragment = (props) => { )}
); + } case 'TEXT': return ( From 5b29f4f13435b40b21f872f1140ded0f99b8bb4a Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Tue, 10 May 2022 23:41:46 +0300 Subject: [PATCH 09/12] Add comment about spread operator in containsOnlyEmojis --- src/libs/EmojiUtils.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index b928f33fedbe..edbdf14c33fb 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -91,6 +91,8 @@ function containsOnlyEmojis(message) { return code; })); + // Emojis are stored as multiple characters, so we're using spread operator + // to iterate over the actual emojis, not just characters that compose them const messageCodes = _.filter(_.map([...message.replace(/ /g, '').replaceAll('\n', '')], char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); return codes.length === messageCodes.length; From e493a51fdc3a1292247b9d933145cf1bc2ba5fac Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Wed, 11 May 2022 10:44:37 +0300 Subject: [PATCH 10/12] Add comment in ReportActionItemFragment --- src/pages/home/report/ReportActionItemFragment.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index 25a651929549..8cfcfe9aac73 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -97,6 +97,9 @@ const ReportActionItemFragment = (props) => { ); } + // If the only difference between fragment.text and fragment.html is
tags + // we replace them with line breaks and render it as text, not as html. + // This is done to render emojis with line breaks between them as text. const differByLineBreaksOnly = props.fragment.html.replaceAll('
', ' ') === props.fragment.text; if (differByLineBreaksOnly) { const textWithLineBreaks = props.fragment.html.replaceAll('
', '\n'); From 7933540ff0f350f41f6623f5fa91793d8230721d Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Wed, 11 May 2022 17:34:49 +0300 Subject: [PATCH 11/12] Fix linter error --- src/CONST.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CONST.js b/src/CONST.js index fcb1a245e30a..c0e26e78fca7 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -388,7 +388,7 @@ const CONST = { EMOJI_FREQUENT_ROW_COUNT: 3, EMOJI_INVISIBLE_CODEPOINT: 'fe0f', - + TOOLTIP_MAX_LINES: 3, LOGIN_TYPE: { From 9c86b32dab4b12dc2f0a5d2ea5ad7646fb42498d Mon Sep 17 00:00:00 2001 From: Yevhenii Voloshchak Date: Thu, 12 May 2022 20:50:27 +0300 Subject: [PATCH 12/12] Trim message only once --- src/libs/EmojiUtils.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index edbdf14c33fb..208dd6b1cf4d 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -77,7 +77,8 @@ function isSingleEmoji(message) { * @returns {Boolean} */ function containsOnlyEmojis(message) { - const match = message.replace(/ /g, '').replaceAll('\n', '').match(CONST.REGEX.EMOJIS); + const trimmedMessage = message.replace(/ /g, '').replaceAll('\n', ''); + const match = trimmedMessage.match(CONST.REGEX.EMOJIS); if (!match) { return false; @@ -93,8 +94,7 @@ function containsOnlyEmojis(message) { // Emojis are stored as multiple characters, so we're using spread operator // to iterate over the actual emojis, not just characters that compose them - const messageCodes = _.filter(_.map([...message.replace(/ /g, '').replaceAll('\n', '')], - char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); + const messageCodes = _.filter(_.map([...trimmedMessage], char => getEmojiUnicode(char)), string => string.length > 0 && string !== CONST.EMOJI_INVISIBLE_CODEPOINT); return codes.length === messageCodes.length; }