feat: 系统终端

This commit is contained in:
bietiaop
2025-02-01 20:35:01 +08:00
parent 5120786708
commit 4157746478
15 changed files with 349 additions and 259 deletions

View File

@@ -1,6 +1,6 @@
import { useEffect, useRef } from 'react'
import WebUIManager from '@/controllers/webui_manager'
import TerminalManager from '@/controllers/terminal_manager'
import XTerm, { XTermRef } from '../xterm'
@@ -10,48 +10,29 @@ interface TerminalInstanceProps {
export function TerminalInstance({ id }: TerminalInstanceProps) {
const termRef = useRef<XTermRef>(null)
const wsRef = useRef<WebSocket>(null)
useEffect(() => {
const ws = WebUIManager.connectTerminal(id, (data) => {
termRef.current?.write(data)
})
wsRef.current = ws
// 添加连接状态监听
ws.onopen = () => {
console.log('Terminal connected:', id)
const handleData = (data: string) => {
try {
const parsed = JSON.parse(data)
if (parsed.data) {
termRef.current?.write(parsed.data)
}
} catch (e) {
termRef.current?.write(data)
}
}
ws.onerror = (error) => {
console.error('Terminal connection error:', error)
termRef.current?.write(
'\r\n\x1b[31mConnection error. Please try reconnecting.\x1b[0m\r\n'
)
}
ws.onclose = () => {
console.log('Terminal disconnected:', id)
termRef.current?.write('\r\n\x1b[31mConnection closed.\x1b[0m\r\n')
}
TerminalManager.connectTerminal(id, handleData)
return () => {
ws.close()
TerminalManager.disconnectTerminal(id, handleData)
}
}, [id])
const handleInput = (data: string) => {
const ws = wsRef.current
if (ws?.readyState === WebSocket.OPEN) {
try {
ws.send(JSON.stringify({ type: 'input', data }))
} catch (error) {
console.error('Failed to send terminal input:', error)
}
} else {
console.warn('WebSocket is not in OPEN state')
}
TerminalManager.sendInput(id, data)
}
return <XTerm ref={termRef} onInput={handleInput} className="h-full" />
return <XTerm ref={termRef} onInput={handleInput} className="w-full h-full" />
}