| 1 | import type { TerminalSessionState } from "@t3tools/client-runtime/state/terminal"; |
| 2 | import { |
| 3 | AuthTerminalOperateScope, |
| 4 | type EnvironmentId, |
| 5 | type TerminalResizeInput, |
| 6 | type ThreadId, |
| 7 | } from "@t3tools/contracts"; |
| 8 | import { useEffect } from "react"; |
| 9 | |
| 10 | import type { TerminalGridSize } from "./terminalUiState"; |
| 11 | import { readEnvironmentScope } from "../../state/session"; |
| 12 | |
| 13 | /** Replay the measured grid when a writable attachment becomes ready or reconnects. */ |
| 14 | export function useTerminalGridSync({ |
| 15 | environmentId, |
| 16 | threadId, |
| 17 | terminalId, |
| 18 | canOperate, |
| 19 | terminal, |
| 20 | size, |
| 21 | resize, |
| 22 | }: { |
| 23 | readonly environmentId: EnvironmentId | null; |
| 24 | readonly threadId: ThreadId | null; |
| 25 | readonly terminalId: string; |
| 26 | readonly canOperate: boolean; |
| 27 | readonly terminal: Pick<TerminalSessionState, "output" | "status" | "version">; |
| 28 | readonly size: TerminalGridSize; |
| 29 | readonly resize: (target: { |
| 30 | readonly environmentId: EnvironmentId; |
| 31 | readonly input: TerminalResizeInput; |
| 32 | }) => void; |
| 33 | }): void { |
| 34 | const generation = |
| 35 | canOperate && terminal.version > 0 && terminal.status === "running" |
| 36 | ? terminal.output.generation |
| 37 | : null; |
| 38 | |
| 39 | useEffect(() => { |
| 40 | if ( |
| 41 | generation === null || |
| 42 | environmentId === null || |
| 43 | threadId === null || |
| 44 | !readEnvironmentScope(environmentId, AuthTerminalOperateScope) |
| 45 | ) |
| 46 | return; |
| 47 | resize({ |
| 48 | environmentId, |
| 49 | input: { threadId, terminalId, cols: size.cols, rows: size.rows }, |
| 50 | }); |
| 51 | }, [environmentId, generation, resize, size.cols, size.rows, terminalId, threadId]); |
| 52 | } |