Update terminal-panel.tsx

This commit is contained in:
MacRimi
2026-03-28 21:50:04 +01:00
parent 2f9959c009
commit 7858fb0283

View File

@@ -16,6 +16,7 @@ import {
Grid2X2,
GripHorizontal,
ChevronDown,
Clipboard,
} from "lucide-react"
import {
DropdownMenu,
@@ -578,6 +579,19 @@ export const TerminalPanel: React.FC<TerminalPanelProps> = ({ websocketUrl, onCl
prev.map((t) => (t.id === terminal.id ? { ...t, isConnected: true, term, ws, fitAddon, pingInterval } : t)),
)
syncSizeWithBackend()
// Auto-refresh for mobile/VPN: send a newline after 1 second to ensure connection is active
// This fixes the issue where mobile connections sometimes don't fully initialize
const isMobileDevice = window.innerWidth < 768 ||
('ontouchstart' in window && navigator.maxTouchPoints > 0)
if (isMobileDevice) {
setTimeout(() => {
if (ws.readyState === WebSocket.OPEN) {
// Send empty string to trigger a refresh without executing any command
ws.send('\n')
}
}, 1000)
}
}
ws.onmessage = (event) => {
@@ -724,13 +738,39 @@ const handleClose = () => {
e.preventDefault()
e.stopPropagation()
}
const activeTerminal = terminals.find((t) => t.id === activeTerminalId)
if (activeTerminal?.ws && activeTerminal.ws.readyState === WebSocket.OPEN) {
activeTerminal.ws.send(seq)
}
}
// Paste from clipboard - essential for mobile devices
const handlePaste = async (e?: React.MouseEvent | React.TouchEvent) => {
if (e) {
e.preventDefault()
e.stopPropagation()
}
try {
const text = await navigator.clipboard.readText()
if (text) {
const activeTerminal = terminals.find((t) => t.id === activeTerminalId)
if (activeTerminal?.ws && activeTerminal.ws.readyState === WebSocket.OPEN) {
// Send text character by character to handle special characters properly
activeTerminal.ws.send(text)
}
}
} catch (err) {
console.warn('[Terminal] Clipboard access denied:', err)
// Fallback: show a message in terminal
const activeTerminal = terminals.find((t) => t.id === activeTerminalId)
if (activeTerminal?.term) {
activeTerminal.term.writeln('\r\n\x1b[33m[INFO] Clipboard access denied. Please allow clipboard permissions.\x1b[0m')
}
}
}
const getLayoutClass = () => {
const count = terminals.length
if (isMobile || count === 1) return "grid grid-cols-1"
@@ -1032,6 +1072,16 @@ const handleClose = () => {
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<Button
onPointerDown={(e) => handlePaste(e)}
variant="outline"
size="sm"
className="h-8 px-2 text-xs gap-1 bg-green-600/20 hover:bg-green-600/30 border-green-600/50 text-green-400"
title="Paste from clipboard"
>
<Clipboard className="h-3.5 w-3.5" />
Paste
</Button>
</div>
)}