74 lines
1.7 KiB
TypeScript
74 lines
1.7 KiB
TypeScript
import { Index } from 'flexsearch-ts';
|
|
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
|
|
|
import data from './data';
|
|
|
|
import type { Emoji } from './index';
|
|
|
|
const index = new Index({
|
|
tokenize: 'full',
|
|
optimize: true,
|
|
context: true,
|
|
});
|
|
|
|
for (const [key, emoji] of Object.entries(data.emojis)) {
|
|
index.add('n' + key, emoji.name);
|
|
}
|
|
|
|
export interface searchOptions {
|
|
maxResults?: number
|
|
custom?: any
|
|
}
|
|
|
|
export const addCustomToPool = (customEmojis: any[]) => {
|
|
// @ts-ignore
|
|
for (const key in index.register) {
|
|
if (key[0] === 'c') {
|
|
index.remove(key); // remove old custom emojis
|
|
}
|
|
}
|
|
|
|
let i = 0;
|
|
|
|
for (const emoji of customEmojis) {
|
|
index.add('c' + i++, emoji.id);
|
|
}
|
|
};
|
|
|
|
// we can share an index by prefixing custom emojis with 'c' and native with 'n'
|
|
const search = (
|
|
str: string, { maxResults = 5 }: searchOptions = {},
|
|
custom_emojis?: ImmutableList<ImmutableMap<string, string>>,
|
|
): Emoji[] => {
|
|
return index.search(str, maxResults)
|
|
.flatMap((id) => {
|
|
if (typeof id !== 'string') return;
|
|
|
|
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', ''),
|
|
};
|
|
}
|
|
}
|
|
|
|
const skins = data.emojis[id.slice(1)]?.skins;
|
|
|
|
if (skins) {
|
|
return {
|
|
id: id.slice(1),
|
|
colons: ':' + id.slice(1) + ':',
|
|
unified: skins[0].unified,
|
|
native: skins[0].native,
|
|
};
|
|
}
|
|
}).filter(Boolean) as Emoji[];
|
|
};
|
|
|
|
export default search;
|