feat: 重设计搜索帖子 UI/UX,新增筛选面板与结果页 chips

将高级筛选移入独立面板,统一 URL 状态与清除逻辑,并优化移动端搜索与空结果反馈。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-27 19:21:55 +08:00
parent c6df703b96
commit 55b1831da2
8 changed files with 1190 additions and 214 deletions

View File

@@ -6,9 +6,11 @@ import type { PostItem } from '../api/types';
import type { LayoutCtx } from '../layouts/MainLayout';
import VirtualPostList from '../components/VirtualPostList';
import FeedHeader from '../components/FeedHeader';
import FeedSearchFilters from '../components/search/FeedSearchFilters';
import FeedPageSkeleton from '../components/FeedPageSkeleton';
import FeedSortBar, { parseFeedSort, buildHomeUrl, type FeedSort } from '../components/FeedSortBar';
import { useForumLimits } from '../hooks/useForumLimits';
import { parseSearchFromUrl, usePostSearch } from '../hooks/usePostSearch';
import {
getFeedCache,
setFeedCache,
@@ -41,6 +43,7 @@ export default function HomePage() {
const ctx = useOutletContext<LayoutCtx>();
const { branding } = useSiteBranding();
const { limits, loading: limitsLoading } = useForumLimits();
const postSearch = usePostSearch(limits);
const pageSize = Math.max(1, limits.page_size_default);
const boardId = boardIdFromLocation(boardRouteId, params);
@@ -60,7 +63,7 @@ export default function HomePage() {
const feedTitle = tag
? `标签:${tag}`
: keyword || author
? `搜索:${keyword || ''}${author ? (keyword ? ` · 作者 ${author}` : `作者 ${author}`) : ''}${titleOnly ? '(仅标题)' : ''}`
? '搜索结果'
: (boardId && board ? board.name : '');
usePageSEO({
title: feedTitle || undefined,
@@ -273,6 +276,8 @@ export default function HomePage() {
};
const showSortBar = !keyword && !tag && !author;
const searchFilters = parseSearchFromUrl(location.pathname, params);
const isSearchActive = !!(keyword || author);
if (isInvalidBoardRoute || isMissingBoard) {
return (
@@ -298,7 +303,6 @@ export default function HomePage() {
keyword={keyword}
tag={tag}
author={author}
titleOnly={titleOnly}
boards={ctx?.boards ?? []}
stats={ctx?.stats ?? null}
postTotal={postTotal}
@@ -308,6 +312,14 @@ export default function HomePage() {
<FeedSortBar value={sort} onChange={handleSortChange} postTotal={postTotal} />
)}
</div>
{isSearchActive && (
<FeedSearchFilters
filters={postSearch.filters}
boards={ctx?.boards ?? []}
onRemove={postSearch.removeFilter}
onClear={postSearch.clearSearch}
/>
)}
</div>
<VirtualPostList
posts={posts}
@@ -325,6 +337,12 @@ export default function HomePage() {
onScrollTopChange={(top) => { scrollTopRef.current = top; }}
onScrollRestored={() => setRestoreScrollTop(null)}
keyword={keyword || tag || author}
isSearchMode={!!(keyword || author)}
searchKeyword={keyword}
searchAuthor={author}
searchTitleOnly={titleOnly}
searchScopeBoardId={searchFilters.scopeBoardId}
onClearSearch={postSearch.clearSearch}
boardId={boardId}
boardName={ctx?.boards?.find(b => b.id === boardId)?.name || ''}
noBoards={!ctx?.boardsLoading && (ctx?.boards?.length ?? 0) === 0}