This commit is contained in:
leejinho 2020-02-17 14:53:55 +09:00
commit c589053b88
10 changed files with 64 additions and 160 deletions

11
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "ucap-webmessenger", "name": "ucap-webmessenger",
"version": "0.0.20", "version": "0.0.21",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -3392,15 +3392,6 @@
"integrity": "sha512-g1QUuhYVVAamfCifK7oB7G3aIl4BbOyzDOqVyUfEr4tfBKrXfeH+M+Tg7HKCXSrbzxYdhyCP7z9WbKo0R2hBCw==", "integrity": "sha512-g1QUuhYVVAamfCifK7oB7G3aIl4BbOyzDOqVyUfEr4tfBKrXfeH+M+Tg7HKCXSrbzxYdhyCP7z9WbKo0R2hBCw==",
"dev": true "dev": true
}, },
"@types/file-type": {
"version": "10.9.1",
"resolved": "https://registry.npmjs.org/@types/file-type/-/file-type-10.9.1.tgz",
"integrity": "sha512-oq0fy8Jqj19HofanFsZ56o5anMDUQtFO9B3wfLqM9o42RyCe1WT+wRbSvRbL2l8ARZXNaJturHk0b442+0yi+g==",
"dev": true,
"requires": {
"file-type": "*"
}
},
"@types/filesize": { "@types/filesize": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/@types/filesize/-/filesize-4.2.0.tgz", "resolved": "https://registry.npmjs.org/@types/filesize/-/filesize-4.2.0.tgz",

View File

@ -89,7 +89,6 @@
"@types/electron-debug": "^2.1.0", "@types/electron-debug": "^2.1.0",
"@types/electron-devtools-installer": "^2.2.0", "@types/electron-devtools-installer": "^2.2.0",
"@types/extract-text-webpack-plugin": "^3.0.4", "@types/extract-text-webpack-plugin": "^3.0.4",
"@types/file-type": "^10.9.1",
"@types/file-saver": "^2.0.1", "@types/file-saver": "^2.0.1",
"@types/filesize": "^4.1.0", "@types/filesize": "^4.1.0",
"@types/fs-extra": "^8.0.1", "@types/fs-extra": "^8.0.1",

View File

@ -1,4 +1,4 @@
import { Injectable, Inject } from '@angular/core'; import { Injectable, Inject, ChangeDetectorRef } from '@angular/core';
import { import {
HttpClient, HttpClient,
HttpEventType, HttpEventType,
@ -179,7 +179,10 @@ export class CommonApiService {
'POST', 'POST',
!!fileTalkSaveUrl ? fileTalkSaveUrl : this.urls.fileTalkSave, !!fileTalkSaveUrl ? fileTalkSaveUrl : this.urls.fileTalkSave,
encodeFileTalkSave(req), encodeFileTalkSave(req),
{ reportProgress: true, responseType: 'text' as 'json' } {
reportProgress: true,
responseType: 'text' as 'json'
}
); );
const progress = req.fileUploadItem.uploadStart(); const progress = req.fileUploadItem.uploadStart();
@ -200,11 +203,8 @@ export class CommonApiService {
); );
} }
public acceptableExtensionForFileTalk( public acceptableExtensionForFileTalk(extensions: string[]): string[] {
extensions: string[] const rejected: string[] = [];
): { accept: boolean; reject: string[] } {
let accept = true;
const reject: string[] = [];
for (const extension of extensions) { for (const extension of extensions) {
if ( if (
!extension || !extension ||
@ -213,51 +213,39 @@ export class CommonApiService {
extension.toLowerCase() extension.toLowerCase()
) )
) { ) {
reject.push(!!extension ? extension : 'empty-ext'); rejected.push(!!extension ? extension : 'empty-ext');
accept = false;
} }
} }
return { return 0 === rejected.length ? undefined : rejected;
accept,
reject
};
} }
public checkInvalidMediaMimeForFileTalk( public checkInvalidMediaMimeForFileTalk(files: File[]): Promise<string[]> {
files: File[] return new Promise<string[]>(async (resolve, reject) => {
): Promise<{ accept: boolean; rejected: string[] }> { const mediaFiles = this.mediaFiles(files);
return new Promise<{ accept: boolean; rejected: string[] }>( if (!mediaFiles) {
async (resolve, reject) => { resolve(undefined);
const mediaFiles = this.mediaFiles(files); return;
if (!mediaFiles) {
resolve({
accept: true,
rejected: undefined
});
return;
}
let accept = true;
const rejected: string[] = [];
for (const file of mediaFiles) {
const info = await MimeUtil.getMimeFromBlob(file);
// console.log('mime info', info);
if (
!file ||
!info ||
(-1 === info.mime.indexOf('video/') &&
-1 === info.mime.indexOf('image/'))
) {
rejected.push(file.name);
accept = false;
}
}
resolve({
accept,
rejected
});
} }
);
const rejected: string[] = [];
for (const file of mediaFiles) {
const info = await MimeUtil.getMimeFromBuffer(
await FileUtil.fromBlobToBuffer(file)
);
if (
!file ||
!info ||
(-1 === info.mime.indexOf('video/') &&
-1 === info.mime.indexOf('image/'))
) {
rejected.push(file.name);
}
}
resolve(0 === rejected.length ? undefined : rejected);
return;
});
} }
mediaFiles(files: File[]): File[] { mediaFiles(files: File[]): File[] {

View File

@ -71,7 +71,7 @@ import {
RoomType, RoomType,
UserInfoShort UserInfoShort
} from '@ucap-webmessenger/protocol-room'; } from '@ucap-webmessenger/protocol-room';
import { take, map, catchError } from 'rxjs/operators'; import { take, map, catchError, tap } from 'rxjs/operators';
import { import {
FormComponent as UCapUiChatFormComponent, FormComponent as UCapUiChatFormComponent,
MessagesComponent as UCapUiChatMessagesComponent, MessagesComponent as UCapUiChatMessagesComponent,
@ -1075,6 +1075,8 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
roomSeq: this.roomInfoSubject.value.roomSeq roomSeq: this.roomInfoSubject.value.roomSeq
}; };
const files: File[] = fileUploadItems.map(fui => fui.file);
const allObservables: Observable<FileTalkSaveResponse>[] = []; const allObservables: Observable<FileTalkSaveResponse>[] = [];
const fileAllowSize = const fileAllowSize =
@ -1083,11 +1085,7 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
: environment.productConfig.CommonSetting.defaultFileAllowSize; : environment.productConfig.CommonSetting.defaultFileAllowSize;
if (fileAllowSize > 0) { if (fileAllowSize > 0) {
if ( if (files.filter(f => f.size > fileAllowSize * 1024 * 1024).length) {
fileUploadItems.filter(
fui => fui.file.size > fileAllowSize * 1024 * 1024
).length
) {
this.snackBarService.open( this.snackBarService.open(
this.translateService.instant('common.file.errors.oversize', { this.translateService.instant('common.file.errors.oversize', {
maxSize: fileAllowSize maxSize: fileAllowSize
@ -1112,9 +1110,9 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
// ); // );
const checkExt = this.commonApiService.acceptableExtensionForFileTalk( const checkExt = this.commonApiService.acceptableExtensionForFileTalk(
fileUploadItems.map(fui => FileUtil.getExtension(fui.file.name)) files.map(f => FileUtil.getExtension(f.name))
); );
if (!checkExt.accept) { if (!!checkExt) {
if (!!this.fileUploadQueue) { if (!!this.fileUploadQueue) {
this.fileUploadQueue.onUploadComplete(); this.fileUploadQueue.onUploadComplete();
} }
@ -1130,8 +1128,7 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
html: this.translateService.instant( html: this.translateService.instant(
'common.file.errors.notSupporedType', 'common.file.errors.notSupporedType',
{ {
supporedType: supporedType: checkExt.join(',')
checkExt.reject.length > 0 ? checkExt.reject.join(',') : ''
} }
) )
} }
@ -1140,10 +1137,10 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
return; return;
} }
const fakeMedia = await this.commonApiService.checkInvalidMediaMimeForFileTalk( const fakeMedias = await this.commonApiService.checkInvalidMediaMimeForFileTalk(
fileUploadItems.map(fui => fui.file) files
); );
if (!fakeMedia.accept) { if (!!fakeMedias) {
if (!!this.fileUploadQueue) { if (!!this.fileUploadQueue) {
this.fileUploadQueue.onUploadComplete(); this.fileUploadQueue.onUploadComplete();
} }
@ -1159,10 +1156,7 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
html: this.translateService.instant( html: this.translateService.instant(
'common.file.errors.notAcceptableMime', 'common.file.errors.notAcceptableMime',
{ {
supporedType: supporedType: fakeMedias.length > 0 ? fakeMedias.join(',') : ''
fakeMedia.rejected.length > 0
? fakeMedia.rejected.join(',')
: ''
} }
) )
} }
@ -1250,13 +1244,11 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
this.translateService.instant('common.file.errors.failToUpload'), this.translateService.instant('common.file.errors.failToUpload'),
this.translateService.instant('common.file.errors.label') this.translateService.instant('common.file.errors.label')
); );
},
() => {
if (!!this.fileUploadQueue) { if (!!this.fileUploadQueue) {
this.fileUploadQueue.onUploadComplete(); this.fileUploadQueue.onUploadComplete();
} }
},
() => {
this.fileUploadQueue.onUploadComplete();
} }
); );
} }

View File

@ -31,7 +31,7 @@ export class FileUtil {
static fromBlobToBuffer(blob: Blob): Promise<Buffer> { static fromBlobToBuffer(blob: Blob): Promise<Buffer> {
return new Promise<Buffer>((resolve, reject) => { return new Promise<Buffer>((resolve, reject) => {
const fileReader = new FileReader(); const fileReader = new FileReader();
fileReader.onload = () => { fileReader.onloadend = () => {
return resolve(Buffer.from(fileReader.result as ArrayBuffer)); return resolve(Buffer.from(fileReader.result as ArrayBuffer));
}; };
fileReader.onerror = (event: ProgressEvent) => { fileReader.onerror = (event: ProgressEvent) => {

View File

@ -86,11 +86,4 @@
#chatMessagesBufferContainer #chatMessagesBufferContainer
fxFlexFill fxFlexFill
class="chat-messages-buffer-container disappear" class="chat-messages-buffer-container disappear"
> ></div>
<div
#chatMessagesBuffer
fxFlexFill
perfectScrollbar
class="chat-messages-buffer"
></div>
</div>

View File

@ -169,8 +169,6 @@ $tablet-l-width: 1024px;
overflow-y: hidden !important; overflow-y: hidden !important;
padding: 2vh 2vw; padding: 2vh 2vw;
flex-direction: column; flex-direction: column;
.chat-messages-buffer {
}
} }
.translation-container { .translation-container {
font-size: 0.9em; font-size: 0.9em;

View File

@ -114,9 +114,6 @@ export class MessagesComponent implements OnInit, OnDestroy {
@ViewChild('chatMessagesContainer', { static: false }) @ViewChild('chatMessagesContainer', { static: false })
chatMessagesContainer: ElementRef<HTMLElement>; chatMessagesContainer: ElementRef<HTMLElement>;
@ViewChild('chatMessagesBuffer', { static: false })
chatMessagesBuffer: ElementRef<HTMLElement>;
@ViewChild('chatMessagesBufferContainer', { static: false }) @ViewChild('chatMessagesBufferContainer', { static: false })
chatMessagesBufferContainer: ElementRef<HTMLElement>; chatMessagesBufferContainer: ElementRef<HTMLElement>;
@ -457,15 +454,17 @@ export class MessagesComponent implements OnInit, OnDestroy {
if (useSwap && !this.swapped) { if (useSwap && !this.swapped) {
this.chatMessagesBufferContainer.nativeElement.classList.add('hide'); this.chatMessagesBufferContainer.nativeElement.classList.add('hide');
this.chatMessagesBuffer.nativeElement.innerHTML = this.chatMessagesContainer.nativeElement.innerHTML; const scrollElement: HTMLElement = this.virtualScroller[
// tslint:disable-next-line: no-string-literal
'element'
].nativeElement;
this.chatMessagesBufferContainer.nativeElement.innerHTML =
scrollElement.innerHTML;
this.chatMessagesBufferContainer.nativeElement.classList.remove( this.chatMessagesBufferContainer.nativeElement.classList.remove(
'disappear' 'disappear'
); );
this.chatMessagesBuffer.nativeElement.scrollTop = this.virtualScroller[
// tslint:disable-next-line: no-string-literal
'element'
].nativeElement.scrollTop;
this.chatMessagesBufferContainer.nativeElement.classList.remove('hide'); this.chatMessagesBufferContainer.nativeElement.classList.remove('hide');
this.swapped = true; this.swapped = true;
@ -479,8 +478,7 @@ export class MessagesComponent implements OnInit, OnDestroy {
postSwapScroll(useHide: boolean, useSwap: boolean) { postSwapScroll(useHide: boolean, useSwap: boolean) {
if (useSwap && this.swapped) { if (useSwap && this.swapped) {
this.chatMessagesBuffer.nativeElement.innerHTML = ''; this.chatMessagesBufferContainer.nativeElement.innerHTML = '';
this.chatMessagesBuffer.nativeElement.scrollTop = 0;
this.chatMessagesBufferContainer.nativeElement.classList.add('disappear'); this.chatMessagesBufferContainer.nativeElement.classList.add('disappear');
this.swapped = false; this.swapped = false;
} }

View File

@ -266,7 +266,7 @@ export class WriteComponent implements OnInit, OnDestroy, AfterViewInit {
const checkExt = this.commonApiService.acceptableExtensionForFileTalk( const checkExt = this.commonApiService.acceptableExtensionForFileTalk(
FileUtil.getExtensions(fileList) FileUtil.getExtensions(fileList)
); );
if (!checkExt.accept) { if (!!checkExt) {
this.ngZone.run(() => { this.ngZone.run(() => {
this.snackBarService.openFromComponent< this.snackBarService.openFromComponent<
AlertSnackbarComponent, AlertSnackbarComponent,
@ -279,8 +279,7 @@ export class WriteComponent implements OnInit, OnDestroy, AfterViewInit {
html: this.translateService.instant( html: this.translateService.instant(
'common.file.errors.notSupporedType', 'common.file.errors.notSupporedType',
{ {
supporedType: supporedType: checkExt.join(',')
checkExt.reject.length > 0 ? checkExt.reject.join(',') : ''
} }
) )
} }
@ -297,7 +296,7 @@ export class WriteComponent implements OnInit, OnDestroy, AfterViewInit {
const fakeMedia = await this.commonApiService.checkInvalidMediaMimeForFileTalk( const fakeMedia = await this.commonApiService.checkInvalidMediaMimeForFileTalk(
files files
); );
if (!fakeMedia.accept) { if (!!fakeMedia) {
this.ngZone.run(() => { this.ngZone.run(() => {
this.snackBarService.openFromComponent< this.snackBarService.openFromComponent<
AlertSnackbarComponent, AlertSnackbarComponent,
@ -310,10 +309,7 @@ export class WriteComponent implements OnInit, OnDestroy, AfterViewInit {
html: this.translateService.instant( html: this.translateService.instant(
'common.file.errors.notAcceptableMime', 'common.file.errors.notAcceptableMime',
{ {
supporedType: supporedType: fakeMedia.join(',')
fakeMedia.rejected.length > 0
? fakeMedia.rejected.join(',')
: ''
} }
) )
} }

View File

@ -11,19 +11,6 @@ import {
import { NGXLogger } from 'ngx-logger'; import { NGXLogger } from 'ngx-logger';
import { FileUploadQueueComponent } from '../components/file-upload-queue.component'; import { FileUploadQueueComponent } from '../components/file-upload-queue.component';
import { FileUploadItem } from '@ucap-webmessenger/api'; import { FileUploadItem } from '@ucap-webmessenger/api';
import { CommonApiService } from '@ucap-webmessenger/api-common';
import { FileUtil } from '@ucap-webmessenger/core';
import {
AlertDialogComponent,
AlertDialogResult,
AlertDialogData
} from '../dialogs/alert.dialog.component';
import { TranslateService } from '@ngx-translate/core';
import { SnackBarService } from '../services/snack-bar.service';
import {
AlertSnackbarComponent,
AlertSnackbarData
} from '../snackbars/alert.snackbar.component';
@Directive({ @Directive({
selector: 'input[ucapFileUploadFor], div[ucapFileUploadFor]' selector: 'input[ucapFileUploadFor], div[ucapFileUploadFor]'
@ -46,13 +33,7 @@ export class FileUploadForDirective implements AfterViewInit {
dragOver = false; dragOver = false;
constructor( constructor(private elementRef: ElementRef, private logger: NGXLogger) {}
private commonApiService: CommonApiService,
private elementRef: ElementRef,
private logger: NGXLogger,
private translateService: TranslateService,
private snackBarService: SnackBarService
) {}
ngAfterViewInit(): void {} ngAfterViewInit(): void {}
@ -114,38 +95,6 @@ export class FileUploadForDirective implements AfterViewInit {
} }
const files: FileList = event.dataTransfer.files; const files: FileList = event.dataTransfer.files;
const checkExt = this.commonApiService.acceptableExtensionForFileTalk(
FileUtil.getExtensions(files)
);
if (!checkExt.accept) {
this.logger.debug('window:drop not acceptable');
if (!!this.fileUploadQueue) {
this.fileUploadQueue.onDragLeave();
}
this.elementRef.nativeElement.value = '';
this.dragOver = false;
this.snackBarService.openFromComponent<
AlertSnackbarComponent,
AlertSnackbarData
>(AlertSnackbarComponent, {
duration: 1000,
verticalPosition: 'bottom',
horizontalPosition: 'center',
data: {
html: this.translateService.instant(
'common.file.errors.notSupporedType',
{
supporedType:
checkExt.reject.length > 0 ? checkExt.reject.join(',') : ''
}
)
}
});
return;
}
const fileUploadItems = FileUploadItem.fromFiles(files); const fileUploadItems = FileUploadItem.fromFiles(files);
this.fileSelected.emit(fileUploadItems); this.fileSelected.emit(fileUploadItems);
event.preventDefault(); event.preventDefault();