1- import React , { ReactNode , useEffect , useState } from 'react' ;
1+ import React , { ReactNode , useEffect , useMemo , useState } from 'react' ;
22import type { MenuDataItem } from '@ant-design/pro-components' ;
33import { PageContainer , ProLayout } from '@ant-design/pro-components' ;
44import { useLocation , Link , useNavigate } from 'react-router-dom' ;
@@ -1731,12 +1731,10 @@ const debounce = (func: (...args: any[]) => void, wait: number) => {
17311731 let timeout : NodeJS . Timeout ;
17321732 return ( ...args : any [ ] ) => {
17331733 clearTimeout ( timeout ) ;
1734- timeout = setTimeout ( ( ) => func . apply ( this , args ) , wait ) ;
1734+ timeout = setTimeout ( ( ) => func ( ... args ) , wait ) ;
17351735 } ;
17361736} ;
17371737
1738- const contexts = import . meta. glob ( '../dump/*/index.json' ) ;
1739-
17401738const SearchBar = ( ) => {
17411739 const navigate = useNavigate ( ) ;
17421740 const [ form ] = Form . useForm ( ) ;
@@ -1745,42 +1743,45 @@ const SearchBar = () => {
17451743 const [ resetVisibility , setResetVisibility ] = useState ( true ) ;
17461744 const [ results , setResults ] = useState < any [ ] > ( [ ] ) ;
17471745 const [ loading , setLoading ] = useState ( true ) ;
1748- const [ fuse , setFuse ] = useState < any > ( null ) ;
1746+ const [ fuse , setFuse ] = useState < Fuse < any > | null > ( null ) ;
17491747
17501748 useEffect ( ( ) => {
1751- const loadData = async ( ) => {
1752- setLoading ( true ) ;
1753- const posts : any [ ] = [ ] ;
1754- for ( const path in contexts ) {
1755- const data = await contexts [ path ] ( ) ;
1756- const postId = path . split ( '/' ) . slice ( - 2 , - 1 ) [ 0 ] ;
1757- // @ts -expect-error reddit should send data in a the following format
1758- const title = data ?. [ 0 ] ?. data ?. children ?. [ 0 ] ?. data ?. title || postId ;
1759- // @ts -expect-error reddit should send data in a the following format
1760- const body = data ?. [ 0 ] ?. data ?. children ?. [ 0 ] ?. data ?. selftext || '' ;
1761- posts . push ( { id : postId , title, body } ) ;
1762- }
1763-
1764- const fuseInstance = new Fuse ( posts , {
1765- keys : [ 'title' , 'body' ] ,
1766- threshold : 0.4 ,
1749+ // Flatten your menus for Fuse index
1750+ const flattenMenus = ( menus : any [ ] , acc : any [ ] = [ ] ) : any [ ] => {
1751+ menus . forEach ( ( menu ) => {
1752+ if ( menu . children ) {
1753+ flattenMenus ( menu . children , acc ) ;
1754+ } else {
1755+ acc . push ( {
1756+ id : menu . path . replace ( '/' , '' ) ,
1757+ title : menu . name ,
1758+ } ) ;
1759+ }
17671760 } ) ;
1768- setFuse ( fuseInstance ) ;
1769- setLoading ( false ) ;
1761+ return acc ;
17701762 } ;
17711763
1772- loadData ( ) ;
1764+ const flatList = flattenMenus ( defaultMenus ) ;
1765+ const fuseInstance = new Fuse ( flatList , {
1766+ keys : [ 'title' ] ,
1767+ threshold : 0.4 ,
1768+ } ) ;
1769+ setFuse ( fuseInstance ) ;
1770+ setLoading ( false ) ;
17731771 } , [ ] ) ;
17741772
1775- const doSearch = debounce ( ( keyword : string ) => {
1776- if ( fuse && keyword ) {
1777- const searchResults = fuse . search ( keyword ) ;
1778- // @ts -expect-error fuse search returns an array of objects with item property
1779- setResults ( searchResults . map ( ( r ) => r . item ) ) ;
1780- } else {
1781- setResults ( [ ] ) ;
1782- }
1783- } , 30 ) ; // 30ms debounce
1773+ const doSearch = useMemo (
1774+ ( ) =>
1775+ debounce ( ( keyword : string ) => {
1776+ if ( fuse && keyword ) {
1777+ const searchResults = fuse . search ( keyword ) ;
1778+ setResults ( searchResults . map ( ( r ) => r . item ) ) ;
1779+ } else {
1780+ setResults ( [ ] ) ;
1781+ }
1782+ } , 200 ) ,
1783+ [ fuse ]
1784+ ) ;
17841785
17851786 const onValuesChange = ( _changedValues : any , allValues : any ) => {
17861787 const { keyword } = allValues ;
@@ -1794,7 +1795,7 @@ const SearchBar = () => {
17941795
17951796 const onFinish = ( ) => {
17961797 if ( results . length > 0 ) {
1797- navigate ( `/${ results [ 0 ] . id } ` ) ;
1798+ navigate ( results [ 0 ] . path || `/${ results [ 0 ] . id } ` ) ;
17981799 form . resetFields ( ) ;
17991800 setResults ( [ ] ) ;
18001801 }
@@ -1823,7 +1824,7 @@ const SearchBar = () => {
18231824 </ Form . Item >
18241825
18251826 < Form . Item name = "keyword" style = { { flex : 1 } } >
1826- < Input placeholder = "Search..." allowClear />
1827+ < Input placeholder = "Search posts ..." allowClear />
18271828 </ Form . Item >
18281829
18291830 < Form . Item hidden = { resetVisibility } >
@@ -1837,7 +1838,7 @@ const SearchBar = () => {
18371838
18381839 { loading ? (
18391840 < div style = { { marginTop : 12 , textAlign : 'center' } } >
1840- < Spin tip = "Loading posts for search..." />
1841+ < Spin tip = "Building search index ..." />
18411842 </ div >
18421843 ) : results . length > 0 ? (
18431844 < List
@@ -1855,7 +1856,7 @@ const SearchBar = () => {
18551856 < List . Item
18561857 style = { { cursor : 'pointer' } }
18571858 onClick = { ( ) => {
1858- navigate ( `/${ item . id } ` ) ;
1859+ navigate ( item . path || `/${ item . id } ` ) ;
18591860 form . resetFields ( ) ;
18601861 setResults ( [ ] ) ;
18611862 } }
0 commit comments