Handle connecting to websocket instance

Very beta code for handling sockets
This commit is contained in:
Dane Everitt 2019-06-29 16:14:32 -07:00
parent 6618a124e7
commit f0ca8bc3a3
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
15 changed files with 297 additions and 30 deletions

View file

@ -9,7 +9,7 @@ import { Link } from 'react-router-dom';
export default () => (
<div className={'my-10'}>
<Link to={'/server/123'} className={'flex no-underline text-neutral-200 cursor-pointer items-center bg-neutral-700 p-4 border border-transparent hover:border-neutral-500'}>
<Link to={'/server/e9d6c836'} className={'flex no-underline text-neutral-200 cursor-pointer items-center bg-neutral-700 p-4 border border-transparent hover:border-neutral-500'}>
<div className={'rounded-full bg-neutral-500 p-3'}>
<FontAwesomeIcon icon={faServer}/>
</div>

View file

@ -0,0 +1,6 @@
import React from 'react';
import classNames from 'classnames';
export default ({ large }: { large?: boolean }) => (
<div className={classNames('spinner-circle spinner-white', { 'spinner-lg': large })}/>
);

View file

@ -1,6 +1,7 @@
import React from 'react';
import classNames from 'classnames';
import { CSSTransition } from 'react-transition-group';
import Spinner from '@/components/elements/Spinner';
export default ({ large, visible }: { visible: boolean; large?: boolean }) => (
<CSSTransition timeout={150} classNames={'fade'} in={visible} unmountOnExit={true}>
@ -8,7 +9,7 @@ export default ({ large, visible }: { visible: boolean; large?: boolean }) => (
className={classNames('absolute pin-t pin-l flex items-center justify-center w-full h-full rounded')}
style={{ background: 'rgba(0, 0, 0, 0.45)' }}
>
<div className={classNames('spinner-circle spinner-white', { 'spinner-lg': large })}></div>
<Spinner large={large}/>
</div>
</CSSTransition>
);

View file

@ -0,0 +1,71 @@
import React, { createRef, useEffect, useRef } from 'react';
import { Terminal } from 'xterm';
import * as TerminalFit from 'xterm/lib/addons/fit/fit';
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
const theme = {
background: 'transparent',
cursor: 'transparent',
black: '#000000',
red: '#E54B4B',
green: '#9ECE58',
yellow: '#FAED70',
blue: '#396FE2',
magenta: '#BB80B3',
cyan: '#2DDAFD',
white: '#d0d0d0',
brightBlack: 'rgba(255, 255, 255, 0.2)',
brightRed: '#FF5370',
brightGreen: '#C3E88D',
brightYellow: '#FFCB6B',
brightBlue: '#82AAFF',
brightMagenta: '#C792EA',
brightCyan: '#89DDFF',
brightWhite: '#ffffff',
};
export default () => {
const ref = createRef<HTMLDivElement>();
const terminal = useRef(new Terminal({
disableStdin: true,
cursorStyle: 'underline',
allowTransparency: true,
fontSize: 12,
fontFamily: 'Menlo, Monaco, Consolas, monospace',
rows: 30,
theme: theme,
}));
useEffect(() => {
ref.current && terminal.current.open(ref.current);
// @see https://github.com/xtermjs/xterm.js/issues/2265
// @see https://github.com/xtermjs/xterm.js/issues/2230
TerminalFit.fit(terminal.current);
terminal.current.writeln('Testing console data');
terminal.current.writeln('Testing other data');
}, []);
return (
<div className={'text-xs font-mono relative'}>
<SpinnerOverlay visible={true} large={true}/>
<div
className={'rounded-t p-2 bg-black overflow-scroll w-full'}
style={{
minHeight: '16rem',
maxHeight: '64rem',
}}
>
<div id={'terminal'} ref={ref}/>
</div>
<div className={'rounded-b bg-neutral-900 text-neutral-100 flex'}>
<div className={'flex-no-shrink p-2 font-bold'}>$</div>
<div className={'w-full'}>
<input type={'text'} className={'bg-transparent text-neutral-100 p-2 pl-0 w-full'}/>
</div>
</div>
</div>
);
};

View file

@ -1,7 +1,13 @@
import React from 'react';
import Console from '@/components/server/Console';
export default () => (
<div className={'my-10'}>
Test
<div className={'my-10 flex'}>
<div className={'mx-4 w-3/4 mr-4'}>
<Console/>
</div>
<div className={'flex-1 ml-4'}>
<p>Testing</p>
</div>
</div>
);

View file

@ -0,0 +1,34 @@
import React, { useEffect } from 'react';
import { Actions, State, useStoreActions, useStoreState } from 'easy-peasy';
import { ApplicationState } from '@/state/types';
import Sockette from 'sockette';
export default () => {
const server = useStoreState((state: State<ApplicationState>) => state.server.data);
const instance = useStoreState((state: State<ApplicationState>) => state.server.socket.instance);
const setInstance = useStoreActions((actions: Actions<ApplicationState>) => actions.server.socket.setInstance);
const setConnectionState = useStoreActions((actions: Actions<ApplicationState>) => actions.server.socket.setConnectionState);
useEffect(() => {
// If there is already an instance or there is no server, just exit out of this process
// since we don't need to make a new connection.
if (instance || !server) {
return;
}
console.log('need to connect to instance');
const socket = new Sockette(`wss://wings.pterodactyl.test:8080/api/servers/${server.uuid}/ws`, {
protocols: 'CC8kHCuMkXPosgzGO6d37wvhNcksWxG6kTrA',
// onmessage: (ev) => console.log(ev),
onopen: () => setConnectionState(true),
onclose: () => setConnectionState(false),
onerror: () => setConnectionState(false),
});
console.log('Setting instance!');
setInstance(socket);
}, [server]);
return null;
};