import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import FullscreenIcon from "@mui/icons-material/Fullscreen"; import FullscreenExitIcon from "@mui/icons-material/FullscreenExit"; import KeyboardAltIcon from "@mui/icons-material/KeyboardAlt"; import { IconButton, Tooltip } from "@mui/material"; import React, { useEffect } from "react"; import { useNavigate, useParams } from "react-router-dom"; import { VncScreen, VncScreenHandle } from "react-vnc"; import { ServerApi } from "../api/ServerApi"; import { VMApi, VMInfo } from "../api/VMApi"; import { useSnackbar } from "../hooks/providers/SnackbarProvider"; import { time } from "../utils/DateUtils"; import { AsyncWidget } from "../widgets/AsyncWidget"; interface VNCTokenInfo { url: string; expire: number; } export function VNCRoute(): React.ReactElement { const { uuid } = useParams(); const [vm, setVM] = React.useState(); const load = async () => { setVM(await VMApi.GetSingle(uuid!)); }; return ( } /> ); } function VNCInner(p: { vm: VMInfo }): React.ReactElement { const snackbar = useSnackbar(); const navigate = useNavigate(); const [token, setToken] = React.useState(); const [counter, setCounter] = React.useState(1); const [connected, setConnected] = React.useState(false); const vncRef = React.useRef(null); const vncScreenRef = React.useRef(null); const connect = async (force: boolean) => { try { if (force) setCounter(counter + 1); // Check if getting new time is useless if ((token?.expire ?? 0) > time()) return; setToken(undefined); const u = await VMApi.OneShotVNCURL(p.vm); console.info("VNC URL", u); if (!token) setToken({ expire: time() + ServerApi.Config.constraints.vnc_token_duration, url: u, }); } catch (e) { console.error(e); snackbar("Failed to initialize VNC connection!"); } }; const disconnected = () => { setConnected(false); connect(true); }; const goBack = () => { navigate(p.vm.ViewURL); }; const goFullScreen = () => { if (vncRef.current) vncRef.current.requestFullscreen(); }; const exitFullScreen = () => { document.exitFullscreen(); }; useEffect(() => { connect(false); if (vncRef.current) { vncRef.current.onfullscreenchange = () => { setCounter(counter + 1); }; } }); if (token === undefined) return

Please wait, connecting to the machine...

; return (
{/* Controls */}
{/* Toggle fullscreen */} {!document.fullscreenElement ? ( ) : ( )} {/* Keystrokes */} {connected && ( vncScreenRef.current?.sendCtrlAltDel()}> )}
{/* Screen */}
{ console.info("VNC disconnected " + token.url); disconnected(); }} onConnect={() => { setConnected(true); }} />
); }