Show differences
Some checks failed
backend / cross (aarch64) (push) Has been cancelled
backend / cross (arm) (push) Has been cancelled
backend / cross (armhf) (push) Has been cancelled
backend / cross (i686) (push) Has been cancelled
backend / cross (mips) (push) Has been cancelled
backend / cross (mips64) (push) Has been cancelled
backend / cross (mips64el) (push) Has been cancelled
backend / cross (mipsel) (push) Has been cancelled
backend / cross (s390x) (push) Has been cancelled
backend / cross (win32) (push) Has been cancelled
backend / cross (x86_64) (push) Has been cancelled
docker / build (push) Has been cancelled
frontend / build (push) Has been cancelled
Some checks failed
backend / cross (aarch64) (push) Has been cancelled
backend / cross (arm) (push) Has been cancelled
backend / cross (armhf) (push) Has been cancelled
backend / cross (i686) (push) Has been cancelled
backend / cross (mips) (push) Has been cancelled
backend / cross (mips64) (push) Has been cancelled
backend / cross (mips64el) (push) Has been cancelled
backend / cross (mipsel) (push) Has been cancelled
backend / cross (s390x) (push) Has been cancelled
backend / cross (win32) (push) Has been cancelled
backend / cross (x86_64) (push) Has been cancelled
docker / build (push) Has been cancelled
frontend / build (push) Has been cancelled
This commit is contained in:
@@ -1,2 +1 @@
|
|||||||
dist/
|
dist/
|
||||||
src/
|
|
||||||
|
|||||||
@@ -6,10 +6,9 @@ import type { ITerminalOptions, ITheme } from '@xterm/xterm';
|
|||||||
import type { ClientOptions, FlowControl } from './terminal/xterm';
|
import type { ClientOptions, FlowControl } from './terminal/xterm';
|
||||||
|
|
||||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||||
|
|
||||||
const path = window.location.pathname.replace(/[/]+$/, '');
|
const path = window.location.pathname.replace(/[/]+$/, '');
|
||||||
const wsUrl = [protocol, '//', window.location.host, path,'/ws'].join('');
|
const wsUrl = [protocol, '//', window.location.host, path, '/ws', window.location.search].join('');
|
||||||
const tokenUrl = [window.location.protocol, '//', window.location.host, path,'/token'].join('');
|
const tokenUrl = [window.location.protocol, '//', window.location.host, path, '/token'].join('');
|
||||||
const clientOptions = {
|
const clientOptions = {
|
||||||
rendererType: 'webgl',
|
rendererType: 'webgl',
|
||||||
disableLeaveAlert: false,
|
disableLeaveAlert: false,
|
||||||
@@ -24,7 +23,6 @@ const clientOptions = {
|
|||||||
const termOptions = {
|
const termOptions = {
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontFamily: 'Consolas,Liberation Mono,Menlo,Courier,monospace',
|
fontFamily: 'Consolas,Liberation Mono,Menlo,Courier,monospace',
|
||||||
cursorBlink: true,
|
|
||||||
theme: {
|
theme: {
|
||||||
foreground: '#d2d2d2',
|
foreground: '#d2d2d2',
|
||||||
background: '#2b2b2b',
|
background: '#2b2b2b',
|
||||||
|
|||||||
@@ -16,22 +16,7 @@ interface State {
|
|||||||
export class Terminal extends Component<Props, State> {
|
export class Terminal extends Component<Props, State> {
|
||||||
private container: HTMLElement;
|
private container: HTMLElement;
|
||||||
private xterm: Xterm;
|
private xterm: Xterm;
|
||||||
private intervalID: NodeJS.Timeout;
|
|
||||||
private currentDevcontainer = {
|
|
||||||
title: 'Devcontainer Info',
|
|
||||||
detail: 'No Devcontainer Created yet',
|
|
||||||
port: '',
|
|
||||||
ip:'',
|
|
||||||
steps: [
|
|
||||||
// {
|
|
||||||
// summary: '',
|
|
||||||
// duration: '',
|
|
||||||
// status: '',
|
|
||||||
// logs:{
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
],
|
|
||||||
};
|
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super();
|
super();
|
||||||
this.xterm = new Xterm(props, this.showModal);
|
this.xterm = new Xterm(props, this.showModal);
|
||||||
@@ -39,42 +24,8 @@ export class Terminal extends Component<Props, State> {
|
|||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
await this.xterm.refreshToken();
|
await this.xterm.refreshToken();
|
||||||
const options = new URLSearchParams(decodeURIComponent(window.location.search));
|
|
||||||
|
|
||||||
const params = new URLSearchParams({
|
|
||||||
repo: options.get('repoid') as string,
|
|
||||||
user: options.get('userid') as string,
|
|
||||||
});
|
|
||||||
fetch('http://' +
|
|
||||||
options.get('domain') +
|
|
||||||
':'+
|
|
||||||
options.get('port') +
|
|
||||||
'/' +
|
|
||||||
options.get('user') +
|
|
||||||
'/' +
|
|
||||||
options.get('repo') +
|
|
||||||
'/devcontainer/status?' +
|
|
||||||
params
|
|
||||||
)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
if (data.status !== '-1') {
|
|
||||||
if (options.get('type') === 'docker') {
|
|
||||||
this.xterm.open(this.container);
|
this.xterm.open(this.container);
|
||||||
this.xterm.connect();
|
this.xterm.connect();
|
||||||
} else {
|
|
||||||
this.intervalID = setInterval(this.loadOutput, 3000);
|
|
||||||
this.xterm.open(this.container);
|
|
||||||
this.xterm.changeUrl(this.currentDevcontainer.ip, this.currentDevcontainer.port)
|
|
||||||
this.xterm.changeStatus(true);
|
|
||||||
this.xterm.connect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error:', error);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
@@ -105,48 +56,4 @@ export class Terminal extends Component<Props, State> {
|
|||||||
const files = (event.target as HTMLInputElement).files;
|
const files = (event.target as HTMLInputElement).files;
|
||||||
if (files) this.xterm.sendFile(files);
|
if (files) this.xterm.sendFile(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
@bind
|
|
||||||
private loadOutput() {
|
|
||||||
const options = new URLSearchParams(decodeURIComponent(window.location.search));
|
|
||||||
const params = new URLSearchParams({
|
|
||||||
repo: options.get('repoid') as string,
|
|
||||||
user: options.get('userid') as string,
|
|
||||||
});
|
|
||||||
|
|
||||||
fetch(
|
|
||||||
'http://' + options.get('domain') + ':'+ options.get('port') +'/' +
|
|
||||||
options.get('user') +
|
|
||||||
'/' +
|
|
||||||
options.get('repo') +
|
|
||||||
'/devcontainer/output?' +
|
|
||||||
params
|
|
||||||
)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(job => {
|
|
||||||
if (!job) {
|
|
||||||
clearInterval(this.intervalID);
|
|
||||||
this.intervalID = null as any;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(this.currentDevcontainer.steps.length < job.currentDevcontainer.steps.length){
|
|
||||||
for(let i = this.currentDevcontainer.steps.length; i < job.currentDevcontainer.steps.length; i++) {
|
|
||||||
this.xterm.writeData(job.currentDevcontainer.steps[i].summary);
|
|
||||||
this.xterm.writeData('\r\n');
|
|
||||||
for(let j = 0; j < job.currentDevcontainer.steps[i].logs.length; j++) {
|
|
||||||
this.xterm.writeData(job.currentDevcontainer.steps[i].logs[j].message.replace(/\r\n/g, '\n').replace(/\n/g, '\r\n'));
|
|
||||||
this.xterm.writeData('\r\n');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.currentDevcontainer = job.currentDevcontainer;
|
|
||||||
if (this.currentDevcontainer.detail === '4' && this.intervalID) {
|
|
||||||
clearInterval(this.intervalID);
|
|
||||||
this.intervalID = null as any;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error:', error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,13 +101,9 @@ export class Xterm {
|
|||||||
private reconnect = true;
|
private reconnect = true;
|
||||||
private doReconnect = true;
|
private doReconnect = true;
|
||||||
private closeOnDisconnect = false;
|
private closeOnDisconnect = false;
|
||||||
private intervalID: NodeJS.Timeout;
|
|
||||||
private writeFunc = (data: ArrayBuffer) => this.writeData(new Uint8Array(data));
|
private writeFunc = (data: ArrayBuffer) => this.writeData(new Uint8Array(data));
|
||||||
private status = false;
|
|
||||||
private titleStatus = false;
|
|
||||||
private checkStatus = false;
|
|
||||||
private connectStatus = false;
|
|
||||||
private beforeCommand?: string;
|
|
||||||
constructor(
|
constructor(
|
||||||
private options: XtermOptions,
|
private options: XtermOptions,
|
||||||
private sendCb: () => void
|
private sendCb: () => void
|
||||||
@@ -183,16 +179,7 @@ export class Xterm {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
register(
|
register(terminal.onData(data => sendData(data)));
|
||||||
terminal.onData(data =>
|
|
||||||
{
|
|
||||||
if (this.status) {
|
|
||||||
sendData(data);
|
|
||||||
} else {
|
|
||||||
this.writeData('\b \b');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
register(terminal.onBinary(data => sendData(Uint8Array.from(data, v => v.charCodeAt(0)))));
|
register(terminal.onBinary(data => sendData(Uint8Array.from(data, v => v.charCodeAt(0)))));
|
||||||
register(
|
register(
|
||||||
terminal.onResize(({ cols, rows }) => {
|
terminal.onResize(({ cols, rows }) => {
|
||||||
@@ -257,18 +244,6 @@ export class Xterm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@bind
|
|
||||||
public changeUrl(ip: string, port: string) {
|
|
||||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
||||||
this.options.wsUrl = [protocol, '//' + ip + ':' + port +'/ws', window.location.search].join('');
|
|
||||||
this.options.tokenUrl = [window.location.protocol, '//' + ip + ':' + port +'/token'].join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
@bind
|
|
||||||
public changeStatus(v: boolean){
|
|
||||||
this.status = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
@bind
|
@bind
|
||||||
public connect() {
|
public connect() {
|
||||||
this.socket = new WebSocket(this.options.wsUrl, ['tty']);
|
this.socket = new WebSocket(this.options.wsUrl, ['tty']);
|
||||||
@@ -279,10 +254,6 @@ export class Xterm {
|
|||||||
register(addEventListener(socket, 'message', this.onSocketData as EventListener));
|
register(addEventListener(socket, 'message', this.onSocketData as EventListener));
|
||||||
register(addEventListener(socket, 'close', this.onSocketClose as EventListener));
|
register(addEventListener(socket, 'close', this.onSocketClose as EventListener));
|
||||||
register(addEventListener(socket, 'error', () => (this.doReconnect = false)));
|
register(addEventListener(socket, 'error', () => (this.doReconnect = false)));
|
||||||
const options = new URLSearchParams(decodeURIComponent(window.location.search));
|
|
||||||
if (options.get('type') === 'docker') {
|
|
||||||
this.intervalID = setInterval(this.loadCommand, 3000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@bind
|
@bind
|
||||||
@@ -334,52 +305,6 @@ export class Xterm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@bind
|
|
||||||
private loadCommand() {
|
|
||||||
const options = new URLSearchParams(decodeURIComponent(window.location.search));
|
|
||||||
const params = new URLSearchParams({
|
|
||||||
repo: options.get('repoid') as string,
|
|
||||||
user: options.get('userid') as string,
|
|
||||||
});
|
|
||||||
|
|
||||||
fetch(
|
|
||||||
'http://' + options.get('domain') + ':'+ options.get('port') +'/' +
|
|
||||||
options.get('user') +
|
|
||||||
'/' +
|
|
||||||
options.get('repo') +
|
|
||||||
'/devcontainer/command?' +
|
|
||||||
params
|
|
||||||
)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
if (data.status !== '4' && data.status !== '0') {
|
|
||||||
this.sendData(data.command);
|
|
||||||
} else {
|
|
||||||
clearInterval(this.intervalID);
|
|
||||||
if (data.status === '4') {
|
|
||||||
fetch(
|
|
||||||
'http://' + options.get('domain') + ':'+ options.get('port') +'/' +
|
|
||||||
options.get('user') +
|
|
||||||
'/' +
|
|
||||||
options.get('repo') +
|
|
||||||
'/devcontainer/command?' +
|
|
||||||
params
|
|
||||||
)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
this.sendData(data.command);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error:', error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error:', error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@bind
|
@bind
|
||||||
private parseOptsFromUrlQuery(query: string): Preferences {
|
private parseOptsFromUrlQuery(query: string): Preferences {
|
||||||
const { terminal } = this;
|
const { terminal } = this;
|
||||||
@@ -420,60 +345,16 @@ export class Xterm {
|
|||||||
const rawData = event.data as ArrayBuffer;
|
const rawData = event.data as ArrayBuffer;
|
||||||
const cmd = String.fromCharCode(new Uint8Array(rawData)[0]);
|
const cmd = String.fromCharCode(new Uint8Array(rawData)[0]);
|
||||||
const data = rawData.slice(1);
|
const data = rawData.slice(1);
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case Command.OUTPUT:
|
case Command.OUTPUT:
|
||||||
console.log(this.status + ': ' + textDecoder.decode(data) + this.connectStatus + ' ' + this.checkStatus + ' ' + this.titleStatus );
|
|
||||||
const options = new URLSearchParams(decodeURIComponent(window.location.search));
|
|
||||||
if (options.get('type') === 'docker') {
|
|
||||||
if (
|
|
||||||
this.status === false &&
|
|
||||||
textDecoder.decode(data).replace(/\s/g, '').includes('Successfully connected to the container'.replace(/\s/g, ''))
|
|
||||||
) {
|
|
||||||
if(this.connectStatus == true){
|
|
||||||
this.status = true;
|
|
||||||
}
|
|
||||||
this.connectStatus = true;
|
|
||||||
}
|
|
||||||
if (this.checkStatus) {
|
|
||||||
if (textDecoder.decode(data).replace(/\s/g, '').includes('You have out the container. Please refresh the terminal to reconnect.'.replace(/\s/g, ''))) {
|
|
||||||
this.checkStatus = false;
|
|
||||||
this.status = false;
|
|
||||||
this.connectStatus = false;
|
|
||||||
}
|
|
||||||
if(textDecoder.decode(data).includes('\x1b')){
|
|
||||||
this.checkStatus = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.titleStatus && textDecoder.decode(data).includes('\x1b')) {
|
|
||||||
this.titleStatus = false;
|
|
||||||
this.checkStatus = true;
|
|
||||||
this.sendData(
|
|
||||||
`echo $WEB_TERMINAL\n`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
!(this.status === false && (textDecoder.decode(data).includes('\x1b') || textDecoder.decode(data).replace(/\s/g, '').includes('docker'))) &&
|
|
||||||
this.titleStatus !== true &&
|
|
||||||
this.checkStatus !== true
|
|
||||||
){
|
|
||||||
this.writeFunc(data);
|
this.writeFunc(data);
|
||||||
}
|
|
||||||
if (textDecoder.decode(data).replace(/\s/g, '').includes('exit')) {
|
|
||||||
this.titleStatus = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.writeFunc(data);
|
|
||||||
}
|
|
||||||
console.log(this.status + ': ' + textDecoder.decode(data) + this.connectStatus + ' ' + this.checkStatus + ' ' + this.titleStatus );
|
|
||||||
break;
|
break;
|
||||||
case Command.SET_WINDOW_TITLE:
|
case Command.SET_WINDOW_TITLE:
|
||||||
console.log('SET_WINDOW_TITLESET_WINDOW_TITLE');
|
|
||||||
this.title = textDecoder.decode(data);
|
this.title = textDecoder.decode(data);
|
||||||
document.title = this.title;
|
document.title = this.title;
|
||||||
break;
|
break;
|
||||||
case Command.SET_PREFERENCES:
|
case Command.SET_PREFERENCES:
|
||||||
console.log('SET_PREFERENCESSET_PREFERENCESSET_PREFERENCES');
|
|
||||||
this.applyPreferences({
|
this.applyPreferences({
|
||||||
...this.options.clientOptions,
|
...this.options.clientOptions,
|
||||||
...JSON.parse(textDecoder.decode(data)),
|
...JSON.parse(textDecoder.decode(data)),
|
||||||
|
|||||||
19448
html/yarn.lock
19448
html/yarn.lock
File diff suppressed because it is too large
Load Diff
32640
src/html.h
generated
32640
src/html.h
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user