Commit 8a2d19b8 authored by 神楽坂玲奈's avatar 神楽坂玲奈

OnPush

parent b4b3c595
{ {
"name": "mycard-mobile", "name": "mycard-mobile",
"version": "1.0.23", "version": "1.0.29",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
...@@ -122,9 +122,9 @@ ...@@ -122,9 +122,9 @@
} }
}, },
"@angular/cdk": { "@angular/cdk": {
"version": "6.2.1", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-6.2.1.tgz", "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-6.3.0.tgz",
"integrity": "sha512-uwW4eIGJKqOkR+ew6YcEAh1J4SP98jdyDpsZ4IEMkV9+jXcKfcwcxGFpZvs9wJsAvAr8EgNmZ8h+iuZLwJsvmA==", "integrity": "sha512-L1NM2hU8xvb35mDKIw+SR9UZGZtbSQl6fmd9X/tedaNYjIvyQ7SIX7iDJ+LqD0xUQopB+SeuhDL7D6IwGMV2bQ==",
"requires": { "requires": {
"tslib": "^1.7.1" "tslib": "^1.7.1"
} }
...@@ -358,9 +358,9 @@ ...@@ -358,9 +358,9 @@
"dev": true "dev": true
}, },
"@angular/material": { "@angular/material": {
"version": "6.2.1", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/@angular/material/-/material-6.2.1.tgz", "resolved": "https://registry.npmjs.org/@angular/material/-/material-6.3.0.tgz",
"integrity": "sha512-SBoUXxHknkgwzp5pNDHW0jyrTM0d0Tk4lVyDbtEX8VEPtXqG5nL3BSgyjpJbTvqlmy2kOooUu3qgAmt87VH9lw==", "integrity": "sha512-asSzdfLkDDbQEyM/GKUxrlvuj8OvO5DqrNJ3e3uvi0OmZDpaO50yubQvrJ26nbqgwgRo+qwiGNN6XcFwYTRVPQ==",
"requires": { "requires": {
"tslib": "^1.7.1" "tslib": "^1.7.1"
} }
...@@ -434,6 +434,13 @@ ...@@ -434,6 +434,13 @@
"@angular-devkit/core": "0.6.8", "@angular-devkit/core": "0.6.8",
"@angular-devkit/schematics": "0.6.8", "@angular-devkit/schematics": "0.6.8",
"typescript": ">=2.6.2 <2.8" "typescript": ">=2.6.2 <2.8"
},
"dependencies": {
"typescript": {
"version": "2.7.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.2.tgz",
"integrity": "sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw=="
}
} }
}, },
"@schematics/update": { "@schematics/update": {
...@@ -451,15 +458,15 @@ ...@@ -451,15 +458,15 @@
} }
}, },
"@types/lodash": { "@types/lodash": {
"version": "4.14.109", "version": "4.14.110",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.109.tgz", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.110.tgz",
"integrity": "sha512-hop8SdPUEzbcJm6aTsmuwjIYQo1tqLseKCM+s2bBqTU2gErwI4fE+aqUVOlscPSQbKHKgtMMPoC+h4AIGOJYvw==", "integrity": "sha512-iXYLa6olt4tnsCA+ZXeP6eEW3tk1SulWeYyP/yooWfAtXjozqXgtX4+XUtMuOCfYjKGz3F34++qUc3Q+TJuIIw==",
"dev": true "dev": true
}, },
"@types/node": { "@types/node": {
"version": "10.3.3", "version": "10.3.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.3.3.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.3.4.tgz",
"integrity": "sha512-/gwCgiI2e9RzzZTKbl+am3vgNqOt7a9fJ/uxv4SqYKxenoEDNVU3KZEadlpusWhQI0A0dOrZ0T68JYKVjzmgdQ==", "integrity": "sha512-YMLlzdeNnAyLrQew39IFRkMacAR5BqKGIEei9ZjdHsIZtv+ZWKYTu1i7QJhetxQ9ReXx8w5f+cixdHZG3zgMQA==",
"dev": true "dev": true
}, },
"@webassemblyjs/ast": { "@webassemblyjs/ast": {
...@@ -8221,9 +8228,9 @@ ...@@ -8221,9 +8228,9 @@
"integrity": "sha512-AVP5Xol3WivEr7hnssHDsaM+lVrVXWUvd1cfXTRkTj80b//6g2wIFEH6hZG0muGZRnHGrfttpdzRk3YlBkWjKw==" "integrity": "sha512-AVP5Xol3WivEr7hnssHDsaM+lVrVXWUvd1cfXTRkTj80b//6g2wIFEH6hZG0muGZRnHGrfttpdzRk3YlBkWjKw=="
}, },
"tslint": { "tslint": {
"version": "5.9.1", "version": "5.10.0",
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.9.1.tgz", "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.10.0.tgz",
"integrity": "sha1-ElX4ej/1frCw4fDmEKi0dIBGya4=", "integrity": "sha1-EeJrzLiK+gLdDZlWyuPUVAtfVMM=",
"dev": true, "dev": true,
"requires": { "requires": {
"babel-code-frame": "^6.22.0", "babel-code-frame": "^6.22.0",
...@@ -8312,7 +8319,8 @@ ...@@ -8312,7 +8319,8 @@
"typescript": { "typescript": {
"version": "2.7.2", "version": "2.7.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.2.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.2.tgz",
"integrity": "sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==" "integrity": "sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==",
"dev": true
}, },
"uglify-js": { "uglify-js": {
"version": "3.3.28", "version": "3.3.28",
......
{ {
"name": "mycard-mobile", "name": "mycard-mobile",
"version": "1.0.28", "version": "1.0.30",
"license": "UNLISENCED", "license": "UNLISENCED",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
...@@ -14,13 +14,13 @@ ...@@ -14,13 +14,13 @@
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "6.0.5", "@angular/animations": "6.0.5",
"@angular/cdk": "^6.2.1", "@angular/cdk": "^6.3.0",
"@angular/common": "6.0.5", "@angular/common": "6.0.5",
"@angular/compiler": "6.0.5", "@angular/compiler": "6.0.5",
"@angular/core": "6.0.5", "@angular/core": "6.0.5",
"@angular/forms": "6.0.5", "@angular/forms": "6.0.5",
"@angular/http": "6.0.5", "@angular/http": "6.0.5",
"@angular/material": "^6.2.1", "@angular/material": "^6.3.0",
"@angular/platform-browser": "6.0.5", "@angular/platform-browser": "6.0.5",
"@angular/platform-browser-dynamic": "6.0.5", "@angular/platform-browser-dynamic": "6.0.5",
"@angular/pwa": "^0.6.8", "@angular/pwa": "^0.6.8",
...@@ -41,11 +41,11 @@ ...@@ -41,11 +41,11 @@
"@angular/cli": "^6.0.8", "@angular/cli": "^6.0.8",
"@angular/compiler-cli": "6.0.5", "@angular/compiler-cli": "6.0.5",
"@angular/language-service": "6.0.5", "@angular/language-service": "6.0.5",
"@types/lodash": "^4.14.109", "@types/lodash": "^4.14.110",
"@types/node": "^10.3.3", "@types/node": "^10.3.4",
"codelyzer": "^4.0.1", "codelyzer": "^4.0.1",
"prettier": "^1.12.1", "prettier": "^1.12.1",
"tslint": "~5.9.1", "tslint": "~5.10.0",
"typescript": "2.7.2" "typescript": "^2.7.2"
} }
} }
...@@ -27,9 +27,9 @@ import { environment } from '../environments/environment'; ...@@ -27,9 +27,9 @@ import { environment } from '../environments/environment';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { LobbyComponent } from './lobby/lobby.component'; import { LobbyComponent } from './lobby/lobby.component';
import { MatchDialogComponent } from './match/match.component'; import { MatchDialogComponent } from './match-dialog/match-dialog.component';
import { NewRoomComponent } from './new-room/new-room.component'; import { NewRoomComponent } from './new-room/new-room.component';
import { ResultDialogComponent } from './result/result.dialog'; import { ResultDialogComponent } from './result-dialog/result-dialog.component';
import { RoomListComponent } from './room-list/room-list.component'; import { RoomListComponent } from './room-list/room-list.component';
import { StorageService } from './storage.service'; import { StorageService } from './storage.service';
import { ToolbarComponent } from './toolbar/toolbar.component'; import { ToolbarComponent } from './toolbar/toolbar.component';
......
import { Component, Inject, OnInit } from '@angular/core'; import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
@Component({ @Component({
selector: 'app-confirm-dialog', selector: 'app-confirm-dialog',
templateUrl: './confirm-dialog.component.html', templateUrl: './confirm-dialog.component.html',
styleUrls: ['./confirm-dialog.component.css'] styleUrls: ['./confirm-dialog.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class ConfirmDialogComponent implements OnInit { export class ConfirmDialogComponent implements OnInit {
constructor(public dialogRef: MatDialogRef<ConfirmDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {} constructor(public dialogRef: MatDialogRef<ConfirmDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {}
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
</mat-option> </mat-option>
</mat-autocomplete> </mat-autocomplete>
</form> </form>
<button mat-icon-button *ngIf="storage.working"> <button mat-icon-button *ngIf="storage.working | async">
<mat-icon class="fa-spin">sync</mat-icon> <mat-icon class="fa-spin">sync</mat-icon>
</button> </button>
<a href="https://accounts.moecube.com/profiles" target="_blank" mat-icon-button> <a href="https://accounts.moecube.com/profiles" target="_blank" mat-icon-button>
...@@ -84,83 +84,83 @@ ...@@ -84,83 +84,83 @@
<!--<br>轮抽 (开发中)</a></mat-grid-tile>--> <!--<br>轮抽 (开发中)</a></mat-grid-tile>-->
</mat-grid-list> </mat-grid-list>
<mat-card *ngIf="ygopro.points"> <mat-card *ngIf="ygopro.points | async as points">
<mat-grid-list id="points" cols="4" rowHeight="20px"> <mat-grid-list id="points" cols="4" rowHeight="20px">
<mat-grid-tile> <mat-grid-tile>
<dt>竞技排名</dt> <dt>竞技排名</dt>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dd>{{ygopro.points.arena_rank}}</dd> <dd>{{points.arena_rank}}</dd>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dt>娱乐排名</dt> <dt>娱乐排名</dt>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dd>{{ygopro.points.exp_rank}}</dd> <dd>{{points.exp_rank}}</dd>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dt>竞技胜率</dt> <dt>竞技胜率</dt>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dd>{{ygopro.points.athletic_wl_ratio}}%</dd> <dd>{{points.athletic_wl_ratio}}%</dd>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dt>经验</dt> <dt>经验</dt>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dd>{{ygopro.points.exp}}</dd> <dd>{{points.exp}}</dd>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dt>胜场</dt> <dt>胜场</dt>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dd>{{ygopro.points.athletic_win}}</dd> <dd>{{points.athletic_win}}</dd>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dt>胜场</dt> <dt>胜场</dt>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dd>{{ygopro.points.entertain_win}}</dd> <dd>{{points.entertain_win}}</dd>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dt>负场</dt> <dt>负场</dt>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dd>{{ygopro.points.athletic_lose}}</dd> <dd>{{points.athletic_lose}}</dd>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dt>负场</dt> <dt>负场</dt>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dd>{{ygopro.points.entertain_lose}}</dd> <dd>{{points.entertain_lose}}</dd>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dt>平局</dt> <dt>平局</dt>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dd>{{ygopro.points.athletic_draw}}</dd> <dd>{{points.athletic_draw}}</dd>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dt>平局</dt> <dt>平局</dt>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dd>{{ygopro.points.entertain_draw}}</dd> <dd>{{points.entertain_draw}}</dd>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dt>总场</dt> <dt>总场</dt>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dd>{{ygopro.points.athletic_all}}</dd> <dd>{{points.athletic_all}}</dd>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dt>总场</dt> <dt>总场</dt>
</mat-grid-tile> </mat-grid-tile>
<mat-grid-tile> <mat-grid-tile>
<dd>{{ygopro.points.entertain_all}}</dd> <dd>{{points.entertain_all}}</dd>
</mat-grid-tile> </mat-grid-tile>
</mat-grid-list> </mat-grid-list>
</mat-card> </mat-card>
<mat-card *ngFor="let item of ygopro.news" class="example-card"> <mat-card *ngFor="let item of ygopro.news | async" class="example-card">
<a [href]="item.url" target="_blank"> <a [href]="item.url" target="_blank">
<mat-card-header> <mat-card-header>
<img *ngIf="item.image" mat-card-avatar [src]="item.image"> <img *ngIf="item.image" mat-card-avatar [src]="item.image">
......
import { Component, HostBinding } from '@angular/core'; import { ChangeDetectionStrategy, Component, HostBinding } from '@angular/core';
import { FormControl } from '@angular/forms'; import { FormControl } from '@angular/forms';
import { environment } from '../../environments/environment'; import { environment } from '../../environments/environment';
import { LoginService } from '../login.service'; import { LoginService } from '../login.service';
...@@ -13,7 +13,8 @@ import { distinctUntilChanged, filter, map, switchMap } from 'rxjs/internal/oper ...@@ -13,7 +13,8 @@ import { distinctUntilChanged, filter, map, switchMap } from 'rxjs/internal/oper
selector: 'app-lobby', selector: 'app-lobby',
templateUrl: 'lobby.component.html', templateUrl: 'lobby.component.html',
styleUrls: ['lobby.component.css'], styleUrls: ['lobby.component.css'],
animations: routerTransition animations: routerTransition,
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class LobbyComponent { export class LobbyComponent {
@HostBinding('@routerTransition2') animation; @HostBinding('@routerTransition2') animation;
......
...@@ -6,6 +6,7 @@ mat-icon { ...@@ -6,6 +6,7 @@ mat-icon {
mat-dialog-content { mat-dialog-content {
display: flex; display: flex;
overflow: hidden;
} }
mat-dialog-actions { mat-dialog-actions {
justify-content: flex-end justify-content: flex-end
......
import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; import { ChangeDetectionStrategy, Component, Inject, OnDestroy, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
import { Subscription, timer } from 'rxjs'; import { Subscription, timer } from 'rxjs';
import { LoginService } from '../login.service'; import { LoginService } from '../login.service';
...@@ -11,8 +11,9 @@ const offset = new Date().getTimezoneOffset() * 60 * second; ...@@ -11,8 +11,9 @@ const offset = new Date().getTimezoneOffset() * 60 * second;
@Component({ @Component({
selector: 'app-match', selector: 'app-match',
templateUrl: './match.component.html', templateUrl: './match-dialog.component.html',
styleUrls: ['./match.component.css'] styleUrls: ['./match-dialog.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class MatchDialogComponent implements OnInit, OnDestroy { export class MatchDialogComponent implements OnInit, OnDestroy {
expect_wait = this.http expect_wait = this.http
......
...@@ -20,10 +20,6 @@ form { ...@@ -20,10 +20,6 @@ form {
/*margin: 0 10px;*/ /*margin: 0 10px;*/
/*}*/ /*}*/
mat-select {
padding: 1.2734375em 0;
}
#actions { #actions {
text-align: right; text-align: right;
} }
...@@ -19,17 +19,21 @@ ...@@ -19,17 +19,21 @@
</button> </button>
<mat-hint align="end">把这个分享给你的朋友</mat-hint> <mat-hint align="end">把这个分享给你的朋友</mat-hint>
</mat-form-field> </mat-form-field>
<mat-select class="full-width" placeholder="卡片允许" name="rule" [(ngModel)]="room.options.rule" required> <mat-form-field class="full-width">
<mat-option [value]="0">OCG</mat-option> <mat-select placeholder="卡片允许" name="rule" [(ngModel)]="room.options.rule" required>
<mat-option [value]="1">TCG</mat-option> <mat-option [value]="0">OCG</mat-option>
<mat-option [value]="2">OCG & TCG</mat-option> <mat-option [value]="1">TCG</mat-option>
<mat-option [value]="3">专有卡禁止</mat-option> <mat-option [value]="2">OCG & TCG</mat-option>
</mat-select> <mat-option [value]="3">专有卡禁止</mat-option>
<mat-select class="full-width" placeholder="决斗模式" name="mode" [(ngModel)]="room.options.mode" (ngModelChange)="set_start_lp()" required> </mat-select>
<mat-option [value]="0">单局模式</mat-option> </mat-form-field>
<mat-option [value]="1">比赛模式</mat-option> <mat-form-field class="full-width">
<mat-option [value]="2">TAG</mat-option> <mat-select placeholder="决斗模式" name="mode" [(ngModel)]="room.options.mode" (ngModelChange)="set_start_lp()" required>
</mat-select> <mat-option [value]="0">单局模式</mat-option>
<mat-option [value]="1">比赛模式</mat-option>
<mat-option [value]="2">TAG</mat-option>
</mat-select>
</mat-form-field>
<!--<h2>额外选项</h2>--> <!--<h2>额外选项</h2>-->
<!--<mat-slide-toggle #extra class="example-margin" color="primary">额外选项</mat-slide-toggle>--> <!--<mat-slide-toggle #extra class="example-margin" color="primary">额外选项</mat-slide-toggle>-->
......
import { Component, ElementRef, HostBinding, ViewChild } from '@angular/core'; import { ChangeDetectionStrategy, Component, ElementRef, HostBinding, ViewChild } from '@angular/core';
import { MatSnackBar } from '@angular/material'; import { MatSnackBar } from '@angular/material';
import { LoginService } from '../login.service'; import { LoginService } from '../login.service';
import { routerTransition } from '../router.animations'; import { routerTransition } from '../router.animations';
...@@ -8,7 +8,8 @@ import { YGOProService } from '../ygopro.service'; ...@@ -8,7 +8,8 @@ import { YGOProService } from '../ygopro.service';
selector: 'app-new-room', selector: 'app-new-room',
templateUrl: 'new-room.component.html', templateUrl: 'new-room.component.html',
styleUrls: ['new-room.component.css'], styleUrls: ['new-room.component.css'],
animations: routerTransition animations: routerTransition,
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class NewRoomComponent { export class NewRoomComponent {
@HostBinding('@routerTransition') animation; @HostBinding('@routerTransition') animation;
...@@ -25,16 +26,11 @@ export class NewRoomComponent { ...@@ -25,16 +26,11 @@ export class NewRoomComponent {
constructor(public ygopro: YGOProService, private login: LoginService, private snackBar: MatSnackBar) {} constructor(public ygopro: YGOProService, private login: LoginService, private snackBar: MatSnackBar) {}
copy(host_password: string) { copy(host_password: string) {
try { this.hostPasswordInput.nativeElement.select();
this.hostPasswordInput.nativeElement.select(); if (document.execCommand('copy')) {
this.snackBar.open(`房间密码 ${host_password} 已复制到剪贴板`, undefined, { duration: 3000 });
if (document.execCommand('copy')) { } else {
this.snackBar.open(`房间密码 ${host_password} 已复制到剪贴板`, undefined, { duration: 3000 }); console.log('Oops, unable to copy');
} else {
console.log('Oops, unable to copy');
}
} catch (error) {
console.log(error);
} }
} }
......
...@@ -19,6 +19,5 @@ ...@@ -19,6 +19,5 @@
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions> <mat-dialog-actions>
<button mat-button mat-dialog-close>关闭</button> <button mat-button mat-dialog-close>关闭</button>
<!-- Can optionally provide a result for the closing dialog. --> <button mat-button [mat-dialog-close]="true">再来一局</button>
<button mat-button (click)="again()">再来一局</button>
</mat-dialog-actions> </mat-dialog-actions>
import { Component, Inject } from '@angular/core'; import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material'; import { MAT_DIALOG_DATA } from '@angular/material';
import { LoginService } from '../login.service'; import { LoginService } from '../login.service';
import { MatchDialogComponent } from '../match/match.component';
@Component({ @Component({
selector: 'app-result', selector: 'app-result',
templateUrl: './result.dialog.html', templateUrl: './result-dialog.component.html',
styleUrls: ['./result.dialog.css'] styleUrls: ['./result-dialog.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class ResultDialogComponent { export class ResultDialogComponent implements OnInit {
result: 'win' | 'lose' | 'draw'; result: 'win' | 'lose' | 'draw';
dp: string | undefined; dp: string | undefined;
exp: string | undefined; exp: string | undefined;
firstWin: string | undefined; firstWin: string | undefined;
constructor( constructor(@Inject(MAT_DIALOG_DATA) public last: any, public login: LoginService) {}
@Inject(MAT_DIALOG_DATA) public last: any,
public login: LoginService, ngOnInit() {
public dialog: MatDialog,
private dialogRef: MatDialogRef<MatchDialogComponent>
) {
if (this.last.userscorea === this.last.userscoreb) { if (this.last.userscorea === this.last.userscoreb) {
this.result = 'draw'; this.result = 'draw';
} else if (this.last.winner === this.login.user.username) { } else if (this.last.winner === this.login.user.username) {
...@@ -43,8 +40,4 @@ export class ResultDialogComponent { ...@@ -43,8 +40,4 @@ export class ResultDialogComponent {
const result = Math.round(current) - Math.round(ex); const result = Math.round(current) - Math.round(ex);
return result ? `${result < 0 ? '' : '+'}${Math.round(result)}` : undefined; return result ? `${result < 0 ? '' : '+'}${Math.round(result)}` : undefined;
} }
again() {
this.dialogRef.close(true);
}
} }
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
left: 0; left: 0;
bottom: 56px; bottom: 56px;
right: 0; right: 0;
z-index: 1; z-index: 2;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
<div id="container"> <div id="container">
<div class="hint" *ngIf="dataSource.loading"> <div class="hint" *ngIf="dataSource.loading | async">
<mat-spinner></mat-spinner> <mat-spinner></mat-spinner>
</div> </div>
<div class="hint" *ngIf="dataSource.empty">现在没有等待中的游戏,可以自行创建一个房间或者去匹配</div> <div class="hint" *ngIf="dataSource.empty | async">现在没有等待中的游戏,可以自行创建一个房间或者去匹配</div>
<div class="hint" *ngIf="dataSource.error">网络错误</div> <div class="hint" *ngIf="dataSource.error | async">网络错误</div>
<mat-table #table [dataSource]="dataSource"> <mat-table #table [dataSource]="dataSource">
......
import { ChangeDetectorRef, Component, HostBinding, OnInit } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostBinding, OnInit } from '@angular/core';
import { LoginService } from '../login.service'; import { LoginService } from '../login.service';
import { routerTransition } from '../router.animations'; import { routerTransition } from '../router.animations';
...@@ -8,7 +8,8 @@ import { RoomListDataSource, YGOProService } from '../ygopro.service'; ...@@ -8,7 +8,8 @@ import { RoomListDataSource, YGOProService } from '../ygopro.service';
selector: 'app-room-list', selector: 'app-room-list',
styleUrls: ['room-list.component.css'], styleUrls: ['room-list.component.css'],
templateUrl: 'room-list.component.html', templateUrl: 'room-list.component.html',
animations: routerTransition animations: routerTransition,
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class RoomListComponent implements OnInit { export class RoomListComponent implements OnInit {
@HostBinding('@routerTransition') animation; @HostBinding('@routerTransition') animation;
......
import { Injectable } from '@angular/core'; import { EventEmitter, Injectable } from '@angular/core';
import * as path from 'path'; import * as path from 'path';
import * as webdav from 'webdav'; import * as webdav from 'webdav';
import { LoginService } from './login.service'; import { LoginService } from './login.service';
...@@ -27,7 +27,7 @@ export class StorageService { ...@@ -27,7 +27,7 @@ export class StorageService {
app_id = 'ygopro'; app_id = 'ygopro';
client = webdav('https://api.mycard.moe/storage/', this.login.user.username, this.login.user.external_id.toString()); client = webdav('https://api.mycard.moe/storage/', this.login.user.username, this.login.user.external_id.toString());
working = false; working = new EventEmitter();
constructor(private login: LoginService) {} constructor(private login: LoginService) {}
...@@ -111,11 +111,11 @@ export class StorageService { ...@@ -111,11 +111,11 @@ export class StorageService {
// fixme: 如果远端和本地同时没有,但是 localStorage 里有,要删除 // fixme: 如果远端和本地同时没有,但是 localStorage 里有,要删除
// console.log('sync', 'done'); // console.log('sync', 'done');
this.working = false; this.working.emit(false);
} }
async download(local_path: string, remote_path: string, index_path: string, time: number) { async download(local_path: string, remote_path: string, index_path: string, time: number) {
this.working = true; this.working.emit(true);
// console.log('download', local_path, remote_path, index_path, time); // console.log('download', local_path, remote_path, index_path, time);
const data: ArrayBuffer = await this.client.getFileContents(remote_path); const data: ArrayBuffer = await this.client.getFileContents(remote_path);
window.ygopro.writeFile(local_path, Buffer.from(data).toString('base64')); window.ygopro.writeFile(local_path, Buffer.from(data).toString('base64'));
...@@ -125,7 +125,7 @@ export class StorageService { ...@@ -125,7 +125,7 @@ export class StorageService {
} }
async upload(local_path: string, remote_path: string, index_path: string) { async upload(local_path: string, remote_path: string, index_path: string) {
this.working = true; this.working.emit(true);
// console.log('upload', local_path, remote_path, index_path); // console.log('upload', local_path, remote_path, index_path);
const data = this.read_local(local_path); const data = this.read_local(local_path);
await this.client.putFileContents(remote_path, data); await this.client.putFileContents(remote_path, data);
...@@ -141,13 +141,13 @@ export class StorageService { ...@@ -141,13 +141,13 @@ export class StorageService {
} }
remove_local(local_path: string, remote_path: string, index_path: string) { remove_local(local_path: string, remote_path: string, index_path: string) {
this.working = true; this.working.emit(true);
window.ygopro.unlink(local_path); window.ygopro.unlink(local_path);
localStorage.removeItem(index_path); localStorage.removeItem(index_path);
} }
async remove_remote(local_path: string, remote_path: string, index_path: string) { async remove_remote(local_path: string, remote_path: string, index_path: string) {
this.working = true; this.working.emit(true);
await this.client.deleteFile(remote_path); await this.client.deleteFile(remote_path);
localStorage.removeItem(index_path); localStorage.removeItem(index_path);
} }
...@@ -157,7 +157,7 @@ export class StorageService { ...@@ -157,7 +157,7 @@ export class StorageService {
const remote_path = path.join(root, local_path); const remote_path = path.join(root, local_path);
const index_path = '_FILE_' + remote_path; const index_path = '_FILE_' + remote_path;
this.working = true; this.working.emit(true);
window.ygopro.unlink(local_path); window.ygopro.unlink(local_path);
await this.client.deleteFile(remote_path); await this.client.deleteFile(remote_path);
localStorage.removeItem(index_path); localStorage.removeItem(index_path);
......
import { Component } from '@angular/core'; import { ChangeDetectionStrategy, Component } from '@angular/core';
import { routerTransition } from '../router.animations'; import { routerTransition } from '../router.animations';
@Component({ @Component({
selector: 'app-toolbar', selector: 'app-toolbar',
templateUrl: './toolbar.component.html', templateUrl: './toolbar.component.html',
styleUrls: ['./toolbar.component.css'], styleUrls: ['./toolbar.component.css'],
animations: [routerTransition] animations: [routerTransition],
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class ToolbarComponent { export class ToolbarComponent {
history = history; history = history;
......
...@@ -13,9 +13,9 @@ ...@@ -13,9 +13,9 @@
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
bottom: 56px; bottom: 0;
right: 0; right: 0;
z-index: 1; z-index: 2;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
...@@ -33,4 +33,5 @@ ...@@ -33,4 +33,5 @@
#container { #container {
position: relative; position: relative;
flex: 1;
} }
<app-toolbar>观战</app-toolbar> <app-toolbar>观战</app-toolbar>
<div id="container"> <div id="container">
<div class="hint" *ngIf="dataSource.loading"> <div class="hint" *ngIf="dataSource.loading | async">
<mat-spinner></mat-spinner> <mat-spinner></mat-spinner>
</div> </div>
<div class="hint" *ngIf="dataSource.empty">现在没有进行中的游戏</div> <div class="hint" *ngIf="dataSource.empty | async">现在没有进行中的游戏</div>
<div class="hint" *ngIf="dataSource.error">网络错误</div> <div class="hint" *ngIf="dataSource.error | async">网络错误</div>
<mat-table #table [dataSource]="dataSource"> <mat-table #table [dataSource]="dataSource">
......
import { ChangeDetectorRef, Component, HostBinding, OnInit } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostBinding, OnInit } from '@angular/core';
import { LoginService } from '../login.service'; import { LoginService } from '../login.service';
import { routerTransition } from '../router.animations'; import { routerTransition } from '../router.animations';
import { RoomListDataSource, YGOProService } from '../ygopro.service'; import { RoomListDataSource, YGOProService } from '../ygopro.service';
...@@ -7,7 +7,8 @@ import { RoomListDataSource, YGOProService } from '../ygopro.service'; ...@@ -7,7 +7,8 @@ import { RoomListDataSource, YGOProService } from '../ygopro.service';
selector: 'app-watch', selector: 'app-watch',
templateUrl: './watch.component.html', templateUrl: './watch.component.html',
styleUrls: ['./watch.component.css'], styleUrls: ['./watch.component.css'],
animations: routerTransition animations: routerTransition,
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class WatchComponent implements OnInit { export class WatchComponent implements OnInit {
@HostBinding('@routerTransition') animation; @HostBinding('@routerTransition') animation;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<mat-icon mat-list-icon>&#xe195;</mat-icon><!-- airplanemode_active --> <mat-icon mat-list-icon>&#xe195;</mat-icon><!-- airplanemode_active -->
<h4 mat-line>随机</h4> <h4 mat-line>随机</h4>
</mat-list-item> </mat-list-item>
<mat-list-item *ngFor="let windbot of ygopro.windbot" (click)="ygopro.join_windbot(windbot)"> <mat-list-item *ngFor="let windbot of ygopro.windbot | async" (click)="ygopro.join_windbot(windbot)">
<img mat-list-icon [src]="login.avatar(windbot)"> <img mat-list-icon [src]="login.avatar(windbot)">
<h4 mat-line>{{windbot}}</h4> <h4 mat-line>{{windbot}}</h4>
</mat-list-item> </mat-list-item>
......
import { Component, HostBinding } from '@angular/core'; import { ChangeDetectionStrategy, Component, HostBinding } from '@angular/core';
import { LoginService } from '../login.service'; import { LoginService } from '../login.service';
import { routerTransition } from '../router.animations'; import { routerTransition } from '../router.animations';
import { YGOProService } from '../ygopro.service'; import { YGOProService } from '../ygopro.service';
...@@ -7,7 +7,8 @@ import { YGOProService } from '../ygopro.service'; ...@@ -7,7 +7,8 @@ import { YGOProService } from '../ygopro.service';
selector: 'app-windbot', selector: 'app-windbot',
templateUrl: './windbot.component.html', templateUrl: './windbot.component.html',
styleUrls: ['./windbot.component.css'], styleUrls: ['./windbot.component.css'],
animations: routerTransition animations: routerTransition,
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class WindbotComponent { export class WindbotComponent {
@HostBinding('@routerTransition') animation; @HostBinding('@routerTransition') animation;
......
import { DataSource } from '@angular/cdk/collections'; import { DataSource } from '@angular/cdk/collections';
import { Injectable } from '@angular/core'; import { EventEmitter, Injectable } from '@angular/core';
import { MatDialog } from '@angular/material'; import { MatDialog } from '@angular/material';
import { sortBy } from 'lodash'; import { sample, sortBy } from 'lodash';
import { combineLatest, fromEvent, Observable, of } from 'rxjs'; import { BehaviorSubject, combineLatest, fromEvent, Observable, of } from 'rxjs';
import { LoginService } from './login.service'; import { LoginService } from './login.service';
import { MatchDialogComponent } from './match/match.component'; import { MatchDialogComponent } from './match-dialog/match-dialog.component';
import { ResultDialogComponent } from './result/result.dialog'; import { ResultDialogComponent } from './result-dialog/result-dialog.component';
import { StorageService } from './storage.service'; import { StorageService } from './storage.service';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { catchError, filter, map, scan } from 'rxjs/internal/operators'; import { catchError, filter, map, mergeMap, scan, startWith } from 'rxjs/internal/operators';
import { webSocket } from 'rxjs/webSocket'; import { webSocket } from 'rxjs/webSocket';
export interface User { export interface User {
...@@ -112,12 +112,10 @@ export interface Points { ...@@ -112,12 +112,10 @@ export interface Points {
@Injectable() @Injectable()
export class YGOProService { export class YGOProService {
news: News[]; news: Promise<News[]>;
windbot: string[]; topics: Promise<any[]>;
topics: Observable<any>; windbot: Promise<string[]>;
points: Points; points: BehaviorSubject<Points | undefined> = new BehaviorSubject(undefined);
last_game_at: Date;
readonly default_options: Options = { readonly default_options: Options = {
mode: 1, mode: 1,
...@@ -131,7 +129,6 @@ export class YGOProService { ...@@ -131,7 +129,6 @@ export class YGOProService {
lflist: 0, lflist: 0,
time_limit: 180 time_limit: 180
}; };
readonly servers: Server[] = [ readonly servers: Server[] = [
{ {
id: 'tiramisu', id: 'tiramisu',
...@@ -152,70 +149,77 @@ export class YGOProService { ...@@ -152,70 +149,77 @@ export class YGOProService {
]; ];
constructor(private login: LoginService, private http: HttpClient, private dialog: MatDialog, private storage: StorageService) { constructor(private login: LoginService, private http: HttpClient, private dialog: MatDialog, private storage: StorageService) {
this.load(); const app = this.http.get<App[]>('https://api.mycard.moe/apps.json').pipe(map(apps => apps.find(_app => _app.id === 'ygopro')!));
} this.news = app.pipe(map(_app => _app.news['zh-CN'])).toPromise();
this.windbot = app.pipe(map(_app => (<YGOProData>_app.data).windbot['zh-CN'])).toPromise();
async load() {
const apps = await this.http.get<App[]>('https://api.mycard.moe/apps.json').toPromise(); this.topics = this.http
const app = apps.find(_app => _app.id === 'ygopro')!; .get<TopResponse>('https://ygobbs.com/top/quarterly.json')
this.news = app.news['zh-CN']; .pipe(
this.windbot = (<YGOProData>app.data).windbot['zh-CN']; map(data =>
this.topics = this.http.get<TopResponse>('https://ygobbs.com/top/quarterly.json').pipe( data.topic_list.topics.slice(0, 5).map((topic: any) => ({
map(data => ...topic,
data.topic_list.topics.slice(0, 5).map((topic: any) => ({ url: new URL(`/t/${topic.slug}/${topic.id}`, 'https://ygobbs.com').toString(),
...topic, image_url: topic.image_url && new URL(topic.image_url, 'https://ygobbs.com').toString()
url: new URL(`/t/${topic.slug}/${topic.id}`, 'https://ygobbs.com').toString(), }))
image_url: topic.image_url && new URL(topic.image_url, 'https://ygobbs.com').toString() )
}))
) )
);
this.storage.sync();
this.load_points();
await this.load_result(false);
this.listen_result();
}
async load_result(load_points = true) {
const last = await this.http
.get<{ data: any[] }>('https://mycard.moe/ygopro/api/history', {
params: { username: this.login.user.username, type: '0', page_num: '1' }
})
.pipe(map(data => data.data[0]))
.toPromise(); .toPromise();
// 从来没打过 const refresh = fromEvent(document, 'visibilitychange').pipe(
if (!last) { filter(() => document.visibilityState === 'visible'),
return; startWith(undefined)
} );
const last_game_at = localStorage.getItem('last_game_at'); refresh
localStorage.setItem('last_game_at', last.end_time); .pipe(
mergeMap(() =>
this.http.get<Points>('https://api.mycard.moe/ygopro/arena/user', { params: { username: this.login.user.username } })
)
)
.subscribe(this.points);
refresh
.pipe(
mergeMap(() =>
this.http.get<{ data: any[] }>('https://mycard.moe/ygopro/api/history', {
params: { username: this.login.user.username, type: '0', page_num: '1' }
})
),
map(data => data.data[0])
)
.subscribe(async (last: any) => {
// 从来没打过
if (!last) {
return;
}
const last_game_at = localStorage.getItem('last_game_at');
localStorage.setItem('last_game_at', last.end_time);
// 初次运行 // 初次运行
if (!last_game_at) { if (!last_game_at) {
return; return;
} }
// 无新对局 // 无新对局
if (last_game_at === last.end_time) { if (last_game_at === last.end_time) {
return; return;
} }
// 10分钟内有新对局 // 10分钟内有新对局
if (Date.now() - Date.parse(last.end_time) < 10 * 60 * 1000) { if (Date.now() - Date.parse(last.end_time) < 10 * 60 * 1000) {
// console.log(last); const again = await this.dialog
if (load_points) { .open(ResultDialogComponent, { data: last })
this.load_points(); .afterClosed()
} .toPromise();
const again = await this.dialog if (again) {
.open(ResultDialogComponent, { data: last }) this.request_match(last.type);
.afterClosed() }
.toPromise(); }
if (again) { });
this.request_match(last.type);
} refresh.subscribe(() => {
} this.storage.sync();
});
} }
async request_match(arena: string) { async request_match(arena: string) {
...@@ -228,33 +232,6 @@ export class YGOProService { ...@@ -228,33 +232,6 @@ export class YGOProService {
} }
} }
listen_result() {
// 那些兼容性的垃圾事儿
// https://www.html5rocks.com/en/tutorials/pagevisibility/intro/
const hidden = ['hidden', 'webkitHidden', 'mozHidden', 'msHidden', 'oHidden'].find(prop => prop in document);
if (hidden) {
const evtname = hidden.replace(/[H|h]idden/, '') + 'visibilitychange';
fromEvent(document, evtname).subscribe(() => {
if (!document[hidden]) {
this.load_result();
this.storage.sync();
}
});
} else {
fromEvent(window, 'focus').subscribe(() => {
this.load_result();
this.storage.sync();
});
}
}
async load_points() {
this.points = await this.http
.get<Points>('https://api.mycard.moe/ygopro/arena/user', { params: { username: this.login.user.username } })
.toPromise();
}
create_room(room: Room, host_password: string) { create_room(room: Room, host_password: string) {
const options_buffer = Buffer.alloc(6); const options_buffer = Buffer.alloc(6);
// 建主密码 https://docs.google.com/document/d/1rvrCGIONua2KeRaYNjKBLqyG9uybs9ZI-AmzZKNftOI/edit // 建主密码 https://docs.google.com/document/d/1rvrCGIONua2KeRaYNjKBLqyG9uybs9ZI-AmzZKNftOI/edit
...@@ -331,9 +308,9 @@ export class YGOProService { ...@@ -331,9 +308,9 @@ export class YGOProService {
this.join(name, this.servers[0]); this.join(name, this.servers[0]);
} }
join_windbot(name?: string) { async join_windbot(name?: string) {
if (!name) { if (!name) {
name = this.windbot[Math.floor(Math.random() * this.windbot.length)]; name = sample(await this.windbot.toPromise());
} }
return this.join('AI#' + name, this.servers[0]); return this.join('AI#' + name, this.servers[0]);
} }
...@@ -422,9 +399,9 @@ type Message = ...@@ -422,9 +399,9 @@ type Message =
| { event: 'delete'; data: string }; | { event: 'delete'; data: string };
export class RoomListDataSource extends DataSource<Room> { export class RoomListDataSource extends DataSource<Room> {
loading = true; loading = new EventEmitter();
empty = false; empty = new EventEmitter();
error: any; error = new EventEmitter();
constructor(private servers: Server[], private type = 'waiting') { constructor(private servers: Server[], private type = 'waiting') {
super(); super();
...@@ -432,6 +409,7 @@ export class RoomListDataSource extends DataSource<Room> { ...@@ -432,6 +409,7 @@ export class RoomListDataSource extends DataSource<Room> {
/** Connect function called by the table to retrieve one stream containing the data to render. */ /** Connect function called by the table to retrieve one stream containing the data to render. */
connect(): Observable<Room[]> { connect(): Observable<Room[]> {
this.loading.emit(true);
return combineLatest( return combineLatest(
this.servers.map(server => { this.servers.map(server => {
const url = new URL(server.url!); const url = new URL(server.url!);
...@@ -473,13 +451,13 @@ export class RoomListDataSource extends DataSource<Room> { ...@@ -473,13 +451,13 @@ export class RoomListDataSource extends DataSource<Room> {
), ),
// loading、empty、error // loading、empty、error
filter(rooms => { filter(rooms => {
this.loading = false; this.loading.emit(false);
this.empty = rooms.length === 0; this.empty.emit(rooms.length === 0);
return true; return true;
}), }),
catchError(error => { catchError(error => {
this.loading = false; this.loading.emit(false);
this.error = error; this.error.emit(error);
return of([]); return of([]);
}) })
); );
......
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
// import 'core-js/es7/reflect'; // import 'core-js/es7/reflect';
import 'core-js/fn/symbol/async-iterator'; import 'core-js/fn/symbol/async-iterator';
/** /**
* Required to support Web Animations `@angular/platform-browser/animations`. * Required to support Web Animations `@angular/platform-browser/animations`.
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
...@@ -57,11 +56,11 @@ import 'core-js/fn/symbol/async-iterator'; ...@@ -57,11 +56,11 @@ import 'core-js/fn/symbol/async-iterator';
* user can disable parts of macroTask/DomEvents patch by setting following flags * user can disable parts of macroTask/DomEvents patch by setting following flags
*/ */
// (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
// (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
// (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
/* /*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge * with the following flag, it will bypass `zone.js` patch for IE/Edge
*/ */
...@@ -70,9 +69,7 @@ import 'core-js/fn/symbol/async-iterator'; ...@@ -70,9 +69,7 @@ import 'core-js/fn/symbol/async-iterator';
/*************************************************************************************************** /***************************************************************************************************
* Zone JS is required by default for Angular itself. * Zone JS is required by default for Angular itself.
*/ */
import 'zone.js/dist/zone'; // Included with Angular CLI. import 'zone.js/dist/zone'; // Included with Angular CLI.
/*************************************************************************************************** /***************************************************************************************************
* APPLICATION IMPORTS * APPLICATION IMPORTS
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
"moduleResolution": "node", "moduleResolution": "node",
"emitDecoratorMetadata": true, "emitDecoratorMetadata": true,
"experimentalDecorators": true, "experimentalDecorators": true,
"target": "es2016", "target": "es2017",
"strict": true, "strict": true,
"noImplicitAny": false, "noImplicitAny": false,
"strictPropertyInitialization": false, "strictPropertyInitialization": false,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment