"use client"; import { createContext, useContext, useEffect, useRef, useState, type ReactNode, } from "react"; import { useRouter } from "next/navigation"; import { realtime, RT_SETTINGS_CHANGED, type RtSettingsData } from "@/lib/realtime"; type CommentsPolicy = { open: boolean; requireLogin: boolean; }; const CommentsPolicyContext = createContext({ open: true, requireLogin: false, }); /** 前台是否开放评论(SSR 初值 + 后台开关热更新) */ export function useAllowComments(): boolean { return useContext(CommentsPolicyContext).open; } /** 评论是否仅登录可见 */ export function useCommentsRequireLogin(): boolean { return useContext(CommentsPolicyContext).requireLogin; } /** * 根布局注入:关闭评论后前台立即隐藏评论区/数量; * 「登录可见」切换时刷新以重拉/清空评论树。 */ export default function CommentsPolicyProvider({ allowComments, requireLogin = false, children, }: { allowComments: boolean; requireLogin?: boolean; children: ReactNode; }) { const router = useRouter(); const [policy, setPolicy] = useState({ open: allowComments, requireLogin, }); const policyRef = useRef(policy); policyRef.current = policy; useEffect(() => { setPolicy({ open: allowComments, requireLogin }); }, [allowComments, requireLogin]); useEffect(() => { return realtime.on(RT_SETTINGS_CHANGED, (data) => { if (!data) return; const prev = policyRef.current; const nextOpen = typeof data.allow_comments === "boolean" ? data.allow_comments : prev.open; const nextRequire = typeof data.comments_require_login === "boolean" ? data.comments_require_login : prev.requireLogin; if (nextOpen === prev.open && nextRequire === prev.requireLogin) return; setPolicy({ open: nextOpen, requireLogin: nextRequire }); router.refresh(); }); }, [router]); return ( {children} ); }