From 80c490a18b5957052f729bcebbfa89fa89052290 Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Sat, 7 Nov 2020 21:28:28 +0900
Subject: [PATCH] =?UTF-8?q?=E7=B5=B5=E6=96=87=E5=AD=97=E3=83=94=E3=83=83?=
 =?UTF-8?q?=E3=82=AB=E3=83=BC=E3=81=A7AND=E6=A4=9C=E7=B4=A2=E3=81=AB?=
 =?UTF-8?q?=E5=AF=BE=E5=BF=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/client/components/emoji-picker.vue | 136 ++++++++++++++++---------
 1 file changed, 90 insertions(+), 46 deletions(-)

diff --git a/src/client/components/emoji-picker.vue b/src/client/components/emoji-picker.vue
index 21d39e8e9..e38206f14 100644
--- a/src/client/components/emoji-picker.vue
+++ b/src/client/components/emoji-picker.vue
@@ -190,36 +190,58 @@ export default defineComponent({
 				const exactMatch = emojis.find(e => e.name === q);
 				if (exactMatch) matches.add(exactMatch);
 
-				for (const emoji of emojis) {
-					if (emoji.name.startsWith(q)) {
-						matches.add(emoji);
-						if (matches.size >= max) break;
-					}
-				}
-				if (matches.size >= max) return matches;
+				if (q.includes(' ')) { // AND検索
+					const keywords = q.split(' ');
 
-				for (const emoji of emojis) {
-					if (emoji.aliases.some(alias => alias.startsWith(q))) {
-						matches.add(emoji);
-						if (matches.size >= max) break;
+					// 名前にキーワードが含まれている
+					for (const emoji of emojis) {
+						if (keywords.every(keyword => emoji.name.includes(keyword))) {
+							matches.add(emoji);
+							if (matches.size >= max) break;
+						}
 					}
-				}
-				if (matches.size >= max) return matches;
+					if (matches.size >= max) return matches;
 
-				for (const emoji of emojis) {
-					if (emoji.name.includes(q)) {
-						matches.add(emoji);
-						if (matches.size >= max) break;
+					// 名前またはエイリアスにキーワードが含まれている
+					for (const emoji of emojis) {
+						if (keywords.every(keyword => emoji.name.includes(keyword) || emoji.aliases.some(alias => alias.includes(keyword)))) {
+							matches.add(emoji);
+							if (matches.size >= max) break;
+						}
 					}
-				}
-				if (matches.size >= max) return matches;
+				} else {
+					for (const emoji of emojis) {
+						if (emoji.name.startsWith(q)) {
+							matches.add(emoji);
+							if (matches.size >= max) break;
+						}
+					}
+					if (matches.size >= max) return matches;
 
-				for (const emoji of emojis) {
-					if (emoji.aliases.some(alias => alias.includes(q))) {
-						matches.add(emoji);
-						if (matches.size >= max) break;
+					for (const emoji of emojis) {
+						if (emoji.aliases.some(alias => alias.startsWith(q))) {
+							matches.add(emoji);
+							if (matches.size >= max) break;
+						}
+					}
+					if (matches.size >= max) return matches;
+
+					for (const emoji of emojis) {
+						if (emoji.name.includes(q)) {
+							matches.add(emoji);
+							if (matches.size >= max) break;
+						}
+					}
+					if (matches.size >= max) return matches;
+
+					for (const emoji of emojis) {
+						if (emoji.aliases.some(alias => alias.includes(q))) {
+							matches.add(emoji);
+							if (matches.size >= max) break;
+						}
 					}
 				}
+
 				return matches;
 			};
 
@@ -231,36 +253,58 @@ export default defineComponent({
 				const exactMatch = emojis.find(e => e.name === q);
 				if (exactMatch) matches.add(exactMatch);
 
-				for (const emoji of emojis) {
-					if (emoji.name.startsWith(q)) {
-						matches.add(emoji);
-						if (matches.size >= max) break;
-					}
-				}
-				if (matches.size >= max) return matches;
+				if (q.includes(' ')) { // AND検索
+					const keywords = q.split(' ');
 
-				for (const emoji of emojis) {
-					if (emoji.keywords.some(keyword => keyword.startsWith(q))) {
-						matches.add(emoji);
-						if (matches.size >= max) break;
+					// 名前にキーワードが含まれている
+					for (const emoji of emojis) {
+						if (keywords.every(keyword => emoji.name.includes(keyword))) {
+							matches.add(emoji);
+							if (matches.size >= max) break;
+						}
 					}
-				}
-				if (matches.size >= max) return matches;
+					if (matches.size >= max) return matches;
 
-				for (const emoji of emojis) {
-					if (emoji.name.includes(q)) {
-						matches.add(emoji);
-						if (matches.size >= max) break;
+					// 名前またはエイリアスにキーワードが含まれている
+					for (const emoji of emojis) {
+						if (keywords.every(keyword => emoji.name.includes(keyword) || emoji.keywords.some(alias => alias.includes(keyword)))) {
+							matches.add(emoji);
+							if (matches.size >= max) break;
+						}
 					}
-				}
-				if (matches.size >= max) return matches;
+				} else {
+					for (const emoji of emojis) {
+						if (emoji.name.startsWith(q)) {
+							matches.add(emoji);
+							if (matches.size >= max) break;
+						}
+					}
+					if (matches.size >= max) return matches;
 
-				for (const emoji of emojis) {
-					if (emoji.keywords.some(keyword => keyword.includes(q))) {
-						matches.add(emoji);
-						if (matches.size >= max) break;
+					for (const emoji of emojis) {
+						if (emoji.keywords.some(keyword => keyword.startsWith(q))) {
+							matches.add(emoji);
+							if (matches.size >= max) break;
+						}
+					}
+					if (matches.size >= max) return matches;
+
+					for (const emoji of emojis) {
+						if (emoji.name.includes(q)) {
+							matches.add(emoji);
+							if (matches.size >= max) break;
+						}
+					}
+					if (matches.size >= max) return matches;
+
+					for (const emoji of emojis) {
+						if (emoji.keywords.some(keyword => keyword.includes(q))) {
+							matches.add(emoji);
+							if (matches.size >= max) break;
+						}
 					}
 				}
+
 				return matches;
 			};