Improve keyboard view and fix various issues with it

This commit is contained in:
LukeGus
2025-09-06 16:20:49 -05:00
parent ba3c60d00c
commit 420d57c6f1
5 changed files with 20 additions and 89 deletions

View File

@@ -98,49 +98,6 @@ export const Terminal = forwardRef<any, SSHTerminalProps>(function SSHTerminal(
return () => window.removeEventListener('resize', handleWindowResize);
}, []);
useEffect(() => {
if (!terminal) return;
const textarea = (terminal as any)._core?._textarea as HTMLTextAreaElement | undefined;
if (textarea) {
textarea.setAttribute("readonly", "true");
textarea.setAttribute("inputmode", "none");
textarea.style.caretColor = "transparent";
const preventKeyboard = () => {
textarea.blur();
};
textarea.addEventListener('focus', preventKeyboard);
textarea.blur();
return () => {
textarea.removeEventListener('focus', preventKeyboard);
};
}
}, [terminal]);
function syncOverlay() {
if (!terminal || !overlayTextareaRef.current) return;
const buffer = terminal.buffer.active;
let text = "";
for (let i = 0; i < buffer.length; i++) {
text += buffer.getLine(i)?.translateToString() + "\n";
}
overlayTextareaRef.current.value = text;
}
useEffect(() => {
if (!terminal) return;
syncOverlay();
const disposeRender = terminal.onRender(() => syncOverlay());
return () => {
disposeRender.dispose();
};
}, [terminal]);
function handleWindowResize() {
if (!isVisibleRef.current) return;
fitAddonRef.current?.fit();
@@ -300,26 +257,10 @@ export const Terminal = forwardRef<any, SSHTerminalProps>(function SSHTerminal(
return (
<div
className="h-full w-full m-1 relative"
style={{ opacity: visible && isVisible ? 1 : 0 }}
>
<div ref={xtermRef} className="h-full w-full" />
<textarea
ref={overlayTextareaRef}
readOnly
className="absolute top-0 left-0 w-full h-full"
style={{
opacity: 0.01,
cursor: "text",
background: "none",
border: "none",
resize: "none",
userSelect: "text",
WebkitUserSelect: "text",
}}
/>
</div>
ref={xtermRef}
className="h-full w-full m-1"
style={{opacity: visible && isVisible ? 1 : 0, overflow: 'hidden'}}
/>
);
});

View File

@@ -12,19 +12,6 @@ export function TerminalKeyboard({onSendInput}: TerminalKeyboardProps) {
const [isCtrl, setIsCtrl] = useState(false);
const [isAlt, setIsAlt] = useState(false);
const handlePaste = useCallback(async () => {
if (navigator.clipboard?.readText) {
try {
const text = await navigator.clipboard.readText();
if (text) {
onSendInput(text);
}
} catch (err) {
console.error("Paste failed:", err);
}
}
}, [onSendInput]);
const onKeyPress = useCallback((button: string) => {
if (button === "{shift}") {
setLayoutName("shift");
@@ -60,11 +47,6 @@ export function TerminalKeyboard({onSendInput}: TerminalKeyboardProps) {
return;
}
if (button === "{paste}") {
handlePaste();
return;
}
let input = button;
const specialKeyMap: { [key: string]: string } = {
@@ -103,7 +85,7 @@ export function TerminalKeyboard({onSendInput}: TerminalKeyboardProps) {
}
onSendInput(input);
}, [onSendInput, handlePaste, isCtrl, isAlt]);
}, [onSendInput, isCtrl, isAlt]);
const buttonTheme = [
{
@@ -151,7 +133,7 @@ export function TerminalKeyboard({onSendInput}: TerminalKeyboardProps) {
"! @ # $ % ^ & * ( ) _ +",
"[ ] { } | \\ ; : ' \" , . / < >",
"F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12",
"{arrowLeft} {arrowRight} {arrowUp} {arrowDown} {paste} {backspace}",
"{arrowLeft} {arrowRight} {arrowUp} {arrowDown} {backspace}",
"{hide} {less} {space} {enter}",
],
hide: [
@@ -178,7 +160,6 @@ export function TerminalKeyboard({onSendInput}: TerminalKeyboardProps) {
"{tab}": "tab",
"{ctrl}": "ctrl",
"{alt}": "alt",
"{paste}": "paste",
"{end}": "end",
"{home}": "home",
"{pgUp}": "pgUp",

View File

@@ -134,7 +134,7 @@ const AppContent: FC = () => {
{tabs.map(tab => (
<div
key={tab.id}
className="absolute inset-0"
className="absolute inset-0 mb-2"
style={{
visibility: tab.id === currentTab ? 'visible' : 'hidden',
opacity: ready ? 1 : 0,
@@ -148,13 +148,18 @@ const AppContent: FC = () => {
</div>
))}
{tabs.length === 0 && (
<div className="flex items-center justify-center h-full text-white">
Select a host to start a terminal session.
<div className="flex flex-col items-center justify-center h-full text-white gap-3 px-4 text-center">
<h1 className="text-lg font-semibold">
Select a host to start your terminal session
</h1>
<p className="text-sm text-gray-300 max-w-xs">
Mobile support is currently limited. A dedicated mobile app is coming soon to enhance your experience.
</p>
</div>
)}
</div>
{currentTab &&
<div className="mb-1">
<div className="mb-1 z-10">
<TerminalKeyboard onSendInput={handleKeyboardInput}/>
</div>
}

View File

@@ -153,7 +153,7 @@ export function LeftSidebar({isSidebarOpen, setIsSidebarOpen, onHostConnect, dis
</SidebarHeader>
<Separator/>
<SidebarContent className="px-2 py-2">
<div className="!bg-[#222225] rounded-lg mb-2">
<div className="!bg-[#222225] rounded-lg">
<Input
value={search}
onChange={e => setSearch(e.target.value)}