Skip to content

Commit 1ae3740

Browse files
committed
Still completely broken terminal...
1 parent 54339c1 commit 1ae3740

File tree

1 file changed

+56
-81
lines changed

1 file changed

+56
-81
lines changed
Lines changed: 56 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import React, { createRef } from 'react';
1+
import React, { createRef, useEffect } from 'react';
22
import { Terminal } from 'xterm';
33
import * as TerminalFit from 'xterm/lib/addons/fit/fit';
44
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
5-
import { connect } from 'react-redux';
6-
import { Websocket } from '@/plugins/Websocket';
7-
import { ServerStore } from '@/state/server';
5+
import { ServerContext } from '@/state/server';
86

97
const theme = {
108
background: 'transparent',
@@ -27,94 +25,71 @@ const theme = {
2725
brightWhite: '#ffffff',
2826
};
2927

30-
interface Props {
31-
connected: boolean;
32-
instance: Websocket | null;
33-
}
28+
const terminal = new Terminal({
29+
disableStdin: true,
30+
cursorStyle: 'underline',
31+
allowTransparency: true,
32+
fontSize: 12,
33+
fontFamily: 'Menlo, Monaco, Consolas, monospace',
34+
rows: 30,
35+
theme: theme,
36+
});
3437

35-
class Console extends React.PureComponent<Readonly<Props>> {
36-
ref = createRef<HTMLDivElement>();
37-
terminal = new Terminal({
38-
disableStdin: true,
39-
cursorStyle: 'underline',
40-
allowTransparency: true,
41-
fontSize: 12,
42-
fontFamily: 'Menlo, Monaco, Consolas, monospace',
43-
rows: 30,
44-
theme: theme,
45-
});
38+
export default () => {
39+
const ref = createRef<HTMLDivElement>();
40+
const connected = ServerContext.useStoreState(state => state.socket.connected);
41+
const instance = ServerContext.useStoreState(state => state.socket.instance);
4642

47-
componentDidMount () {
48-
if (this.ref.current) {
49-
this.terminal.open(this.ref.current);
50-
this.terminal.clear();
43+
const handleConsoleOutput = (line: string) => terminal.writeln(
44+
line.replace(/(?:\r\n|\r|\n)$/im, '') + '\u001b[0m',
45+
);
46+
47+
useEffect(() => {
48+
if (ref.current) {
49+
terminal.open(ref.current);
5150

5251
// @see https://github.com/xtermjs/xterm.js/issues/2265
5352
// @see https://github.com/xtermjs/xterm.js/issues/2230
54-
TerminalFit.fit(this.terminal);
53+
TerminalFit.fit(terminal);
5554
}
55+
}, [ ref.current ]);
5656

57-
if (this.props.connected && this.props.instance) {
58-
this.listenForEvents();
59-
}
60-
}
57+
useEffect(() => {
58+
if (connected && instance) {
59+
terminal.clear();
6160

62-
componentDidUpdate (prevProps: Readonly<Readonly<Props>>) {
63-
if (!prevProps.connected && this.props.connected) {
64-
this.listenForEvents();
65-
}
66-
}
61+
instance
62+
.addListener('stats', data => console.log(JSON.parse(data)))
63+
.addListener('console output', handleConsoleOutput);
6764

68-
componentWillUnmount () {
69-
if (this.props.instance) {
70-
this.props.instance.removeListener('server log', this.handleServerLog);
71-
this.props.instance.removeListener('server log', this.handleConsoleOutput);
65+
instance.send('send logs');
7266
}
73-
}
7467

75-
listenForEvents () {
76-
const instance = this.props.instance!;
68+
return () => {
69+
instance && instance
70+
.removeListener('console output', handleConsoleOutput)
71+
.removeAllListeners('stats');
72+
};
73+
}, [ connected, instance ]);
7774

78-
instance.addListener('server log', this.handleServerLog);
79-
instance.addListener('console output', this.handleConsoleOutput);
80-
instance.send('send logs');
81-
}
82-
83-
handleServerLog = (lines: string[]) => lines.forEach(data => {
84-
return data.split(/\n/g).forEach(line => this.terminal.writeln(line + '\u001b[0m'));
85-
});
86-
87-
handleConsoleOutput = (line: string) => this.terminal.writeln(
88-
line.replace(/(?:\r\n|\r|\n)$/im, '') + '\u001b[0m'
89-
);
90-
91-
render () {
92-
return (
93-
<div className={'text-xs font-mono relative'}>
94-
<SpinnerOverlay visible={!this.props.connected} size={'large'}/>
95-
<div
96-
className={'rounded-t p-2 bg-black overflow-scroll w-full'}
97-
style={{
98-
minHeight: '16rem',
99-
maxHeight: '64rem',
100-
}}
101-
>
102-
<div id={'terminal'} ref={this.ref}/>
103-
</div>
104-
<div className={'rounded-b bg-neutral-900 text-neutral-100 flex'}>
105-
<div className={'flex-no-shrink p-2 font-bold'}>$</div>
106-
<div className={'w-full'}>
107-
<input type={'text'} className={'bg-transparent text-neutral-100 p-2 pl-0 w-full'}/>
108-
</div>
75+
return (
76+
<div className={'text-xs font-mono relative'}>
77+
<SpinnerOverlay visible={!connected} size={'large'}/>
78+
<div
79+
className={'rounded-t p-2 bg-black overflow-scroll w-full'}
80+
style={{
81+
minHeight: '16rem',
82+
maxHeight: '64rem',
83+
}}
84+
>
85+
<div id={'terminal'} ref={ref}/>
86+
</div>
87+
<div className={'rounded-b bg-neutral-900 text-neutral-100 flex'}>
88+
<div className={'flex-no-shrink p-2 font-bold'}>$</div>
89+
<div className={'w-full'}>
90+
<input type={'text'} className={'bg-transparent text-neutral-100 p-2 pl-0 w-full'}/>
10991
</div>
11092
</div>
111-
);
112-
}
113-
}
114-
115-
export default connect(
116-
(state: ServerStore) => ({
117-
connected: state.socket.connected,
118-
instance: state.socket.instance,
119-
}),
120-
)(Console);
93+
</div>
94+
);
95+
};

0 commit comments

Comments
 (0)