mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-04-18 10:02:16 +00:00
Update terminal-panel.tsx
This commit is contained in:
@@ -16,6 +16,7 @@ import {
|
|||||||
Grid2X2,
|
Grid2X2,
|
||||||
GripHorizontal,
|
GripHorizontal,
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
|
Clipboard,
|
||||||
} from "lucide-react"
|
} from "lucide-react"
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
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)),
|
prev.map((t) => (t.id === terminal.id ? { ...t, isConnected: true, term, ws, fitAddon, pingInterval } : t)),
|
||||||
)
|
)
|
||||||
syncSizeWithBackend()
|
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) => {
|
ws.onmessage = (event) => {
|
||||||
@@ -724,13 +738,39 @@ const handleClose = () => {
|
|||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
}
|
}
|
||||||
|
|
||||||
const activeTerminal = terminals.find((t) => t.id === activeTerminalId)
|
const activeTerminal = terminals.find((t) => t.id === activeTerminalId)
|
||||||
if (activeTerminal?.ws && activeTerminal.ws.readyState === WebSocket.OPEN) {
|
if (activeTerminal?.ws && activeTerminal.ws.readyState === WebSocket.OPEN) {
|
||||||
activeTerminal.ws.send(seq)
|
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 getLayoutClass = () => {
|
||||||
const count = terminals.length
|
const count = terminals.length
|
||||||
if (isMobile || count === 1) return "grid grid-cols-1"
|
if (isMobile || count === 1) return "grid grid-cols-1"
|
||||||
@@ -1032,6 +1072,16 @@ const handleClose = () => {
|
|||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</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>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user