Skip to content

Commit

Permalink
fix(forwardRef): forward connect(), disconnect() and connected from V…
Browse files Browse the repository at this point in the history
…ncScreen (#20)

* fix(forwardRef): forward connect(), disconnect() and connected from VncScreen

* fix(build): fix failing builds

* ci(build): run build:lib alongside build script
  • Loading branch information
roerohan authored Feb 19, 2022
1 parent 793907c commit 9392ab3
Show file tree
Hide file tree
Showing 8 changed files with 628 additions and 324 deletions.
1 change: 1 addition & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ jobs:
run: |
npm install
npm run build
npm run build:lib
847 changes: 545 additions & 302 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 12 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,15 @@
"author": "roerohan",
"license": "MIT",
"main": "dist/index.js",
"module": "dist/index.es.js",
"source": "src/lib/index.tsx",
"typings": "dist/types/lib/index.d.ts",
"exports": {
".": {
"import": "./dist/index.es.js",
"require": "./dist/index.js"
}
},
"keywords": [
"vnc",
"noVNC",
Expand All @@ -32,7 +39,6 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
"typescript": "^4.2.4",
"web-vitals": "^1.1.1"
},
"scripts": {
Expand All @@ -42,11 +48,12 @@
"eject": "react-scripts eject",
"build:lib": "rollup -c",
"lint": "eslint . --ext .ts --ext .js",
"lint:fix": "eslint . --ext .ts --ext .js --fix",
"lint:fix": "npm run lint -- --fix",
"prepare": "is-ci || husky install",
"prepack": "npm run build:lib",
"prepublishOnly": "cp package.json package.json.bak && node prepublish.js",
"postpublish": "mv package.json.bak package.json"
"postpublish": "mv package.json.bak package.json",
"submodule": "git submodule update --init --recursive"
},
"eslintConfig": {
"extends": [
Expand Down Expand Up @@ -80,7 +87,8 @@
"is-ci": "^2.0.0",
"rollup": "^2.44.0",
"rollup-plugin-typescript2": "^0.30.0",
"semantic-release": "^18.0.0"
"semantic-release": "^18.0.0",
"typescript": "^4.5.5"
},
"commitlint": {
"extends": [
Expand Down
3 changes: 2 additions & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ const config = {
input: pkg.source,
output: [
{ file: pkg.main, format: 'cjs' },
{ file: pkg.module, format: 'es' },
],
plugins: [typescript({ tsconfig: './tsconfig.json', useTsconfigDeclarationDir: true })],
external: Object.keys(pkg.peerDependencies || {}),
external: Object.keys(pkg.peerDependencies ?? {}),
};

export default config;
19 changes: 18 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { useState } from 'react';
import React, { useRef, useState } from 'react';
import './App.css';
import { VncScreen } from './lib';

function App() {
const [vncUrl, setVncUrl] = useState('');
const [inputUrl, setInputUrl] = useState('');
const vncScreenRef = useRef<React.ElementRef<typeof VncScreen>>(null);

const isValid = (vncUrl: string) => {
if (!vncUrl.startsWith('ws://') && !vncUrl.startsWith('wss://')) {
Expand Down Expand Up @@ -36,6 +37,21 @@ function App() {
To test a `ws://` URL, clone the application and run it on http://localhost:3000, or <a href="https://experienceleague.adobe.com/docs/target/using/experiences/vec/troubleshoot-composer/mixed-content.html?lang=en#task_5448763B8DC941FD80F84041AEF0A14D">enable Mixed Content on your browser</a>.
</div>

<div style={{ margin: '1rem' }}>
<button
onClick={() => {
const { connect, connected, disconnect } = vncScreenRef.current ?? {};
if (connected) {
disconnect?.();
return;
}
connect?.();
}}
>
Connect / Disconnect
</button>
</div>

<div style={{ margin: '1rem' }}>
{
isValid(vncUrl)
Expand All @@ -50,6 +66,7 @@ function App() {
height: '75vh',
}}
debug
ref={vncScreenRef}
/>
)
: <div>VNC URL not provided.</div>
Expand Down
57 changes: 42 additions & 15 deletions src/lib/VncScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import React, { useEffect, useRef, useState } from 'react';
import React, {
forwardRef,
useEffect,
useImperativeHandle,
useRef,
useState,
} from 'react';
import RFB from '../noVNC/core/rfb';

interface Props {
export interface Props {
url: string;
style?: object;
className?: string;
Expand All @@ -19,8 +25,15 @@ interface Props {
debug?: boolean;
}

export default function VncScreen(props: Props) {
export type VncScreenHandle = {
connect: () => void;
disconnect: () => void;
connected: boolean;
};

const VncScreen: React.ForwardRefRenderFunction<VncScreenHandle, Props> = (props, ref) => {
const [rfb, setRfb] = useState<RFB | null>(null);
const [connected, setConnected] = useState<boolean>(false);
const screen = useRef<HTMLDivElement>(null);
const [loading, setLoading] = useState<boolean>(true);

Expand Down Expand Up @@ -55,6 +68,7 @@ export default function VncScreen(props: Props) {

rfb.disconnect();
setRfb(null);
setConnected(false);
};

const connect = () => {
Expand All @@ -69,16 +83,16 @@ export default function VncScreen(props: Props) {

const _rfb = new RFB(screen.current, url);

_rfb.viewOnly = viewOnly || false;
_rfb.focusOnClick = focusOnClick || false;
_rfb.clipViewport = clipViewport || false;
_rfb.dragViewport = dragViewport || false;
_rfb.resizeSession = resizeSession || false;
_rfb.scaleViewport = scaleViewport || false;
_rfb.showDotCursor = showDotCursor || false;
_rfb.background = background || '';
_rfb.qualityLevel = qualityLevel || 6;
_rfb.compressionLevel = compressionLevel || 2;
_rfb.viewOnly = viewOnly ?? false;
_rfb.focusOnClick = focusOnClick ?? false;
_rfb.clipViewport = clipViewport ?? false;
_rfb.dragViewport = dragViewport ?? false;
_rfb.resizeSession = resizeSession ?? false;
_rfb.scaleViewport = scaleViewport ?? false;
_rfb.showDotCursor = showDotCursor ?? false;
_rfb.background = background ?? '';
_rfb.qualityLevel = qualityLevel ?? 6;
_rfb.compressionLevel = compressionLevel ?? 2;
setRfb(_rfb);

_rfb.addEventListener('connect', () => {
Expand All @@ -87,8 +101,11 @@ export default function VncScreen(props: Props) {
});

_rfb.addEventListener('disconnect', () => {
logger.info(`Disconnected from remote VNC, retrying in ${retryDuration / 1000} seconds.`);
setTimeout(connect, retryDuration);
if (connected) {
logger.info(`Unexpectedly disconnected from remote VNC, retrying in ${retryDuration / 1000} seconds.`);
setTimeout(connect, retryDuration);
}
logger.info(`Disconnected from remote VNC.`);
setLoading(true);
});

Expand All @@ -100,11 +117,19 @@ export default function VncScreen(props: Props) {
_rfb.addEventListener('desktopname', (e: { detail: { name: string } }) => {
logger.info(`Desktop name is ${e.detail.name}`);
});

setConnected(true);
} catch (err) {
logger.error(err);
}
};

useImperativeHandle(ref, () => ({
connect,
disconnect,
connected,
}));

useEffect(() => {
connect();

Expand Down Expand Up @@ -147,3 +172,5 @@ export default function VncScreen(props: Props) {
</>
);
}

export default forwardRef(VncScreen);
7 changes: 7 additions & 0 deletions src/lib/index.tsx
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
import VncScreen from './VncScreen';
import type {
VncScreenHandle as IVncScreenHandle,
Props as IVncScreenProps,
} from './VncScreen';

export { VncScreen };
export type VncScreenHandle = IVncScreenHandle;
export type VncScreenProps = IVncScreenProps;
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "es5",
"target": "es6",
"lib": [
"dom",
"dom.iterable",
Expand Down

0 comments on commit 9392ab3

Please sign in to comment.