Refactor emoji utils in mastodon features

The refactoring of emoji utilities in the mastodon feature has been done to enhance readability and maintenance of the code. The types and functions involved in sanitizing and getting data have been clarified, including the introduction of an interface for skin tones. Additionally, erroneous typescript comments have been removed and the emojis type has been exported for further use.
This commit is contained in:
taichi221228 2024-05-02 11:22:49 +09:00 committed by Eugen Rochko
parent 5b34a4e347
commit a172892470
2 changed files with 57 additions and 44 deletions

View File

@ -8,7 +8,7 @@ import type { Search, ShortCodesToEmojiData } from './emoji_compressed';
import emojiCompressed from './emoji_compressed'; import emojiCompressed from './emoji_compressed';
import { unicodeToUnifiedName } from './unicode_to_unified_name'; import { unicodeToUnifiedName } from './unicode_to_unified_name';
type Emojis = { export type Emojis = {
[key in NonNullable<keyof ShortCodesToEmojiData>]: { [key in NonNullable<keyof ShortCodesToEmojiData>]: {
native: BaseEmoji['native']; native: BaseEmoji['native'];
search: Search; search: Search;

View File

@ -7,7 +7,7 @@ import type {
EmojiSkin, EmojiSkin,
PickerProps, PickerProps,
} from 'emoji-mart'; } from 'emoji-mart';
import type { Emoji } from 'emoji-mart/dist-es/utils/data'; import type { Emoji, SkinVariation } from 'emoji-mart/dist-es/utils/data';
import * as data from './emoji_mart_data_light'; import * as data from './emoji_mart_data_light';
@ -58,11 +58,16 @@ function unifiedToNative(unified: Emoji['unified']) {
* The type and implementation have different maintainers and packages, so the installed versions of `@types/emoji-mart` and `emoji-mart` may not match. * The type and implementation have different maintainers and packages, so the installed versions of `@types/emoji-mart` and `emoji-mart` may not match.
*/ */
interface SkinTone {
skin_tone?: EmojiSkin;
}
function sanitize( function sanitize(
emoji: BaseEmoji & emoji: BaseEmoji &
CustomEmoji & CustomEmoji &
Pick<Emoji, 'skin_variations'> & Pick<Emoji, 'skin_variations'> &
Pick<PickerProps, 'custom'> & { skin_tone?: EmojiSkin }, Pick<PickerProps, 'custom'> &
SkinTone,
): ):
| BaseEmoji | BaseEmoji
| (Omit<CustomEmoji, 'short_names'> & Pick<PickerProps, 'custom'>) { | (Omit<CustomEmoji, 'short_names'> & Pick<PickerProps, 'custom'>) {
@ -106,25 +111,45 @@ function sanitize(
}; };
} }
/* eslint-disable */ function getSanitizedData(
...args: [
function getSanitizedData() { emoji: BaseEmoji | string,
// @ts-expect-error skin: EmojiSkin | null,
return sanitize(getData(...arguments)); set?:
| 'apple'
| 'google'
| 'twitter'
| 'facebook'
| 'emojione'
| 'messenger',
]
) {
return sanitize(getData(...args));
} }
// @ts-expect-error function getData(
function getData(emoji, skin, set) { emoji: BaseEmoji | string,
let emojiData = {}; skin: EmojiSkin | null,
set?: 'apple' | 'google' | 'twitter' | 'facebook' | 'emojione' | 'messenger',
) {
/* eslint-disable @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return */
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
let emojiData: any = {};
if (typeof emoji === 'string') { if (typeof emoji === 'string') {
let matches = emoji.match(COLONS_REGEX); const matches = emoji.match(COLONS_REGEX);
if (matches) { if (matches) {
emoji = matches[1]; emoji = matches[1];
if (matches[2]) { const int = parseInt(matches[2]);
skin = parseInt(matches[2]); const isValid = (value: number): value is EmojiSkin =>
([1, 2, 3, 4, 5, 6] satisfies EmojiSkin[]).some(
(skin) => skin === value,
);
if (isValid(int)) {
skin = int;
} }
} }
@ -142,63 +167,51 @@ function getData(emoji, skin, set) {
if (Object.hasOwn(data.emojis, emoji.id)) { if (Object.hasOwn(data.emojis, emoji.id)) {
emojiData = data.emojis[emoji.id]; emojiData = data.emojis[emoji.id];
skin = skin || emoji.skin; skin = skin ?? emoji.skin;
} }
} }
if (!Object.keys(emojiData).length) { if (!Object.keys(emojiData).length && typeof emoji === 'object') {
emojiData = emoji; emojiData = emoji;
// @ts-expect-error
emojiData.custom = true; emojiData.custom = true;
// @ts-expect-error
if (!emojiData.search) { if (!emojiData.search) {
// @ts-expect-error
emojiData.search = buildSearch(emoji); emojiData.search = buildSearch(emoji);
} }
} }
// @ts-expect-error
emojiData.emoticons = emojiData.emoticons || []; emojiData.emoticons = emojiData.emoticons || [];
// @ts-expect-error
emojiData.variations = emojiData.variations || []; emojiData.variations = emojiData.variations || [];
// @ts-expect-error if (emojiData.skin_variations && skin && skin > 1 && set) {
if (emojiData.skin_variations && skin > 1 && set) { const skinKey = SKINS[skin - 1];
emojiData = JSON.parse(_JSON.stringify(emojiData)); const variationData = emojiData.skin_variations[skinKey];
let skinKey = SKINS[skin - 1],
// @ts-expect-error
variationData = emojiData.skin_variations[skinKey];
// @ts-expect-error
if (!variationData.variations && emojiData.variations) {
// @ts-expect-error
delete emojiData.variations;
}
if (variationData[`has_img_${set}`]) { if (variationData[`has_img_${set}`]) {
// @ts-expect-error
emojiData.skin_tone = skin; emojiData.skin_tone = skin;
for (let k in variationData) { for (const k in variationData) {
let v = variationData[k]; type K = keyof typeof emojiData;
// @ts-expect-error emojiData[k as K] = variationData[k as keyof SkinVariation];
emojiData[k] = v;
} }
} }
} }
// @ts-expect-error if (emojiData.variations.length) {
if (emojiData.variations && emojiData.variations.length) {
emojiData = JSON.parse(_JSON.stringify(emojiData));
// @ts-expect-error
emojiData.unified = emojiData.variations.shift(); emojiData.unified = emojiData.variations.shift();
} }
return emojiData; return emojiData as BaseEmoji &
CustomEmoji &
Pick<Emoji, 'skin_variations'> &
Pick<PickerProps, 'custom'> &
SkinTone;
/* eslint-enable @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return */
} }
/* eslint-disable */
// @ts-expect-error // @ts-expect-error
function uniq(arr) { function uniq(arr) {
// @ts-expect-error // @ts-expect-error