### File

`src/app/ide/ide.component.ts`

### Implements

`OnInit`

### Metadata

selector | `app-ide`
styleUrls | `./ide.component.scss`
templateUrl | `./ide.component.html`

### Index

###### Properties

- extensions
- file
- inp
- inputField
- isCompiling
- isError
- isSaved
- isUploading
- isUpToDate
- loadingFile
- Public route
- Public runCodeService
- runField
- saveField

###### Methods

- ngOnInit
- optimizeURI
- runFile
- updateFile
- updateInput

### Constructor

`constructor(route: ActivatedRoute, runCodeService: RunCodeService, fileService: FileService, apiService: ApiService, router: Router)`
Defined in src/app/ide/ide.component.ts:37

Parameters :

Name | Type | Optional
route | `ActivatedRoute` | No
runCodeService | `RunCodeService` | No
fileService | `FileService` | No
apiService | `ApiService` | No
router | `Router` | No

### Methods

ngOnInit
`ngOnInit()`
Defined in src/app/ide/ide.component.ts:43
Returns : `void`

optimizeURI
`optimizeURI(uri: string)`
Defined in src/app/ide/ide.component.ts:186

Parameters :

Name | Type | Optional
uri | `string` | No

Returns : `string`

runFile
`runFile()`
Defined in src/app/ide/ide.component.ts:150
Returns : `void`

updateFile
`updateFile()`
Defined in src/app/ide/ide.component.ts:130
Returns : `void`

updateInput
`updateInput(val: string)`
Defined in src/app/ide/ide.component.ts:126

Parameters :

Name | Type | Optional
val | `string` | No

Returns : `void`

### Properties

extensions
Type : `[]`
Default value : `['.cpp', '.py', '.java']`
Defined in src/app/ide/ide.component.ts:21

file
Type : `File`
Default value : `{ filename: 'Untitled', language: '.cpp', text: '', username: JSON.parse(this.apiService.getToken()).username, path: '/' }`
Defined in src/app/ide/ide.component.ts:28

inp
Type : `string`
Default value : `''`
Defined in src/app/ide/ide.component.ts:20

inputField
Decorators : `@ViewChild(InputComponent)`
Defined in src/app/ide/ide.component.ts:35

isCompiling
Default value : `false`
Defined in src/app/ide/ide.component.ts:25

isError
Default value : `false`
Defined in src/app/ide/ide.component.ts:26

isSaved
Default value : `false`
Defined in src/app/ide/ide.component.ts:23

isUploading
Default value : `false`
Defined in src/app/ide/ide.component.ts:24

isUpToDate
Default value : `false`
Defined in src/app/ide/ide.component.ts:27

loadingFile
Default value : `false`
Defined in src/app/ide/ide.component.ts:22

Public route
Type : `ActivatedRoute`
Defined in src/app/ide/ide.component.ts:39

Public runCodeService
Type : `RunCodeService`
Defined in src/app/ide/ide.component.ts:39

runField
Decorators : `@ViewChild(IdeCompileComponent)`
Defined in src/app/ide/ide.component.ts:36

