fix: Improve quality of search results from : emoji search

closes #6073
This commit is contained in:
Tom Moor
2023-10-25 22:13:03 -04:00
parent d7dacd0cd3
commit afb5ccbf74

View File

@@ -1,6 +1,8 @@
import data, { type Emoji as TEmoji, EmojiMartData } from "@emoji-mart/data";
import data, { type Emoji as TEmoji } from "@emoji-mart/data";
import { init, Data } from "emoji-mart";
import FuzzySearch from "fuzzy-search";
import capitalize from "lodash/capitalize";
import sortBy from "lodash/sortBy";
import React from "react";
import { emojiMartToGemoji, snakeCase } from "@shared/editor/lib/emoji";
import EmojiMenuItem from "./EmojiMenuItem";
@@ -16,14 +18,8 @@ type Emoji = {
attrs: { markup: string; "data-name": string };
};
const searcher = new FuzzySearch<TEmoji>(
Object.values((data as EmojiMartData).emojis),
["keywords"],
{
caseSensitive: true,
sort: true,
}
);
void init({ data });
let searcher: FuzzySearch<TEmoji>;
type Props = Omit<
SuggestionsMenuProps<Emoji>,
@@ -33,24 +29,35 @@ type Props = Omit<
const EmojiMenu = (props: Props) => {
const { search = "" } = props;
if (!searcher) {
searcher = new FuzzySearch(Object.values(Data.emojis), ["search"], {
caseSensitive: false,
sort: true,
});
}
const items = React.useMemo(() => {
const n = search.toLowerCase();
const result = searcher.search(n).map((item) => {
// We snake_case the shortcode for backwards compatability with gemoji to
// avoid multiple formats being written into documents.
const shortcode = snakeCase(emojiMartToGemoji[item.id] || item.id);
const emoji = item.skins[0].native;
return {
name: "emoji",
title: emoji,
description: capitalize(item.name.toLowerCase()),
emoji,
attrs: { markup: shortcode, "data-name": shortcode },
};
});
return sortBy(searcher.search(n), (item) => {
const nlc = item.name.toLowerCase();
return nlc === n ? -1 : nlc.startsWith(n) ? 0 : 1;
})
.map((item) => {
// We snake_case the shortcode for backwards compatability with gemoji to
// avoid multiple formats being written into documents.
const shortcode = snakeCase(emojiMartToGemoji[item.id] || item.id);
const emoji = item.skins[0].native;
return result.slice(0, 10);
return {
name: "emoji",
title: emoji,
description: capitalize(item.name.toLowerCase()),
emoji,
attrs: { markup: shortcode, "data-name": shortcode },
};
})
.slice(0, 15);
}, [search]);
return (