signal-desktop/ts/components/conversation/Emojify.tsx

68 lines
2 KiB
TypeScript
Raw Normal View History

2023-01-03 11:55:46 -08:00
// Copyright 2018 Signal Messenger, LLC
2020-10-30 15:34:04 -05:00
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { RenderTextCallbackType } from '../../types/Util';
import { splitByEmoji } from '../../util/emoji';
import { missingCaseError } from '../../util/missingCaseError';
2025-03-26 12:35:32 -07:00
import { FunInlineEmoji } from '../fun/FunEmoji';
import {
getEmojiParentByKey,
getEmojiParentKeyByVariantKey,
getEmojiVariantByKey,
getEmojiVariantKeyByValue,
isEmojiVariantValue,
} from '../fun/data/emojis';
import { strictAssert } from '../../util/assert';
export type Props = {
2025-03-26 12:35:32 -07:00
fontSizeOverride?: number | null;
text: string;
/** When behind a spoiler, this emoji needs to be visibility: hidden */
isInvisible?: boolean;
/** Allows you to customize now non-newlines are rendered. Simplest is just a <span>. */
2019-01-14 13:49:58 -08:00
renderNonEmoji?: RenderTextCallbackType;
};
2022-11-09 20:59:36 -08:00
const defaultRenderNonEmoji: RenderTextCallbackType = ({ text }) => text;
export function Emojify({
2025-03-26 12:35:32 -07:00
fontSizeOverride,
text,
2025-03-26 12:35:32 -07:00
renderNonEmoji = defaultRenderNonEmoji,
}: Props): JSX.Element {
return (
<>
{splitByEmoji(text).map(({ type, value: match }, index) => {
if (type === 'emoji') {
2025-03-26 12:35:32 -07:00
strictAssert(
isEmojiVariantValue(match),
`Must be emoji variant value: ${match}`
);
const variantKey = getEmojiVariantKeyByValue(match);
const variant = getEmojiVariantByKey(variantKey);
const parentKey = getEmojiParentKeyByVariantKey(variantKey);
const parent = getEmojiParentByKey(parentKey);
return (
<FunInlineEmoji
// eslint-disable-next-line react/no-array-index-key
key={index}
role="img"
aria-label={parent.englishShortNameDefault}
emoji={variant}
size={fontSizeOverride}
/>
);
}
if (type === 'text') {
return renderNonEmoji({ text: match, key: index });
}
throw missingCaseError(type);
})}
</>
);
}