fix: route terminal callbacks and status per session

The recent redraw fix keeps all xterm instances mounted (display:none)
when switching sessions. However, sendData/focus/font-size refs and the
header connection status were still stored globally, so the last-mounted
hidden session could own keyboard input, font-size buttons, and the
status dot for the active session.

- Pass sessionId to onTerminalReady from TerminalComponent.
- Store terminal callbacks and status keyed by sessionId in use-terminal-page.
- Use activeSessionId to route special-key input, font-size changes, and header status.
- Clean up per-session refs and status when sessions are closed.
- Update MobileTerminalWrapper signature for the new callback shape.

Quality gates: npm run typecheck, npm run lint, npm test (87 passed)
This commit is contained in:
Developer
2026-06-15 13:53:09 +00:00
parent a6ad8268b9
commit 82ff8b8801
5 changed files with 1216 additions and 1118 deletions
@@ -27,10 +27,17 @@ export const MobileTerminalWrapper: React.FC<MobileTerminalWrapperProps> = ({
const { isOpen: isKeyboardOpen, height: keyboardHeight } =
useVirtualKeyboard();
const [showPanel, setShowPanel] = useState(false);
const [activeModifier, setActiveModifier] = useState<ModifierKey | null>(null);
const [activeModifier, setActiveModifier] = useState<ModifierKey | null>(
null,
);
const [terminalRef, setTerminalRef] = useState<{
sendData: (data: string) => void;
connectionStatus: "connecting" | "connected" | "disconnected" | "error" | "resetting";
connectionStatus:
| "connecting"
| "connected"
| "disconnected"
| "error"
| "resetting";
focusInput: () => void;
changeFontSize: (delta: number) => void;
} | null>(null);
@@ -42,17 +49,33 @@ export const MobileTerminalWrapper: React.FC<MobileTerminalWrapperProps> = ({
}, [headerAutoHide]);
const handleTerminalReady = useCallback(
(sendData: (data: string) => void, connectionStatus: "connecting" | "connected" | "disconnected" | "error" | "resetting", focusInput: () => void, changeFontSize: (delta: number) => void) => {
setTerminalRef({ sendData, connectionStatus, focusInput, changeFontSize });
(
_sessionId: string | undefined,
sendData: (data: string) => void,
connectionStatus:
| "connecting"
| "connected"
| "disconnected"
| "error"
| "resetting",
focusInput: () => void,
changeFontSize: (delta: number) => void,
) => {
setTerminalRef({
sendData,
connectionStatus,
focusInput,
changeFontSize,
});
},
[]
[],
);
const handleSendKey = useCallback(
(data: string) => {
terminalRef?.sendData(data);
},
[terminalRef]
[terminalRef],
);
if (!isMobile) {