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;