返回 DeepSeek-Reasonix
useTabProjectionLifecycle.ts
根目录 / desktop / frontend / src / app-runtime / useTabProjectionLifecycle.ts
1 import { useEffect, type Dispatch, type MutableRefObject, type SetStateAction } from "react";
2 import type { TabMeta } from "../lib/types";
3 import { hydrateComposerProfileFromMeta, hydrateComposerProfilesFromTabs, pruneUserPlanModeIntents, type ComposerProfile, type UserPlanModeIntents } from "../lib/composerProfile";
4
5 export function useTabProjectionLifecycle(input: {
6 tabs: readonly TabMeta[];
7 activeTabId?: string | null;
8 activeMeta: TabMeta | null | undefined;
9 meta: Parameters<typeof hydrateComposerProfileFromMeta>[2] | null | undefined;
10 planIntentsRef: MutableRefObject<UserPlanModeIntents>;
11 setOrder: Dispatch<SetStateAction<string[]>>;
12 setProfiles: Dispatch<SetStateAction<Record<string, ComposerProfile>>>;
13 }) {
14 const { tabs, activeTabId, meta, planIntentsRef, setOrder, setProfiles } = input;
15 useEffect(() => {
16 const ids = tabs.map((tab) => tab.id);
17 setOrder((current) => {
18 const next = current.filter((id) => ids.includes(id));
19 for (const id of ids) if (!next.includes(id)) next.push(id);
20 return next.join("\u0000") === current.join("\u0000") ? current : next;
21 });
22 const present = new Set(ids);
23 planIntentsRef.current = pruneUserPlanModeIntents(planIntentsRef.current, present);
24 setProfiles((current) => hydrateComposerProfilesFromTabs(current, [...tabs]));
25 }, [planIntentsRef, setOrder, setProfiles, tabs]);
26
27 useEffect(() => {
28 if (!activeTabId || !meta) return;
29 setProfiles((current) => hydrateComposerProfileFromMeta(current, activeTabId, meta));
30 }, [activeTabId, meta, setProfiles]);
31 }
32
32 lines TYPESCRIPT