// Copyright (C) 2018 Avatao.com Innovative Learning Kft. // All Rights Reserved. See LICENSE file for details. import { ChangeDetectorRef, Component, EventEmitter, OnInit, Output } from '@angular/core'; import { IDECommand } from '../message-types/ide-command'; import { WebSocketService } from '../services/websocket.service'; import { ProcessManagerService } from '../services/processmanager.service'; import { DeploymentNotificationService } from '../services/deployment-notification.service'; import { config } from '../config'; import { CommandMessage } from '../message-types/command-message'; enum DeployButtonState { DEPLOYED, DEPLOYING, FAILED, TODEPLOY } enum CodeState { SAVED, DIRTY } @Component({ selector: 'app-ide', templateUrl: './ide.component.html', styleUrls: ['./ide.component.scss'] }) export class IdeComponent implements OnInit { CodeState = CodeState; DeployButtonState = DeployButtonState; key_id = 'ide'; files: string[]; filename = ''; directory = ''; code: string = config.ide.defaultCode; codeState = CodeState.SAVED; deployButtonState = DeployButtonState.DEPLOYED; showDeployButton: boolean = config.ide.showDeployButton; autosave = null; language: string = config.ide.defaultLanguage; editorOptions = {theme: 'vs-dark', language: 'python'}; @Output() newLogs = new EventEmitter(); options: any = {enableBasicAutocompletion: true, enableSnippets: true, enableLiveAutocompletion: true}; command_handlers = {'reload': this.reloadHandler.bind(this), 'read': this.readHandler.bind(this), 'select': this.selectHandler.bind(this), 'write': this.writeHandler.bind(this), 'selectdir': this.selectdirHandler.bind(this)}; constructor(private webSocketService: WebSocketService, private changeDetectorRef: ChangeDetectorRef, private processManagerService: ProcessManagerService, private deploymentNotificationService: DeploymentNotificationService) { } ngOnInit() { this.webSocketService.connect(); this.subscribeWS(); this.requestCode(); this.initProcessManagerService(); this.resetAutoSaveCountdown(); } subscribeWS() { this.webSocketService.observeKey(this.key_id).subscribe((event) => { this.command_handlers[event.data.command](event.data); this.changeDetectorRef.detectChanges(); }); } initProcessManagerService() { this.processManagerService.init(); this.processManagerService.subscribeCallback( config.ide.deployProcessName, (event) => { this.deploymentNotificationService.deploying.next(false); this.newLogs.emit({ stdout: event.data.stdout, stderr: event.data.stderr }); } ); this.processManagerService.subscribeSuccessCallback( config.ide.deployProcessName, (event) => this.setDeployButtonState(DeployButtonState.DEPLOYED) ); this.processManagerService.subscribeErrorCallback( config.ide.deployProcessName, (event) => this.setDeployButtonState(DeployButtonState.FAILED) ); } updateFileData(data: IDECommand) { this.filename = data.filename; this.directory = data.directory; this.code = (data.content != null) ? data.content : this.code; this.files = data.files; } selectHandler(data: IDECommand) { this.updateFileData(data); } reloadHandler(data: CommandMessage) { this.requestCode(); } readHandler(data: IDECommand) { if (this.codeState === CodeState.SAVED) { this.updateFileData(data); } } writeHandler(data: CommandMessage) { this.setCodeState(CodeState.SAVED); } selectdirHandler(data: IDECommand) { this.updateFileData(data); } resetAutoSaveCountdown() { if (this.autosave) { clearInterval(this.autosave); } this.autosave = setInterval( () => { this.sendCodeIfDirty(); }, config.ide.autoSaveInterval ); } tabSwitchButtonHandler(file: string) { if (this.codeState === CodeState.DIRTY) { this.sendCodeContents(); } this.selectCode(file); this.requestCode(); } setCodeState(state: CodeState) { this.codeState = state; } setDeployButtonState(state: DeployButtonState) { this.deployButtonState = state; } deployCode() { this.processManagerService.restartProcess(config.ide.deployProcessName); this.setDeployButtonState(DeployButtonState.DEPLOYING); this.deploymentNotificationService.deploying.next(true); } sendCodeIfDirty() { if (this.codeState === CodeState.DIRTY) { this.sendCodeContents(); } } sendCodeContents() { this.webSocketService.send(this.key_id, { 'command': 'write', 'content': this.code }); } requestCode() { this.webSocketService.send(this.key_id, { 'command': 'read' }); } selectCode(filename: string) { this.webSocketService.send(this.key_id, { 'command': 'select', 'filename': filename }); } }