From 33a1937407b214262e3e24d6567f347be7fc12d3 Mon Sep 17 00:00:00 2001 From: Bhwa233 <404174262@qq.com> Date: Fri, 1 Mar 2024 17:12:04 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=89=93=E5=BC=80=E5=BC=B9=E7=AA=97?= =?UTF-8?q?=E8=87=AA=E5=8A=A8focus?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/AlgoliaSearchModal.js | 44 +++++++++++++++++--------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/components/AlgoliaSearchModal.js b/components/AlgoliaSearchModal.js index 26ed7d88..9eecf076 100644 --- a/components/AlgoliaSearchModal.js +++ b/components/AlgoliaSearchModal.js @@ -19,7 +19,7 @@ export default function AlgoliaSearchModal({ cRef }) { const [totalPage, setTotalPage] = useState(0) const [totalHit, setTotalHit] = useState(0) const [useTime, setUseTime] = useState(0) - + const inputRef = useRef(null) /** * 对外暴露方法 */ @@ -27,6 +27,9 @@ export default function AlgoliaSearchModal({ cRef }) { return { openSearch: () => { setIsModalOpen(true) + setTimeout(() => { + inputRef.current.focus() + }, 100) } } }) @@ -119,15 +122,13 @@ export default function AlgoliaSearchModal({ cRef }) { return (
{/* 模态框 */}
搜索
@@ -144,6 +145,7 @@ export default function AlgoliaSearchModal({ cRef }) { placeholder="在这里输入搜索关键词..." onChange={e => handleInputChange(e)} className="text-black dark:text-gray-200 bg-gray-50 dark:bg-gray-600 outline-blue-500 w-full px-4 my-2 py-1 mb-4 border rounded-md" + ref={inputRef} /> {/* 标签组 */} @@ -197,20 +199,20 @@ function TagGroups(props) { const firstTenTags = tagOptions?.slice(0, 10) return
- { - firstTenTags?.map((tag, index) => { - return -
-
{tag.name}
{tag.count ? {tag.count} : <>} -
+ { + firstTenTags?.map((tag, index) => { + return +
+
{tag.name}
{tag.count ? {tag.count} : <>} +
- - }) - } -
+ + }) + } +
} /** @@ -229,7 +231,7 @@ function Pagination(props) { pagesElement.push(getPageElement(i, selected, switchPage)) } return
- {pagesElement.map(p => p)} + {pagesElement.map(p => p)}
} From 569b2d393e974aec40119f330d00ac00c9701718 Mon Sep 17 00:00:00 2001 From: Bhwa233 <404174262@qq.com> Date: Sat, 2 Mar 2024 15:31:58 +0800 Subject: [PATCH 2/4] =?UTF-8?q?1.=E5=88=86=E9=A1=B5=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96=EF=BC=8C=E5=B9=B6=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0key=E3=80=82=202.=E5=A2=9E=E5=8A=A0=E9=94=AE=E7=9B=98?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=EF=BC=8C=E4=BC=98=E5=8C=96=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E3=80=82=203.=E6=8F=90=E7=A4=BA=E6=96=87?= =?UTF-8?q?=E6=9C=AC=E6=A0=B7=E5=BC=8F=E4=BC=98=E5=8C=96=E3=80=82=204.?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=97=A0=E6=B3=95=E5=88=87=E6=8D=A2=E9=A1=B5?= =?UTF-8?q?=E7=A0=81bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/AlgoliaSearchModal.js | 147 +++++++++++++++++++++---------- package.json | 1 + yarn.lock | 5 ++ 3 files changed, 107 insertions(+), 46 deletions(-) diff --git a/components/AlgoliaSearchModal.js b/components/AlgoliaSearchModal.js index 9eecf076..9747bf21 100644 --- a/components/AlgoliaSearchModal.js +++ b/components/AlgoliaSearchModal.js @@ -1,10 +1,11 @@ -import { useState, useImperativeHandle, useRef } from 'react' +import { useState, useImperativeHandle, useRef, useEffect } from 'react' import algoliasearch from 'algoliasearch' import replaceSearchResult from '@/components/Mark' import Link from 'next/link' import { useGlobal } from '@/lib/global' import throttle from 'lodash/throttle' import { siteConfig } from '@/lib/config' +import { useHotkeys } from "react-hotkeys-hook"; /** * 结合 Algolia 实现的弹出式搜索框 @@ -20,6 +21,62 @@ export default function AlgoliaSearchModal({ cRef }) { const [totalHit, setTotalHit] = useState(0) const [useTime, setUseTime] = useState(0) const inputRef = useRef(null) + const [activeIndex, setActiveIndex] = useState(0) + useHotkeys('ctrl+k', (e) => { + e.preventDefault() + setIsModalOpen(true) + }) + // 方向键调整选中 + useHotkeys('down', (e) => { + e.preventDefault() + if (activeIndex < searchResults.length - 1) { + setActiveIndex(activeIndex + 1) + } + }, { enableOnFormTags: true }) + useHotkeys('up', (e) => { + e.preventDefault() + if (activeIndex > 0) { + setActiveIndex(activeIndex - 1) + } + }, { enableOnFormTags: true }) + // esc关闭 + useHotkeys('esc', (e) => { + e.preventDefault() + setIsModalOpen(false) + }, { enableOnFormTags: true }) + // 跳转Search结果 + const onJumpSearchResult = () => { + if (searchResults.length > 0) { + window.location.href = `${siteConfig('SUB_PATH', '')}/${searchResults[activeIndex].slug}` + } + } + // enter跳转 + useHotkeys('enter', (e) => { + if (searchResults.length > 0) { + onJumpSearchResult(index) + } + }, { enableOnFormTags: true }) + + const resetSearch = () => { + setActiveIndex(0) + setKeyword('') + setSearchResults([]) + setUseTime(0) + setTotalPage(0) + setTotalHit(0) + if (inputRef.current) inputRef.current.value = '' + } + + + useEffect(() => { + if (isModalOpen) { + setTimeout(() => { + inputRef.current?.focus() + }, 100) + } else { + resetSearch() + } + }, [isModalOpen]) /** * 对外暴露方法 */ @@ -27,9 +84,6 @@ export default function AlgoliaSearchModal({ cRef }) { return { openSearch: () => { setIsModalOpen(true) - setTimeout(() => { - inputRef.current.focus() - }, 100) } } }) @@ -48,6 +102,7 @@ export default function AlgoliaSearchModal({ cRef }) { setUseTime(0) setTotalPage(0) setTotalHit(0) + setActiveIndex(0) if (!query || query === '') { return } @@ -59,7 +114,6 @@ export default function AlgoliaSearchModal({ cRef }) { setTotalPage(nbPages) setTotalHit(nbHits) setSearchResults(hits) - const doms = document.getElementById('search-wrapper').getElementsByClassName('replace') setTimeout(() => { @@ -78,8 +132,8 @@ export default function AlgoliaSearchModal({ cRef }) { } // 定义节流函数,确保在用户停止输入一段时间后才会调用处理搜索的方法 - const throttledHandleInputChange = useRef(throttle((query) => { - handleSearch(query, 0); + const throttledHandleInputChange = useRef(throttle((query, page = 0) => { + handleSearch(query, page); }, 1000)); // 用于存储搜索延迟的计时器 @@ -118,7 +172,6 @@ export default function AlgoliaSearchModal({ cRef }) { if (!siteConfig('ALGOLIA_APP_ID')) { return <> } - return (
- - -
- {totalHit > 0 && ( -
- 共搜索到 {totalHit} 条结果,用时 {useTime} 毫秒 -
- )} -
-
- - Algolia 提供搜索服务 - {' '} +
+
+ {totalHit > 0 && ( +

+ 共搜索到 {totalHit} 条结果,用时 {useTime} 毫秒 +

+ )} +
+
+ + Algolia 提供搜索服务 + +
+
{/* 遮罩 */} @@ -193,7 +249,7 @@ export default function AlgoliaSearchModal({ cRef }) { /** * 标签组 */ -function TagGroups(props) { +function TagGroups() { const { tagOptions } = useGlobal() // 获取tagOptions数组前十个 const firstTenTags = tagOptions?.slice(0, 10) @@ -224,24 +280,23 @@ function Pagination(props) { if (totalPage <= 0) { return <> } - const pagesElement = [] + return ( +
+ {Array.from({ length: totalPage }, (_, i) => { + const classNames = page === i + ? 'font-bold text-white bg-blue-600 rounded' + : 'hover:text-blue-600 hover:font-bold' - for (let i = 0; i < totalPage; i++) { - const selected = page === i - pagesElement.push(getPageElement(i, selected, switchPage)) - } - return
- {pagesElement.map(p => p)} -
-} - -/** - * 获取分页按钮 - * @param {*} i - * @param {*} selected - */ -function getPageElement(i, selected, switchPage) { - return
switchPage(i)} className={`${selected ? 'font-bold text-white bg-blue-600 rounded' : 'hover:text-blue-600 hover:font-bold'} text-center cursor-pointer w-6 h-6 `}> - {i + 1} -
-} + return ( +
switchPage(i)} + className={`text-center cursor-pointer w-6 h-6 ${classNames}`} + key={i} + > + {i + 1} +
+ ) + })} +
+ ) +} \ No newline at end of file diff --git a/package.json b/package.json index 088edf4d..8f7d27ea 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-facebook": "^8.1.4", + "react-hotkeys-hook": "^4.5.0", "react-notion-x": "6.16.0", "react-share": "^4.4.1", "react-tweet-embed": "~2.0.0", diff --git a/yarn.lock b/yarn.lock index 398a5d8f..7935bfbc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4219,6 +4219,11 @@ react-hotkeys-hook@^3.0.3: dependencies: hotkeys-js "3.9.4" +react-hotkeys-hook@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/react-hotkeys-hook/-/react-hotkeys-hook-4.5.0.tgz#807b389b15256daf6a813a1ec09e6698064fe97f" + integrity sha512-Samb85GSgAWFQNvVt3PS90LPPGSf9mkH/r4au81ZP1yOIFayLC3QAvqTgGtJ8YEDMXtPmaVBs6NgipHO6h4Mug== + react-image@^4.0.3: version "4.1.0" resolved "https://registry.yarnpkg.com/react-image/-/react-image-4.1.0.tgz#92f2d4a809a178b3bf69acd7bad7da7aa5e7364c" From cb7bc62b1378127728505ea6189b772ff3a441e5 Mon Sep 17 00:00:00 2001 From: Bhwa233 <404174262@qq.com> Date: Sat, 2 Mar 2024 16:03:52 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=97=A0=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/AlgoliaSearchModal.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/components/AlgoliaSearchModal.js b/components/AlgoliaSearchModal.js index 9747bf21..4044f9df 100644 --- a/components/AlgoliaSearchModal.js +++ b/components/AlgoliaSearchModal.js @@ -205,6 +205,16 @@ export default function AlgoliaSearchModal({ cRef }) {
+ { + searchResults.length === 0 && keyword && ( +
+

无法找到相关结果 + "{keyword}"

+
+ ) + }
    {searchResults.map((result, index) => (
  • Date: Mon, 4 Mar 2024 14:37:31 +0800 Subject: [PATCH 4/4] =?UTF-8?q?algoliamodel=20=E5=AD=97=E4=BD=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/AlgoliaSearchModal.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/components/AlgoliaSearchModal.js b/components/AlgoliaSearchModal.js index 4044f9df..6554e353 100644 --- a/components/AlgoliaSearchModal.js +++ b/components/AlgoliaSearchModal.js @@ -5,7 +5,7 @@ import Link from 'next/link' import { useGlobal } from '@/lib/global' import throttle from 'lodash/throttle' import { siteConfig } from '@/lib/config' -import { useHotkeys } from "react-hotkeys-hook"; +import { useHotkeys } from 'react-hotkeys-hook'; /** * 结合 Algolia 实现的弹出式搜索框 @@ -67,7 +67,6 @@ export default function AlgoliaSearchModal({ cRef }) { if (inputRef.current) inputRef.current.value = '' } - useEffect(() => { if (isModalOpen) { setTimeout(() => { @@ -122,7 +121,7 @@ export default function AlgoliaSearchModal({ cRef }) { search: query, target: { element: 'span', - className: 'text-blue-600 border-b border-dashed' + className: 'font-bold border-b border-dashed' } }) }, 200) // 延时高亮 @@ -211,7 +210,7 @@ export default function AlgoliaSearchModal({ cRef }) {

    无法找到相关结果 "{keyword}"

    + >"{keyword}"

) } @@ -220,9 +219,9 @@ export default function AlgoliaSearchModal({ cRef }) {
  • setActiveIndex(index)} onClick={() => onJumpSearchResult(index)} - className={`cursor-pointer replace my-2 p-2 ${activeIndex === index ? 'bg-blue-600 ' : ''}`}> + className={`cursor-pointer replace my-2 p-2 duration-100 ${activeIndex === index ? 'bg-blue-600 ' : ''}`}> {result.title} @@ -309,4 +308,4 @@ function Pagination(props) { })}
  • ) -} \ No newline at end of file +}