From 21c90c6224e35af2d79eac612d4e85335d180114 Mon Sep 17 00:00:00 2001 From: Josue Date: Wed, 21 Jul 2021 17:59:04 -0400 Subject: [PATCH] feat(front-end): add a fetcher with timeout and controlls to reconnect to the server --- striker-ui/components/Display/FullSize.tsx | 168 +++++++++++------- .../lib/fetchers/putFetchWithTimeout.ts | 25 +++ 2 files changed, 128 insertions(+), 65 deletions(-) create mode 100644 striker-ui/lib/fetchers/putFetchWithTimeout.ts diff --git a/striker-ui/components/Display/FullSize.tsx b/striker-ui/components/Display/FullSize.tsx index 07317905..b52f9c29 100644 --- a/striker-ui/components/Display/FullSize.tsx +++ b/striker-ui/components/Display/FullSize.tsx @@ -1,6 +1,6 @@ import { useState, useRef, useEffect, Dispatch, SetStateAction } from 'react'; import { RFB } from 'novnc-node'; -import { Box, Menu, MenuItem, Typography } from '@material-ui/core'; +import { Box, Menu, MenuItem, Typography, Button } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; import CloseIcon from '@material-ui/icons/Close'; import KeyboardIcon from '@material-ui/icons/Keyboard'; @@ -9,7 +9,8 @@ import VncDisplay from './VncDisplay'; import { Panel } from '../Panels'; import { BLACK, RED, TEXT } from '../../lib/consts/DEFAULT_THEME'; import keyCombinations from './keyCombinations'; -import putJSON from '../../lib/fetchers/putJSON'; +import putFetch from '../../lib/fetchers/putFetch'; +import putFetchWithTimeout from '../../lib/fetchers/putFetchWithTimeout'; import { HeaderText } from '../Text'; import Spinner from '../Spinner'; @@ -54,6 +55,9 @@ const useStyles = makeStyles(() => ({ backgroundColor: TEXT, }, }, + buttonText: { + color: BLACK, + }, })); interface PreviewProps { @@ -74,6 +78,7 @@ const FullSize = ({ setMode, uuid, serverName }: PreviewProps): JSX.Element => { const [vncConnection, setVncConnection] = useState< VncConnectionProps | undefined >(undefined); + const [isError, setIsError] = useState(false); const [displaySize] = useState<{ width: string; height: string; @@ -87,23 +92,28 @@ const FullSize = ({ setMode, uuid, serverName }: PreviewProps): JSX.Element => { if (!vncConnection) (async () => { - const res = await putJSON( - `${process.env.NEXT_PUBLIC_API_URL}/manage_vnc_pipes`, - { - server_uuid: uuid, - is_open: true, - }, - ); - setVncConnection(await res.json()); + try { + const res = await putFetchWithTimeout( + `${process.env.NEXT_PUBLIC_API_URL}/manage_vnc_pipes`, + { + server_uuid: uuid, + is_open: true, + }, + 120000, + ); + setVncConnection(await res.json()); + } catch { + setIsError(true); + } })(); - }, [uuid, vncConnection]); + }, [uuid, vncConnection, isError]); const handleClick = (event: React.MouseEvent): void => { setAnchorEl(event.currentTarget); }; const handleClickClose = async () => { - await putJSON(`${process.env.NEXT_PUBLIC_API_URL}/manage_vnc_pipes`, { + await putFetch(`${process.env.NEXT_PUBLIC_API_URL}/manage_vnc_pipes`, { server_uuid: uuid, is_open: false, }); @@ -135,63 +145,91 @@ const FullSize = ({ setMode, uuid, serverName }: PreviewProps): JSX.Element => { {vncConnection ? ( - - - + <> + + + + + + { + handleClickClose(); + setMode(true); + }} + > + + + + + + + + setAnchorEl(null)} + > + {keyCombinations.map(({ keys, scans }) => { + return ( + handleSendKeys(scans)} + className={classes.keysItem} + key={keys} + > + {keys} + + ); + })} + + + + ) : ( - - - - )} - - - { - handleClickClose(); - setMode(true); - }} - > - - - - - - - - setAnchorEl(null)} - > - {keyCombinations.map(({ keys, scans }) => { - return ( - handleSendKeys(scans)} - className={classes.keysItem} - key={keys} + {!isError ? ( + <> + + + + + ) : ( + <> + + + + + Reconnect + + + + )} - + )} ); diff --git a/striker-ui/lib/fetchers/putFetchWithTimeout.ts b/striker-ui/lib/fetchers/putFetchWithTimeout.ts new file mode 100644 index 00000000..6f58d034 --- /dev/null +++ b/striker-ui/lib/fetchers/putFetchWithTimeout.ts @@ -0,0 +1,25 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +const putFetchTimeout = async ( + uri: string, + data: T, + timeout: number, +): Promise => { + const controller = new AbortController(); + + const id = setTimeout(() => controller.abort(), timeout); + + const res = await fetch(uri, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + 'Keep-Alive': 'timeout=120', + }, + signal: controller.signal, + body: JSON.stringify(data), + }); + clearTimeout(id); + + return res; +}; + +export default putFetchTimeout;