Improve emoji search (#11768)

Co-authored-by: mpcjazz <mail@mpcjazz.com>
This commit is contained in:
mpcjazz 2024-06-20 12:39:16 +09:00 committed by GitHub
parent 47d79042fd
commit 0b51219f50
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 11643 additions and 9494 deletions

File diff suppressed because it is too large Load diff

View file

@ -7783,7 +7783,7 @@
}, },
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": " の後に続けて絵文字の名前 (英語) を入力します" "Data": " の後に続けて絵文字のキーワードを入力します"
} }
] ]
} }

View file

@ -897,15 +897,15 @@
}, },
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": " を入力し、それ" "Data": " を入力し、続けて"
}, },
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": "に続けて文字を入力すると絵文字検索を" "Data": "キーワードを入力すると絵文字検索が"
}, },
{ {
"Type": "NodeText", "Type": "NodeText",
"Data": "開始できます 😄 😆 😵 😭 😰 😅 😢 😤 😍 😌👍 👎 💯 👏 🔔 🎁 ❓ 💣 ❤️ ☕️ 🌀 🙇 💋 🙏 💢" "Data": "開始されます 😄 😆 😵 😭 😰 😅 😢 😤 😍 😌👍 👎 💯 👏 🔔 🎁 ❓ 💣 ❤️ ☕️ 🌀 🙇 💋 🙏 💢"
} }
] ]
} }

View file

