Local modifications to ClusterLabs/Anvil by Alteeve
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

150 lines
3.1 KiB

import RFB from '@novnc/novnc/core/rfb';
import Websock from '@novnc/novnc/core/websock';
import { useEffect } from 'react';
const rfbConnect: RfbConnectFunction = ({
background = '',
clipViewport = false,
compressionLevel = 2,
dragViewport = false,
focusOnClick = false,
onConnect,
onDisconnect,
onWsClose,
onWsError,
qualityLevel = 6,
resizeSession = true,
rfb,
rfbScreen,
scaleViewport = true,
showDotCursor = false,
url,
viewOnly = false,
}) => {
if (!rfbScreen?.current || rfb?.current) return;
rfbScreen.current.innerHTML = '';
rfb.current = new RFB(rfbScreen.current, url);
rfb.current.background = background;
rfb.current.clipViewport = clipViewport;
rfb.current.compressionLevel = compressionLevel;
rfb.current.dragViewport = dragViewport;
rfb.current.focusOnClick = focusOnClick;
rfb.current.qualityLevel = qualityLevel;
rfb.current.resizeSession = resizeSession;
rfb.current.scaleViewport = scaleViewport;
rfb.current.showDotCursor = showDotCursor;
rfb.current.viewOnly = viewOnly;
// RFB extends custom class EventTargetMixin;
// the usual .on or .once doesn't exist.
if (onConnect) {
rfb.current.addEventListener('connect', onConnect);
}
if (onDisconnect) {
rfb.current.addEventListener('disconnect', onDisconnect);
}
/* eslint-disable no-underscore-dangle */
const ws: typeof Websock = rfb.current._sock;
const socketClose = ws._eventHandlers.close;
const socketError = ws._eventHandlers.error;
ws.on('close', (e?: WebsockCloseEvent) => {
socketClose(e);
onWsClose?.call(null, e);
});
ws.on('error', (e: Event) => {
socketError(e);
onWsError?.call(null, e);
});
/* eslint-enable no-underscore-dangle */
};
const rfbDisconnect: RfbDisconnectFunction = (rfb) => {
if (!rfb?.current) return;
rfb.current.disconnect();
rfb.current = null;
};
const VncDisplay = (props: VncDisplayProps): JSX.Element => {
const {
onConnect,
onDisconnect,
onWsClose,
onWsError,
rfb,
rfbConnectArgs,
rfbScreen,
url: initUrl,
} = props;
useEffect(() => {
if (rfbConnectArgs) {
const { url = initUrl } = rfbConnectArgs;
if (!url) return;
const args: RfbConnectArgs = {
onConnect,
onDisconnect,
onWsClose,
onWsError,
rfb,
rfbScreen,
url,
...rfbConnectArgs,
};
rfbConnect(args);
} else {
rfbDisconnect(rfb);
}
}, [
initUrl,
onConnect,
onDisconnect,
onWsClose,
onWsError,
rfb,
rfbConnectArgs,
rfbScreen,
]);
useEffect(
() => () => {
rfbDisconnect(rfb);
},
[rfb],
);
const handleMouseEnter = () => {
if (
document.activeElement &&
document.activeElement instanceof HTMLElement
) {
document.activeElement.blur();
}
if (rfb?.current) rfb.current.focus();
};
return (
<div
style={{ width: '100%', height: '75vh' }}
ref={rfbScreen}
onMouseEnter={handleMouseEnter}
/>
);
};
VncDisplay.displayName = 'VncDisplay';
export default VncDisplay;