返回 DeepSeek-Reasonix
shellExpand.tsx
根目录 / desktop / frontend / src / lib / shellExpand.tsx
1 import { createContext, useCallback, useContext, useMemo, useRef, type ReactNode } from "react";
2
3 // Shell-expand coordination: ToolCards register their toggle callbacks, and
4 // Cmd+B (from App) calls the most recent one.
5
6 type ToggleFn = () => void;
7
8 interface ShellExpandCtx {
9 register: (id: string, toggle: ToggleFn) => void;
10 toggleLast: () => void;
11 }
12
13 const Ctx = createContext<ShellExpandCtx | null>(null);
14
15 export function ShellExpandProvider({ children }: { children: ReactNode }) {
16 const mapRef = useRef(new Map<string, ToggleFn>());
17 const orderRef: { current: string[] } = useRef<string[]>([]);
18
19 const register = useCallback((id: string, toggle: ToggleFn) => {
20 mapRef.current.set(id, toggle);
21 if (!orderRef.current.includes(id)) {
22 orderRef.current.push(id);
23 }
24 return () => {
25 mapRef.current.delete(id);
26 orderRef.current = orderRef.current.filter((x) => x !== id);
27 };
28 }, []);
29
30 const toggleLast = useCallback(() => {
31 const ids = orderRef.current;
32 if (ids.length === 0) return;
33 const fn = mapRef.current.get(ids[ids.length - 1]);
34 fn?.();
35 }, []);
36
37 const value = useMemo(() => ({ register, toggleLast }), [register, toggleLast]);
38 return <Ctx.Provider value={value}>{children}</Ctx.Provider>;
39 }
40
41 export function useShellExpand() {
42 return useContext(Ctx);
43 }
44
44 lines Plain Text