Update terminal-panel.tsx

This commit is contained in:
MacRimi
2025-11-22 21:58:29 +01:00
parent ebe3a51398
commit 3b8ae2c879

View File

@@ -317,20 +317,23 @@ export const TerminalPanel: React.FC<TerminalPanelProps> = ({ websocketUrl, onCl
term.open(container) term.open(container)
setTimeout(() => { const performResize = () => {
const xtermViewport = container.querySelector(".xterm-viewport") as HTMLElement const xtermViewport = container.querySelector(".xterm-viewport") as HTMLElement
const xtermScreen = container.querySelector(".xterm-screen") as HTMLElement const xtermScreen = container.querySelector(".xterm-screen") as HTMLElement
if (xtermViewport) xtermViewport.style.padding = "0" if (xtermViewport) xtermViewport.style.padding = "0"
if (xtermScreen) xtermScreen.style.padding = "0" if (xtermScreen) xtermScreen.style.padding = "0"
fitAddon.fit() fitAddon.fit()
console.log(`[v0] Terminal fitted: ${term.cols}x${term.rows}`) const cols = term.cols
const rows = term.rows
console.log(`[v0] Terminal resized: ${cols}x${rows}`)
// Send resize to backend via HTTP // Send resize to backend via HTTP
const apiUrl = getApiUrl() const apiUrl = getApiUrl()
fetch(`${apiUrl}/api/terminal/${terminal.id}/resize`, { fetch(`${apiUrl}/api/terminal/${terminal.id}/resize`, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ cols: term.cols, rows: term.rows }), body: JSON.stringify({ cols, rows }),
}) })
.then((res) => res.json()) .then((res) => res.json())
.then((data) => { .then((data) => {
@@ -339,7 +342,11 @@ export const TerminalPanel: React.FC<TerminalPanelProps> = ({ websocketUrl, onCl
.catch((err) => { .catch((err) => {
console.error(`[v0] Error resizing backend PTY:`, err) console.error(`[v0] Error resizing backend PTY:`, err)
}) })
}, 100) }
setTimeout(() => performResize(), 100)
setTimeout(() => performResize(), 300)
setTimeout(() => performResize(), 600)
const wsUrl = websocketUrl || getWebSocketUrl() const wsUrl = websocketUrl || getWebSocketUrl()
const ws = new WebSocket(wsUrl) const ws = new WebSocket(wsUrl)
@@ -347,6 +354,9 @@ export const TerminalPanel: React.FC<TerminalPanelProps> = ({ websocketUrl, onCl
ws.onopen = () => { ws.onopen = () => {
setTerminals((prev) => prev.map((t) => (t.id === terminal.id ? { ...t, isConnected: true, term, ws } : t))) setTerminals((prev) => prev.map((t) => (t.id === terminal.id ? { ...t, isConnected: true, term, ws } : t)))
term.writeln("\x1b[32mConnected to ProxMenux terminal.\x1b[0m") term.writeln("\x1b[32mConnected to ProxMenux terminal.\x1b[0m")
setTimeout(() => performResize(), 200)
setTimeout(() => performResize(), 500)
} }
ws.onmessage = (event) => { ws.onmessage = (event) => {
@@ -372,20 +382,7 @@ export const TerminalPanel: React.FC<TerminalPanelProps> = ({ websocketUrl, onCl
const handleResize = () => { const handleResize = () => {
try { try {
fitAddon.fit() performResize()
const cols = term.cols
const rows = term.rows
console.log(`[v0] Window resized, terminal now: ${cols}x${rows}`)
// Send resize to backend via HTTP
const apiUrl = getApiUrl()
fetch(`${apiUrl}/api/terminal/${terminal.id}/resize`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ cols, rows }),
}).catch((err) => {
console.error(`[v0] Error resizing backend PTY:`, err)
})
} catch { } catch {
// Ignore resize errors // Ignore resize errors
} }
@@ -613,25 +610,36 @@ export const TerminalPanel: React.FC<TerminalPanelProps> = ({ websocketUrl, onCl
))} ))}
</Tabs> </Tabs>
) : ( ) : (
<div className={`${getLayoutClass()} h-full gap-0.5 bg-zinc-800 p-0.5`}> <div className={`${getLayoutClass()} gap-2 flex-1 min-h-0 p-2`}>
{terminals.map((terminal) => ( {terminals.map((terminal) => (
<div key={terminal.id} className="relative bg-zinc-900 overflow-hidden"> <div
<div className="absolute top-0 left-0 right-0 z-10 flex items-center justify-between px-2 py-1 bg-zinc-900/95 border-b border-zinc-800"> key={terminal.id}
<button className={`relative bg-black rounded flex flex-col overflow-hidden border ${
onClick={() => setActiveTerminalId(terminal.id)} terminal.id === activeTerminalId ? "border-blue-500" : "border-zinc-700"
className={`text-xs font-medium ${ }`}
activeTerminalId === terminal.id ? "text-blue-400" : "text-zinc-500" onClick={() => setActiveTerminalId(terminal.id)}
}`} >
> <div className="flex items-center justify-between px-2 py-1 bg-zinc-800 border-b border-zinc-700">
{terminal.title} <span className="text-xs font-medium text-white">{terminal.title}</span>
</button>
{terminals.length > 1 && ( {terminals.length > 1 && (
<button onClick={() => closeTerminal(terminal.id)} className="hover:bg-zinc-700 rounded p-0.5"> <Button
variant="ghost"
size="sm"
className="h-5 w-5 p-0"
onClick={(e) => {
e.stopPropagation()
closeTerminal(terminal.id)
}}
>
<X className="h-3 w-3" /> <X className="h-3 w-3" />
</button> </Button>
)} )}
</div> </div>
<div ref={setContainerRef(terminal.id)} className="w-full h-full bg-black pt-7" /> <div
ref={setContainerRef(terminal.id)}
className="flex-1 overflow-hidden"
style={{ width: "100%", height: "100%" }}
/>
</div> </div>
))} ))}
</div> </div>