mirror of https://github.com/elisescu/tty-share
Refactor the whole receiver part
- remove unused dependencies - move to typescript - add an automatic way to resize the tty-receiverpull/14/merge
parent
bc832b8357
commit
71ebda8e8f
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"sourceMap": true,
|
||||
"noImplicitAny": true,
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"jsx": "react",
|
||||
"allowJs": true
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
import React, { Component } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import MuiThemePro from 'material-ui/styles/MuiThemeProvider';
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
import TextField from 'material-ui/TextField';
|
||||
|
||||
class App extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
render() {
|
||||
return (<div> </div>);
|
||||
}
|
||||
}
|
||||
export default App;
|
@ -0,0 +1,12 @@
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#terminal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
import 'xterm/dist/xterm.css';
|
||||
import { Terminal } from 'xterm';
|
||||
import pbkdf2 from 'pbkdf2';
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './app';
|
||||
import base64 from './base64'
|
||||
|
||||
|
||||
ReactDOM.render(
|
||||
<App />,
|
||||
document.querySelector('#settings')
|
||||
);
|
||||
|
||||
var term = new Terminal({
|
||||
cursorBlink: true,
|
||||
macOptionIsMeta: true,
|
||||
});
|
||||
|
||||
var derivedKey = pbkdf2.pbkdf2Sync('password', 'salt', 4096, 32, 'sha256');
|
||||
console.log(derivedKey);
|
||||
|
||||
let wsAddress = "";
|
||||
if (window.location.protocol === "https:") {
|
||||
wsAddress = 'wss://';
|
||||
} else {
|
||||
wsAddress = "ws://";
|
||||
}
|
||||
|
||||
wsAddress += window.location.host + window.ttyInitialData.wsPath;
|
||||
let connection = new WebSocket(wsAddress);
|
||||
|
||||
|
||||
|
||||
term.open(document.getElementById('terminal'), true);
|
||||
|
||||
term.write("$");
|
||||
|
||||
connection.onclose = function(evt) {
|
||||
console.log("Got the WS closed: ", evt);
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
connection.onmessage = function(evt) {
|
||||
let message = JSON.parse(evt.data)
|
||||
|
||||
let msgData = base64.decode(message.Data)
|
||||
|
||||
if (message.Type === "Write") {
|
||||
let writeMsg = JSON.parse(msgData)
|
||||
term.write(base64.decode(writeMsg.Data))
|
||||
}
|
||||
|
||||
if (message.Type == "WinSize") {
|
||||
let winSizeMsg = JSON.parse(msgData)
|
||||
term.resize(winSizeMsg.Cols, winSizeMsg.Rows)
|
||||
}
|
||||
}
|
||||
|
||||
term.on('data', function (data) {
|
||||
//console.log('TERM->WS:', data);
|
||||
let writeMessage = {
|
||||
Type: "Write",
|
||||
Data: base64.encode(JSON.stringify({ Size: data.length, Data: base64.encode(data)})),
|
||||
}
|
||||
let dataToSend = JSON.stringify(writeMessage)
|
||||
//console.log("Sending : ", dataToSend)
|
||||
connection.send(dataToSend);
|
||||
|
||||
})
|
@ -0,0 +1,28 @@
|
||||
import 'xterm/dist/xterm.css';
|
||||
import './main.css';
|
||||
|
||||
import { Terminal } from 'xterm';
|
||||
import * as pbkdf2 from 'pbkdf2';
|
||||
|
||||
import { TTYReceiver } from './tty-receiver';
|
||||
|
||||
const term = new Terminal({
|
||||
cursorBlink: true,
|
||||
macOptionIsMeta: true,
|
||||
});
|
||||
|
||||
const derivedKey = pbkdf2.pbkdf2Sync('password', 'salt', 4096, 32, 'sha256');
|
||||
console.log(derivedKey);
|
||||
|
||||
let wsAddress = "";
|
||||
if (window.location.protocol === "https:") {
|
||||
wsAddress = 'wss://';
|
||||
} else {
|
||||
wsAddress = "ws://";
|
||||
}
|
||||
|
||||
let ttyWindow = window as any;
|
||||
wsAddress += ttyWindow.location.host + ttyWindow.ttyInitialData.wsPath;
|
||||
|
||||
|
||||
const ttyReceiver = new TTYReceiver(wsAddress, document.getElementById('terminal') as HTMLDivElement);
|
@ -0,0 +1,110 @@
|
||||
import { Terminal, IEvent, IDisposable } from "xterm";
|
||||
|
||||
import base64 from './base64';
|
||||
|
||||
interface IRectSize {
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
class TTYReceiver {
|
||||
private xterminal: Terminal;
|
||||
private containerElement: HTMLElement;
|
||||
|
||||
constructor(wsAddress: string, container: HTMLDivElement) {
|
||||
const connection = new WebSocket(wsAddress);
|
||||
|
||||
this.xterminal = new Terminal({
|
||||
cursorBlink: true,
|
||||
macOptionIsMeta: true,
|
||||
scrollback: 0,
|
||||
fontSize: 12,
|
||||
letterSpacing: 0,
|
||||
});
|
||||
|
||||
this.containerElement = container;
|
||||
this.xterminal.open(container);
|
||||
|
||||
connection.onclose = (evt: CloseEvent) => {
|
||||
// TODO: notify the user that the session was closed.
|
||||
}
|
||||
|
||||
this.xterminal.focus();
|
||||
|
||||
const containerPixSize = this.getElementPixelsSize(container);
|
||||
const newFontSize = this.guessNewFontSize(this.xterminal.cols, this.xterminal.rows, containerPixSize.width, containerPixSize.height);
|
||||
this.xterminal.setOption('fontSize', newFontSize);
|
||||
|
||||
connection.onmessage = (ev: MessageEvent) => {
|
||||
let message = JSON.parse(ev.data)
|
||||
let msgData = base64.decode(message.Data)
|
||||
|
||||
if (message.Type === "Write") {
|
||||
let writeMsg = JSON.parse(msgData)
|
||||
this.xterminal.write(base64.decode(writeMsg.Data))
|
||||
}
|
||||
|
||||
if (message.Type == "WinSize") {
|
||||
let winSizeMsg = JSON.parse(msgData)
|
||||
|
||||
const containerPixSize = this.getElementPixelsSize(container);
|
||||
const newFontSize = this.guessNewFontSize(winSizeMsg.Cols, winSizeMsg.Rows, containerPixSize.width, containerPixSize.height);
|
||||
this.xterminal.setOption('fontSize', newFontSize);
|
||||
|
||||
// Now set the new size.
|
||||
this.xterminal.resize(winSizeMsg.Cols, winSizeMsg.Rows)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: .on() is deprecated. Should be replaced.
|
||||
this.xterminal.on('data', function (data) {
|
||||
let writeMessage = {
|
||||
Type: "Write",
|
||||
Data: base64.encode(JSON.stringify({ Size: data.length, Data: base64.encode(data)})),
|
||||
}
|
||||
let dataToSend = JSON.stringify(writeMessage)
|
||||
connection.send(dataToSend);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Get the pixels size of the element, after all CSS was applied. This will be used in an ugly
|
||||
// hack to guess what fontSize to set on the xterm object. Horrible hack, but I feel less bad
|
||||
// about it seeing that VSV does it too:
|
||||
// https://github.com/microsoft/vscode/blob/d14ee7613fcead91c5c3c2bddbf288c0462be876/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts#L363
|
||||
private getElementPixelsSize(element: HTMLElement): IRectSize {
|
||||
const defView = this.containerElement.ownerDocument.defaultView;
|
||||
let width = parseInt(defView.getComputedStyle(element).getPropertyValue('width').replace('px', ''), 10);
|
||||
let height = parseInt(defView.getComputedStyle(element).getPropertyValue('height').replace('px', ''), 10);
|
||||
|
||||
return {
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}
|
||||
|
||||
// Tries to guess the new font size, for the new terminal size, so that the rendered terminal
|
||||
// will have the newWidth and newHeight dimensions
|
||||
private guessNewFontSize(newCols: number, newRows: number, targetWidth: number, targetHeight: number): number {
|
||||
const cols = this.xterminal.cols;
|
||||
const rows = this.xterminal.rows;
|
||||
const fontSize = this.xterminal.getOption('fontSize');
|
||||
const xtermPixelsSize = this.getElementPixelsSize(this.containerElement.querySelector(".xterm-screen"));
|
||||
|
||||
const newHFontSizeMultiplier = (cols / newCols) * (targetWidth / xtermPixelsSize.width);
|
||||
const newVFontSizeMultiplier = (rows / newRows) * (targetHeight / xtermPixelsSize.height);
|
||||
|
||||
let newFontSize;
|
||||
|
||||
if (newHFontSizeMultiplier > newVFontSizeMultiplier) {
|
||||
newFontSize = Math.floor(fontSize * newVFontSizeMultiplier);
|
||||
} else {
|
||||
newFontSize = Math.floor(fontSize * newHFontSizeMultiplier);
|
||||
}
|
||||
return newFontSize;
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
TTYReceiver
|
||||
}
|
Loading…
Reference in New Issue