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

Commit 98e1c31

Browse files
authored
Make inline emojis bigger (#5401)
1 parent 8a9d869 commit 98e1c31

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

res/css/views/rooms/_EventTile.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,11 @@ $left-gutter: 64px;
233233
overflow-y: hidden;
234234
}
235235

236+
.mx_EventTile_Emoji {
237+
font-size: 1.8rem;
238+
vertical-align: bottom;
239+
}
240+
236241
&.mx_EventTile_selected .mx_EventTile_line,
237242
&:hover .mx_EventTile_line {
238243
border-top-left-radius: 4px;

src/HtmlUtils.tsx

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,46 @@ export interface IOptsReturnString extends IOpts {
402402
returnString: true;
403403
}
404404

405+
/**
406+
* Wraps emojis in <span> to style them separately from the rest of message. Consecutive emojis (and modifiers) are wrapped
407+
* in the same <span>.
408+
* @param {string} message the text to format
409+
* @param {boolean} isHtmlMessage whether the message contains HTML
410+
* @returns if isHtmlMessage is true, returns an array of strings, otherwise return an array of React Elements for emojis
411+
* and plain text for everything else
412+
*/
413+
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>;
416+
const result: (JSX.Element | string)[] = [];
417+
let text = '';
418+
let emojis = '';
419+
let key = 0;
420+
for (const char of message) {
421+
if (mightContainEmoji(char) || ZWJ_REGEX.test(char) || char === '\ufe0f') {
422+
if (text) {
423+
result.push(text);
424+
text = '';
425+
}
426+
emojis += char;
427+
} else {
428+
if (emojis) {
429+
result.push(emojiToSpan(emojis, key));
430+
key++;
431+
emojis = '';
432+
}
433+
text += char;
434+
}
435+
}
436+
if (text) {
437+
result.push(text);
438+
}
439+
if (emojis) {
440+
result.push(emojiToSpan(emojis, key));
441+
}
442+
return result;
443+
}
444+
405445
/* turn a matrix event body into html
406446
*
407447
* content: 'content' of the MatrixEvent
@@ -488,6 +528,9 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
488528
});
489529
safeBody = phtml.html();
490530
}
531+
if (bodyHasEmoji) {
532+
safeBody = formatEmojis(safeBody, true).join('');
533+
}
491534
}
492535
} finally {
493536
delete sanitizeParams.textFilter;
@@ -530,14 +573,21 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
530573
'markdown-body': isHtmlMessage && !emojiBody,
531574
});
532575

576+
let emojiBodyElements: JSX.Element[];
577+
if (!isDisplayedWithHtml && bodyHasEmoji && !emojiBody) {
578+
emojiBodyElements = formatEmojis(strippedBody, false) as JSX.Element[];
579+
}
580+
533581
return isDisplayedWithHtml ?
534582
<span
535583
key="body"
536584
ref={opts.ref}
537585
className={className}
538586
dangerouslySetInnerHTML={{ __html: safeBody }}
539587
dir="auto"
540-
/> : <span key="body" ref={opts.ref} className={className} dir="auto">{ strippedBody }</span>;
588+
/> : <span key="body" ref={opts.ref} className={className} dir="auto">
589+
{ emojiBodyElements || strippedBody }
590+
</span>;
541591
}
542592

543593
/**

0 commit comments

Comments
 (0)