Hanage999 57246a0539 [Glitch] Fix categorised custom emojis missing from the emoji picker
Port b4be90f9ea3e29e166b4fb0d0e0cc6b32dbf908b to glitch-soc

Signed-off-by: Hanage999 <hanage999@crazynewworld.net>
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2026-06-16 21:52:32 +02:00

118 lines
2.9 KiB
TypeScript

import type { CategoryName, CustomEmoji } from 'emoji-mart';
import { autoPlayGif } from '@/flavours/glitch/initial_state';
import {
createAppSelector,
useAppSelector,
} from '@/flavours/glitch/store/typed_functions';
import { createLimitedCache } from '@/flavours/glitch/utils/cache';
import { emojiLogger } from './utils';
const log = emojiLogger('picker');
const searchCache = createLimitedCache<LegacyEmoji[]>({ maxSize: 10, log });
type LegacyEmoji =
| { id: string; custom?: false; native: string }
| {
id: string;
custom: true;
};
// Replicates the old legacy search function.
export async function emojiMartSearch(
token: string,
locale: string,
limit = 5,
): Promise<LegacyEmoji[]> {
const query = token.replace(':', '').trim();
if (!query.length) {
return [];
}
const cacheKey = `${query}|${locale}|${limit}`;
const cachedResult = searchCache.get(cacheKey);
if (cachedResult) {
return cachedResult;
}
const { search } = await import('./database');
const results = await search({ query, locale, limit });
const legacyResults = results.map((emoji) =>
'shortcode' in emoji
? ({ id: emoji.shortcode, custom: true } as const)
: {
id: emoji.label.replaceAll(' ', '_').toLowerCase(),
native: emoji.unicode,
},
);
searchCache.set(cacheKey, legacyResults);
return legacyResults;
}
const defaultCategories = [
'people',
'nature',
'foods',
'activity',
'places',
'objects',
'symbols',
'flags',
] as CategoryName[];
const selectPickerData = createAppSelector(
[(state) => state.emojis.custom, (state) => state.emojis.customCategories],
(emojis, categories) => {
// Create a map of shortcode to category name.
const categoryMap = new Map<string, string>();
for (const category in categories) {
const catEmojis = categories[category];
if (!catEmojis?.length) {
continue;
}
for (const shortcode of catEmojis) {
categoryMap.set(shortcode, category);
}
}
const customEmojis: CustomEmoji[] = [];
for (const shortcode in emojis) {
const emoji = emojis[shortcode];
if (!emoji) {
continue;
}
customEmojis.push({
name: shortcode,
id: shortcode,
custom: true,
short_names: [shortcode],
imageUrl: autoPlayGif ? emoji.url : emoji.static_url,
customCategory: categoryMap.get(shortcode),
} as CustomEmoji);
}
searchCache.clear();
log('regenerated the picker data');
return {
emojis: customEmojis,
categories: [
'recent',
'custom',
...Object.keys(categories)
.toSorted()
.map((category) => `custom-${category}`),
...defaultCategories,
] as CategoryName[],
};
},
);
export function usePickerEmojis() {
return useAppSelector(selectPickerData);
}