Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit af8b3c2

Browse files
authored
Add tooltips to emoji in messages (#7592)
1 parent 35ebca2 commit af8b3c2

File tree

2 files changed

+16
-18
lines changed

2 files changed

+16
-18
lines changed

res/css/views/rooms/_EventTile.scss

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -391,10 +391,9 @@ $left-gutter: 64px;
391391
position: absolute;
392392
}
393393

394-
/* HACK to override line-height which is already marked important elsewhere */
395-
.mx_EventTile_bigEmoji.mx_EventTile_bigEmoji {
394+
.mx_EventTile_bigEmoji .mx_EventTile_Emoji {
396395
font-size: 48px !important;
397-
line-height: 57px !important;
396+
line-height: 57px;
398397
}
399398

400399
.mx_EventTile_content .mx_EventTile_edited {

src/HtmlUtils.tsx

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import sanitizeHtml from 'sanitize-html';
2222
import cheerio from 'cheerio';
2323
import classNames from 'classnames';
2424
import EMOJIBASE_REGEX from 'emojibase-regex';
25+
import { split } from 'lodash';
2526
import katex from 'katex';
2627
import { AllHtmlEntities } from 'html-entities';
2728
import { IContent } from 'matrix-js-sdk/src/models/event';
@@ -402,6 +403,11 @@ export interface IOptsReturnString extends IOpts {
402403
returnString: true;
403404
}
404405

406+
const emojiToHtmlSpan = (emoji: string) =>
407+
`<span class='mx_EventTile_Emoji' title='${unicodeToShortcode(emoji)}'>${emoji}</span>`;
408+
const emojiToJsxSpan = (emoji: string, key: number) =>
409+
<span key={key} className='mx_EventTile_Emoji' title={unicodeToShortcode(emoji)}>{ emoji }</span>;
410+
405411
/**
406412
* Wraps emojis in <span> to style them separately from the rest of message. Consecutive emojis (and modifiers) are wrapped
407413
* in the same <span>.
@@ -411,34 +417,27 @@ export interface IOptsReturnString extends IOpts {
411417
* and plain text for everything else
412418
*/
413419
function formatEmojis(message: string, isHtmlMessage: boolean): (JSX.Element | string)[] {
414-
const emojiToSpan = isHtmlMessage ? (emoji: string) => `<span class='mx_EventTile_Emoji'>${emoji}</span>` :
415-
(emoji: string, key: number) => <span key={key} className='mx_EventTile_Emoji'>{ emoji }</span>;
420+
const emojiToSpan = isHtmlMessage ? emojiToHtmlSpan : emojiToJsxSpan;
416421
const result: (JSX.Element | string)[] = [];
417422
let text = '';
418-
let emojis = '';
419423
let key = 0;
420-
for (const char of message) {
421-
if (mightContainEmoji(char) || ZWJ_REGEX.test(char) || char === '\ufe0f') {
424+
425+
// We use lodash's grapheme splitter to avoid breaking apart compound emojis
426+
for (const char of split(message, '')) {
427+
if (mightContainEmoji(char)) {
422428
if (text) {
423429
result.push(text);
424430
text = '';
425431
}
426-
emojis += char;
432+
result.push(emojiToSpan(char, key));
433+
key++;
427434
} else {
428-
if (emojis) {
429-
result.push(emojiToSpan(emojis, key));
430-
key++;
431-
emojis = '';
432-
}
433435
text += char;
434436
}
435437
}
436438
if (text) {
437439
result.push(text);
438440
}
439-
if (emojis) {
440-
result.push(emojiToSpan(emojis, key));
441-
}
442441
return result;
443442
}
444443

@@ -574,7 +573,7 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
574573
});
575574

576575
let emojiBodyElements: JSX.Element[];
577-
if (!isDisplayedWithHtml && bodyHasEmoji && !emojiBody) {
576+
if (!isDisplayedWithHtml && bodyHasEmoji) {
578577
emojiBodyElements = formatEmojis(strippedBody, false) as JSX.Element[];
579578
}
580579

0 commit comments

Comments
 (0)