mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2025-12-15 00:26:23 +00:00
Update script-terminal-modal.tsx
This commit is contained in:
@@ -64,6 +64,7 @@ export function ScriptTerminalModal({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) {
|
if (!open) {
|
||||||
|
// Cleanup
|
||||||
if (checkConnectionInterval.current) {
|
if (checkConnectionInterval.current) {
|
||||||
clearInterval(checkConnectionInterval.current)
|
clearInterval(checkConnectionInterval.current)
|
||||||
}
|
}
|
||||||
@@ -78,42 +79,30 @@ export function ScriptTerminalModal({
|
|||||||
wsRef.current.close()
|
wsRef.current.close()
|
||||||
wsRef.current = null
|
wsRef.current = null
|
||||||
}
|
}
|
||||||
|
// Reset for next open
|
||||||
sessionIdRef.current = null
|
sessionIdRef.current = null
|
||||||
hasInitializedRef.current = false
|
hasInitializedRef.current = false
|
||||||
return
|
setIsComplete(false)
|
||||||
}
|
setExitCode(null)
|
||||||
|
setInteractionInput("")
|
||||||
if (!sessionIdRef.current) {
|
setCurrentInteraction(null)
|
||||||
const generateSessionId = () => {
|
setIsConnected(false)
|
||||||
return Math.random().toString(36).substring(2, 8)
|
setIsWaitingNextInteraction(false)
|
||||||
}
|
|
||||||
sessionIdRef.current = generateSessionId()
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsComplete(false)
|
|
||||||
setExitCode(null)
|
|
||||||
setInteractionInput("")
|
|
||||||
setCurrentInteraction(null)
|
|
||||||
setIsConnected(false)
|
|
||||||
setIsWaitingNextInteraction(false)
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
if (checkConnectionInterval.current) {
|
|
||||||
clearInterval(checkConnectionInterval.current)
|
|
||||||
}
|
|
||||||
if (waitingTimeoutRef.current) {
|
|
||||||
clearTimeout(waitingTimeoutRef.current)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, [open])
|
}, [open])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open || !sessionIdRef.current || !terminalContainerRef.current || hasInitializedRef.current) {
|
if (!open || !terminalContainerRef.current || hasInitializedRef.current) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
hasInitializedRef.current = true
|
hasInitializedRef.current = true
|
||||||
|
|
||||||
|
// Generate session ID once
|
||||||
|
if (!sessionIdRef.current) {
|
||||||
|
sessionIdRef.current = Math.random().toString(36).substring(2, 8)
|
||||||
|
}
|
||||||
|
|
||||||
const initTerminal = async () => {
|
const initTerminal = async () => {
|
||||||
const [TerminalClass, FitAddonClass] = await Promise.all([
|
const [TerminalClass, FitAddonClass] = await Promise.all([
|
||||||
import("xterm").then((mod) => mod.Terminal),
|
import("xterm").then((mod) => mod.Terminal),
|
||||||
@@ -166,7 +155,7 @@ export function ScriptTerminalModal({
|
|||||||
try {
|
try {
|
||||||
fitAddon.fit()
|
fitAddon.fit()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn("[v0] Initial fit failed:", err)
|
// Silent fail on initial fit
|
||||||
}
|
}
|
||||||
}, 50)
|
}, 50)
|
||||||
|
|
||||||
@@ -179,7 +168,7 @@ export function ScriptTerminalModal({
|
|||||||
ws.onopen = () => {
|
ws.onopen = () => {
|
||||||
setIsConnected(true)
|
setIsConnected(true)
|
||||||
|
|
||||||
const initData = {
|
const initMessage = {
|
||||||
script_path: scriptPath,
|
script_path: scriptPath,
|
||||||
params: {
|
params: {
|
||||||
EXECUTION_MODE: "web",
|
EXECUTION_MODE: "web",
|
||||||
@@ -187,8 +176,9 @@ export function ScriptTerminalModal({
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
ws.send(JSON.stringify(initData))
|
ws.send(JSON.stringify(initMessage))
|
||||||
|
|
||||||
|
// Fit and resize after connection
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
try {
|
try {
|
||||||
fitAddon.fit()
|
fitAddon.fit()
|
||||||
@@ -200,7 +190,7 @@ export function ScriptTerminalModal({
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn("[v0] Failed to send resize:", err)
|
// Silent fail
|
||||||
}
|
}
|
||||||
}, 100)
|
}, 100)
|
||||||
}
|
}
|
||||||
@@ -209,7 +199,8 @@ export function ScriptTerminalModal({
|
|||||||
try {
|
try {
|
||||||
const msg = JSON.parse(event.data)
|
const msg = JSON.parse(event.data)
|
||||||
|
|
||||||
if (msg.type === "web_interaction") {
|
// Detect web interactions
|
||||||
|
if (msg.type === "web_interaction" && msg.interaction) {
|
||||||
setIsWaitingNextInteraction(false)
|
setIsWaitingNextInteraction(false)
|
||||||
if (waitingTimeoutRef.current) {
|
if (waitingTimeoutRef.current) {
|
||||||
clearTimeout(waitingTimeoutRef.current)
|
clearTimeout(waitingTimeoutRef.current)
|
||||||
@@ -222,20 +213,28 @@ export function ScriptTerminalModal({
|
|||||||
options: msg.interaction.options,
|
options: msg.interaction.options,
|
||||||
default: msg.interaction.default,
|
default: msg.interaction.default,
|
||||||
})
|
})
|
||||||
} else if (msg.type === "error") {
|
return // Don't write JSON to terminal
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.type === "error") {
|
||||||
term.writeln(`\x1b[31m${msg.message}\x1b[0m`)
|
term.writeln(`\x1b[31m${msg.message}\x1b[0m`)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
term.write(event.data)
|
// Not JSON, it's regular terminal output
|
||||||
setIsWaitingNextInteraction(false)
|
}
|
||||||
if (waitingTimeoutRef.current) {
|
|
||||||
clearTimeout(waitingTimeoutRef.current)
|
// Write regular output to terminal
|
||||||
}
|
term.write(event.data)
|
||||||
|
|
||||||
|
// Hide spinner when output arrives
|
||||||
|
setIsWaitingNextInteraction(false)
|
||||||
|
if (waitingTimeoutRef.current) {
|
||||||
|
clearTimeout(waitingTimeoutRef.current)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ws.onerror = (error) => {
|
ws.onerror = (error) => {
|
||||||
console.error("[v0] WebSocket error:", error)
|
|
||||||
setIsConnected(false)
|
setIsConnected(false)
|
||||||
term.writeln("\x1b[31mWebSocket error occurred\x1b[0m")
|
term.writeln("\x1b[31mWebSocket error occurred\x1b[0m")
|
||||||
}
|
}
|
||||||
@@ -258,6 +257,7 @@ export function ScriptTerminalModal({
|
|||||||
|
|
||||||
wsRef.current = ws
|
wsRef.current = ws
|
||||||
|
|
||||||
|
// Monitor connection status
|
||||||
checkConnectionInterval.current = setInterval(() => {
|
checkConnectionInterval.current = setInterval(() => {
|
||||||
if (ws) {
|
if (ws) {
|
||||||
setIsConnected(ws.readyState === WebSocket.OPEN)
|
setIsConnected(ws.readyState === WebSocket.OPEN)
|
||||||
@@ -266,7 +266,7 @@ export function ScriptTerminalModal({
|
|||||||
}
|
}
|
||||||
|
|
||||||
initTerminal()
|
initTerminal()
|
||||||
}, [open, scriptPath])
|
}, [open]) // Only depend on open, not scriptPath or params
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!terminalContainerRef.current || !terminalRef.current || !fitAddonRef.current) {
|
if (!terminalContainerRef.current || !terminalRef.current || !fitAddonRef.current) {
|
||||||
|
|||||||
Reference in New Issue
Block a user