fix: resize cols and rows, not the other way around *sigh*

This commit is contained in:
Aarnav Tale
2025-06-18 13:24:34 -04:00
parent 1e86b0e95b
commit bf1d75a27a
4 changed files with 45 additions and 29 deletions
+8
View File
@@ -23,6 +23,13 @@ export async function loader({
request,
context,
}: LoaderFunctionArgs<LoadContext>) {
if (!context.agents?.agentID()) {
throw data(
'WebSSH is only available with the Headplane agent integration',
400,
);
}
const session = await context.sessions.auth(request);
const user = session.get('user');
if (!user) {
@@ -35,6 +42,7 @@ export async function loader({
'v1/user',
session.get('api_key')!,
);
// MARK: This assumes that a user has authenticated with Headscale first
// Since the only way to enforce permissions via ACLs is to generate a
// pre-authkey which REQUIRES a user ID, meaning the user has to have
-12
View File
@@ -46,18 +46,6 @@ interface XtermConfig {
OnDisconnect: () => void;
}
// interface SSHTerminalConfig {
// writeFn: (data: string) => void;
// writeErrorFn: (error: string) => void;
// setReadFn: (cb: (input: string) => void) => void;
// rows: number;
// cols: number;
// timeoutSeconds?: number;
// onConnectionProgress: (message: string) => void;
// onConnected: () => void;
// onDone: () => void;
// }
interface SSHSession {
Close(): boolean;
Resize(rows: number, cols: number): boolean;
+36 -16
View File
@@ -30,6 +30,17 @@ export default function XTerm({ ipn, username, hostname }: XTermProps) {
useEffect(() => {
pause();
if (!container.current) {
console.error('Container ref is not set');
return;
}
// Don't create a new terminal if one already exists
if (term.current) {
console.warn('Terminal already exists, skipping initialization');
return;
}
const terminal = new xterm.Terminal({
allowProposedApi: true,
cursorBlink: true,
@@ -52,24 +63,23 @@ export default function XTerm({ ipn, username, hostname }: XTermProps) {
);
terminal.unicode.activeVersion = '11';
const gl = new WebglAddon();
terminal.loadAddon(gl);
const fit = new FitAddon();
terminal.loadAddon(fit);
const gl = new WebglAddon();
terminal.loadAddon(gl);
gl.onContextLoss(() => {
console.warn('WebGL context lost, falling back to canvas rendering');
gl.dispose();
});
fit.fit();
term.current = terminal;
terminal.open(container.current!);
terminal.focus();
term.current = terminal;
let ro: ResizeObserver | null = null;
let onUnload: ((e: Event) => void) | null = null;
const session = ipn.OpenSSH(hostname, username, {
Rows: terminal.rows,
Cols: terminal.cols,
@@ -103,8 +113,7 @@ export default function XTerm({ ipn, username, hostname }: XTermProps) {
},
});
const parent = container.current?.ownerDocument.defaultView ?? window;
ro = new parent.ResizeObserver(() => {
const ro = new ResizeObserver(() => {
if (term.current) {
setIsResizing(true);
fit.fit();
@@ -112,12 +121,10 @@ export default function XTerm({ ipn, username, hostname }: XTermProps) {
}
});
if (container.current) {
ro.observe(container.current);
}
ro.observe(container.current);
terminal.onResize(({ cols, rows }) => {
session.Resize(rows, cols);
console.log(`Terminal resized to ${cols}x${rows}`);
session.Resize(cols, rows);
});
terminal.onData((data) => {
@@ -126,12 +133,25 @@ export default function XTerm({ ipn, username, hostname }: XTermProps) {
onUnload = (_) => session.Close();
parent.addEventListener('unload', onUnload);
return () => {
if (onUnload) {
parent.removeEventListener('unload', onUnload);
}
session.Close();
ro?.disconnect();
terminal.dispose();
term.current = null;
inputRef.current = null;
console.log('SSH session closed and terminal disposed');
};
}, []);
return (
<div className="relative w-full h-full group">
<>
{isLoading ? (
<div className="mx-auto h-screen flex items-center justify-center">
<div className="absolute w-screen z-50 mx-auto h-screen flex items-center justify-center">
<Loader2 className="animate-spin size-10 text-headplane-50" />
</div>
) : undefined}
@@ -159,6 +179,6 @@ export default function XTerm({ ipn, username, hostname }: XTermProps) {
Failed to connect to SSH session
</div>
) : undefined}
</div>
</>
);
}
+1 -1
View File
@@ -150,7 +150,7 @@ func (s *SSHSession) Resize(rows, cols int) error {
return nil
}
return s.Pty.WindowChange(rows, cols)
return s.Pty.WindowChange(cols, rows)
}
// Closes the SSH session.