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

Commit b4f4dc5

Browse files
committed
Make inline emojis bigger
1 parent a7e6d8e commit b4f4dc5

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
@@ -145,6 +145,11 @@ $left-gutter: 64px;
145145
margin-right: 10px;
146146
}
147147

148+
.mx_EventTile_Emoji {
149+
font-size: 2rem;
150+
vertical-align: bottom;
151+
}
152+
148153
/* HACK to override line-height which is already marked important elsewhere */
149154
.mx_EventTile_bigEmoji.mx_EventTile_bigEmoji {
150155
font-size: 48px !important;

src/HtmlUtils.tsx

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

364+
/**
365+
* Wraps emojis in <span> to style them separately from the rest of message. Consecutive emojis (and modifiers) are wrapped
366+
* in the same <span>.
367+
* @param {string} message the text to format
368+
* @param {boolean} isHtmlMessage whether the message contains HTML
369+
* @returns if isHtmlMessage is true, returns an array of strings, otherwise return an array of React Elements for emojis
370+
* and plain text for everything else
371+
*/
372+
function formatEmojis(message: string, isHtmlMessage: boolean): (JSX.Element | string)[] {
373+
const emojiToSpan = isHtmlMessage ? (emoji: string) => `<span class='mx_EventTile_Emoji'>${emoji}</span>` :
374+
(emoji: string, key: number) => <span key={key} className='mx_EventTile_Emoji'>{emoji}</span>;
375+
const result: (JSX.Element | string)[] = [];
376+
let text = '';
377+
let emojis = '';
378+
let key = 0;
379+
for (const char of message) {
380+
if (mightContainEmoji(char)) {
381+
if (text) {
382+
result.push(text);
383+
text = '';
384+
}
385+
emojis += char;
386+
} else {
387+
if (emojis) {
388+
result.push(emojiToSpan(emojis, key));
389+
key++;
390+
emojis = '';
391+
}
392+
text += char;
393+
}
394+
}
395+
if (text) {
396+
result.push(text);
397+
}
398+
if (emojis) {
399+
result.push(emojiToSpan(emojis, key));
400+
}
401+
return result;
402+
}
403+
364404
/* turn a matrix event body into html
365405
*
366406
* content: 'content' of the MatrixEvent
@@ -414,6 +454,9 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
414454
if (isHtmlMessage) {
415455
isDisplayedWithHtml = true;
416456
safeBody = sanitizeHtml(formattedBody, sanitizeParams);
457+
if (bodyHasEmoji) {
458+
safeBody = formatEmojis(safeBody, true).join('');
459+
}
417460
}
418461
} finally {
419462
delete sanitizeParams.textFilter;
@@ -455,14 +498,21 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
455498
'markdown-body': isHtmlMessage && !emojiBody,
456499
});
457500

501+
let emojiBodyElements: JSX.Element[];
502+
if (!isDisplayedWithHtml && bodyHasEmoji && !emojiBody) {
503+
emojiBodyElements = formatEmojis(strippedBody, false) as JSX.Element[];
504+
}
505+
458506
return isDisplayedWithHtml ?
459507
<span
460508
key="body"
461509
ref={opts.ref}
462510
className={className}
463511
dangerouslySetInnerHTML={{ __html: safeBody }}
464512
dir="auto"
465-
/> : <span key="body" ref={opts.ref} className={className} dir="auto">{ strippedBody }</span>;
513+
/> : <span key="body" ref={opts.ref} className={className} dir="auto">
514+
{emojiBodyElements || strippedBody}
515+
</span>;
466516
}
467517

468518
/**

0 commit comments

Comments
 (0)