mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 06:05:24 +00:00
feat: move session sharing and collab rooms into a plugin (B12)
This commit is contained in:
1 parent
791d8656a1
commit
a276f6898c
207 files changed
+35771
-11072
No files matched your search
@@ -60,6 +60,12 @@
|
||||
"editorTab": "telnet"
|
||||
}
|
||||
],
|
||||
"actionSlots": [
|
||||
{
|
||||
"id": "remote-desktop.toolbar",
|
||||
"accepts": ["button"]
|
||||
}
|
||||
],
|
||||
"guest": true
|
||||
},
|
||||
"locales": "locales",
|
||||
|
||||
@@ -45,7 +45,6 @@ import {
|
||||
ConnectionLogProvider,
|
||||
useConnectionLog,
|
||||
} from "@/ssh/connection-log/ConnectionLogContext.tsx";
|
||||
import { ShareSessionModal } from "@/features/session-sharing/ShareSessionModal.tsx";
|
||||
import type { SSHHost } from "@/types";
|
||||
import { useConnectionDefaults } from "@/contexts/ConnectionDefaultsContext";
|
||||
import { resolveConnectionDefaults } from "@/lib/connection-defaults";
|
||||
@@ -68,8 +67,6 @@ export type GuacamoleQuickHost = GuacamoleAppInnerProps["hostConfig"] & {
|
||||
export interface GuacamoleAppHandle {
|
||||
disconnect: () => void;
|
||||
isConnected: () => boolean;
|
||||
openShareModal: () => void;
|
||||
canShare: () => boolean;
|
||||
/** Reconnects, from the tab bar's refresh. */
|
||||
refresh: () => void;
|
||||
}
|
||||
@@ -202,7 +199,6 @@ const GuacamoleAppInner = React.forwardRef<
|
||||
id: string;
|
||||
origin: ConnectionOrigin;
|
||||
} | null>(null);
|
||||
const [shareModalOpen, setShareModalOpen] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [connectionError, setConnectionError] = useState<string | null>(null);
|
||||
const [isDisplayReady, setIsDisplayReady] = useState(false);
|
||||
@@ -299,8 +295,6 @@ const GuacamoleAppInner = React.forwardRef<
|
||||
useImperativeHandle(ref, () => ({
|
||||
disconnect: () => displayRef.current?.disconnect(),
|
||||
isConnected: () => displayRef.current?.isConnected() === true,
|
||||
openShareModal: () => setShareModalOpen(true),
|
||||
canShare: () => guacamoleConnectionId !== null,
|
||||
refresh: () => reconnectRef.current(),
|
||||
}));
|
||||
|
||||
@@ -649,16 +643,16 @@ const GuacamoleAppInner = React.forwardRef<
|
||||
onTouchModeChange={setTouchMode}
|
||||
zoom={displayZoom}
|
||||
onHide={() => setToolbarHidden(true)}
|
||||
/>
|
||||
)}
|
||||
{shareModalOpen && guacamoleConnectionId && (
|
||||
<ShareSessionModal
|
||||
open={shareModalOpen}
|
||||
onClose={() => setShareModalOpen(false)}
|
||||
hostId={hostId}
|
||||
sessionId={guacamoleConnectionId}
|
||||
protocol={resolvedProtocol}
|
||||
tabInstanceId={tabId}
|
||||
slotContext={
|
||||
typeof hostId === "number"
|
||||
? {
|
||||
hostId,
|
||||
sessionId: guacamoleConnectionId,
|
||||
protocol: resolvedProtocol,
|
||||
tabInstanceId: tabId,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -32,6 +32,7 @@ import type {
|
||||
GuacamoleTouchMode,
|
||||
} from "./GuacamoleDisplay.tsx";
|
||||
import { useTranslation } from "@termix/plugin-sdk/frontend";
|
||||
import { ActionSlot } from "@termix/plugin-sdk/ui";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
detectRuntimeMetaKeyFamily,
|
||||
@@ -50,6 +51,19 @@ interface GuacamoleToolbarProps {
|
||||
zoom?: number;
|
||||
onHide?: () => void;
|
||||
metaKeyFamily?: MetaKeyFamily;
|
||||
/** Handed to "remote-desktop.toolbar" actions (the share button). */
|
||||
slotContext?: RemoteDesktopToolbarContext;
|
||||
}
|
||||
|
||||
export const REMOTE_DESKTOP_TOOLBAR_SLOT = "remote-desktop.toolbar";
|
||||
|
||||
/** What a "remote-desktop.toolbar" action is invoked with. */
|
||||
export interface RemoteDesktopToolbarContext {
|
||||
hostId: number;
|
||||
/** guacd's connection id, once the session is up. */
|
||||
sessionId: string | null;
|
||||
protocol: "rdp" | "vnc" | "telnet";
|
||||
tabInstanceId?: string;
|
||||
}
|
||||
|
||||
const MODIFIER_KEYSYMS = {
|
||||
@@ -140,6 +154,7 @@ export const GuacamoleToolbar: React.FC<GuacamoleToolbarProps> = ({
|
||||
zoom = 1,
|
||||
onHide,
|
||||
metaKeyFamily,
|
||||
slotContext,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const meta = metaKeyLabels(
|
||||
@@ -574,6 +589,16 @@ export const GuacamoleToolbar: React.FC<GuacamoleToolbarProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{slotContext && (
|
||||
<ActionSlot
|
||||
slotId={REMOTE_DESKTOP_TOOLBAR_SLOT}
|
||||
className={cn(BTN_ICON)}
|
||||
hideLabels
|
||||
when={{ ...slotContext }}
|
||||
context={() => [slotContext]}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Collapse */}
|
||||
<div className="w-px h-5 bg-border mx-0.5 shrink-0" />
|
||||
<Tooltip>
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
} from "./HostEditorGuacamoleTabs";
|
||||
import { getGuacamoleTokenFromHost } from "./guacamole-api";
|
||||
import { quickConnectGuacHost } from "./quick-connect-guac-host";
|
||||
import { REMOTE_DESKTOP_TOOLBAR_SLOT } from "./GuacamoleToolbar.tsx";
|
||||
|
||||
type Protocol = "rdp" | "vnc" | "telnet";
|
||||
|
||||
@@ -220,6 +221,12 @@ export function activate(app: TermixApp): void {
|
||||
});
|
||||
if (app.guest) return;
|
||||
|
||||
// The share button lives here, contributed by session sharing.
|
||||
app.declareActionSlot({
|
||||
id: REMOTE_DESKTOP_TOOLBAR_SLOT,
|
||||
accepts: ["button"],
|
||||
});
|
||||
|
||||
// Mints a token for presenting a host in a collab room.
|
||||
app.registerAction(
|
||||
"session.remoteDisplay.token",
|
||||
|
||||
@@ -4,7 +4,8 @@ import { describe, expect, it, vi } from "vitest";
|
||||
import { GuacamoleToolbar } from "../../src/frontend/GuacamoleToolbar.js";
|
||||
import type { GuacamoleDisplayHandle } from "../../src/frontend/GuacamoleDisplay.js";
|
||||
|
||||
vi.mock("react-i18next", () => ({
|
||||
vi.mock("react-i18next", async (importOriginal) => ({
|
||||
...(await importOriginal<typeof import("react-i18next")>()),
|
||||
useTranslation: () => ({ t: (key: string) => key }),
|
||||
}));
|
||||
|
||||
|
||||
Reference in new issue
Block a user