@ -53,7 +53,7 @@ export const lazyLoadEmoji = (element: HTMLElement) => {
if ((typeof entrie.isIntersecting === "undefined" ? entrie.intersectionRatio !== 0 : entrie.isIntersecting) && index) { if ((typeof entrie.isIntersecting === "undefined" ? entrie.intersectionRatio !== 0 : entrie.isIntersecting) && index) {
let html = ""; let html = "";
window.siyuan.emojis[parseInt(index)].items.forEach(emoji => { window.siyuan.emojis[parseInt(index)].items.forEach(emoji => {
html += `<button data-unicode="${emoji.unicode}" class="emojis__item ariaLabel" aria-label="${window.siyuan.config.lang === "zh_CN" ? emoji.description_zh_cn : emoji.description}"> html += `<button data-unicode="${emoji.unicode}" class="emojis__item ariaLabel" aria-label="${window.siyuan.config.lang === "zh_CN" ? emoji.description_zh_cn : window.siyuan.config.lang === "ja_JP" ? emoji.description_ja_jp : emoji.description}">
${unicode2Emoji(emoji.unicode)}</button>`; ${unicode2Emoji(emoji.unicode)}</button>`;
}); });
entrie.target.innerHTML = html; entrie.target.innerHTML = html;
@ -87,6 +87,7 @@ export const filterEmoji = (key = "", max?: number) => {
unicode: string, unicode: string,
description: string, description: string,
description_zh_cn: string, description_zh_cn: string,
description_ja_jp: string,
keywords: string keywords: string
}[] = []; }[] = [];
if (key) { if (key) {
@ -98,11 +99,12 @@ export const filterEmoji = (key = "", max?: number) => {
unicode: string, unicode: string,
description: string, description: string,
description_zh_cn: string, description_zh_cn: string,
description_ja_jp: string,
keywords: string keywords: string
}[] = []; }[] = [];
window.siyuan.emojis.forEach((category, index) => { window.siyuan.emojis.forEach((category, index) => {
if (!key) { if (!key) {
html += `<div class="emojis__title" data-type="${index + 1}">${window.siyuan.config.lang === "zh_CN" ? category.title_zh_cn : category.title}</div><div style="min-height:${index === 0 ? "28px" : "336px"}" class="emojis__content"${index > 1 ? ' data-index="' + index + '"' : ""}>`; html += `<div class="emojis__title" data-type="${index + 1}">${window.siyuan.config.lang === "zh_CN" ? category.title_zh_cn : window.siyuan.config.lang === "ja_JP" ? category.title_ja_jp : category.title}</div><div style="min-height:${index === 0 ? "28px" : "336px"}" class="emojis__content"${index > 1 ? ' data-index="' + index + '"' : ""}>`;
} }
if (category.items.length === 0 && index === 0 && !key) { if (category.items.length === 0 && index === 0 && !key) {
html += `<div style="margin-left: 4px">${window.siyuan.languages.setEmojiTip}</div>`; html += `<div style="margin-left: 4px">${window.siyuan.languages.setEmojiTip}</div>`;
@ -111,17 +113,17 @@ export const filterEmoji = (key = "", max?: number) => {
category.items.forEach(emoji => { category.items.forEach(emoji => {
if (key) { if (key) {
if (window.siyuan.config.editor.emoji.includes(emoji.unicode) && if (window.siyuan.config.editor.emoji.includes(emoji.unicode) &&
(unicode2Emoji(emoji.unicode) === key || emoji.keywords.toLowerCase().indexOf(key.toLowerCase()) > -1 || emoji.description.toLowerCase().indexOf(key.toLowerCase()) > -1 || emoji.description_zh_cn.toLowerCase().indexOf(key.toLowerCase()) > -1)) { (unicode2Emoji(emoji.unicode) === key || emoji.keywords.toLowerCase().indexOf(key.toLowerCase()) > -1 || emoji.description.toLowerCase().indexOf(key.toLowerCase()) > -1 || emoji.description_zh_cn.toLowerCase().indexOf(key.toLowerCase()) > -1 || emoji.description_ja_jp.toLowerCase().indexOf(key.toLowerCase()) > -1)) {
recentEmojis.push(emoji); recentEmojis.push(emoji);
} }
if (max && maxCount > max) { if (max && maxCount > max) {
return; return;
} }
if (unicode2Emoji(emoji.unicode) === key || emoji.keywords.toLowerCase().indexOf(key.toLowerCase()) > -1 || emoji.description.toLowerCase().indexOf(key.toLowerCase()) > -1 || emoji.description_zh_cn.toLowerCase().indexOf(key.toLowerCase()) > -1) { if (unicode2Emoji(emoji.unicode) === key || emoji.keywords.toLowerCase().indexOf(key.toLowerCase()) > -1 || emoji.description.toLowerCase().indexOf(key.toLowerCase()) > -1 || emoji.description_zh_cn.toLowerCase().indexOf(key.toLowerCase()) > -1 || emoji.description_ja_jp.toLowerCase().indexOf(key.toLowerCase()) > -1) {
if (category.id === "custom") { if (category.id === "custom") {
customStore.push(emoji); customStore.push(emoji);
} else { } else {
keyHTML += `<button data-unicode="${emoji.unicode}" class="emojis__item ariaLabel" aria-label="${window.siyuan.config.lang === "zh_CN" ? emoji.description_zh_cn : emoji.description}"> keyHTML += `<button data-unicode="${emoji.unicode}" class="emojis__item ariaLabel" aria-label="${window.siyuan.config.lang === "zh_CN" ? emoji.description_zh_cn : window.siyuan.config.lang === "ja_JP" ? emoji.description_ja_jp : emoji.description}">
${unicode2Emoji(emoji.unicode, undefined, false, true)}</button>`; ${unicode2Emoji(emoji.unicode, undefined, false, true)}</button>`;
} }
maxCount++; maxCount++;
@ -131,7 +133,7 @@ ${unicode2Emoji(emoji.unicode, undefined, false, true)}</button>`;
recentEmojis.push(emoji); recentEmojis.push(emoji);
} }
if (index < 2) { if (index < 2) {
html += `<button data-unicode="${emoji.unicode}" class="emojis__item ariaLabel" aria-label="${window.siyuan.config.lang === "zh_CN" ? emoji.description_zh_cn : emoji.description}"> html += `<button data-unicode="${emoji.unicode}" class="emojis__item ariaLabel" aria-label="${window.siyuan.config.lang === "zh_CN" ? emoji.description_zh_cn : window.siyuan.config.lang === "ja_JP" ? emoji.description_ja_jp : emoji.description}">
${unicode2Emoji(emoji.unicode, undefined, false, true)}</button>`; ${unicode2Emoji(emoji.unicode, undefined, false, true)}</button>`;
} }
} }
@ -156,7 +158,7 @@ ${unicode2Emoji(emoji.unicode, undefined, false, true)}</button>`;
} }
return 0; return 0;
}).forEach(item => { }).forEach(item => {
html += `<button data-unicode="${item.unicode}" class="emojis__item ariaLabel" aria-label="${window.siyuan.config.lang === "zh_CN" ? item.description_zh_cn : item.description}"> html += `<button data-unicode="${item.unicode}" class="emojis__item ariaLabel" aria-label="${window.siyuan.config.lang === "zh_CN" ? item.description_zh_cn : window.siyuan.config.lang === "ja_JP" ? item.description_ja_jp : item.description}">
${unicode2Emoji(item.unicode, undefined, false, true)}</button>`; ${unicode2Emoji(item.unicode, undefined, false, true)}</button>`;
}); });
html = html + keyHTML + "</div>"; html = html + keyHTML + "</div>";
@ -167,7 +169,7 @@ ${unicode2Emoji(item.unicode, undefined, false, true)}</button>`;
window.siyuan.config.editor.emoji.forEach(emojiUnicode => { window.siyuan.config.editor.emoji.forEach(emojiUnicode => {
const emoji = recentEmojis.filter((item) => item.unicode === emojiUnicode); const emoji = recentEmojis.filter((item) => item.unicode === emojiUnicode);
if (emoji[0]) { if (emoji[0]) {
recentHTML += `<button data-unicode="${emoji[0].unicode}" class="emojis__item ariaLabel" aria-label="${window.siyuan.config.lang === "zh_CN" ? emoji[0].description_zh_cn : emoji[0].description}"> recentHTML += `<button data-unicode="${emoji[0].unicode}" class="emojis__item ariaLabel" aria-label="${window.siyuan.config.lang === "zh_CN" ? emoji[0].description_zh_cn : window.siyuan.config.lang === "ja_JP" ? emoji[0].description_ja_jp : emoji[0].description}">
${unicode2Emoji(emoji[0].unicode, undefined, false, true)} ${unicode2Emoji(emoji[0].unicode, undefined, false, true)}
</button>`; </button>`;
} }
@ -197,14 +199,22 @@ export const openEmojiPanel = (id: string, type: "doc" | "notebook" | "av", posi
} else { } else {
window.siyuan.menus.menu.removeScrollEvent(); window.siyuan.menus.menu.removeScrollEvent();
} }
const getEmojiTitle = (emojiIndex: number) => {
const lang = window.siyuan.config.lang;
const titleKey = lang === "zh_CN" ? "title_zh_cn" : lang === "ja_JP" ? "title_ja_jp" : "title";
return window.siyuan.emojis[emojiIndex][titleKey];
};
const dialog = new Dialog({ const dialog = new Dialog({
disableAnimation: true, disableAnimation: true,
transparent: true, transparent: true,
hideCloseIcon: true, hideCloseIcon: true,
width: isMobile() ? "80vw" : "360px", width: isMobile() ? "80vw" : "360px",
height: "50vh", height: "50vh",
content: `<div class="emojis"> content: `
<div class="fn__flex"> <div class="emojis">
<div class="fn__flex">
<span class="fn__space"></span> <span class="fn__space"></span>
<label class="b3-form__icon fn__flex-1" style="overflow:initial;"> <label class="b3-form__icon fn__flex-1" style="overflow:initial;">
<svg class="b3-form__icon-icon"><use xlink:href="#iconSearch"></use></svg> <svg class="b3-form__icon-icon"><use xlink:href="#iconSearch"></use></svg>
@ -215,20 +225,24 @@ export const openEmojiPanel = (id: string, type: "doc" | "notebook" | "av", posi
<span class="fn__space"></span> <span class="fn__space"></span>
<span class="block__icon block__icon--show fn__flex-center b3-tooltips b3-tooltips__sw" aria-label="${window.siyuan.languages.remove}"><svg><use xlink:href="#iconTrashcan"></use></svg></span> <span class="block__icon block__icon--show fn__flex-center b3-tooltips b3-tooltips__sw" aria-label="${window.siyuan.languages.remove}"><svg><use xlink:href="#iconTrashcan"></use></svg></span>
<span class="fn__space"></span> <span class="fn__space"></span>
</div> </div>
<div class="emojis__panel">${filterEmoji()}</div> <div class="emojis__panel">${filterEmoji()}</div>
<div class="fn__flex"> <div class="fn__flex">
<div data-type="0" class="emojis__type ariaLabel" aria-label="${window.siyuan.languages.recentEmoji}">${unicode2Emoji("2b50")}</div> ${[
<div data-type="1" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[0][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("1f527")}</div> ["2b50", window.siyuan.languages.recentEmoji],
<div data-type="2" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[1][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("1f60d")}</div> ["1f527", getEmojiTitle(0)],
<div data-type="3" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[2][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("1f433")}</div> ["1f60d", getEmojiTitle(1)],
<div data-type="4" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[3][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("1f96a")}</div> ["1f433", getEmojiTitle(2)],
<div data-type="5" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[4][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("1f3a8")}</div> ["1f96a", getEmojiTitle(3)],
<div data-type="6" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[5][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("1f3dd-fe0f")}</div> ["1f3a8", getEmojiTitle(4)],
<div data-type="7" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[6][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("1f52e")}</div> ["1f3dd-fe0f", getEmojiTitle(5)],
<div data-type="8" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[7][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("267e-fe0f")}</div> ["1f52e", getEmojiTitle(6)],
<div data-type="9" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[8][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("1f6a9")}</div> ["267e-fe0f", getEmojiTitle(7)],
</div> ["1f6a9", getEmojiTitle(8)],
].map(([unicode, title], index) =>
`<div data-type="${index}" class="emojis__type ariaLabel" aria-label="${title}">${unicode2Emoji(unicode)}</div>`
).join('')}
</div>
</div>` </div>`
}); });
dialog.element.setAttribute("data-key", Constants.DIALOG_EMOJIS); dialog.element.setAttribute("data-key", Constants.DIALOG_EMOJIS);
@ -398,7 +412,7 @@ export const openEmojiPanel = (id: string, type: "doc" | "notebook" | "av", posi
if (index) { if (index) {
let html = ""; let html = "";
window.siyuan.emojis[parseInt(index)].items.forEach(emoji => { window.siyuan.emojis[parseInt(index)].items.forEach(emoji => {
html += `<button data-unicode="${emoji.unicode}" class="emojis__item ariaLabel" aria-label="${window.siyuan.config.lang === "zh_CN" ? emoji.description_zh_cn : emoji.description}"> html += `<button data-unicode="${emoji.unicode}" class="emojis__item ariaLabel" aria-label="${window.siyuan.config.lang === "zh_CN" ? emoji.description_zh_cn : window.siyuan.config.lang === "ja_JP" ? emoji.description_ja_jp : emoji.description}">
${unicode2Emoji(emoji.unicode)}</button>`; ${unicode2Emoji(emoji.unicode)}</button>`;
}); });
titleElement.nextElementSibling.innerHTML = html; titleElement.nextElementSibling.innerHTML = html;

View file

@ -72,7 +72,7 @@ export class Hint {
if (index) { if (index) {
let html = ""; let html = "";
window.siyuan.emojis[parseInt(index)].items.forEach(emoji => { window.siyuan.emojis[parseInt(index)].items.forEach(emoji => {
html += `<button data-unicode="${emoji.unicode}" class="emojis__item ariaLabel" aria-label="${window.siyuan.config.lang === "zh_CN" ? emoji.description_zh_cn : emoji.description}"> html += `<button data-unicode="${emoji.unicode}" class="emojis__item ariaLabel" aria-label="${window.siyuan.config.lang === "zh_CN" ? emoji.description_zh_cn : window.siyuan.config.lang === "ja_JP" ? emoji.description_ja_jp : emoji.description}">
${unicode2Emoji(emoji.unicode)}</button>`; ${unicode2Emoji(emoji.unicode)}</button>`;
}); });
titleElement.nextElementSibling.innerHTML = html; titleElement.nextElementSibling.innerHTML = html;
@ -347,6 +347,13 @@ ${genHintItemHTML(item)}
if (value && !this.enableEmoji) { if (value && !this.enableEmoji) {
return; return;
} }
const getEmojiTitle = (emojiIndex: number) => {
const lang = window.siyuan.config.lang;
const titleKey = lang === "zh_CN" ? "title_zh_cn" : lang === "ja_JP" ? "title_ja_jp" : "title";
return window.siyuan.emojis[emojiIndex][titleKey];
};
const panelElement = this.element.querySelector(".emojis__panel"); const panelElement = this.element.querySelector(".emojis__panel");
if (panelElement) { if (panelElement) {
panelElement.innerHTML = filterEmoji(value, 256); panelElement.innerHTML = filterEmoji(value, 256);
@ -360,16 +367,21 @@ ${genHintItemHTML(item)}
this.element.innerHTML = `<div style="padding: 0;max-height:402px" class="emojis"> this.element.innerHTML = `<div style="padding: 0;max-height:402px" class="emojis">
<div class="emojis__panel">${filterEmoji(value, 256)}</div> <div class="emojis__panel">${filterEmoji(value, 256)}</div>
<div class="fn__flex${value ? " fn__none" : ""}"> <div class="fn__flex${value ? " fn__none" : ""}">
<button data-type="0" class="emojis__type ariaLabel" aria-label="${window.siyuan.languages.recentEmoji}">${unicode2Emoji("2b50")}</button> ${[
<button data-type="1" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[0][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("1f527")}</button> ["1f527", getEmojiTitle(0)],
<button data-type="2" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[1][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("1f60d")}</button> ["1f60d", getEmojiTitle(1)],
<button data-type="3" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[2][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("1f433")}</button> ["1f433", getEmojiTitle(2)],
<button data-type="4" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[3][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("1f96a")}</button> ["1f96a", getEmojiTitle(3)],
<button data-type="5" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[4][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("1f3a8")}</button> ["1f3a8", getEmojiTitle(4)],
<button data-type="6" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[5][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("1f3dd-fe0f")}</button> ["1f3dd-fe0f", getEmojiTitle(5)],
<button data-type="7" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[6][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("1f52e")}</button> ["1f52e", getEmojiTitle(6)],
<button data-type="8" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[7][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("267e-fe0f")}</button> ["267e-fe0f", getEmojiTitle(7)],
<button data-type="9" class="emojis__type ariaLabel" aria-label="${window.siyuan.emojis[8][window.siyuan.config.lang === "zh_CN" ? "title_zh_cn" : "title"]}">${unicode2Emoji("1f6a9")}</button> ["1f6a9", getEmojiTitle(8)],
].map(([unicode, title], index) =>
`<button data-type="${index + 1}" class="emojis__type ariaLabel" aria-label="${title}">${unicode2Emoji(
unicode,
)}</button>`
).join("")}
</div> </div>
</div>`; </div>`;
lazyLoadEmoji(this.element); lazyLoadEmoji(this.element);

View file

@ -323,10 +323,12 @@ interface IEmoji {
id: string, id: string,
title: string, title: string,
title_zh_cn: string, title_zh_cn: string,
title_ja_jp: string,
items: { items: {
unicode: string, unicode: string,
description: string, description: string,
description_zh_cn: string, description_zh_cn: string,
description_ja_jp: string,
keywords: string keywords: string
}[] }[]
} }

View file

@ -117,6 +117,7 @@ func getEmojiConf(c *gin.Context) {
"id": "custom", "id": "custom",
"title": "Custom", "title": "Custom",
"title_zh_cn": "自定义", "title_zh_cn": "自定义",
"title_ja_jp": "カスタム",
} }
items := []map[string]interface{}{} items := []map[string]interface{}{}
custom["items"] = items custom["items"] = items
@ -173,6 +174,7 @@ func addCustomEmoji(name string, items *[]map[string]interface{}) {
"unicode": name, "unicode": name,
"description": nameWithoutExt, "description": nameWithoutExt,
"description_zh_cn": nameWithoutExt, "description_zh_cn": nameWithoutExt,
"description_ja_jp": nameWithoutExt,
"keywords": nameWithoutExt, "keywords": nameWithoutExt,
} }
*items = append(*items, emoji) *items = append(*items, emoji)