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

Commit 9294c78

Browse files
committed
Make inline emojis bigger
1 parent 6726b73 commit 9294c78

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
@@ -137,6 +137,11 @@ $left-gutter: 64px;
137137
margin-right: 10px;
138138
}
139139

140+
.mx_EventTile_Emoji {
141+
font-size: 2rem;
142+
vertical-align: bottom;
143+
}
144+
140145
/* HACK to override line-height which is already marked important elsewhere */
141146
.mx_EventTile_bigEmoji.mx_EventTile_bigEmoji {
142147
font-size: 48px !important;

src/HtmlUtils.tsx

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,46 @@ interface IOpts {
365365
ref?: React.Ref<any>;
366366
}
367367

368+
/**
369+
* Wraps emojis in <span> to style them separately from the rest of message. Consecutive emojis (and modifiers) are wrapped
370+
* in the same <span>.
371+
* @param {string} message the text to format
372+
* @param {boolean} isHtmlMessage whether the message contains HTML
373+
* @returns if isHtmlMessage is true, returns an array of strings, otherwise return an array of React Elements for emojis
374+
* and plain text for everything else
375+
*/
376+
function formatEmojis(message: string, isHtmlMessage: boolean): (JSX.Element | string)[] {
377+
const emojiToSpan = isHtmlMessage ? (emoji: string) => `<span class='mx_EventTile_Emoji'>${emoji}</span>` :
378+
(emoji: string, key: number) => <span key={key} className='mx_EventTile_Emoji'>{emoji}</span>;
379+
const result: (JSX.Element | string)[] = [];
380+
let text = '';
381+
let emojis = '';
382+
let key = 0;
383+
for (const char of message) {
384+
if (mightContainEmoji(char) || ZWJ_REGEX.test(char) || char === '\ufe0f') {
385+
if (text) {
386+
result.push(text);
387+
text = '';
388+
}
389+
emojis += char;
390+
} else {
391+
if (emojis) {
392+
result.push(emojiToSpan(emojis, key));
393+
key++;
394+
emojis = '';
395+
}
396+
text += char;
397+
}
398+
}
399+
if (text) {
400+
result.push(text);
401+
}
402+
if (emojis) {
403+
result.push(emojiToSpan(emojis, key));
404+
}
405+
return result;
406+
}
407+
368408
/* turn a matrix event body into html
369409
*
370410
* content: 'content' of the MatrixEvent
@@ -433,6 +473,9 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
433473
});
434474
safeBody = phtml.html();
435475
}
476+
if (bodyHasEmoji) {
477+
safeBody = formatEmojis(safeBody, true).join('');
478+
}
436479
}
437480
} finally {
438481
delete sanitizeParams.textFilter;
@@ -474,14 +517,21 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
474517
'markdown-body': isHtmlMessage && !emojiBody,
475518
});
476519

520+
let emojiBodyElements: JSX.Element[];
521+
if (!isDisplayedWithHtml && bodyHasEmoji && !emojiBody) {
522+
emojiBodyElements = formatEmojis(strippedBody, false) as JSX.Element[];
523+
}
524+
477525
return isDisplayedWithHtml ?
478526
<span
479527
key="body"
480528
ref={opts.ref}
481529
className={className}
482530
dangerouslySetInnerHTML={{ __html: safeBody }}
483531
dir="auto"
484-
/> : <span key="body" ref={opts.ref} className={className} dir="auto">{ strippedBody }</span>;
532+
/> : <span key="body" ref={opts.ref} className={className} dir="auto">
533+
{emojiBodyElements || strippedBody}
534+
</span>;
485535
}
486536

487537
/**

0 commit comments

Comments
 (0)