From a02d103cfebb674c5b3f9917e0cb0b3f53d288b1 Mon Sep 17 00:00:00 2001 From: freefire Date: Tue, 1 Sep 2026 07:48:18 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=8E=92=E5=BA=8F=E6=A0=8F=20count=20?= =?UTF-8?q?=E7=B4=A7=E8=B7=9F=E6=A0=87=E7=AD=BE=EF=BC=8CFeedSortBar=20?= =?UTF-8?q?=E4=B8=8E=20SSR=20=E7=BB=9F=E4=B8=80=E4=B8=BA=20a=20=E6=A0=87?= =?UTF-8?q?=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- frontend/src/components/FeedSortBar.tsx | 39 ++++++++++++++++++++----- frontend/src/styles/global.css | 5 ++-- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/FeedSortBar.tsx b/frontend/src/components/FeedSortBar.tsx index 578372c..b9527cb 100644 --- a/frontend/src/components/FeedSortBar.tsx +++ b/frontend/src/components/FeedSortBar.tsx @@ -1,5 +1,6 @@ import { useMemo, useRef } from 'react'; -import { boardPath, type PermalinkOpts } from '../utils/permalink'; +import { useParams, useSearchParams } from 'react-router-dom'; +import { boardPath, parsePermalinkID, type PermalinkOpts } from '../utils/permalink'; import { getCachedForumLimits, useForumLimits } from '../hooks/useForumLimits'; import { Clock, MessageCircle, BadgeCheck, Loader2 } from 'lucide-react'; import { cn } from '@/lib/utils'; @@ -86,14 +87,35 @@ export default function FeedSortBar({ pendingValue, }: Props) { const { limits } = useForumLimits(); + const { id: boardRouteId } = useParams(); + const [params] = useSearchParams(); + // 与 SSR href / HomePage 一致:从路由与查询串解析板块与筛选 + const boardId = boardRouteId + ? (() => { + const id = parsePermalinkID(boardRouteId); + return Number.isFinite(id) && id > 0 ? id : 0; + })() + : (Number(params.get('board')) || 0); + const keyword = params.get('keyword') || ''; + const tag = params.get('tag') || ''; + const author = params.get('author') || ''; + const titleOnly = params.get('title_only') === '1'; + const options = useMemo( () => enabledFeedSortTabs(limits.feed_sort_tabs).map(t => ({ key: t.id as FeedSort, label: t.label, hint: SORT_META[t.id]?.hint ?? '', icon: SORT_META[t.id]?.icon ?? Clock, + href: buildHomeUrl(boardId, t.id as FeedSort, { + keyword, + tag, + author, + titleOnly, + permalink: limits, + }), })), - [limits.feed_sort_tabs], + [limits, boardId, keyword, tag, author, titleOnly], ); const listRef = useRef(null); @@ -121,25 +143,28 @@ export default function FeedSortBar({ aria-label="帖子排序" onKeyDown={onKeyDown} > - {options.map(({ key, label, hint, icon: Icon }, i) => { + {options.map(({ key, label, hint, icon: Icon, href }, i) => { const pending = pendingValue === key; return ( - + ); })} diff --git a/frontend/src/styles/global.css b/frontend/src/styles/global.css index 36fb0bc..0c884c6 100644 --- a/frontend/src/styles/global.css +++ b/frontend/src/styles/global.css @@ -2791,12 +2791,12 @@ a.post-row { .board-chip.active.board-chip--6 { background: var(--board-6-bg); color: var(--board-6-color); } .board-chip.active.board-chip--7 { background: var(--board-7-bg); color: var(--board-7-color); } -/* 帖子排序栏:与左侧栏 active 样式保持一致 */ +/* 帖子排序栏:与左侧栏 active 样式保持一致;不占满整行,避免「共 N 条」贴中栏右缘 */ .feed-sort-bar { display: flex; align-items: center; gap: 2px; - flex: 1; + flex: 0 1 auto; min-width: 0; overflow-x: auto; scrollbar-width: none; @@ -2819,6 +2819,7 @@ a.post-row { cursor: pointer; flex-shrink: 0; white-space: nowrap; + text-decoration: none; transition: background 0.15s, color 0.15s; }