soapbox/app/soapbox/features/emoji/search.ts

76 wiersze
1.9 KiB
TypeScript
Czysty Zwykły widok Historia

2023-03-20 00:56:01 +00:00
import { Index } from 'flexsearch-ts';
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
2022-07-05 02:08:47 +00:00
import data from './data';
2022-07-05 04:03:09 +00:00
import type { Emoji } from './index';
2022-07-05 02:08:47 +00:00
const index = new Index({
2022-07-05 06:37:07 +00:00
tokenize: 'full',
2022-07-05 02:08:47 +00:00
optimize: true,
2022-07-05 06:37:07 +00:00
context: true,
2022-07-05 02:08:47 +00:00
});
2023-06-05 16:39:32 +00:00
const sortedEmojis = Object.entries(data.emojis).sort((a, b) => a[0].localeCompare(b[0]));
for (const [key, emoji] of sortedEmojis) {
index.add('n' + key, `${emoji.id} ${emoji.name} ${emoji.keywords.join(' ')}`);
2022-07-05 02:08:47 +00:00
}
2022-07-04 23:07:04 +00:00
2022-07-04 20:30:35 +00:00
export interface searchOptions {
maxResults?: number
custom?: any
2022-07-04 20:30:35 +00:00
}
2022-07-09 16:03:22 +00:00
export const addCustomToPool = (customEmojis: any[]) => {
2022-07-09 23:32:34 +00:00
// @ts-ignore
for (const key in index.register) {
if (key[0] === 'c') {
index.remove(key); // remove old custom emojis
}
}
2022-07-05 02:08:47 +00:00
let i = 0;
2022-07-04 20:30:35 +00:00
2022-07-05 02:08:47 +00:00
for (const emoji of customEmojis) {
2022-07-09 23:32:34 +00:00
index.add('c' + i++, emoji.id);
2022-07-05 02:08:47 +00:00
}
2022-07-04 20:30:35 +00:00
};
2022-07-09 23:32:34 +00:00
// we can share an index by prefixing custom emojis with 'c' and native with 'n'
2023-03-20 00:56:01 +00:00
const search = (
str: string, { maxResults = 5 }: searchOptions = {},
custom_emojis?: ImmutableList<ImmutableMap<string, string>>,
): Emoji[] => {
2022-07-05 07:11:24 +00:00
return index.search(str, maxResults)
2023-03-20 00:56:01 +00:00
.flatMap((id) => {
if (typeof id !== 'string') return;
2022-07-05 03:11:46 +00:00
2023-03-20 00:56:01 +00:00
if (id[0] === 'c' && custom_emojis) {
const index = Number(id.slice(1));
const custom = custom_emojis.get(index);
if (custom) {
return {
id: custom.get('shortcode', ''),
colons: ':' + custom.get('shortcode', '') + ':',
custom: true,
imageUrl: custom.get('static_url', ''),
};
}
2022-07-05 02:08:47 +00:00
}
2023-03-20 00:56:01 +00:00
const skins = data.emojis[id.slice(1)]?.skins;
2022-07-05 02:08:47 +00:00
2023-03-20 00:56:01 +00:00
if (skins) {
return {
id: id.slice(1),
colons: ':' + id.slice(1) + ':',
unified: skins[0].unified,
native: skins[0].native,
};
}
}).filter(Boolean) as Emoji[];
2022-07-04 20:30:35 +00:00
};
export default search;