Fix rendering non/overly-qualified emoji in emojify

This commit is contained in:
Jamie Kyle
2025-03-28 16:01:27 -07:00
committed by GitHub
parent d66ce9ad6a
commit 22fb468481
3 changed files with 42 additions and 5 deletions

View File

@@ -121,3 +121,19 @@ export function TensOfThousandsOfEmojiInterspersedWithText(): JSX.Element {
return <Emojify {...props} />;
}
export function NonQualifiedEmoji(): JSX.Element {
const props = createProps({
text: '\u{00AE}',
});
return <Emojify {...props} />;
}
export function OverlyQualifiedEmoji(): JSX.Element {
const props = createProps({
text: '\u{26AA}\u{FE0F}',
});
return <Emojify {...props} />;
}

View File

@@ -11,8 +11,9 @@ import {
getEmojiVariantByKey,
getEmojiVariantKeyByValue,
isEmojiVariantValue,
isEmojiVariantValueNonQualified,
} from '../fun/data/emojis';
import { strictAssert } from '../../util/assert';
import * as log from '../../logging/log';
export type Props = {
fontSizeOverride?: number | null;
@@ -34,10 +35,16 @@ export function Emojify({
<>
{splitByEmoji(text).map(({ type, value: match }, index) => {
if (type === 'emoji') {
strictAssert(
isEmojiVariantValue(match),
`Must be emoji variant value: ${match}`
);
// If we don't recognize the emoji, render it as text.
if (!isEmojiVariantValue(match)) {
log.error(`Found emoji that we did not recognize: ${match}`);
return renderNonEmoji({ text: match, key: index });
}
// Render emoji as text if they are a non-qualified emoji value.
if (isEmojiVariantValueNonQualified(match)) {
return renderNonEmoji({ text: match, key: index });
}
const variantKey = getEmojiVariantKeyByValue(match);
const variant = getEmojiVariantByKey(variantKey);

View File

@@ -252,10 +252,12 @@ type EmojiIndex = Readonly<{
parentByKey: Record<EmojiParentKey, EmojiParentData>;
parentKeysByName: Record<EmojiEnglishShortName, EmojiParentKey>;
parentKeysByValue: Record<EmojiParentValue, EmojiParentKey>;
parentKeysByValueNonQualified: Record<EmojiParentValue, EmojiParentKey>;
parentKeysByVariantKeys: Record<EmojiVariantKey, EmojiParentKey>;
variantByKey: Record<EmojiVariantKey, EmojiVariantData>;
variantKeysByValue: Record<EmojiVariantValue, EmojiVariantKey>;
variantKeysByValueNonQualified: Record<EmojiVariantValue, EmojiVariantKey>;
unicodeCategories: Record<EmojiUnicodeCategory, Array<EmojiParentKey>>;
pickerCategories: Record<EmojiPickerCategory, Array<EmojiParentKey>>;
@@ -266,10 +268,12 @@ type EmojiIndex = Readonly<{
const EMOJI_INDEX: EmojiIndex = {
parentByKey: {},
parentKeysByValue: {},
parentKeysByValueNonQualified: {},
parentKeysByName: {},
parentKeysByVariantKeys: {},
variantByKey: {},
variantKeysByValue: {},
variantKeysByValueNonQualified: {},
unicodeCategories: {
[EmojiUnicodeCategory.SmileysAndEmotion]: [],
[EmojiUnicodeCategory.PeopleAndBody]: [],
@@ -300,6 +304,8 @@ function addParent(parent: EmojiParentData, rank: number) {
EMOJI_INDEX.parentKeysByValue[parent.value] = parent.key;
if (parent.valueNonqualified != null) {
EMOJI_INDEX.parentKeysByValue[parent.valueNonqualified] = parent.key;
EMOJI_INDEX.parentKeysByValueNonQualified[parent.valueNonqualified] =
parent.key;
}
EMOJI_INDEX.parentKeysByName[parent.englishShortNameDefault] = parent.key;
EMOJI_INDEX.unicodeCategories[parent.unicodeCategory].push(parent.key);
@@ -327,6 +333,8 @@ function addVariant(parentKey: EmojiParentKey, variant: EmojiVariantData) {
EMOJI_INDEX.variantKeysByValue[variant.value] = variant.key;
if (variant.valueNonqualified) {
EMOJI_INDEX.variantKeysByValue[variant.valueNonqualified] = variant.key;
EMOJI_INDEX.variantKeysByValueNonQualified[variant.valueNonqualified] =
variant.key;
}
}
@@ -419,6 +427,12 @@ export function isEmojiVariantValue(input: string): input is EmojiVariantValue {
return Object.hasOwn(EMOJI_INDEX.variantKeysByValue, input);
}
export function isEmojiVariantValueNonQualified(
input: EmojiVariantValue
): boolean {
return Object.hasOwn(EMOJI_INDEX.variantKeysByValueNonQualified, input);
}
/** @deprecated Prefer EmojiKey for refs, load short names from translations */
export function isEmojiEnglishShortName(
input: string