降权全站字重;优化右栏公告/数据块;类型状态徽章用固定浅色区分;TipHost 仅在文案不一致、非文字或省略时显示。 Co-authored-by: Cursor <cursoragent@cursor.com>
76 lines
2.2 KiB
TypeScript
76 lines
2.2 KiB
TypeScript
"use client";
|
||
|
||
import { useEffect, useState } from "react";
|
||
import { useRouter } from "next/navigation";
|
||
import { ArrowUp } from "lucide-react";
|
||
import {
|
||
realtime,
|
||
RT_FEED_CHANGED,
|
||
type RtFeedChangedData,
|
||
} from "@/lib/realtime";
|
||
import type { FeedSort } from "@/components/home/FeedTabs";
|
||
|
||
interface FeedNewTipProps {
|
||
sort: FeedSort;
|
||
boardId?: number;
|
||
page?: number;
|
||
userId: number;
|
||
}
|
||
|
||
// 帖子流「有新内容」提示(三期):WS feed:changed → tip → 点击 refresh SSR
|
||
export default function FeedNewTip({
|
||
sort,
|
||
boardId = 0,
|
||
page = 1,
|
||
userId,
|
||
}: FeedNewTipProps) {
|
||
const router = useRouter();
|
||
const [visible, setVisible] = useState(false);
|
||
|
||
useEffect(() => {
|
||
// 第 2+ 页与推荐帖不订阅展示(推荐不随新帖/新评变化)
|
||
if (page !== 1 || sort === "recommended") {
|
||
setVisible(false);
|
||
return;
|
||
}
|
||
|
||
const off = realtime.on<RtFeedChangedData>(RT_FEED_CHANGED, (data) => {
|
||
if (!data || typeof data.post_id !== "number") return;
|
||
// 忽略自己刚发布的内容,避免回首页又弹 tip
|
||
if (data.actor_id === userId) return;
|
||
if (boardId > 0 && data.board_id !== boardId) return;
|
||
// 「新帖子」tab 只关心新帖;「新评论」tab 接受帖与评
|
||
if (sort === "new" && data.kind !== "post") return;
|
||
if (data.kind !== "post" && data.kind !== "comment") return;
|
||
setVisible(true);
|
||
});
|
||
return off;
|
||
}, [sort, boardId, page, userId]);
|
||
|
||
if (!visible || page !== 1 || sort === "recommended") return null;
|
||
|
||
const handleClick = () => {
|
||
setVisible(false);
|
||
router.refresh();
|
||
window.scrollTo({ top: 0, behavior: "smooth" });
|
||
};
|
||
|
||
return (
|
||
<div className="px-3 sm:px-4 pb-2.5">
|
||
<button
|
||
type="button"
|
||
onClick={handleClick}
|
||
className="j13-feed-new-tip w-full inline-flex items-center justify-center gap-1.5 py-2 px-3 text-[13px] rounded-[var(--r-sm)] transition-colors"
|
||
style={{
|
||
color: "var(--accent)",
|
||
background: "var(--accent-soft)",
|
||
border: "1px solid var(--nav-active-line, var(--accent))",
|
||
}}
|
||
>
|
||
<ArrowUp size={14} aria-hidden />
|
||
有新内容
|
||
</button>
|
||
</div>
|
||
);
|
||
}
|