mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-02-19 08:56:23 +00:00
Update lxc-terminal-modal.tsx
This commit is contained in:
@@ -54,10 +54,7 @@ export function LxcTerminalModal({
|
|||||||
const [connectionStatus, setConnectionStatus] = useState<"connecting" | "online" | "offline">("connecting")
|
const [connectionStatus, setConnectionStatus] = useState<"connecting" | "online" | "offline">("connecting")
|
||||||
const [isMobile, setIsMobile] = useState(false)
|
const [isMobile, setIsMobile] = useState(false)
|
||||||
const [isTablet, setIsTablet] = useState(false)
|
const [isTablet, setIsTablet] = useState(false)
|
||||||
|
const isInsideLxcRef = useRef(false)
|
||||||
// Track host prompt to detect when user exits LXC
|
|
||||||
const hostPromptRef = useRef<string>("")
|
|
||||||
const insideLxcRef = useRef(false)
|
|
||||||
const outputBufferRef = useRef<string>("")
|
const outputBufferRef = useRef<string>("")
|
||||||
|
|
||||||
const [modalHeight, setModalHeight] = useState(500)
|
const [modalHeight, setModalHeight] = useState(500)
|
||||||
@@ -65,6 +62,13 @@ export function LxcTerminalModal({
|
|||||||
const resizeBarRef = useRef<HTMLDivElement>(null)
|
const resizeBarRef = useRef<HTMLDivElement>(null)
|
||||||
const modalHeightRef = useRef(500)
|
const modalHeightRef = useRef(500)
|
||||||
|
|
||||||
|
const [showLoginModal, setShowLoginModal] = useState(false)
|
||||||
|
const [loginUsername, setLoginUsername] = useState("")
|
||||||
|
const [loginPassword, setLoginPassword] = useState("")
|
||||||
|
const [loginError, setLoginError] = useState("")
|
||||||
|
const [isLoggingIn, setIsLoggingIn] = useState(false)
|
||||||
|
const waitingForPasswordRef = useRef(false)
|
||||||
|
|
||||||
// Detect mobile/tablet
|
// Detect mobile/tablet
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const checkDevice = () => {
|
const checkDevice = () => {
|
||||||
@@ -93,8 +97,7 @@ export function LxcTerminalModal({
|
|||||||
termRef.current = null
|
termRef.current = null
|
||||||
}
|
}
|
||||||
setConnectionStatus("connecting")
|
setConnectionStatus("connecting")
|
||||||
hostPromptRef.current = ""
|
isInsideLxcRef.current = false
|
||||||
insideLxcRef.current = false
|
|
||||||
outputBufferRef.current = ""
|
outputBufferRef.current = ""
|
||||||
}
|
}
|
||||||
}, [isOpen])
|
}, [isOpen])
|
||||||
@@ -227,53 +230,45 @@ export function LxcTerminalModal({
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = event.data
|
// Buffer output until we detect we're inside the LXC
|
||||||
|
// pct enter always enters directly without login prompt when run as root
|
||||||
|
if (!isInsideLxcRef.current) {
|
||||||
|
outputBufferRef.current += event.data
|
||||||
|
|
||||||
// Buffer output until we're inside the LXC
|
// Detect when we're inside the LXC container
|
||||||
if (!insideLxcRef.current) {
|
// The LXC prompt will NOT contain "constructor" (the host name)
|
||||||
outputBufferRef.current += data
|
// It will be something like "root@plex:/#" or "user@containername:~$"
|
||||||
|
const buffer = outputBufferRef.current
|
||||||
|
|
||||||
// Capture host prompt (pattern like "root@hostname" or "[user@hostname")
|
// Look for a prompt that:
|
||||||
if (!hostPromptRef.current) {
|
// 1. Comes after pct enter command
|
||||||
const hostMatch = outputBufferRef.current.match(/\[?(\w+@[\w-]+)/)
|
// 2. Has @ followed by container name (not host name)
|
||||||
if (hostMatch) {
|
// 3. Ends with # or $
|
||||||
hostPromptRef.current = hostMatch[1]
|
const pctEnterMatch = buffer.match(/pct enter \d+\r?\n/)
|
||||||
}
|
if (pctEnterMatch) {
|
||||||
}
|
const afterPctEnter = buffer.substring(buffer.indexOf(pctEnterMatch[0]) + pctEnterMatch[0].length)
|
||||||
|
|
||||||
// Detect when we're inside the LXC
|
// Find the LXC prompt - it should be a line ending with :~# :~$ :/# or similar
|
||||||
// Look for a prompt that is different from the host prompt after pct enter
|
// and NOT containing the host name "constructor"
|
||||||
if (hostPromptRef.current && outputBufferRef.current.includes(`pct enter ${vmid}`)) {
|
const lxcPromptMatch = afterPctEnter.match(/\r?\n?([^\r\n]*@(?!constructor)[^\r\n]*[#$]\s*)$/)
|
||||||
const hostName = hostPromptRef.current.split('@')[1]
|
|
||||||
// Look for a new prompt line that doesn't contain the host name
|
if (lxcPromptMatch) {
|
||||||
const lines = outputBufferRef.current.split('\n')
|
// Successfully inside LXC - only show from the LXC prompt onwards
|
||||||
for (let i = lines.length - 1; i >= 0; i--) {
|
isInsideLxcRef.current = true
|
||||||
const line = lines[i]
|
|
||||||
// Check if this line has a prompt (@) but NOT the host name
|
// Find where the LXC prompt line starts
|
||||||
if (line.includes('@') && !line.includes(hostName) && (line.includes('#') || line.includes('$'))) {
|
const promptStart = afterPctEnter.lastIndexOf(lxcPromptMatch[1])
|
||||||
// Found LXC prompt - we're inside
|
if (promptStart !== -1) {
|
||||||
insideLxcRef.current = true
|
// Only show the LXC prompt itself
|
||||||
// Only show from this prompt onwards
|
term.write(lxcPromptMatch[1])
|
||||||
term.write(line)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Already inside LXC - write directly
|
|
||||||
// But check if user exited (host prompt appears again)
|
|
||||||
if (hostPromptRef.current && data.includes(hostPromptRef.current)) {
|
|
||||||
// User exited LXC, close modal after short delay
|
|
||||||
term.write(data)
|
|
||||||
setTimeout(() => {
|
|
||||||
onClose()
|
|
||||||
}, 500)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
term.write(data)
|
// Already inside LXC, write directly
|
||||||
|
term.write(event.data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user