865b9411da
TypeScript build failed because 'resetting' status was not included in the onTerminalReady callback type definition. Updated types in: - TerminalComponent props - MobileTerminalWrapper state and callback - MobileTerminalHeader props
117 lines
3.5 KiB
TypeScript
117 lines
3.5 KiB
TypeScript
import React, { useState, useCallback } from "react";
|
|
import { TerminalComponent } from "./terminal";
|
|
import { MobileTerminalHeader } from "./mobile-terminal-header";
|
|
import { SpecialKeysStrip } from "./special-keys-strip";
|
|
import { SpecialKeysPanel } from "./special-keys-panel";
|
|
import { useMobileViewport } from "../hooks/use-mobile-viewport";
|
|
import { useVirtualKeyboard } from "../hooks/use-virtual-keyboard";
|
|
import { useAutoHide } from "../hooks/use-auto-hide";
|
|
import type { ModifierKey } from "../hooks/use-special-keys";
|
|
|
|
interface MobileTerminalWrapperProps {
|
|
instanceId: string;
|
|
instanceName?: string;
|
|
onClose?: () => void;
|
|
onBack?: () => void;
|
|
onMenuToggle?: () => void;
|
|
}
|
|
|
|
export const MobileTerminalWrapper: React.FC<MobileTerminalWrapperProps> = ({
|
|
instanceId,
|
|
instanceName,
|
|
onClose,
|
|
onBack,
|
|
onMenuToggle,
|
|
}) => {
|
|
const isMobile = useMobileViewport();
|
|
const { isOpen: isKeyboardOpen, height: keyboardHeight } =
|
|
useVirtualKeyboard();
|
|
const [showPanel, setShowPanel] = useState(false);
|
|
const [activeModifier, setActiveModifier] = useState<ModifierKey | null>(null);
|
|
const [terminalRef, setTerminalRef] = useState<{
|
|
sendData: (data: string) => void;
|
|
connectionStatus: "connecting" | "connected" | "disconnected" | "error" | "resetting";
|
|
focusInput: () => void;
|
|
changeFontSize: (delta: number) => void;
|
|
} | null>(null);
|
|
|
|
const headerAutoHide = useAutoHide({ timeout: 3000, enabled: isMobile });
|
|
|
|
const handleTerminalTap = useCallback(() => {
|
|
headerAutoHide.toggle();
|
|
}, [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 });
|
|
},
|
|
[]
|
|
);
|
|
|
|
const handleSendKey = useCallback(
|
|
(data: string) => {
|
|
terminalRef?.sendData(data);
|
|
},
|
|
[terminalRef]
|
|
);
|
|
|
|
if (!isMobile) {
|
|
return (
|
|
<TerminalComponent
|
|
instanceId={instanceId}
|
|
onClose={onClose}
|
|
isMobile={false}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="mobile-terminal-wrapper">
|
|
<MobileTerminalHeader
|
|
instanceName={instanceName}
|
|
onBack={onBack}
|
|
onMenuToggle={onMenuToggle}
|
|
onClose={onClose}
|
|
onFontSizeChange={(delta) => terminalRef?.changeFontSize(delta)}
|
|
isVisible={headerAutoHide.isVisible}
|
|
connectionStatus={terminalRef?.connectionStatus}
|
|
/>
|
|
|
|
<div
|
|
className="mobile-terminal-content"
|
|
style={{
|
|
paddingBottom: isKeyboardOpen ? keyboardHeight : 0,
|
|
}}
|
|
onClick={handleTerminalTap}
|
|
>
|
|
<TerminalComponent
|
|
instanceId={instanceId}
|
|
onClose={onClose}
|
|
isMobile={true}
|
|
activeModifier={activeModifier}
|
|
onModifierChange={setActiveModifier}
|
|
onTerminalReady={handleTerminalReady}
|
|
/>
|
|
</div>
|
|
|
|
<SpecialKeysStrip
|
|
onSend={handleSendKey}
|
|
isVisible={!showPanel}
|
|
onMoreClick={() => setShowPanel(true)}
|
|
onKeepFocus={() => terminalRef?.focusInput()}
|
|
activeModifier={activeModifier}
|
|
onModifierChange={setActiveModifier}
|
|
/>
|
|
|
|
<SpecialKeysPanel
|
|
onSend={handleSendKey}
|
|
isOpen={showPanel}
|
|
onClose={() => setShowPanel(false)}
|
|
onKeepFocus={() => terminalRef?.focusInput()}
|
|
activeModifier={activeModifier}
|
|
onModifierChange={setActiveModifier}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|