saveField
Decorators : `@ViewChild(SaveFileComponent)`
Defined in src/app/ide/ide.component.ts:37

    import {Component, OnInit, ViewChild} from '@angular/core';
    import {ActivatedRoute, Router} from '@angular/router';
    import {InputComponent} from '../input/input.component';
    import {IdeCompileComponent} from '../ide-compile/ide-compile.component';
    import {RunCodeService} from '../run-code.service';
    import {SaveFileComponent} from '../save-file/save-file.component';
    import {File} from '../file';
    import {FileService} from '../file.service';
    import {ApiService} from '../api.service';

    declare const CodeMirror: any;

    @Component({
      selector: 'app-ide',
      templateUrl: './ide.component.html',
      styleUrls: ['./ide.component.scss']
    })
    export class IdeComponent implements OnInit {

      inp = '';
      extensions = ['.cpp', '.py', '.java'];
      loadingFile = false;
      isSaved = false;
      isUploading = false;
      isCompiling = false;
      isError = false;
      isUpToDate = false;
      file: File = {
        filename: 'Untitled',
        language: '.cpp',
        text: '',
        username: JSON.parse(this.apiService.getToken()).username,
        path: '/'
      };
      @ViewChild(InputComponent) inputField;
      @ViewChild(IdeCompileComponent) runField;
      @ViewChild(SaveFileComponent) saveField;

      constructor(public route: ActivatedRoute, public runCodeService: RunCodeService, private fileService: FileService,
                  private apiService: ApiService, private router: Router) {
      }

      ngOnInit(): void {
        const filepath = decodeURIComponent(this.route.snapshot.params.filepath);
        const editorArea = document.getElementById('editor');
        const editor = CodeMirror.fromTextArea(editorArea as HTMLTextAreaElement, {
          lineNumbers: true,
          theme: 'material-ocean',
          mode: 'text/x-c++src',
          autoCloseBrackets: true,
          matchBrackets: true
        });
        editor.setSize('auto', '70vh');
        Object.assign((document.getElementsByClassName('CodeMirror')[0] as HTMLTextAreaElement).style, {
          borderBottom: '1px solid #ddf',
          padding: '20px',
          fontFamily: '"Anonymous Pro", monospace',
        });

        let activeLang = 0;
        const langs = ['C++', 'Python', 'Java'];
        const langsMime = ['text/x-c++src', 'text/x-python', 'text/x-java'];
        const code = [`#include <iostream>
    using namespace std;

    int main() {
      cout << "Hello World!\\n";
      return 0;
    }`, `print("Hello World!")`, `class HelloWorld {
        public static void main(String[] args) {
            System.out.println("Hello, World!");
        }
    }`];

        editor.setValue(code[activeLang]);
        this.file.text = code[activeLang];
        const tl = document.getElementById('toggle-lang') as HTMLDivElement;
        tl.onclick = () => {
          if (this.isSaved) {
            return;
          }
          activeLang = (activeLang + 1) % 3;
          this.file.language = this.extensions[activeLang];
          tl.innerHTML = langs[activeLang];
          editor.setValue(code[activeLang]);
          editor.setOption('mode', langsMime[activeLang]);
        };

        editor.on('update', () => {
          if (!this.isUploading) {
            this.isUpToDate = false;
            document.getElementById('saveBtn').innerHTML = 'Save File';
          }
          code[activeLang] = editor.getValue();
          this.file.text = editor.getValue();
        });

        if (filepath !== 'new') {
          const arr = filepath.split('.');
          if (!(['cpp', 'py', 'java']).includes(arr[arr.length - 1])) {
            this.router.navigate(['arena/file/new']).then(() => window.location.reload());
          }
          const arrf = filepath.split('/');
          const arrg = arrf.pop().split('.');
          arrg.pop();
          this.file.filename = arrg.join('.');
          this.file.path = arrf.join('/');
          this.file.language = '.' + arr[arr.length - 1];
          tl.innerHTML = langs[this.extensions.indexOf(this.file.language)];
          this.fileService.getFileContent(this.file.username, filepath)
            .subscribe(data => {
              editor.setValue(data);
              this.isSaved = true;
              this.isUpToDate = true;
              this.loadingFile = false;
              console.log(this.file);
            }, error => {
              this.router.navigate(['arena/file/new']).then(() => window.location.reload());
            });
        } else {
          this.loadingFile = false;
        }

      }

      updateInput(val: string): void {
        this.inp = val;
      }

      updateFile(): void {
        const btn = document.getElementById('saveBtn') as HTMLButtonElement;
        if (btn.classList.contains('disabled')) {
          return;
        }
        this.isUploading = true;
        btn.innerHTML = 'Saving...';
        this.fileService.upload(this.file, false)
          .subscribe(data => {
            btn.innerHTML = 'Saved';
            this.isUploading = false;
            this.isUpToDate = true;
            console.log(data);
          }, error => {
            console.log(error);
            this.isUploading = false;
            btn.innerHTML = 'Save File';
          });
      }

      runFile(): void {
        const btn = document.getElementById('runBtn');
        if (btn.classList.contains('disabled')) {
          return;
        }
        this.isCompiling = true;
        this.runCodeService.compileFile(this.file)
          .subscribe(data => {
            this.runCodeService.executeFile(this.file, this.inp)
              .subscribe(d => {
                console.log(d);
                this.runField.status = '<div class="code">' + d + '</div>';
                this.runField.setState(true);
                this.isCompiling = false;
              }, err => {
                console.log(err);
                this.isCompiling = false;
                this.isError = true;
                this.runField.status = '<div class="error">Runtime Error!</div>';
                this.runField.setState(true);
                setTimeout(() => {
                  this.isError = false;
                }, 3000);
              });
          }, error => {
            console.log(error);
            this.isCompiling = false;
            this.isError = true;
            this.runField.status = '<div class="error">Compilation Error!</div>';
            this.runField.setState(true);
            setTimeout(() => {
              this.isError = false;
            }, 3000);
          });
      }

      optimizeURI(uri: string): string {
        const ret: string[] = [];
        for (const c of uri.split('/')) {
          if (c === '' || c === '.') {
          } else if (c === '..') {
            ret.pop();
          } else {
            ret.push(c);
          }
        }
        return ret.join('') === '' ? '/' : '/' + ret.join('/') + '/';
      }
    }

    <div id="ide-cover" *ngIf="loadingFile">
      <div id="ide-cover-text">
        Loading file...
      </div>
    </div>

    <div class="container">
      <div id="toggle-lang" [class.disabled]="isSaved">C++</div>
      <div id="attempt">
        <span *ngIf="!isUpToDate">• </span>
        <span id="ideFileName">{{optimizeURI(file.path)}}{{file.filename + file.language}}</span>
        <button (click)="inputField.setState(true);" id="inputBtn">Input</button>
        <button (click)="runFile()" id="runBtn" [class.disabled]="isCompiling || isError">{{isError ? 'Error' : (isCompiling ? 'Compiling...' : 'Run File')}}</button>
        <button (click)="!isSaved ? this.saveField.setState(true) : updateFile();"
                [class.disabled]="isUploading || isUpToDate"
                id="saveBtn">{{isUploading ? "Saving File..." : "Save File"}}</button>
      </div>
      <label for="editor"></label>
      <textarea id="editor" name="editor" value="{{inp}}"></textarea>
    </div>
    <app-input (valueEmit)="updateInput($event)"></app-input>
    <app-ide-compile [statusVal]="runCodeService.runStatus"></app-ide-compile>
    <app-save-file (savedFile)="isSaved = isUpToDate = true;" [file]="file"></app-save-file>

