diff --git a/web/app/servers/[id]/console/page.tsx b/web/app/servers/[id]/console/page.tsx index e853e95..bc8d168 100644 --- a/web/app/servers/[id]/console/page.tsx +++ b/web/app/servers/[id]/console/page.tsx @@ -26,6 +26,7 @@ export default function ServerConsolePage() { const [connecting, setConnecting] = useState(false); const [connected, setConnected] = useState(false); const [error, setError] = useState(null); + const [pending, setPending] = useState<{ token: string; wsPath: string } | null>(null); // Inject the vendored Guacamole client script once. useEffect(() => { @@ -83,22 +84,10 @@ export default function ServerConsolePage() { } const { token, ws_path } = await api.connectConsole(body); - - const wsProto = location.protocol === "https:" ? "wss" : "ws"; - const wsUrl = `${wsProto}://${location.host}${ws_path}`; - - if (containerRef.current) { - const rect = containerRef.current.getBoundingClientRect(); - const dpi = Math.round(96 * (window.devicePixelRatio || 1)); - const connectData = - `token=${encodeURIComponent(token)}` + - `&width=${Math.floor(rect.width)}` + - `&height=${Math.floor(rect.height)}` + - `&dpi=${dpi}`; - const conn = openConsole(containerRef.current, wsUrl, connectData); - connectionRef.current = conn; - setConnected(true); - } + // Defer the actual openConsole until after the form is unmounted so the + // container measures at full height (see effect below). + setPending({ token, wsPath: ws_path }); + setConnected(true); } catch (e) { setError(e instanceof Error ? e.message : "Failed to connect"); } finally { @@ -106,6 +95,25 @@ export default function ServerConsolePage() { } } + // Runs after `connected` flips and the connection form is gone, so the + // container now occupies its full flex height. + useEffect(() => { + if (!connected || !pending || !containerRef.current) return; + + const wsProto = location.protocol === "https:" ? "wss" : "ws"; + const wsUrl = `${wsProto}://${location.host}${pending.wsPath}`; + const rect = containerRef.current.getBoundingClientRect(); + const dpi = Math.round(96 * (window.devicePixelRatio || 1)); + const connectData = + `token=${encodeURIComponent(pending.token)}` + + `&width=${Math.floor(rect.width)}` + + `&height=${Math.floor(rect.height)}` + + `&dpi=${dpi}`; + + connectionRef.current = openConsole(containerRef.current, wsUrl, connectData); + setPending(null); + }, [connected, pending]); + function handleDisconnect() { connectionRef.current?.disconnect(); connectionRef.current = null;