enhance(frontend): 絵文字のオートコンプリートのアルゴリズムの改善 (MisskeyIO#261)

* 実際は同じ絵文字なら重複してサジェストに出ないように
* エイリアスではない絵文字>前方一致>部分一致>あいまい検索順で表示されるようになるように
This commit is contained in:
まっちゃとーにゅ 2023-11-24 06:37:06 +09:00 committed by GitHub
parent e11c568852
commit 70d81e40f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -265,7 +265,7 @@ function emojiAutoComplete(query: string | null, emojiDb: EmojiDef[], max = 30):
// //
emojiDb.some(x => { emojiDb.some(x => {
if (x.name.startsWith(query) && !x.aliasOf) { if (x.name.startsWith(query) && !x.aliasOf) {
matched.set(x.name, { emoji: x, score: query.length }); matched.set(x.name, { emoji: x, score: query.length + 1 });
} }
return matched.size === max; return matched.size === max;
}); });
@ -273,8 +273,8 @@ function emojiAutoComplete(query: string | null, emojiDb: EmojiDef[], max = 30):
// //
if (matched.size < max) { if (matched.size < max) {
emojiDb.some(x => { emojiDb.some(x => {
if (x.name.startsWith(query)) { if (x.name.startsWith(query) && !matched.has(x.aliasOf ?? x.name)) {
matched.set(x.name, { emoji: x, score: query.length }); matched.set(x.aliasOf ?? x.name, { emoji: x, score: query.length });
} }
return matched.size === max; return matched.size === max;
}); });
@ -283,36 +283,32 @@ function emojiAutoComplete(query: string | null, emojiDb: EmojiDef[], max = 30):
// //
if (matched.size < max) { if (matched.size < max) {
emojiDb.some(x => { emojiDb.some(x => {
if (x.name.includes(query)) { if (x.name.includes(query) && !matched.has(x.aliasOf ?? x.name)) {
matched.set(x.name, { emoji: x, score: query.length }); matched.set(x.aliasOf ?? x.name, { emoji: x, score: query.length - 1 });
} }
return matched.size === max; return matched.size === max;
}); });
} }
// // 3
if (matched.size < max) { if (matched.size < max && query.length > 3) {
const queryChars = [...query]; const queryChars = [...query];
const hitEmojis = new Map<string, EmojiScore>(); const hitEmojis = new Map<string, EmojiScore>();
for (const x of emojiDb) { for (const x of emojiDb) {
// 1 //
//
let queryCharHitPos = 0; let pos = 0;
let queryCharHitCount = 0; let hit = 0;
for (let idx = 0; idx < queryChars.length; idx++) { for (const c of queryChars) {
queryCharHitPos = x.name.indexOf(queryChars[idx], queryCharHitPos); pos = x.name.indexOf(c, pos);
if (queryCharHitPos <= -1) { if (pos <= -1) break;
break; hit++;
} }
queryCharHitCount++; //
} if (hit > Math.ceil(queryChars.length / 2) && hit - 2 > (matched.get(x.aliasOf ?? x.name)?.score ?? 0)) {
hitEmojis.set(x.aliasOf ?? x.name, { emoji: x, score: hit - 2 });
// 調
if (queryCharHitCount > 2) {
hitEmojis.set(x.name, { emoji: x, score: queryCharHitCount });
} }
} }