From a2652c5265db7276f76a7c58afdd573e73d8a1c1 Mon Sep 17 00:00:00 2001 From: Adam Shiervani Date: Tue, 25 Feb 2025 23:34:25 +0100 Subject: [PATCH] feat(ui): Add other session handling route and modal --- ui/src/components/Modal.tsx | 11 +++-- ui/src/main.tsx | 18 ++++++++- ui/src/routes/devices.$id.other-session.tsx | 45 +++++++++++++++++++++ ui/src/routes/devices.$id.tsx | 34 ++++++++-------- 4 files changed, 84 insertions(+), 24 deletions(-) create mode 100644 ui/src/routes/devices.$id.other-session.tsx diff --git a/ui/src/components/Modal.tsx b/ui/src/components/Modal.tsx index 886469d..438aa5a 100644 --- a/ui/src/components/Modal.tsx +++ b/ui/src/components/Modal.tsx @@ -17,11 +17,11 @@ export default function Modal({
-
+
-
+
-
e.stopPropagation()}> +
e.stopPropagation()} + > {children}
diff --git a/ui/src/main.tsx b/ui/src/main.tsx index 69e3c7b..9b3599a 100644 --- a/ui/src/main.tsx +++ b/ui/src/main.tsx @@ -28,6 +28,7 @@ import WelcomeLocalModeRoute from "./routes/welcome-local.mode"; import WelcomeRoute from "./routes/welcome-local"; import WelcomeLocalPasswordRoute from "./routes/welcome-local.password"; import { CLOUD_API } from "./ui.config"; +import OtherSessionRoute from "./routes/devices.$id.other-session"; export const isOnDevice = import.meta.env.MODE === "device"; export const isInCloud = !isOnDevice; @@ -75,7 +76,14 @@ if (isOnDevice) { errorElement: , element: , loader: DeviceRoute.loader, + children: [ + { + path: "other-session", + element: , + }, + ], }, + { path: "/adopt", element: , @@ -116,6 +124,12 @@ if (isOnDevice) { path: "devices/:id", element: , loader: DeviceRoute.loader, + children: [ + { + path: "other-session", + element: , + }, + ], }, { path: "devices/:id/deregister", @@ -164,8 +178,8 @@ function ErrorBoundary() { } return ( -
-
+
+
Promise; +} + +export default function OtherSessionRoute() { + const outletContext = useOutletContext(); + const navigate = useNavigate(); + + // Function to handle closing the modal + const handleClose = () => { + outletContext?.connectWebRTC().then(() => navigate("..")); + }; + + return ( + +
+
+
+ + +
+ +
+

+ Another Active Session Detected +

+

+ Only one active session is supported at a time. Would you like to take over + this session? +

+
+
+
+
+
+
+ ); +} diff --git a/ui/src/routes/devices.$id.tsx b/ui/src/routes/devices.$id.tsx index bf589ef..d530e8c 100644 --- a/ui/src/routes/devices.$id.tsx +++ b/ui/src/routes/devices.$id.tsx @@ -16,10 +16,12 @@ import { import WebRTCVideo from "@components/WebRTCVideo"; import { LoaderFunctionArgs, + Outlet, Params, redirect, useLoaderData, useNavigate, + useOutlet, useParams, useSearchParams, } from "react-router-dom"; @@ -34,9 +36,9 @@ import UpdateInProgressStatusCard from "../components/UpdateInProgressStatusCard import api from "../api"; import { DeviceStatus } from "./welcome-local"; import FocusTrap from "focus-trap-react"; -import OtherSessionConnectedModal from "@/components/OtherSessionConnectedModal"; import Terminal from "@components/Terminal"; import { CLOUD_API, DEVICE_API } from "@/ui.config"; +import Modal from "../components/Modal"; interface LocalLoaderResp { authMode: "password" | "noPassword" | null; @@ -131,9 +133,6 @@ export default function KvmIdRoute() { setModalView, } = useUpdateStore(); - const [isOtherSessionConnectedModalOpen, setIsOtherSessionConnectedModalOpen] = - useState(false); - const sdp = useCallback( async (event: RTCPeerConnectionIceEvent, pc: RTCPeerConnection) => { if (!pc) return; @@ -243,8 +242,7 @@ export default function KvmIdRoute() { ) { return; } - // We don't want to connect if another session is connected - if (isOtherSessionConnectedModalOpen) return; + if (location.pathname.includes("other-session")) return; connectWebRTC(); }, 3000); @@ -334,7 +332,7 @@ export default function KvmIdRoute() { function onJsonRpcRequest(resp: JsonRpcRequest) { if (resp.method === "otherSessionConnected") { console.log("otherSessionConnected", resp.params); - setIsOtherSessionConnectedModalOpen(true); + navigate("other-session"); } if (resp.method === "usbState") { @@ -445,6 +443,8 @@ export default function KvmIdRoute() { }; }, [kvmTerminal]); + const outlet = useOutlet(); + return ( <> @@ -486,18 +486,16 @@ export default function KvmIdRoute() {
- - { - if (!state) connectWebRTC().then(r => r); - // It takes some time for the WebRTC connection to be established, so we wait a bit before closing the modal - setTimeout(() => { - setIsOtherSessionConnectedModalOpen(state); - }, 1000); - }} - /> + location.pathname !== "/other-session" && navigate("..")} + > + + + + + {kvmTerminal && ( )}