feat: 调整 Feed 排序为新评论/新帖子/推荐帖
默认按新评论;推荐排序优先 featured,并将用户可见「精华」文案改为「推荐」。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Sparkles } from 'lucide-react';
|
||||
import { BadgeCheck } from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
interface Props {
|
||||
@@ -6,13 +6,13 @@ interface Props {
|
||||
size?: number;
|
||||
}
|
||||
|
||||
/** 精华帖标识 */
|
||||
/** 推荐帖标识 */
|
||||
export default function FeaturedIcon({ className, size = 16 }: Props) {
|
||||
return (
|
||||
<Sparkles
|
||||
<BadgeCheck
|
||||
className={cn('post-featured-icon', className)}
|
||||
size={size}
|
||||
aria-label="精华"
|
||||
aria-label="推荐"
|
||||
role="img"
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useRef } from 'react';
|
||||
import { boardPath, type PermalinkOpts } from '../utils/permalink';
|
||||
import { getCachedForumLimits } from '../hooks/useForumLimits';
|
||||
import { Clock, MessageCircle, Flame } from 'lucide-react';
|
||||
import { Clock, MessageCircle, BadgeCheck } from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { moveTabIndex } from '../hooks/useOverlayA11y';
|
||||
|
||||
@@ -13,9 +13,9 @@ const SORT_OPTIONS: {
|
||||
hint: string;
|
||||
icon: typeof Clock;
|
||||
}[] = [
|
||||
{ key: 'latest', label: '最新发帖', hint: '按发布时间', icon: Clock },
|
||||
{ key: 'reply', label: '最新回复', hint: '最近有人回复', icon: MessageCircle },
|
||||
{ key: 'hot', label: '热门讨论', hint: '按互动热度', icon: Flame },
|
||||
{ key: 'reply', label: '新评论', hint: '最近有人评论', icon: MessageCircle },
|
||||
{ key: 'latest', label: '新帖子', hint: '按发帖时间', icon: Clock },
|
||||
{ key: 'hot', label: '推荐帖', hint: '站内推荐', icon: BadgeCheck },
|
||||
];
|
||||
|
||||
interface Props {
|
||||
@@ -24,14 +24,15 @@ interface Props {
|
||||
postTotal?: number;
|
||||
}
|
||||
|
||||
/** 解析 URL sort;缺省为新评论(reply) */
|
||||
export function parseFeedSort(raw: string | null): FeedSort {
|
||||
if (raw === 'reply' || raw === 'hot') return raw;
|
||||
return 'latest';
|
||||
if (raw === 'latest' || raw === 'hot') return raw;
|
||||
return 'reply';
|
||||
}
|
||||
|
||||
export function buildHomeUrl(
|
||||
boardId: number,
|
||||
sort: FeedSort = 'latest',
|
||||
sort: FeedSort = 'reply',
|
||||
opts?: { keyword?: string; tag?: string; author?: string; titleOnly?: boolean; permalink?: PermalinkOpts },
|
||||
) {
|
||||
const p = new URLSearchParams();
|
||||
@@ -47,7 +48,8 @@ export function buildHomeUrl(
|
||||
} else if (author) {
|
||||
p.set('author', author);
|
||||
}
|
||||
if (sort !== 'latest') p.set('sort', sort);
|
||||
// 默认 reply 不写进 URL;latest / hot 显式带上
|
||||
if (sort !== 'reply') p.set('sort', sort);
|
||||
const qs = p.toString();
|
||||
|
||||
if (boardId) {
|
||||
|
||||
@@ -70,9 +70,9 @@ function PostListItem({ post, sort = 'latest', boardId = 0, onSelect }: Props) {
|
||||
<span className="post-pin-badge post-pin-badge--board" title="板块置顶">板块置顶</span>
|
||||
)}
|
||||
{post.featured && (
|
||||
<span className="post-feature-badge" title="精华">
|
||||
<span className="post-feature-badge" title="推荐">
|
||||
<FeaturedIcon size={12} />
|
||||
精华
|
||||
推荐
|
||||
</span>
|
||||
)}
|
||||
{post.status === 'pending' && (
|
||||
|
||||
@@ -147,7 +147,7 @@ export default function PostManageMenu({
|
||||
<DropdownMenuLabel>展示</DropdownMenuLabel>
|
||||
<DropdownMenuItem onSelect={onFeature}>
|
||||
<Sparkles size={14} aria-hidden />
|
||||
{post.featured ? '取消精华' : '设为精华'}
|
||||
{post.featured ? '取消推荐' : '设为推荐'}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onSelect={onPin}>
|
||||
<Pin size={14} aria-hidden />
|
||||
|
||||
@@ -56,7 +56,7 @@ function getMobileFeedScrollEl(): HTMLElement | null {
|
||||
|
||||
export default function VirtualPostList({
|
||||
posts,
|
||||
sort = 'latest',
|
||||
sort = 'reply',
|
||||
loading,
|
||||
hasMore,
|
||||
showPagination,
|
||||
|
||||
Reference in New Issue
Block a user