- Workbench.tsx 937→467 行,抽出 AiToolbar/WorkbenchToolbar/MobileContextBar - P3-3 AI 工具条分组留白 + 眉题 + 主 CTA 凸显 - P3-4 专注写作模式(useFocusMode hook+vitest,隐藏侧栏加宽正文)+ 左双栏面色区分 - P3-5 右栏本章参考小标题去衬线(font-sans) + 空态引导(无标题保 h2→h3 大纲) - P3-6 底栏信息/操作/状态三区 + TOC 当前章高亮;TOC 状态点因无每章状态数据跳过 - P3-7 展示层流式跟随滚动(不触碰 SSE 逻辑,尊重 reduced-motion) - AppShell 加可选 hideNav(加法式,默认 false)
47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
"use client";
|
||
|
||
import { useCallback, useEffect, useState } from "react";
|
||
|
||
// 「专注写作」偏好的持久化键(对齐既有 `ww.` 前缀约定)。
|
||
export const FOCUS_MODE_KEY = "ww.workbench_focus_mode";
|
||
|
||
export interface FocusMode {
|
||
// true=专注模式:隐藏左侧图标导航 + 目录 TOC,让宽给正文;false=常规四栏。
|
||
focus: boolean;
|
||
toggle: () => void;
|
||
}
|
||
|
||
function persist(focus: boolean): void {
|
||
if (typeof window === "undefined") return;
|
||
try {
|
||
window.localStorage.setItem(FOCUS_MODE_KEY, focus ? "1" : "0");
|
||
} catch {
|
||
// 隐私模式/配额异常忽略:专注模式是纯 UI 偏好,写盘失败不影响写作功能。
|
||
}
|
||
}
|
||
|
||
// 记住「专注写作」开关(P3-4):SSR 首帧恒关(避免 hydration 不一致),
|
||
// 挂载后再从 localStorage 恢复;toggle 即时写回。仅桌面(≥xl)改变栅格,窄屏本就单列不受影响。
|
||
export function useFocusMode(): FocusMode {
|
||
const [focus, setFocus] = useState(false);
|
||
|
||
useEffect(() => {
|
||
if (typeof window === "undefined") return;
|
||
try {
|
||
setFocus(window.localStorage.getItem(FOCUS_MODE_KEY) === "1");
|
||
} catch {
|
||
// 读盘失败则维持默认关闭。
|
||
}
|
||
}, []);
|
||
|
||
const toggle = useCallback(() => {
|
||
setFocus((prev) => {
|
||
const next = !prev;
|
||
persist(next);
|
||
return next;
|
||
});
|
||
}, []);
|
||
|
||
return { focus, toggle };
|
||
}
|