Skip to content
This repository was archived by the owner on Aug 8, 2025. It is now read-only.

Commit bfba339

Browse files
committed
[ux]: fixed search bar;
1 parent 33f2163 commit bfba339

File tree

1 file changed

+38
-37
lines changed

1 file changed

+38
-37
lines changed

src/layout/CustomLayout.tsx

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { ReactNode, useEffect, useState } from 'react';
1+
import React, { ReactNode, useEffect, useMemo, useState } from 'react';
22
import type { MenuDataItem } from '@ant-design/pro-components';
33
import { PageContainer, ProLayout } from '@ant-design/pro-components';
44
import { 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-
17401738
const 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

Comments
 (0)