147 lines
3.6 KiB
TypeScript
Raw Normal View History

2019-10-21 13:36:58 +09:00
import {
Directive,
ElementRef,
EventEmitter,
HostListener,
2019-11-05 13:46:17 +09:00
Output,
Input,
AfterViewInit
2019-10-21 13:36:58 +09:00
} from '@angular/core';
import { NGXLogger } from 'ngx-logger';
2019-11-05 13:46:17 +09:00
import { FileUploadQueueComponent } from '../components/file-upload-queue.component';
2019-11-05 14:55:17 +09:00
import {
FileUploadItem,
CommonApiService
} from '@ucap-webmessenger/api-common';
import { FileUtil } from '@ucap-webmessenger/core';
2019-10-21 13:36:58 +09:00
@Directive({
2019-11-05 13:46:17 +09:00
selector: 'input[ucapFileUploadFor], div[ucapFileUploadFor]'
2019-10-21 13:36:58 +09:00
})
2019-11-05 13:46:17 +09:00
export class FileUploadForDirective implements AfterViewInit {
@Input()
fileUploadQueue: FileUploadQueueComponent;
2019-10-21 13:36:58 +09:00
@Output()
2019-10-31 17:09:38 +09:00
public fileDragEnter = new EventEmitter<DataTransferItemList>();
2019-10-21 13:36:58 +09:00
@Output()
2019-10-31 17:09:38 +09:00
public fileDragOver = new EventEmitter<void>();
2019-10-21 13:36:58 +09:00
@Output()
2019-10-31 17:09:38 +09:00
public fileDragLeave = new EventEmitter<void>();
2019-10-21 13:36:58 +09:00
@Output()
2019-11-05 13:46:17 +09:00
public fileSelected = new EventEmitter<FileUploadItem[]>();
2019-10-21 13:36:58 +09:00
dragOver = false;
2019-11-05 14:55:17 +09:00
constructor(
private commonApiService: CommonApiService,
private elementRef: ElementRef,
private logger: NGXLogger
) {}
2019-10-21 13:36:58 +09:00
2019-11-05 13:46:17 +09:00
ngAfterViewInit(): void {}
2019-10-21 13:36:58 +09:00
@HostListener('window:dragenter', ['$event'])
2019-10-31 17:09:38 +09:00
public onDragEnter(event: DragEvent): any {
if (!this.isFileDrag(event.dataTransfer)) {
return;
}
2019-10-21 13:36:58 +09:00
if (!this.dragOver) {
2019-10-31 17:09:38 +09:00
this.fileDragEnter.emit(event.dataTransfer.items);
2019-10-21 13:36:58 +09:00
this.dragOver = true;
2019-11-05 13:46:17 +09:00
if (!!this.fileUploadQueue) {
this.fileUploadQueue.onDragEnter(event.dataTransfer.items);
}
2019-10-21 13:36:58 +09:00
}
}
@HostListener('window:dragover', ['$event'])
2019-10-31 17:09:38 +09:00
public onDragOver(event: DragEvent): any {
if (!this.isFileDrag(event.dataTransfer)) {
return;
}
2019-11-05 13:46:17 +09:00
if (this.fileUploadQueue.isEventInElement(event)) {
2019-10-31 17:09:38 +09:00
event.dataTransfer.dropEffect = 'copy';
} else {
event.dataTransfer.dropEffect = 'none';
}
2019-10-21 13:36:58 +09:00
event.preventDefault();
}
@HostListener('window:dragleave', ['$event'])
2019-10-31 17:09:38 +09:00
public onDragLeave(event: DragEvent): any {
if (!this.isFileDrag(event.dataTransfer)) {
return;
}
2019-10-21 13:36:58 +09:00
if (event && event.pageX === 0 && event.pageY === 0) {
this.fileDragLeave.emit();
this.dragOver = false;
2019-11-05 13:46:17 +09:00
if (!!this.fileUploadQueue) {
this.fileUploadQueue.onDragLeave();
}
2019-10-21 13:36:58 +09:00
}
}
@HostListener('change')
public onChange(): any {
const files = this.elementRef.nativeElement.files;
2019-11-05 13:46:17 +09:00
this.fileSelected.emit(FileUploadItem.fromFiles(files));
2019-10-21 13:36:58 +09:00
this.elementRef.nativeElement.value = '';
}
@HostListener('window:drop', ['$event'])
public onDrop(event: any): any {
2019-10-31 17:09:38 +09:00
if (!this.isFileDrag(event.dataTransfer)) {
return;
}
2019-11-05 14:55:17 +09:00
const files: FileList = event.dataTransfer.files;
if (
!this.commonApiService.acceptableExtensionForFileTalk(
FileUtil.getExtensions(files)
)
) {
this.logger.debug('window:drop not acceptable');
if (!!this.fileUploadQueue) {
this.fileUploadQueue.onDragLeave();
}
this.elementRef.nativeElement.value = '';
this.dragOver = false;
return;
}
2019-11-05 13:46:17 +09:00
const fileUploadItems = FileUploadItem.fromFiles(files);
this.fileSelected.emit(fileUploadItems);
2019-10-21 13:36:58 +09:00
event.preventDefault();
event.stopPropagation();
this.elementRef.nativeElement.value = '';
this.dragOver = false;
2019-11-05 13:46:17 +09:00
if (!!this.fileUploadQueue) {
this.fileUploadQueue.onDrop(fileUploadItems);
}
2019-10-21 13:36:58 +09:00
}
2019-10-31 17:09:38 +09:00
private isFileDrag(dataTransfer: DataTransfer): boolean {
if (0 >= dataTransfer.items.length) {
return false;
}
// tslint:disable-next-line: prefer-for-of
for (let i = 0; i < dataTransfer.items.length; i++) {
const element = dataTransfer.items[i];
if ('file' !== element.kind) {
return false;
}
}
return true;
}
2019-10-21 13:36:58 +09:00
}