diff --git a/app/javascript/mastodon/features/emoji/render.test.ts b/app/javascript/mastodon/features/emoji/render.test.ts index 3c96cbfb5..af7ff75a0 100644 --- a/app/javascript/mastodon/features/emoji/render.test.ts +++ b/app/javascript/mastodon/features/emoji/render.test.ts @@ -7,6 +7,7 @@ import { stringToEmojiState, tokenizeText, } from './render'; +import type { EmojiStateCustom } from './types'; describe('tokenizeText', () => { test('returns an array of text to be a single token', () => { @@ -82,12 +83,8 @@ describe('stringToEmojiState', () => { }); }); - test('returns custom emoji state for valid custom emoji', () => { - expect(stringToEmojiState(':smile:')).toEqual({ - type: 'custom', - code: 'smile', - data: undefined, - }); + test('returns null for custom emoji without data', () => { + expect(stringToEmojiState(':smile:')).toBeNull(); }); test('returns custom emoji state with data when provided', () => { @@ -107,7 +104,6 @@ describe('stringToEmojiState', () => { test('returns null for invalid emoji strings', () => { expect(stringToEmojiState('notanemoji')).toBeNull(); - expect(stringToEmojiState(':invalid-emoji:')).toBeNull(); }); }); @@ -130,18 +126,13 @@ describe('loadEmojiDataToState', () => { }); }); - test('loads custom emoji data into state', async () => { - const dbCall = vi - .spyOn(db, 'loadCustomEmojiByShortcode') - .mockResolvedValueOnce(customEmojiFactory()); - const customState = { type: 'custom', code: 'smile' } as const; - const result = await loadEmojiDataToState(customState, 'en'); - expect(dbCall).toHaveBeenCalledWith('smile'); - expect(result).toEqual({ + test('returns null for custom emoji without data', async () => { + const customState = { type: 'custom', code: 'smile', - data: customEmojiFactory(), - }); + } as const satisfies EmojiStateCustom; + const result = await loadEmojiDataToState(customState, 'en'); + expect(result).toBeNull(); }); test('returns null if unicode emoji not found in database', async () => { @@ -151,13 +142,6 @@ describe('loadEmojiDataToState', () => { expect(result).toBeNull(); }); - test('returns null if custom emoji not found in database', async () => { - vi.spyOn(db, 'loadCustomEmojiByShortcode').mockResolvedValueOnce(undefined); - const customState = { type: 'custom', code: 'smile' } as const; - const result = await loadEmojiDataToState(customState, 'en'); - expect(result).toBeNull(); - }); - test('retries loading emoji data once if initial load fails', async () => { const dbCall = vi .spyOn(db, 'loadEmojiByHexcode') diff --git a/app/javascript/mastodon/features/emoji/render.ts b/app/javascript/mastodon/features/emoji/render.ts index 574d5ef59..39c517b59 100644 --- a/app/javascript/mastodon/features/emoji/render.ts +++ b/app/javascript/mastodon/features/emoji/render.ts @@ -4,11 +4,7 @@ import { EMOJI_TYPE_UNICODE, EMOJI_TYPE_CUSTOM, } from './constants'; -import { - loadCustomEmojiByShortcode, - loadEmojiByHexcode, - LocaleNotLoadedError, -} from './database'; +import { loadEmojiByHexcode, LocaleNotLoadedError } from './database'; import { importEmojiData } from './loader'; import { emojiToUnicodeHex } from './normalize'; import type { @@ -79,7 +75,7 @@ export function tokenizeText(text: string): TokenizedText { export function stringToEmojiState( code: string, customEmoji: ExtraCustomEmojiMap = {}, -): EmojiState | null { +): EmojiStateUnicode | Required | null { if (isUnicodeEmoji(code)) { return { type: EMOJI_TYPE_UNICODE, @@ -89,11 +85,13 @@ export function stringToEmojiState( if (isCustomEmoji(code)) { const shortCode = code.slice(1, -1); - return { - type: EMOJI_TYPE_CUSTOM, - code: shortCode, - data: customEmoji[shortCode], - }; + if (customEmoji[shortCode]) { + return { + type: EMOJI_TYPE_CUSTOM, + code: shortCode, + data: customEmoji[shortCode], + }; + } } return null; @@ -114,26 +112,23 @@ export async function loadEmojiDataToState( return state; } + // Don't try to load data for custom emoji. + if (state.type === EMOJI_TYPE_CUSTOM) { + return null; + } + // First, try to load the data from IndexedDB. try { // This is duplicative, but that's because TS can't distinguish the state type easily. - if (state.type === EMOJI_TYPE_UNICODE) { - const data = await loadEmojiByHexcode(state.code, locale); - if (data) { - return { - ...state, - data, - }; - } - } else { - const data = await loadCustomEmojiByShortcode(state.code); - if (data) { - return { - ...state, - data, - }; - } + const data = await loadEmojiByHexcode(state.code, locale); + if (data) { + return { + ...state, + type: EMOJI_TYPE_UNICODE, + data, + }; } + // If not found, assume it's not an emoji and return null. log( 'Could not find emoji %s of type %s for locale %s',