Use jumbo emoji for short emoji-only messages (#207)
authorEmi <tts1848@cs.rit.edu>
Mon, 27 Dec 2021 04:54:07 +0000 (23:54 -0500)
committerGitHub <noreply@github.com>
Mon, 27 Dec 2021 04:54:07 +0000 (10:24 +0530)
* Display messages containing only <7 emoji bigger

* Amending PR: Address mentioned concerns

This fixes several concerns raised during the PR review process.  A summary of the changes
implemented is below:
- Size jumbo emoji using the text-h1 class, instead of hardcoding a size
- Increase the emoji limit to 10
- Re-wrap m.text messages in a p tag, fixing a bug where newlines were lost

src/app/molecules/message/Message.jsx
src/app/molecules/message/Message.scss

index b9db3aa94a082a329f8bf8401150f6e82dc16e7e..054f60be3a3132eb4c55480090d00439a8050015 100644 (file)
@@ -172,13 +172,42 @@ const MessageBody = React.memo(({
   // if body is not string it is a React element.
   if (typeof body !== 'string') return <div className="message__body">{body}</div>;
 
-  const content = isCustomHTML
+  let content = isCustomHTML
     ? twemojify(sanitizeCustomHtml(body), undefined, true, false)
-    : <p>{twemojify(body, undefined, true)}</p>;
+    : twemojify(body, undefined, true);
+
+  // Determine if this message should render with large emojis
+  // Criteria:
+  // - Contains only emoji
+  // - Contains no more than 10 emoji
+  let emojiOnly = false;
+  if (content.type === 'img') {
+    // If this messages contains only a single (inline) image
+    emojiOnly = true;
+  } else if (content.constructor.name === 'Array') {
+    // Otherwise, it might be an array of images / texb
+
+    // Count the number of emojis
+    const nEmojis = content.filter((e) => e.type === 'img').length;
+
+    // Make sure there's no text besides whitespace
+    if (nEmojis <= 10 && content.every((element) => (
+      (typeof element === 'object' && element.type === 'img')
+      || (typeof element === 'string' && /^\s*$/g.test(element))
+    ))) {
+      emojiOnly = true;
+    }
+  }
+
+  if (!isCustomHTML) {
+    // If this is a plaintext message, wrap it in a <p> element (automatically applying
+    // white-space: pre-wrap) in order to preserve newlines
+    content = (<p>{content}</p>);
+  }
 
   return (
     <div className="message__body">
-      <div className="text text-b1">
+      <div className={`text ${emojiOnly ? 'text-h1' : 'text-b1'}`}>
         { msgType === 'm.emote' && (
           <>
             {'* '}
index c72a0b7bf6c53ce60343a6001fc1cf3de5cf47a3..8f9c0b454a4ac8887791b30efec818903f0a39d4 100644 (file)
       opacity: 0;
     }
   }
+
   .data-mx-spoiler--visible {
     background-color: var(--bg-surface-active) !important;
     color: inherit !important;