show differences
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				backend / cross (aarch64) (push) Waiting to run
				
			
		
			
				
	
				backend / cross (arm) (push) Waiting to run
				
			
		
			
				
	
				backend / cross (armhf) (push) Waiting to run
				
			
		
			
				
	
				backend / cross (i686) (push) Waiting to run
				
			
		
			
				
	
				backend / cross (mips) (push) Waiting to run
				
			
		
			
				
	
				backend / cross (mips64) (push) Waiting to run
				
			
		
			
				
	
				backend / cross (mips64el) (push) Waiting to run
				
			
		
			
				
	
				backend / cross (mipsel) (push) Waiting to run
				
			
		
			
				
	
				backend / cross (s390x) (push) Waiting to run
				
			
		
			
				
	
				backend / cross (win32) (push) Waiting to run
				
			
		
			
				
	
				backend / cross (x86_64) (push) Waiting to run
				
			
		
			
				
	
				frontend / build (push) Waiting to run
				
			
		
			
				
	
				docker / build (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	backend / cross (aarch64) (push) Waiting to run
				
			backend / cross (arm) (push) Waiting to run
				
			backend / cross (armhf) (push) Waiting to run
				
			backend / cross (i686) (push) Waiting to run
				
			backend / cross (mips) (push) Waiting to run
				
			backend / cross (mips64) (push) Waiting to run
				
			backend / cross (mips64el) (push) Waiting to run
				
			backend / cross (mipsel) (push) Waiting to run
				
			backend / cross (s390x) (push) Waiting to run
				
			backend / cross (win32) (push) Waiting to run
				
			backend / cross (x86_64) (push) Waiting to run
				
			frontend / build (push) Waiting to run
				
			docker / build (push) Has been cancelled
				
			This commit is contained in:
		@@ -1 +1,2 @@
 | 
			
		||||
dist/
 | 
			
		||||
src/
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,9 @@ import type { ITerminalOptions, ITheme } from '@xterm/xterm';
 | 
			
		||||
import type { ClientOptions, FlowControl } from './terminal/xterm';
 | 
			
		||||
 | 
			
		||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
 | 
			
		||||
 | 
			
		||||
const path = window.location.pathname.replace(/[/]+$/, '');
 | 
			
		||||
const wsUrl = [protocol, '//', window.location.host, path, '/ws', window.location.search].join('');
 | 
			
		||||
const wsUrl = [protocol, '//', window.location.host, path,'/ws'].join('');
 | 
			
		||||
const tokenUrl = [window.location.protocol, '//', window.location.host, path,'/token'].join('');
 | 
			
		||||
const clientOptions = {
 | 
			
		||||
    rendererType: 'webgl',
 | 
			
		||||
@@ -23,6 +24,7 @@ const clientOptions = {
 | 
			
		||||
const termOptions = {
 | 
			
		||||
    fontSize: 13,
 | 
			
		||||
    fontFamily: 'Consolas,Liberation Mono,Menlo,Courier,monospace',
 | 
			
		||||
    cursorBlink: true,
 | 
			
		||||
    theme: {
 | 
			
		||||
        foreground: '#d2d2d2',
 | 
			
		||||
        background: '#2b2b2b',
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,22 @@ interface State {
 | 
			
		||||
export class Terminal extends Component<Props, State> {
 | 
			
		||||
    private container: HTMLElement;
 | 
			
		||||
    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) {
 | 
			
		||||
        super();
 | 
			
		||||
        this.xterm = new Xterm(props, this.showModal);
 | 
			
		||||
@@ -24,8 +39,42 @@ export class Terminal extends Component<Props, State> {
 | 
			
		||||
 | 
			
		||||
    async componentDidMount() {
 | 
			
		||||
        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.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() {
 | 
			
		||||
@@ -56,4 +105,48 @@ export class Terminal extends Component<Props, State> {
 | 
			
		||||
        const files = (event.target as HTMLInputElement).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,9 +101,13 @@ export class Xterm {
 | 
			
		||||
    private reconnect = true;
 | 
			
		||||
    private doReconnect = true;
 | 
			
		||||
    private closeOnDisconnect = false;
 | 
			
		||||
 | 
			
		||||
    private intervalID: NodeJS.Timeout;
 | 
			
		||||
    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(
 | 
			
		||||
        private options: XtermOptions,
 | 
			
		||||
        private sendCb: () => void
 | 
			
		||||
@@ -179,7 +183,16 @@ export class Xterm {
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
        );
 | 
			
		||||
        register(terminal.onData(data => sendData(data)));
 | 
			
		||||
        register(
 | 
			
		||||
            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.onResize(({ cols, rows }) => {
 | 
			
		||||
@@ -244,6 +257,18 @@ 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
 | 
			
		||||
    public connect() {
 | 
			
		||||
        this.socket = new WebSocket(this.options.wsUrl, ['tty']);
 | 
			
		||||
@@ -254,6 +279,10 @@ export class Xterm {
 | 
			
		||||
        register(addEventListener(socket, 'message', this.onSocketData as EventListener));
 | 
			
		||||
        register(addEventListener(socket, 'close', this.onSocketClose as EventListener));
 | 
			
		||||
        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
 | 
			
		||||
@@ -305,6 +334,52 @@ 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
 | 
			
		||||
    private parseOptsFromUrlQuery(query: string): Preferences {
 | 
			
		||||
        const { terminal } = this;
 | 
			
		||||
@@ -345,16 +420,60 @@ export class Xterm {
 | 
			
		||||
        const rawData = event.data as ArrayBuffer;
 | 
			
		||||
        const cmd = String.fromCharCode(new Uint8Array(rawData)[0]);
 | 
			
		||||
        const data = rawData.slice(1);
 | 
			
		||||
 | 
			
		||||
        switch (cmd) {
 | 
			
		||||
            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);
 | 
			
		||||
                    }
 | 
			
		||||
                    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;
 | 
			
		||||
            case Command.SET_WINDOW_TITLE:
 | 
			
		||||
                console.log('SET_WINDOW_TITLESET_WINDOW_TITLE');
 | 
			
		||||
                this.title = textDecoder.decode(data);
 | 
			
		||||
                document.title = this.title;
 | 
			
		||||
                break;
 | 
			
		||||
            case Command.SET_PREFERENCES:
 | 
			
		||||
                console.log('SET_PREFERENCESSET_PREFERENCESSET_PREFERENCES');
 | 
			
		||||
                this.applyPreferences({
 | 
			
		||||
                    ...this.options.clientOptions,
 | 
			
		||||
                    ...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