aboutsummaryrefslogtreecommitdiffstats
path: root/src/App.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/App.js')
-rw-r--r--src/App.js76
1 files changed, 41 insertions, 35 deletions
diff --git a/src/App.js b/src/App.js
index bc5db46..b671044 100644
--- a/src/App.js
+++ b/src/App.js
@@ -4,14 +4,20 @@ import { Terminal } from 'xterm';
import './xterm.css';
import { FitAddon } from 'xterm-addon-fit';
import React from 'react';
+import { Resizable } from "re-resizable";
+import ResizeObserver from "react-resize-observer";
export default class App extends React.Component {
constructor(props) {
super(props);
+ this.fitAddon = new FitAddon();
this.term = new Terminal({
+ screenKeys: true,
+ useStyle: true,
cursorBlink: true,
fontSize: 18,
fontWeight: 900,
+ fontFamily: `'Fira Mono', monospace`,
theme: {
foreground: "#fff",
background: "#000",
@@ -29,7 +35,10 @@ export default class App extends React.Component {
this.socket = new WebSocket('ws://localhost:8000/ws');
this.socket.binaryType = 'arraybuffer';
- this.fitAddon = new FitAddon();
+ function ab2str(buf) {
+ return String.fromCharCode.apply(null, new Uint8Array(buf));
+ }
+
// this.attachAddon = new AttachAddon(this.socket, false);
this.term.loadAddon(this.fitAddon);
@@ -38,49 +47,41 @@ export default class App extends React.Component {
this.term.open(document.getElementById("xterm"));
this.fitAddon.fit();
- const recvData = data => {
- var type = "text";
-
- if (typeof data !== 'string') {
- data = this.decoder.decode(data);
- var type = "binary";
- }
+ // Terminal events
+ this.term.onData((data) => {
+ this.socket.send(this.encoder.encode("\x00" + data));
+ });
- console.log(`Received ${type}: ${data}`);
- this.term.write(data);
- }
+ this.term.onResize((evt) => {
+ this.socket.send(this.encoder.encode("\x01" + JSON.stringify({ cols: evt.cols, rows: evt.rows })))
+ });
- const sendData = (data, isBinary) => {
- var type = "text";
+ this.term.onTitleChange((title) => {
+ document.title = title;
+ });
- if (isBinary) {
- data = this.encoder.encode(data);
- var type = "binary";
+ // Socket events
+ this.socket.onmessage = (evt) => {
+ if (evt.data instanceof ArrayBuffer) {
+ this.term.write(ab2str(evt.data.slice(1)));
+ } else {
+ alert(evt.data)
}
-
- console.log(`Sending ${type}: ${data}`);
- this.socket.send(data);
+ }
+ this.socket.onclose = (evt) => {
+ this.term.write("Session terminated");
+ this.term.destroy();
}
- this.socket.onmessage = e => recvData(e.data);
- this.term.onKey(Key => {
- switch (Key.domEvent.key) {
- case "Enter":
- sendData('\n');
- break;
-
- default:
- sendData(Key.key);
- break;
+ this.socket.onerror = (evt) => {
+ if (typeof console.log == "function") {
+ console.log(evt)
}
+ }
- });
+ this.fitAddon.fit();
}
- linefeed = () => {
- var shellprompt = "$ ";
- this.term.write("\r\n" + shellprompt);
- };
render() {
return (
@@ -91,7 +92,12 @@ export default class App extends React.Component {
Edit <code>src/App.js</code> and save to reload.
</p>
<div className="terminalContainer">
- <div id="xterm"></div>
+ <div id="xterm" style={{ height: "100%", width: "100%" }} />
+ <ResizeObserver
+ onResize={() => {
+ this.fitAddon.fit();
+ }}
+ />
</div>
</header>
</div>