32 lines
1.7 KiB
TypeScript
32 lines
1.7 KiB
TypeScript
/**
|
|
* 侧栏与画布页面共享的当前board元数据Context。只保存ID、工作区、路由引用与标题,
|
|
* 不保存元素、加载任务或ProjectEngine;目录改名可更新标题而无需重建业务画布。
|
|
*/
|
|
"use client";
|
|
|
|
import { createContext, useContext, useMemo, useState, type Dispatch, type ReactNode, type SetStateAction } from "react";
|
|
import type { Board } from "@/lib/workspace";
|
|
|
|
/** null代表当前没有已解析画布,workspace_ref保留路径slug/引用与真实workspace_id的对应关系。 */
|
|
type ActiveBoard = (Pick<Board, "id" | "workspace_id" | "title" | "slug"> & { workspace_ref?: string }) | null;
|
|
/** 暴露React状态setter,调用方可条件更新以免迟到改名覆盖另一个活动board。 */
|
|
const ActiveBoardContext = createContext<{
|
|
board: ActiveBoard;
|
|
setBoard: Dispatch<SetStateAction<ActiveBoard>>;
|
|
} | null>(null);
|
|
|
|
/** 在工作台布局内保持元数据,useMemo稳定Context对象,避免只因父渲染就通知全部使用方。 */
|
|
export function ActiveBoardProvider({ children }: { children: ReactNode }) {
|
|
// Provider 本身不监听路由/登出,也不推断哪条异步结果较新;发布、清空及身份核对由调用方负责。
|
|
const [board, setBoard] = useState<ActiveBoard>(null);
|
|
const value = useMemo(() => ({ board, setBoard }), [board]);
|
|
return <ActiveBoardContext.Provider value={value}>{children}</ActiveBoardContext.Provider>;
|
|
}
|
|
|
|
/** 缺少Provider时拒绝读取;不从浏览器路径凭空构造一条已认证board记录。 */
|
|
export function useActiveBoard() {
|
|
const context = useContext(ActiveBoardContext);
|
|
if (!context) throw new Error("useActiveBoard requires ActiveBoardProvider");
|
|
return context;
|
|
}
|