diff --git a/components/Search.tsx b/components/Search.tsx index 9ffbb58..e1e6b6f 100644 --- a/components/Search.tsx +++ b/components/Search.tsx @@ -19,7 +19,7 @@ const Search: React.FC = () => { const [recentSearch, setRecentSearch] = useState([]) const [data, setData] = useState>(null) const [loading, setLoading] = useState(false) - const [abortControl, setAbortControl] = useState(new AbortController()) + const abortController = useRef(null) const [hidden, setHidden] = useState(true) useEffect(() => { setQuery('') @@ -32,26 +32,37 @@ const Search: React.FC = () => { } }, [router]) useOutsideClick(ref, () => setHidden(true)) - const SearchResults = async (value: string) => { - setData(null) - setQuery(value) - try { - abortControl.abort() - } catch (e) { - return null + + useEffect(() => { + if (query.length < 2) { + setData(null) + return } - const controller = new AbortController() - setAbortControl(controller) - if (value.length > 1) setLoading(true) - const res = await Fetch(`/search/all?q=${encodeURIComponent(value)}`, { - signal: controller.signal, - }).catch((e) => { - if (e.name !== 'AbortError') throw e - else return - }) - setData(res || {}) - setLoading(false) - } + const timeout = setTimeout(async () => { + setData(null) + try { + if (abortController.current) { + abortController.current.abort() + } + } catch (e) { + return null + } + abortController.current = new AbortController() + if (query.length > 1) setLoading(true) + const res = await Fetch(`/search/all?q=${encodeURIComponent(query)}`, { + signal: abortController.current.signal, + }).catch((e) => { + if (e.name !== 'AbortError') throw e + else return + }) + abortController.current = null + setData(res || {}) + setLoading(false) + }, 1000) + return () => { + clearTimeout(timeout) + } + }, [query]) const onSubmit = () => { if (query.length < 2) return @@ -93,7 +104,7 @@ const Search: React.FC = () => { placeholder='검색...' value={query} onChange={(e) => { - SearchResults(e.target.value) + setQuery(e.target.value) }} onKeyDown={(e) => { if (e.key === 'Enter') { @@ -208,7 +219,7 @@ const Search: React.FC = () => { ))} ) - ) : query.length < 3 ? ( + ) : query.length < 2 ? ( '최소 2글자 이상 입력해주세요.' ) : ( '검색어를 입력해주세요.' diff --git a/utils/Query.ts b/utils/Query.ts index edb0e50..61c3d0f 100644 --- a/utils/Query.ts +++ b/utils/Query.ts @@ -301,8 +301,8 @@ async function getBotList(type: ListType, page = 1, query?: string): Promise await getBot(el.id)))).map((r) => ({ ...r })), currentPage: page, - totalPage: Math.ceil(Number(count) / 16), + totalPage: Math.ceil(Number(count) / 8), } } @@ -402,12 +402,12 @@ async function getServerList(type: ListType, page = 1, query?: string): Promise< )[0][0]['count(*)'] res = ( await knex.raw( - 'SELECT id, votes, MATCH(`name`, `intro`, `desc`) AGAINST(? in boolean mode) as relevance FROM servers WHERE `state` != "blocked" AND last_updated >= ? AND MATCH(`name`, `intro`, `desc`) AGAINST(? in boolean mode) ORDER BY relevance DESC, votes DESC LIMIT 16 OFFSET ?', + 'SELECT id, votes, MATCH(`name`, `intro`, `desc`) AGAINST(? in boolean mode) as relevance FROM servers WHERE `state` != "blocked" AND last_updated >= ? AND MATCH(`name`, `intro`, `desc`) AGAINST(? in boolean mode) ORDER BY relevance DESC, votes DESC LIMIT 8 OFFSET ?', [ decodeURI(query) + '*', new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(), decodeURI(query) + '*', - ((page ? Number(page) : 1) - 1) * 16, + ((page ? Number(page) : 1) - 1) * 8, ] ) )[0] @@ -419,7 +419,7 @@ async function getServerList(type: ListType, page = 1, query?: string): Promise< type, data: (await Promise.all(res.map(async (el) => await getServer(el.id)))).map((r) => ({ ...r })), currentPage: page, - totalPage: Math.ceil(Number(count) / 16), + totalPage: Math.ceil(Number(count) / 8), } }