b6bda3d692
- Add mobile viewport detection hook - Add virtual keyboard detection with fallback - Add auto-hide hook for header/keys strip - Add special keys mapping hook - Create MobileTerminalHeader, SpecialKeysStrip, SpecialKeysPanel components - Create MobileTerminalWrapper component - Update TerminalComponent with mobile support, font scaling, copy/paste, reconnection - Update AppShell to hide chrome on mobile terminal pages - Update TerminalPage to use MobileTerminalWrapper - Add comprehensive mobile terminal styles - TypeScript check passes - Build succeeds
69 lines
2.0 KiB
TypeScript
69 lines
2.0 KiB
TypeScript
import { useState, useEffect, useCallback } from "react";
|
|
|
|
interface VirtualKeyboardState {
|
|
isOpen: boolean;
|
|
height: number;
|
|
viewportHeight: number;
|
|
}
|
|
|
|
export function useVirtualKeyboard() {
|
|
const [state, setState] = useState<VirtualKeyboardState>({
|
|
isOpen: false,
|
|
height: 0,
|
|
viewportHeight: typeof window !== "undefined" ? window.innerHeight : 0,
|
|
});
|
|
|
|
const updateKeyboardState = useCallback(() => {
|
|
const visualViewport = window.visualViewport;
|
|
const windowHeight = window.innerHeight;
|
|
|
|
if (visualViewport) {
|
|
const viewportHeight = visualViewport.height;
|
|
const keyboardHeight = windowHeight - viewportHeight;
|
|
const isOpen = keyboardHeight > 100; // Threshold to avoid false positives
|
|
|
|
setState({
|
|
isOpen,
|
|
height: keyboardHeight,
|
|
viewportHeight,
|
|
});
|
|
} else {
|
|
// Fallback: compare window height to a stored reference
|
|
// This is less reliable but works on older browsers
|
|
const currentHeight = windowHeight;
|
|
const isOpen = currentHeight < state.viewportHeight - 100;
|
|
|
|
setState((prev) => ({
|
|
isOpen,
|
|
height: isOpen ? prev.viewportHeight - currentHeight : 0,
|
|
viewportHeight: isOpen ? prev.viewportHeight : currentHeight,
|
|
}));
|
|
}
|
|
}, [state.viewportHeight]);
|
|
|
|
useEffect(() => {
|
|
const visualViewport = window.visualViewport;
|
|
|
|
if (visualViewport) {
|
|
visualViewport.addEventListener("resize", updateKeyboardState);
|
|
visualViewport.addEventListener("scroll", updateKeyboardState);
|
|
} else {
|
|
window.addEventListener("resize", updateKeyboardState);
|
|
}
|
|
|
|
// Initial check
|
|
updateKeyboardState();
|
|
|
|
return () => {
|
|
if (visualViewport) {
|
|
visualViewport.removeEventListener("resize", updateKeyboardState);
|
|
visualViewport.removeEventListener("scroll", updateKeyboardState);
|
|
} else {
|
|
window.removeEventListener("resize", updateKeyboardState);
|
|
}
|
|
};
|
|
}, [updateKeyboardState]);
|
|
|
|
return state;
|
|
}
|