Files
jiang13-bbs/frontend/components/home/FeedNewTip.tsx
freefire 42c395a864 feat: 实时消息与管理端运营能力
新增群聊/私信与公共 WebSocket 总线,站长用户内容档案,并将通知与待审角标改为推送驱动;同步精简管理仪表盘并修复主题换肤 DOM 冲突。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-15 22:58:16 +08:00

76 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"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] font-semibold 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>
);
}