"use client"; import { createContext, useContext, useEffect, useState, type ReactNode, } from "react"; import { realtime, RT_SETTINGS_CHANGED, type RtSettingsData } from "@/lib/realtime"; export type CodeFoldConfig = { /** 是否启用自动折叠 */ enabled: boolean; /** 超过该行数则折叠(预览高度约同;0=无预览) */ foldLines: number; }; const DEFAULT_CONFIG: CodeFoldConfig = { enabled: true, foldLines: 5 }; const CodeFoldContext = createContext(DEFAULT_CONFIG); /** 代码块自动折叠配置(站点设置) */ export function useCodeFoldConfig(): CodeFoldConfig { return useContext(CodeFoldContext); } function clampFoldLines(n: unknown): number { if (typeof n !== "number" || !Number.isFinite(n)) return DEFAULT_CONFIG.foldLines; const r = Math.round(n); if (r < 0 || r > 100) return DEFAULT_CONFIG.foldLines; return r; } /** * 根布局注入:SSR 初值 + settings:changed 热更新。 */ export default function CodeFoldProvider({ initialEnabled = true, initialFoldLines = 5, children, }: { initialEnabled?: boolean; initialFoldLines?: number; children: ReactNode; }) { const [config, setConfig] = useState(() => ({ enabled: initialEnabled !== false, foldLines: clampFoldLines(initialFoldLines), })); useEffect(() => { setConfig({ enabled: initialEnabled !== false, foldLines: clampFoldLines(initialFoldLines), }); }, [initialEnabled, initialFoldLines]); useEffect(() => { return realtime.on(RT_SETTINGS_CHANGED, (data) => { if (!data) return; setConfig((prev) => ({ enabled: typeof data.code_block_auto_fold === "boolean" ? data.code_block_auto_fold : prev.enabled, foldLines: typeof data.code_block_fold_lines === "number" ? clampFoldLines(data.code_block_fold_lines) : prev.foldLines, })); }); }, []); return ( {children} ); }