`./ide.component.scss`

    .container {
      position: relative;
      padding: 20px;

      #toggle-lang {
        position: absolute;
        background: var(--bgcolor);
        color: var(--color);
        padding: 5px 10px;
        right: 22px;
        top: 22px;
        z-index: 100;
        cursor: pointer;
        user-select: none;

        &.disabled {
          cursor: not-allowed;
        }
      }

      label {
        display: none;
      }

      #attempt {
        position: absolute;
        right: 24px;
        bottom: 24px;
        z-index: 100;

        #runBtn,
        #inputBtn,
        #saveBtn {
          display: inline-block;
          background: transparent;
          color: #ddf;
          margin: 2px;
          cursor: pointer;
          transition: 0.25s all;
          user-select: none;

          &:hover {
            background: var(--color);
            color: var(--bgcolor);
          }

          &.disabled:hover {
            cursor: default;
            background: transparent;
            color: #ddf;
          }
        }
      }
    }

    #ideFileName {
      margin-right: 10px;
    }

    #ide-cover {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: #002e;
      color: #ddf;
      font-size: 1.5em;
      z-index: 10000;

      #ide-cover-text {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%);
      }
    }

    @media screen and (max-width: 800px) {
      .container {
        padding: 20px 0;
      }

      #attempt {
        right: 4px !important;
        bottom: 24px !important;
      }

      #toggle-lang {
        right: 0 !important;
      }
    }

Legend
Html element
Component
Html element with directive

# result-matching ""

# No results matching ""