nicolium: remove flexsearch dependence, use fuzzysort for emojis
Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
@ -87,7 +87,6 @@
|
||||
"exifr": "^7.1.3",
|
||||
"fast-average-color": "^9.5.0",
|
||||
"fasttext.wasm.js": "^1.0.0",
|
||||
"flexsearch": "^0.7.43",
|
||||
"fuzzysort": "^3.1.0",
|
||||
"graphemesplit": "^2.6.0",
|
||||
"html-react-parser": "^5.2.17",
|
||||
|
||||
@ -20,6 +20,7 @@ import {
|
||||
useRelationshipQuery,
|
||||
useUnblockAccountMutation,
|
||||
} from '@/queries/accounts/use-relationship';
|
||||
import { useCustomEmojis } from '@/queries/instance/use-custom-emojis';
|
||||
import { useModalsActions } from '@/stores/modals';
|
||||
import { textAtCursorMatchesToken } from '@/utils/suggestions';
|
||||
|
||||
@ -95,6 +96,7 @@ const ChatComposer = React.forwardRef<HTMLTextAreaElement | null, IChatComposer>
|
||||
const { chat } = useChatContext();
|
||||
const { data: relationship } = useRelationshipQuery(chat?.account.id);
|
||||
const { mutate: unblockAccount } = useUnblockAccountMutation(chat?.account.id!);
|
||||
const { data: customEmojis } = useCustomEmojis();
|
||||
|
||||
const isBlocked = relationship?.blocked_by && false;
|
||||
const isBlocking = relationship?.blocking && false;
|
||||
@ -130,7 +132,7 @@ const ChatComposer = React.forwardRef<HTMLTextAreaElement | null, IChatComposer>
|
||||
);
|
||||
|
||||
if (token && tokenStart) {
|
||||
const results = emojiSearch(token.replace(':', ''), { maxResults: 5 });
|
||||
const results = emojiSearch(token.replace(':', ''), customEmojis, 5);
|
||||
setSuggestions({
|
||||
list: results,
|
||||
token,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import FlexSearch from 'flexsearch';
|
||||
import fuzzysort from 'fuzzysort';
|
||||
|
||||
import type { EmojiData } from './data';
|
||||
import type { Emoji } from './index';
|
||||
@ -6,79 +6,57 @@ import type { CustomEmoji } from 'pl-api';
|
||||
|
||||
let emojis: EmojiData['emojis'] = {};
|
||||
|
||||
const nativeData: Array<{ key: string; id: string }> = [];
|
||||
let customData: Array<{ key: string; id: string }> = [];
|
||||
|
||||
import('./data')
|
||||
.then((data) => {
|
||||
emojis = data.emojis;
|
||||
|
||||
const sortedEmojis = Object.entries(emojis).toSorted((a, b) => a[0].localeCompare(b[0]));
|
||||
for (const [key, emoji] of sortedEmojis) {
|
||||
index.add('n' + key, `${emoji.id} ${emoji.name} ${emoji.keywords.join(' ')}`);
|
||||
nativeData.push({
|
||||
key: `${emoji.id} ${emoji.name} ${emoji.keywords.join(' ')}`,
|
||||
id: 'n' + key,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
|
||||
const index = new FlexSearch.Index({
|
||||
tokenize: 'full',
|
||||
optimize: true,
|
||||
context: true,
|
||||
});
|
||||
|
||||
interface searchOptions {
|
||||
maxResults?: number;
|
||||
custom?: CustomEmoji[];
|
||||
}
|
||||
|
||||
const addCustomToPool = (customEmojis: CustomEmoji[]) => {
|
||||
// @ts-expect-error
|
||||
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.shortcode);
|
||||
}
|
||||
customData = customEmojis.map((emoji, i) => ({
|
||||
key: emoji.shortcode,
|
||||
id: 'c' + i,
|
||||
}));
|
||||
};
|
||||
|
||||
// we can share an index by prefixing custom emojis with 'c' and native with 'n'
|
||||
const search = (
|
||||
str: string,
|
||||
{ maxResults = 5 }: searchOptions = {},
|
||||
custom_emojis?: Array<CustomEmoji>,
|
||||
): Emoji[] =>
|
||||
index
|
||||
.search(str, maxResults)
|
||||
.flatMap((id) => {
|
||||
if (typeof id !== 'string') return;
|
||||
const search = (query: string, customEmojis: Array<CustomEmoji> = [], limit = 5): Emoji[] => {
|
||||
return fuzzysort
|
||||
.go(query, [...nativeData, ...customData], { key: 'key', limit })
|
||||
.map((result) => {
|
||||
const { id } = result.obj;
|
||||
|
||||
if (id[0] === 'c' && custom_emojis) {
|
||||
const index = Number(id.slice(1));
|
||||
const custom = custom_emojis[index];
|
||||
|
||||
if (custom) {
|
||||
return {
|
||||
id: custom.shortcode,
|
||||
colons: ':' + custom.shortcode + ':',
|
||||
custom: true,
|
||||
imageUrl: custom.static_url,
|
||||
};
|
||||
}
|
||||
if (id[0] === 'c') {
|
||||
const customEmoji = customEmojis[Number(id.slice(1))];
|
||||
return {
|
||||
id: customEmoji.shortcode,
|
||||
colons: ':' + customEmoji.shortcode + ':',
|
||||
custom: true,
|
||||
imageUrl: customEmoji.static_url,
|
||||
};
|
||||
}
|
||||
|
||||
const skins = emojis[id.slice(1)]?.skins;
|
||||
|
||||
if (skins) {
|
||||
const emojiData = emojis[id.slice(1)];
|
||||
if (emojiData) {
|
||||
return {
|
||||
id: id.slice(1),
|
||||
colons: ':' + id.slice(1) + ':',
|
||||
unified: skins[0].unified,
|
||||
native: skins[0].native,
|
||||
unified: emojiData.skins[0].unified,
|
||||
native: emojiData.skins[0].native,
|
||||
};
|
||||
}
|
||||
})
|
||||
.filter(Boolean) as Emoji[];
|
||||
.filter(Boolean) as Array<Emoji>;
|
||||
};
|
||||
|
||||
export { search as default, addCustomToPool };
|
||||
|
||||
@ -32,7 +32,7 @@ const useComposeSuggestions = (token: string): Array<AutoSuggestion> => {
|
||||
|
||||
return useMemo((): Array<AutoSuggestion> => {
|
||||
if (searchedType === 'emojis') {
|
||||
return emojiSearch(token.replace(':', ''), { maxResults: 10 }, customEmojis);
|
||||
return emojiSearch(token.replace(':', ''), customEmojis, 10);
|
||||
}
|
||||
|
||||
if (searchedType === 'accounts') {
|
||||
|
||||
@ -621,4 +621,4 @@ div:has(.⁂-background-shapes),
|
||||
&--error svg {
|
||||
@apply text-danger-600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@ -178,9 +178,6 @@ importers:
|
||||
fasttext.wasm.js:
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0
|
||||
flexsearch:
|
||||
specifier: ^0.7.43
|
||||
version: 0.7.43
|
||||
fuzzysort:
|
||||
specifier: ^3.1.0
|
||||
version: 3.1.0
|
||||
@ -3859,9 +3856,6 @@ packages:
|
||||
flatted@3.3.3:
|
||||
resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
|
||||
|
||||
flexsearch@0.7.43:
|
||||
resolution: {integrity: sha512-c5o/+Um8aqCSOXGcZoqZOm+NqtVwNsvVpWv6lfmSclU954O3wvQKxxK8zj74fPaSJbXpSLTs4PRhh+wnoCXnKg==}
|
||||
|
||||
for-each@0.3.5:
|
||||
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -10096,8 +10090,6 @@ snapshots:
|
||||
|
||||
flatted@3.3.3: {}
|
||||
|
||||
flexsearch@0.7.43: {}
|
||||
|
||||
for-each@0.3.5:
|
||||
dependencies:
|
||||
is-callable: 1.2.7
|
||||
|
||||
Reference in New Issue
Block a user