Attempting to solve a weird console loading issue by making into class component; doesn't fix but like the class better for this.

Loading the console, switching to file manager, and then switching back is needed to load the data the first time. After that every 2nd load of the console will load the data (and even send the data to the websocket as the daemon is reporting.)
This commit is contained in:
Dane Everitt 2019-06-29 18:28:23 -07:00
parent 6b42296865
commit 16e6f3f45f
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
4 changed files with 125 additions and 65 deletions

View file

@ -19,6 +19,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-hot-loader": "^4.9.0",
"react-redux": "^7.1.0",
"react-router-dom": "^5.0.1",
"react-transition-group": "^4.1.0",
"socket.io-client": "^2.2.0",
@ -42,6 +43,7 @@
"@types/query-string": "^6.3.0",
"@types/react": "^16.8.19",
"@types/react-dom": "^16.8.4",
"@types/react-redux": "^7.1.1",
"@types/react-router-dom": "^4.3.3",
"@types/react-transition-group": "^2.9.2",
"@types/webpack-env": "^1.13.6",

View file

@ -6,6 +6,7 @@ import { store } from '@/state';
import DashboardRouter from '@/routers/DashboardRouter';
import ServerRouter from '@/routers/ServerRouter';
import AuthenticationRouter from '@/routers/AuthenticationRouter';
import { Provider } from 'react-redux';
interface WindowWithUser extends Window {
PterodactylUser?: {
@ -37,6 +38,7 @@ const App = () => {
return (
<StoreProvider store={store}>
<Provider store={store}>
<Router basename={'/'}>
<div className={'mx-auto w-auto'}>
<BrowserRouter basename={'/'}>
@ -48,6 +50,7 @@ const App = () => {
</BrowserRouter>
</div>
</Router>
</Provider>
</StoreProvider>
);
};

View file

@ -1,9 +1,10 @@
import React, { createRef, useEffect, useRef } from 'react';
import React, { createRef } from 'react';
import { Terminal } from 'xterm';
import * as TerminalFit from 'xterm/lib/addons/fit/fit';
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
import { State, useStoreState } from 'easy-peasy';
import { ApplicationState } from '@/state/types';
import { connect } from 'react-redux';
import { Websocket } from '@/plugins/Websocket';
const theme = {
background: 'transparent',
@ -26,11 +27,14 @@ const theme = {
brightWhite: '#ffffff',
};
export default () => {
const { instance, connected } = useStoreState((state: State<ApplicationState>) => state.server.socket);
interface Props {
connected: boolean;
instance: Websocket | null;
}
const ref = createRef<HTMLDivElement>();
const terminal = useRef(new Terminal({
class Console extends React.PureComponent<Readonly<Props>> {
ref = createRef<HTMLDivElement>();
terminal = new Terminal({
disableStdin: true,
cursorStyle: 'underline',
allowTransparency: true,
@ -38,40 +42,56 @@ export default () => {
fontFamily: 'Menlo, Monaco, Consolas, monospace',
rows: 30,
theme: theme,
}));
const handleServerLog = (lines: string[]) => lines.forEach(data => {
return data.split(/\n/g).forEach(line => terminal.current.writeln(line + '\u001b[0m'));
});
const handleConsoleOutput = (line: string) => terminal.current.writeln(line.replace(/(?:\r\n|\r|\n)$/im, '') + '\u001b[0m');
useEffect(() => {
ref.current && terminal.current.open(ref.current);
componentDidMount () {
if (this.ref.current) {
this.terminal.open(this.ref.current);
this.terminal.clear();
// @see https://github.com/xtermjs/xterm.js/issues/2265
// @see https://github.com/xtermjs/xterm.js/issues/2230
TerminalFit.fit(terminal.current);
}, []);
TerminalFit.fit(this.terminal);
}
useEffect(() => {
if (connected && instance) {
instance.addListener('server log', handleServerLog);
instance.addListener('console output', handleConsoleOutput);
if (this.props.connected && this.props.instance) {
this.listenForEvents();
}
}
componentDidUpdate (prevProps: Readonly<Readonly<Props>>) {
if (!prevProps.connected && this.props.connected) {
this.listenForEvents();
}
}
componentWillUnmount () {
if (this.props.instance) {
this.props.instance.removeListener('server log', this.handleServerLog);
this.props.instance.removeListener('server log', this.handleConsoleOutput);
}
}
listenForEvents () {
const instance = this.props.instance!;
instance.addListener('server log', this.handleServerLog);
instance.addListener('console output', this.handleConsoleOutput);
instance.send('send logs');
}
}, [connected]);
useEffect(() => () => {
if (instance) {
instance.removeListener('server log', handleServerLog);
instance.removeListener('console output', handleConsoleOutput);
}
}, []);
handleServerLog = (lines: string[]) => lines.forEach(data => {
return data.split(/\n/g).forEach(line => this.terminal.writeln(line + '\u001b[0m'));
});
handleConsoleOutput = (line: string) => this.terminal.writeln(
line.replace(/(?:\r\n|\r|\n)$/im, '') + '\u001b[0m'
);
render () {
return (
<div className={'text-xs font-mono relative'}>
<SpinnerOverlay visible={!connected} large={true}/>
<SpinnerOverlay visible={!this.props.connected} large={true}/>
<div
className={'rounded-t p-2 bg-black overflow-scroll w-full'}
style={{
@ -79,7 +99,7 @@ export default () => {
maxHeight: '64rem',
}}
>
<div id={'terminal'} ref={ref}/>
<div id={'terminal'} ref={this.ref}/>
</div>
<div className={'rounded-b bg-neutral-900 text-neutral-100 flex'}>
<div className={'flex-no-shrink p-2 font-bold'}>$</div>
@ -89,4 +109,12 @@ export default () => {
</div>
</div>
);
};
}
}
export default connect(
(state: ApplicationState) => ({
connected: state.server.socket.connected,
instance: state.server.socket.instance,
}),
)(Console);

View file

@ -605,7 +605,7 @@
"@babel/plugin-transform-react-jsx-self" "^7.0.0"
"@babel/plugin-transform-react-jsx-source" "^7.0.0"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.4.0":
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.5":
version "7.4.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12"
dependencies:
@ -778,6 +778,13 @@
version "4.7.2"
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.2.tgz#0e670ea254d559241b6eeb3894f8754991e73220"
"@types/hoist-non-react-statics@^3.3.0":
version "3.3.1"
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
dependencies:
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
"@types/lodash@^4.14.119":
version "4.14.119"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.119.tgz#be847e5f4bc3e35e46d041c394ead8b603ad8b39"
@ -798,6 +805,15 @@
dependencies:
"@types/react" "*"
"@types/react-redux@^7.1.1":
version "7.1.1"
resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.1.tgz#eb01e89cf71cad77df9f442b819d5db692b997cb"
dependencies:
"@types/hoist-non-react-statics" "^3.3.0"
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
redux "^4.0.0"
"@types/react-router-dom@^4.3.3":
version "4.3.3"
resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-4.3.3.tgz#7837e3e9fefbc84a8f6c8a51dca004f4e83e94e3"
@ -3966,7 +3982,7 @@ interpret@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
invariant@^2.2.0, invariant@^2.2.2:
invariant@^2.2.0, invariant@^2.2.2, invariant@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
dependencies:
@ -6094,7 +6110,7 @@ promise@^7.1.1:
dependencies:
asap "~2.0.3"
prop-types@^15.5.10, prop-types@^15.6.1, prop-types@^15.6.2:
prop-types@^15.5.10, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
dependencies:
@ -6272,7 +6288,7 @@ react-hot-loader@^4.9.0:
shallowequal "^1.0.2"
source-map "^0.7.3"
react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1:
react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6:
version "16.8.6"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
@ -6280,6 +6296,17 @@ react-lifecycles-compat@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
react-redux@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.1.0.tgz#72af7cf490a74acdc516ea9c1dd80e25af9ea0b2"
dependencies:
"@babel/runtime" "^7.4.5"
hoist-non-react-statics "^3.3.0"
invariant "^2.2.4"
loose-envify "^1.4.0"
prop-types "^15.7.2"
react-is "^16.8.6"
react-router-dom@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.0.1.tgz#ee66f4a5d18b6089c361958e443489d6bab714be"
@ -6408,7 +6435,7 @@ redux-thunk@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622"
redux@^4.0.1:
redux@^4.0.0, redux@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.1.tgz#436cae6cc40fbe4727689d7c8fae44808f1bfef5"
dependencies: