// 对话区/视图区可调比例:workspace 上的分隔柄拖拽写入 --jc-chat-w(CSS 变量, // 各断点的对话区宽度均以它优先),localStorage 记忆,双击复位回默认配比。 // 任务工作台与消息模块共用同一 storage key —— 两处对话区宽度保持一致。 import { useCallback, useEffect, useState } from "react"; const MIN_W = 340; // 上限随视口收敛:给 视图区(≥480) + 清单列 + 间距 留足空间,避免拖到中栏塌陷 const maxW = () => Math.max(MIN_W, Math.min(720, window.innerWidth - 830)); export function useChatWidth(storageKey = "jc-chat-w") { const [w, setW] = useState(null); // null = 未拖拽,走断点默认 useEffect(() => { const v = Number(localStorage.getItem(storageKey)); if (v) setW(Math.min(maxW(), Math.max(MIN_W, v))); }, [storageKey]); const onSplitDown = useCallback((e: React.PointerEvent) => { e.preventDefault(); const handle = e.currentTarget; const chatEl = handle.parentElement?.querySelector(".session-chat"); const startX = e.clientX; const startW = chatEl?.getBoundingClientRect().width ?? 440; let cur = startW; handle.classList.add("dragging"); document.body.style.cursor = "col-resize"; document.body.style.userSelect = "none"; const move = (ev: PointerEvent) => { cur = Math.min(maxW(), Math.max(MIN_W, Math.round(startW + (startX - ev.clientX)))); setW(cur); }; const up = () => { window.removeEventListener("pointermove", move); window.removeEventListener("pointerup", up); handle.classList.remove("dragging"); document.body.style.cursor = ""; document.body.style.userSelect = ""; localStorage.setItem(storageKey, String(cur)); }; window.addEventListener("pointermove", move); window.addEventListener("pointerup", up); }, [storageKey]); const onSplitReset = useCallback(() => { setW(null); localStorage.removeItem(storageKey); }, [storageKey]); const style = (w ? { "--jc-chat-w": `${w}px` } : undefined) as React.CSSProperties | undefined; return { style, onSplitDown, onSplitReset }; }