Avatar: Use full emoji sequence instead of the first one (#1388)

This commit is contained in:
Alexander Zinchuk 2021-08-27 21:05:49 +03:00
parent 98b3939dea
commit 0625edb308
4 changed files with 37 additions and 5 deletions

View File

@ -4,7 +4,7 @@
cursor: pointer;
position: relative;
img {
img:not(.emoji) {
width: 100%;
object-fit: cover;
}

View File

@ -3,7 +3,7 @@ import EMOJI_REGEX, { removeVS16s } from '../../../lib/twemojiRegex';
import { RE_LINK_TEMPLATE, RE_MENTION_TEMPLATE } from '../../../config';
import { IS_EMOJI_SUPPORTED } from '../../../util/environment';
import { nativeToUnfified } from '../../../util/emoji';
import { fixNonStandardEmoji, nativeToUnified } from '../../../util/emoji';
import buildClassName from '../../../util/buildClassName';
import MentionLink from '../../middle/message/MentionLink';
@ -89,12 +89,14 @@ function replaceEmojis(textParts: TextPart[], size: 'big' | 'small', type: 'jsx'
return [...result, part];
}
part = fixNonStandardEmoji(part);
const parts = part.split(EMOJI_REGEX);
const emojis = part.match(EMOJI_REGEX) || [];
result.push(parts[0]);
return emojis.reduce((emojiResult: TextPart[], emoji, i) => {
const code = nativeToUnfified(removeVS16s(emoji));
const code = nativeToUnified(removeVS16s(emoji));
if (!code) return emojiResult;
const className = buildClassName(
'emoji',
size === 'small' && 'emoji-small',

View File

@ -1,3 +1,5 @@
import EMOJI_REGEX from '../lib/twemojiRegex';
// Due to the fact that emoji from Apple do not contain some characters, it is necessary to remove them from emoji-data
// https://github.com/iamcal/emoji-data/issues/136
const EXCLUDE_EMOJIS = ['female_sign', 'male_sign', 'medical_symbol'];
@ -10,6 +12,13 @@ export type EmojiData = {
emojis: Record<string, Emoji>;
};
// Non-standard variations of emojis, used on some devices
const EMOJI_EXCEPTIONS: [string | RegExp, string][] = [
[/\u{1f3f3}\u200d\u{1f308}/gu, '\u{1f3f3}\ufe0f\u200d\u{1f308}'], // 🏳🌈
[/\u{1f3f3}\u200d\u26a7\ufe0f/gu, '\u{1f3f3}\ufe0f\u200d\u26a7\ufe0f'], // 🏳
[/\u{1f937}\u200d\u2642/gu, '\u{1f937}\u200d\u2642\ufe0f'], // 🤷
]
function unifiedToNative(unified: string) {
const unicodes = unified.split('-');
const codePoints = unicodes.map((i) => parseInt(i, 16));
@ -17,7 +26,17 @@ function unifiedToNative(unified: string) {
return String.fromCodePoint(...codePoints);
}
export function nativeToUnfified(emoji: string) {
export function fixNonStandardEmoji(text: string) {
// Non-standard sequences typically parsed as separate emojis, so no need to fix text without any
if (!text.match(EMOJI_REGEX)) return text;
for (let [regex, replacement] of EMOJI_EXCEPTIONS) {
text = text.replace(regex, replacement);
}
return text;
}
export function nativeToUnified(emoji: string) {
let code;
if (emoji.length === 1) {

View File

@ -1,3 +1,6 @@
import EMOJI_REGEX from "../lib/twemojiRegex";
import { fixNonStandardEmoji } from "./emoji";
export function formatInteger(value: number) {
return String(value).replace(/\d(?=(\d{3})+$)/g, '$& ');
}
@ -29,6 +32,14 @@ export function getFirstLetters(phrase: string, count = 2) {
.trim()
.split(/\s+/)
.slice(0, count)
.map((word: string) => word.length && word.match(/./u)![0].toUpperCase())
.map((word: string) => {
if (!word.length) return '';
word = fixNonStandardEmoji(word);
const emojis = word.match(EMOJI_REGEX);
if (emojis && word.startsWith(emojis[0])) {
return emojis[0];
}
return word.match(/./u)![0].toUpperCase()
})
.join('');
}