import { Component , ViewChild , OnInit , Inject , OnDestroy } from '@angular/core' ; import { MatDialogRef , MAT_DIALOG_DATA } from '@angular/material/dialog' ; import { forkJoin , Subject } from 'rxjs' ; import { takeUntil , filter } from 'rxjs/operators' ; import { NotaddUtils } from '@notadd/utils' ; import { NotaddFileUploadService } from '../file-upload.service' ; export interface DialogData { accept : string ; maxFileSize : number ; maxFiles : number ; fileCount : number ; fileExtensions : string ; } @ Component ( { selector : 'notadd-file-upload-dialog' , templateUrl : './dialog.component.html' , styleUrls : [ './dialog.component.scss' ] } ) export class NotaddFileUploadDialogComponent implements OnInit , OnDestroy { @ ViewChild ( 'file' , { static : true } ) file ; files : Set < File > ; primaryButtonText : string ; showCancelButton : boolean ; uploading : boolean ; uploadSuccessful : boolean ; progress : any ; canBeClosed : boolean ; errors : Array < string > ; private uploadResponse : Array < any > ; private ngUnsubscribe : Subject < boolean > = new Subject ( ) ; constructor ( private dialogRef , private fileUploadService , @ Inject ( MAT_DIALOG_DATA ) public dialogData ) { this . files = new Set ( ) ; this . canBeClosed = false ; this . primaryButtonText = '上传' ; this . showCancelButton = true ; this . uploading = false ; this . uploadSuccessful = false ; this . errors = [ ] ; this . dialogData = Object . assign ( { } , { accept : 'image/*' , maxFileSize : 5 , maxFiles : 5 , fileCount : 5 , fileExtensions : 'JPG, GIF, PNG' } , this . dialogData ) ; } get primaryDisabled ( ) : boolean { if ( this . primaryButtonText === '上传' ) { return ! this . files . size || ! ! this . errors . length || this . uploading ; } else if ( this . primaryButtonText === '重新上传' ) { return ! this . files . size ; } else { return this . uploading || ! this . canBeClosed ; } } get filesErrors ( ) { const filesWithArray = Array . from ( this . files ) ; return [ ... NotaddUtils . isValidFiles ( filesWithArray , this . dialogData . maxFiles ) , ... NotaddUtils . isValidFileExtension ( filesWithArray , this . dialogData . fileExtensions ) , ... NotaddUtils . isValidFileSize ( filesWithArray , this . dialogData . maxFileSize ) ] ; } ngOnInit ( ) { this . fileUploadService . fileUploadProgressChange . pipe ( takeUntil ( this . ngUnsubscribe ) ) . subscribe ( progress => { this . progress = progress ; const allProgressObservables = [ ] ; for ( const key in this . progress ) { allProgressObservables . push ( this . progress [ key ] . progress ) ; } this . primaryButtonText = '完成' ; this . canBeClosed = false ; this . dialogRef . disableClose = true ; this . showCancelButton = false ; forkJoin ( allProgressObservables ) . subscribe ( end => { this . uploadResponse = end ; this . uploadSuccessful = true ; } , error => { this . showCancelButton = true ; this . primaryButtonText = '重新上传' ; this . uploadSuccessful = false ; } , ( ) => { this . canBeClosed = true ; this . dialogRef . disableClose = false ; this . uploading = false ; } ) ; } ) ; this . fileUploadService . fileUploadErrorChange . pipe ( takeUntil ( this . ngUnsubscribe ) , filter ( ( { type } ) => type === 'progress' ) ) . subscribe ( ( { errors } ) => { errors . map ( err => { this . errors . push ( err ) ; } ) ; } ) ; } onFilesAdded ( ) { const files = this . file . nativeElement . files ; for ( const key in files ) { if ( ! isNaN ( parseInt ( key ) ) ) { this . files . add ( files [ key ] ) ; } } this . errors = this . filesErrors ; } addFiles ( ) { this . file . nativeElement . click ( ) ; } removeFile ( file ) { this . files . delete ( file ) ; this . errors = this . filesErrors ; } closeDialog ( ) { if ( this . files . size && this . primaryButtonText !== '重新上传' && this . errors . length ) { return ; } if ( this . uploadSuccessful ) { return this . dialogRef . close ( this . uploadResponse ) ; } this . uploading = true ; this . fileUploadService . startUpload ( Array . from ( this . files ) , 'progress' ) ; } ngOnDestroy ( ) { this . ngUnsubscribe . next ( ) ; this . ngUnsubscribe . complete ( ) ; } }