import React from 'react';
import { InputGroup } from 'reactstrap';
import ResizeObserver from "react-resize-observer";
import { ToggleSlider } from 'react-toggle-slider';
import { Terminal } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
import { ThemeContext, themes } from './theme';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faSun, faMoon } from '@fortawesome/free-solid-svg-icons';
import './App.css';
import './xterm.css';
function App() {
const [darkMode, setDarkMode] = React.useState(true);
return (
{({ changeTheme }) => (
{
setDarkMode(!darkMode);
changeTheme(darkMode ? themes.light : themes.dark);
}}
/>
)}
);
}
class TerminalComponent 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",
cursor: "#fff",
cursorAccent: "#000",
selection: "#fff",
},
});
this.isConnecting = false;
}
componentDidMount() {
this.encoder = new TextEncoder();
this.decoder = new TextDecoder();
this.socket = new WebSocket('ws://localhost:8000/ws');
this.socket.binaryType = 'arraybuffer';
this.term.loadAddon(this.fitAddon);
this.term.open(document.getElementById("xterm"));
this.fitAddon.fit();
// Terminal events
this.term.onData((data) => {
//this.socket.send(this.encoder.encode("\x00" + data));
this.handleSend(this.encoder.encode("\x00" + data));
});
this.term.onResize((evt) => {
//this.socket.send(this.encoder.encode("\x01" + JSON.stringify({ cols: evt.cols, rows: evt.rows })));
this.handleSend(this.encoder.encode("\x01" + JSON.stringify({ cols: evt.cols, rows: evt.rows })));
});
this.term.onTitleChange((title) => {
document.title = title;
});
// Socket events
this.socket.onmessage = (evt) => {
if (evt.data instanceof ArrayBuffer) {
this.term.write(this.decoder.decode(evt.data.slice(1)));
} else {
alert(evt.data)
}
}
this.socket.onclose = (evt) => {
this.term.write("\nSession terminated");
}
this.socket.onerror = (evt) => {
if (typeof console.log == "function") {
console.log(evt)
}
}
this.fitAddon.fit();
}
handleSend(message) {
if (this.socket.readyState === WebSocket.OPEN) {
this.isConnecting = false;
this.socket.send(message);
}
else if (this.socket.readyState === WebSocket.CONNECTING && !this.isConnecting) {
this.isConnecting = true;
this.socket.addEventListener('open', this.handleSend(message));
}
else {
}
};
render() {
return (
{
this.fitAddon.fit();
}}
/>
);
}
}
class Sidebar extends React.Component {
// a sidebar which can take you to other pages
// constructor(props) {
// super(props);
// }
createTemplate(){
// location.replace("index.html");
console.log("create template");
}
toStudentView() {
// location.replace("index.html");
console.log("student view");
}
logOut() {
// location.replace("index.html");
console.log("log out");
}
render() {
return (
);
}
}
export default App;