client: Sort emojis by query similarity in fuzzy picker #156

Merged
norm merged 6 commits from Michcio/FoundKey-0x7f:tostis-emojosort into main 2022-09-19 14:43:13 +00:00
4 changed files with 17 additions and 10 deletions
Showing only changes of commit a0550c786d - Show all commits

View file

@ -41,8 +41,7 @@
"gulp-rename": "2.0.0",
"gulp-replace": "1.1.3",
"gulp-terser": "2.1.0",
"js-yaml": "4.1.0",
"talisman": "^1.1.4"
"js-yaml": "4.1.0"
},
"devDependencies": {
"@types/gulp": "4.0.9",

View file

@ -60,6 +60,7 @@
"strict-event-emitter-types": "2.0.0",
"stringz": "2.1.0",
"syuilo-password-strength": "0.0.1",
"talisman": "^1.1.4",
"textarea-caret": "3.1.0",
"three": "0.142.0",
"throttle-debounce": "5.0.0",

View file

@ -129,13 +129,20 @@ const searchResultCustom = ref<foundkey.entities.CustomEmoji[]>([]);
const searchResultUnicode = ref<UnicodeEmojiDef[]>([]);
const tab = ref<'index' | 'custom' | 'unicode' | 'tags'>('index');
function emojiSearch<Type>(src: Type[], max: number, query: string): Type[] {
function emojiSearch<Type extends foundkey.entities.CustomEmoji|UnicodeEmojiDef>(src: Type[], max: number, query: string): Type[] {
// discount fuzzy matching pattern
const re = new RegExp(query.split(' ').join('.*'), 'i');
const match = (str: string): boolean => str && re.test(str);
const aliases = (emoji: Type): string[] => // Custom and Unicode emojis have different fields
emoji.aliases ? emoji.aliases
: (emoji.keywords ? emoji.keywords : []);
const match = (str: string): boolean => !!str && re.test(str);
const aliases = (emoji: foundkey.entities.CustomEmoji|UnicodeEmojiDef): string[] => {
// Custom and Unicode emojis have different fields
if ('aliases' in emoji) {
return emoji.aliases;
}
if ('keywords' in emoji) {
return emoji.keywords;
}
return [];
};
const matches = src.filter(emoji => match(emoji.name) || aliases(emoji).some(match));
// precompute distances
@ -143,10 +150,10 @@ function emojiSearch<Type>(src: Type[], max: number, query: string): Type[] {
const joinq = query.replace(/\s+/g, '');
const distance = (str: string): number => rodistance(joinq, str);
const mindistance = (strs: string[]): number => Math.min(...strs.map(distance));
matches.forEach(emoji => distances[emoji] = Math.min(distance(emoji.name), mindistance(aliases(emoji))));
matches.forEach(emoji => distances[emoji.name] = Math.min(distance(emoji.name), mindistance(aliases(emoji))));
// sort by distance from query
matches.sort((a, b) => distances[a] - distances[b]);
matches.sort((a, b) => distances[a.name] - distances[b.name]);
if (max <= 0 || matches.length < max) return matches;
return matches.slice(0, max);
}

View file

@ -4742,6 +4742,7 @@ __metadata:
strict-event-emitter-types: 2.0.0
stringz: 2.1.0
syuilo-password-strength: 0.0.1
talisman: ^1.1.4
textarea-caret: 3.1.0
three: 0.142.0
throttle-debounce: 5.0.0
@ -7875,7 +7876,6 @@ __metadata:
gulp-terser: 2.1.0
js-yaml: 4.1.0
start-server-and-test: 1.14.0
talisman: ^1.1.4
typescript: 4.8.3
languageName: unknown
linkType: soft