Yuki Takei 1 anno fa
parent
commit
84029581e1

+ 6 - 3
apps/app/src/features/search/client/components/SearchModal.tsx

@@ -7,6 +7,7 @@ import Downshift, { type DownshiftState, type StateChangeOptions } from 'downshi
 import { useRouter } from 'next/router';
 import { Modal, ModalBody } from 'reactstrap';
 
+import { isIncludeAiMenthion, removeAiMenthion } from '../../utils/ai';
 import type { DownshiftItem } from '../interfaces/downshift';
 import { useSearchModal } from '../stores/search';
 
@@ -65,9 +66,11 @@ const SearchModal = (): JSX.Element => {
   }, [searchModalData?.isOpened, searchModalData?.searchKeyword]);
 
   useEffect(() => {
-    setMenthionedToAi(searchKeyword.includes('@ai'));
+    setMenthionedToAi(isIncludeAiMenthion(searchKeyword));
   }, [searchKeyword]);
 
+  const searchKeywordWithoutAi = removeAiMenthion(searchKeyword);
+
   return (
     <Modal size="lg" isOpen={searchModalData?.isOpened ?? false} toggle={closeSearchModal} data-testid="search-modal">
       <ModalBody className="pb-2">
@@ -107,12 +110,12 @@ const SearchModal = (): JSX.Element => {
                 <div className="border-top mt-2 mb-2" />
                 <SearchMethodMenuItem
                   activeIndex={highlightedIndex}
-                  searchKeyword={searchKeyword}
+                  searchKeyword={searchKeywordWithoutAi}
                   getItemProps={getItemProps}
                 />
                 <SearchResultMenuItem
                   activeIndex={highlightedIndex}
-                  searchKeyword={searchKeyword}
+                  searchKeyword={searchKeywordWithoutAi}
                   getItemProps={getItemProps}
                 />
                 <div className="border-top mt-2 mb-2" />

+ 7 - 0
apps/app/src/features/search/utils/ai.ts

@@ -0,0 +1,7 @@
+export const isIncludeAiMenthion = (keyword: string): boolean => {
+  return keyword.match(/(^|\s)@ai(\s|$)/) != null;
+};
+
+export const removeAiMenthion = (keyword: string): string => {
+  return keyword.replaceAll(/(^|\s)@ai(\s|$)/g, '');
+};

+ 3 - 3
apps/app/src/server/service/search.ts

@@ -4,6 +4,7 @@ import mongoose from 'mongoose';
 import { FilterXSS } from 'xss';
 
 import { CommentEvent, commentEvent } from '~/features/comment/server';
+import { isIncludeAiMenthion, removeAiMenthion } from '~/features/search/utils/ai';
 import { SearchDelegatorName } from '~/interfaces/named-query';
 import type { IFormattedSearchResult, IPageWithSearchMeta, ISearchResult } from '~/interfaces/search';
 import loggerFactory from '~/utils/logger';
@@ -39,8 +40,7 @@ const filterXss = new FilterXSS(filterXssOptions);
 
 const normalizeQueryString = (_queryString: string): string => {
   let queryString = _queryString.trim();
-  queryString = queryString
-    .replace(/\s+@ai\s+/g, ' ') // omit '@ai' keyword
+  queryString = removeAiMenthion(queryString)
     .replace(/\s+/g, ' ');
 
   return queryString;
@@ -302,7 +302,7 @@ class SearchService implements SearchQueryParser, SearchResolver {
       throw err;
     }
 
-    if (keyword.includes('@ai')) {
+    if (isIncludeAiMenthion(keyword)) {
       searchOpts.vector = true;
     }