import { useCallback, useEffect, useState } from "react"; import { SquareTerminal } from "lucide-react"; import { invokeAction, useHosts, usePermission, useTranslation, type PluginHostRecord, } from "@termix/plugin-sdk/frontend"; import { Badge, Button } from "@termix/plugin-sdk/ui"; import { getSharedWithMe } from "./api"; const POLL_MS = 15_000; interface SharedSession { sessionId: string; hostId: number; hostName: string; isConnected: boolean; sharedByUsername: string | null; permissionLevel: string | null; shareId: string | null; } function isSharedSession(value: unknown): value is SharedSession { const row = value as Partial | null; return ( !!row && typeof row.sessionId === "string" && typeof row.hostName === "string" ); } /** * The active connections list's "Shared with me" section: live sessions other * users shared with this one, each joinable in a terminal tab. */ export function SharedWithMeSection({ search = "", openTabData = [], }: { search?: string; openTabData?: Array>; }) { const { t } = useTranslation(); const { hosts } = useHosts(); const allowed = usePermission("use"); const [sessions, setSessions] = useState([]); const load = useCallback(() => { if (!allowed) return; getSharedWithMe() .then((rows) => setSessions(rows.filter(isSharedSession))) .catch(() => setSessions([])); }, [allowed]); useEffect(() => { load(); const timer = window.setInterval(load, POLL_MS); return () => window.clearInterval(timer); }, [load]); const joined = new Set( openTabData .map((data) => data.joinSharedSessionId) .filter((id): id is string => typeof id === "string"), ); const q = search.trim().toLowerCase(); const visible = sessions.filter( (session) => !joined.has(session.sessionId) && (!q || session.hostName.toLowerCase().includes(q) || (session.sharedByUsername ?? "").toLowerCase().includes(q)), ); if (!allowed || visible.length === 0) return null; const join = (session: SharedSession) => { if (!session.shareId) return; const host: PluginHostRecord = hosts.find( (candidate) => String(candidate.id) === String(session.hostId), ) ?? { id: String(session.hostId), name: session.hostName, ip: "", port: 0, username: "", }; void invokeAction("terminal.open", host, { joinSharedSessionId: session.sessionId, joinShareId: session.shareId, label: t("connections.sharedSessionLabel", { hostName: session.hostName, }), }); }; return (
{t("connections.sectionSharedWithMe")} {visible.length}
{visible.map((session) => { const readWrite = session.permissionLevel === "read-write"; return (
{session.hostName} {readWrite ? t("sessionSharing.permissionLevel.readWrite") : t("sessionSharing.permissionLevel.readOnly")}
{t("connections.sharedBy", { username: session.sharedByUsername ?? "?", })}
); })}
); }