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

Commit 54b37c2

Browse files
committed
Make inline emojis bigger
1 parent 351c426 commit 54b37c2

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
@@ -212,6 +212,11 @@ $left-gutter: 64px;
212212
overflow-y: hidden;
213213
}
214214

215+
.mx_EventTile_Emoji {
216+
font-size: 1.8rem;
217+
vertical-align: bottom;
218+
}
219+
215220
&.mx_EventTile_selected .mx_EventTile_line,
216221
&:hover .mx_EventTile_line {
217222
border-top-left-radius: 4px;

src/HtmlUtils.tsx

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,46 @@ export interface IOptsReturnString extends IOpts {
395395
returnString: true;
396396
}
397397

398+
/**
399+
* Wraps emojis in <span> to style them separately from the rest of message. Consecutive emojis (and modifiers) are wrapped
400+
* in the same <span>.
401+
* @param {string} message the text to format
402+
* @param {boolean} isHtmlMessage whether the message contains HTML
403+
* @returns if isHtmlMessage is true, returns an array of strings, otherwise return an array of React Elements for emojis
404+
* and plain text for everything else
405+
*/
406+
function formatEmojis(message: string, isHtmlMessage: boolean): (JSX.Element | string)[] {
407+
const emojiToSpan = isHtmlMessage ? (emoji: string) => `<span class='mx_EventTile_Emoji'>${emoji}</span>` :
408+
(emoji: string, key: number) => <span key={key} className='mx_EventTile_Emoji'>{emoji}</span>;
409+
const result: (JSX.Element | string)[] = [];
410+
let text = '';
411+
let emojis = '';
412+
let key = 0;
413+
for (const char of message) {
414+
if (mightContainEmoji(char) || ZWJ_REGEX.test(char) || char === '\ufe0f') {
415+
if (text) {
416+
result.push(text);
417+
text = '';
418+
}
419+
emojis += char;
420+
} else {
421+
if (emojis) {
422+
result.push(emojiToSpan(emojis, key));
423+
key++;
424+
emojis = '';
425+
}
426+
text += char;
427+
}
428+
}
429+
if (text) {
430+
result.push(text);
431+
}
432+
if (emojis) {
433+
result.push(emojiToSpan(emojis, key));
434+
}
435+
return result;
436+
}
437+
398438
/* turn a matrix event body into html
399439
*
400440
* content: 'content' of the MatrixEvent
@@ -477,6 +517,9 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
477517
});
478518
safeBody = phtml.html();
479519
}
520+
if (bodyHasEmoji) {
521+
safeBody = formatEmojis(safeBody, true).join('');
522+
}
480523
}
481524
} finally {
482525
delete sanitizeParams.textFilter;
@@ -519,14 +562,21 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
519562
'markdown-body': isHtmlMessage && !emojiBody,
520563
});
521564

565+
let emojiBodyElements: JSX.Element[];
566+
if (!isDisplayedWithHtml && bodyHasEmoji && !emojiBody) {
567+
emojiBodyElements = formatEmojis(strippedBody, false) as JSX.Element[];
568+
}
569+
522570
return isDisplayedWithHtml ?
523571
<span
524572
key="body"
525573
ref={opts.ref}
526574
className={className}
527575
dangerouslySetInnerHTML={{ __html: safeBody }}
528576
dir="auto"
529-
/> : <span key="body" ref={opts.ref} className={className} dir="auto">{ strippedBody }</span>;
577+
/> : <span key="body" ref={opts.ref} className={className} dir="auto">
578+
{emojiBodyElements || strippedBody}
579+
</span>;
530580
}
531581

532582
/**

0 commit comments

Comments
 (0)