feat: guacd improvements, created tool bar

This commit is contained in:
LukeGus
2026-05-21 22:35:58 -05:00
parent 23a0160ef0
commit 6bcbadcc25
9 changed files with 1131 additions and 267 deletions
+30 -27
View File
@@ -6,7 +6,8 @@ import {
import { FullScreenAppWrapper } from "@/features/FullScreenAppWrapper.tsx";
import { getGuacamoleTokenFromHost, getGuacdStatus } from "@/main-axios.ts";
import { useTranslation } from "react-i18next";
import { AlertCircle, RefreshCw, Keyboard } from "lucide-react";
import { AlertCircle, RefreshCw } from "lucide-react";
import { GuacamoleToolbar } from "@/features/guacamole/GuacamoleToolbar.tsx";
import { Button } from "@/components/button.tsx";
import { SimpleLoader } from "@/lib/SimpleLoader.tsx";
import type { SSHHost } from "@/types";
@@ -49,9 +50,29 @@ const GuacamoleApp: React.FC<GuacamoleAppProps> = ({ hostId }) => {
);
}
if (!hostId) {
return (
<div
className="flex flex-col items-center justify-center h-full gap-4"
style={{ backgroundColor: "var(--bg-base)" }}
>
<AlertCircle
className="size-10"
style={{ color: "var(--foreground)" }}
/>
<span
className="text-sm font-semibold"
style={{ color: "var(--foreground)" }}
>
{t("guacamole.hostNotFound")}
</span>
</div>
);
}
return (
<GuacamoleAppInner
hostId={parseInt(hostId!, 10)}
hostId={parseInt(hostId, 10)}
hostConfig={hostConfig}
/>
);
@@ -82,9 +103,7 @@ const GuacamoleAppInner: React.FC<GuacamoleAppInnerProps> = ({
getGuacdStatus()
.then((status) => {
if (status.guacd.status !== "connected") {
setError(
"Remote desktop service (guacd) is not available. Please ensure guacd is running and accessible and configured properly in admin settings.",
);
setError(t("guacamole.guacdUnavailable"));
return;
}
return getGuacamoleTokenFromHost(hostId);
@@ -102,18 +121,6 @@ const GuacamoleAppInner: React.FC<GuacamoleAppInnerProps> = ({
setRetryCount((c) => c + 1);
}, []);
const sendCtrlAltDelete = useCallback(() => {
const display = displayRef.current;
if (!display) return;
// keysyms: Control_L=0xffe3, Alt_L=0xffe9, Delete=0xffff
display.sendKey(0xffe3, true);
display.sendKey(0xffe9, true);
display.sendKey(0xffff, true);
display.sendKey(0xffff, false);
display.sendKey(0xffe9, false);
display.sendKey(0xffe3, false);
}, []);
if (error) {
return (
<div
@@ -189,21 +196,17 @@ const GuacamoleAppInner: React.FC<GuacamoleAppInnerProps> = ({
</div>
)}
<GuacamoleDisplay
key={token}
ref={displayRef}
connectionConfig={{ token, protocol, type: protocol }}
isVisible={true}
onError={(err) => setConnectionError(err)}
/>
{(protocol === "rdp" || protocol === "vnc") && (
<button
onClick={sendCtrlAltDelete}
title="Ctrl+Alt+Delete"
className="absolute top-3 right-3 z-10 flex items-center gap-1.5 px-2.5 py-1.5 text-[10px] font-semibold uppercase tracking-wider bg-background/80 backdrop-blur border border-border rounded hover:bg-muted transition-colors opacity-60 hover:opacity-100"
>
<Keyboard className="size-3" />
Ctrl+Alt+Del
</button>
)}
<GuacamoleToolbar
displayRef={displayRef}
protocol={protocol}
onReconnect={handleReconnect}
/>
</div>
);
};