526 lines
13 KiB
TypeScript
Raw Normal View History

2019-12-03 18:59:11 +09:00
import {
Component,
OnInit,
Output,
EventEmitter,
ViewChild,
AfterViewInit,
ChangeDetectorRef,
OnDestroy,
2019-12-11 08:18:32 +09:00
ElementRef,
Input
2019-12-03 18:59:11 +09:00
} from '@angular/core';
2019-12-06 17:53:19 +09:00
import { ucapAnimations, DialogService } from '@ucap-webmessenger/ui';
2019-12-03 18:59:11 +09:00
import { NGXLogger } from 'ngx-logger';
2019-12-06 17:53:19 +09:00
import moment from 'moment';
2019-12-03 18:59:11 +09:00
import { FileUtil } from '@ucap-webmessenger/core';
2019-12-11 08:18:32 +09:00
import { FormGroup, FormBuilder } from '@angular/forms';
2019-12-04 17:58:59 +09:00
import {
ContentType,
CategoryType,
2019-12-11 08:18:32 +09:00
MessageType,
DetailResponse,
2019-12-12 15:11:49 +09:00
DetailReceiver,
DetailContent
2019-12-04 17:58:59 +09:00
} from '@ucap-webmessenger/api-message';
import { FileUploadItem } from '@ucap-webmessenger/api';
import { UserInfo } from '@ucap-webmessenger/protocol-sync';
2019-12-06 17:53:19 +09:00
import {
ScheduleSendDialogComponent,
ScheduleSendDialogData,
ScheduleSendDialogResult
} from '../dialogs/schedule-send.dialog.component';
2019-12-11 08:18:32 +09:00
import { RoleCode } from '@ucap-webmessenger/protocol-authentication';
import { EmployeeType } from '@ucap-webmessenger/protocol-room';
2019-12-12 15:11:49 +09:00
import { contentTracing } from 'electron';
2019-12-04 17:58:59 +09:00
const ATTR_FILE = 'UCAP_ATTR_FILE';
2019-12-03 18:59:11 +09:00
interface Content {
2019-12-04 17:58:59 +09:00
contentType: ContentType;
content: string | File;
2019-12-12 15:11:49 +09:00
resSeq: number;
2019-12-04 17:58:59 +09:00
}
export interface Message {
category: CategoryType;
type: MessageType;
title: string;
listOrder: ContentType[];
textContent: { text: string }[];
recvUserList: { userSeq: number; userName: string }[];
files?: File[];
fileUploadItem?: FileUploadItem;
reservationTime?: string;
smsYn?: boolean;
2019-12-03 18:59:11 +09:00
}
2019-12-12 15:11:49 +09:00
export interface MessageModify extends Message {
resSeqList: number[];
reservationTime: string;
msgId: number;
}
2019-12-03 18:59:11 +09:00
@Component({
selector: 'ucap-message-write',
templateUrl: './write.component.html',
styleUrls: ['./write.component.scss'],
animations: ucapAnimations
})
export class WriteComponent implements OnInit, OnDestroy, AfterViewInit {
2019-12-11 08:18:32 +09:00
@Input()
curReceiverList: UserInfo[] = [];
@Input()
detail?: DetailResponse;
2019-12-12 15:11:49 +09:00
@Input()
detailContents?: string;
@Input()
isModify = false;
2019-12-11 08:18:32 +09:00
2019-12-04 17:58:59 +09:00
@Output()
2019-12-12 15:11:49 +09:00
send = new EventEmitter<Message | MessageModify>();
2019-12-04 17:58:59 +09:00
2019-12-06 17:53:19 +09:00
@Output()
cancel = new EventEmitter<void>();
2019-12-04 17:58:59 +09:00
@Output()
selectReceiver = new EventEmitter<UserInfo[]>();
2019-12-03 18:59:11 +09:00
@ViewChild('editor', { static: true })
editor: ElementRef<HTMLDivElement>;
@ViewChild('fileInput', { static: true })
fileInput: ElementRef<HTMLInputElement>;
messageWriteForm: FormGroup;
2019-12-12 15:11:49 +09:00
oldAttachmentList: DetailContent[] = [];
2019-12-03 18:59:11 +09:00
attachmentList: File[];
2019-12-04 17:58:59 +09:00
fileUploadItem: FileUploadItem;
receiverList: UserInfo[] = [];
2019-12-09 10:53:25 +09:00
contentLength = 0;
2019-12-03 18:59:11 +09:00
constructor(
private formBuilder: FormBuilder,
2019-12-06 17:53:19 +09:00
private dialogService: DialogService,
2019-12-03 18:59:11 +09:00
private changeDetectorRef: ChangeDetectorRef,
private logger: NGXLogger
) {}
ngOnInit() {
this.messageWriteForm = this.formBuilder.group({
2019-12-09 10:53:25 +09:00
title: ['', []]
2019-12-03 18:59:11 +09:00
});
2019-12-11 08:18:32 +09:00
if (!!this.curReceiverList && this.curReceiverList.length > 0) {
this.receiverList = this.curReceiverList;
} else if (!!this.detail && this.detail.recvList.length > 0) {
this.receiverList = this.detail.recvList.map(recvInfo =>
this.convertDetailReceivertoUserInfo(recvInfo)
);
}
2019-12-12 15:11:49 +09:00
if (this.isModify) {
2019-12-11 08:18:32 +09:00
if (!!this.detail.msgInfo.title) {
this.messageWriteForm.setValue({ title: this.detail.msgInfo.title });
}
2019-12-12 15:11:49 +09:00
if (!!this.detailContents) {
this.editor.nativeElement.innerHTML = this.detailContents;
this.onInputEditor();
2019-12-11 08:18:32 +09:00
}
2019-12-12 15:11:49 +09:00
this.detail.contents.forEach(content => {
if (content.resType === ContentType.AttachFile) {
this.oldAttachmentList.push(content);
}
});
2019-12-11 08:18:32 +09:00
}
2019-12-03 18:59:11 +09:00
}
ngOnDestroy(): void {}
ngAfterViewInit(): void {}
2019-12-12 15:11:49 +09:00
onClickDeleteOldAttachment(oldAttachment: DetailContent) {
this.oldAttachmentList = this.oldAttachmentList.filter(
detailContent => detailContent.resSeq !== oldAttachment.resSeq
);
}
2019-12-03 18:59:11 +09:00
onClickImage() {
this.fileInput.nativeElement.click();
const self = this;
2019-12-03 19:06:29 +09:00
this.fileInput.nativeElement.onchange = async () => {
2019-12-03 18:59:11 +09:00
const fileList: FileList = self.fileInput.nativeElement.files;
2019-12-03 19:06:29 +09:00
for (let i = 0; i < fileList.length; i++) {
const file = fileList.item(i);
const dataUrl = await FileUtil.fromBlobToDataUrl(file);
2019-12-03 18:59:11 +09:00
const img = document.createElement('img');
img.src = dataUrl as string;
2019-12-04 17:58:59 +09:00
img[ATTR_FILE] = file;
2019-12-03 18:59:11 +09:00
self.insertNode(img);
2019-12-03 19:06:29 +09:00
}
2019-12-03 18:59:11 +09:00
self.fileInput.nativeElement.value = '';
2019-12-24 16:16:13 +09:00
this.fileInput.nativeElement.onchange = undefined;
2019-12-03 18:59:11 +09:00
};
}
onClickAttachment() {
this.fileInput.nativeElement.click();
const self = this;
this.fileInput.nativeElement.onchange = () => {
const fileList: FileList = this.fileInput.nativeElement.files;
if (!self.attachmentList) {
self.attachmentList = [];
}
for (let i = 0; i < fileList.length; i++) {
const file = fileList.item(i);
self.attachmentList.push(file);
}
self.changeDetectorRef.detectChanges();
self.fileInput.nativeElement.value = '';
};
}
onPasteEditor(event: ClipboardEvent) {
const text = document.createTextNode(
event.clipboardData.getData('text/plain')
);
this.insertNode(text, true);
2019-12-09 10:53:25 +09:00
this.checkContentLength();
2019-12-03 18:59:11 +09:00
return false;
}
2019-12-09 10:53:25 +09:00
onInputEditor() {
this.checkContentLength();
}
2019-12-04 17:58:59 +09:00
onRemovedReceiver(receiver: UserInfo) {
const index = this.receiverList.indexOf(receiver);
if (index >= 0) {
this.receiverList.splice(index, 1);
}
}
onClickReceiverList() {
this.selectReceiver.emit(this.receiverList);
}
onClickSend() {
2019-12-06 17:53:19 +09:00
this.sendMessage();
}
onClickCancel() {
this.cancel.emit();
}
async onClickSendSchedule() {
2019-12-12 15:11:49 +09:00
const reservationDate = this.isModify
? moment(this.detail.msgInfo.reservationTime)
: undefined;
2019-12-06 17:53:19 +09:00
const result = await this.dialogService.open<
ScheduleSendDialogComponent,
ScheduleSendDialogData,
ScheduleSendDialogResult
>(ScheduleSendDialogComponent, {
width: '600px',
height: '600px',
disableClose: true,
2019-12-12 15:11:49 +09:00
data: {
reservationDate
}
2019-12-06 17:53:19 +09:00
});
if (!!result && !!result.scheduleSendDate) {
this.sendMessage(result.scheduleSendDate);
}
}
2019-12-09 10:53:25 +09:00
private checkContentLength() {
const result = this.parseContent();
if (!result) {
return;
}
const { textContent } = result;
if (!textContent || 0 === textContent.length) {
this.contentLength = 0;
} else {
let len = 0;
textContent.forEach(c => {
len += c.text.length;
});
this.contentLength = len;
}
}
2019-12-06 17:53:19 +09:00
private sendMessage(reservationDate?: moment.Moment) {
2019-12-09 10:53:25 +09:00
const result = this.parseContent();
if (!result) {
return;
}
2019-12-12 15:11:49 +09:00
const { listOrder, textContent, files, resSeqList } = result;
2019-12-09 10:53:25 +09:00
if (!listOrder || 0 === listOrder.length) {
2019-12-04 17:58:59 +09:00
return;
}
const recvUserList: { userSeq: number; userName: string }[] = [];
const title = this.messageWriteForm.get('title').value;
this.receiverList.forEach(v => {
recvUserList.push({
userSeq: v.seq,
userName: v.name
});
});
this.fileUploadItem = FileUploadItem.from();
2019-12-12 15:11:49 +09:00
if (!this.isModify) {
const message: Message = {
category: CategoryType.General,
type: !!reservationDate ? MessageType.Reservation : MessageType.Send,
title,
listOrder,
textContent,
recvUserList,
reservationTime: !!reservationDate
? `${reservationDate.format('YYYY-MM-DD HH:mm')}:00`
: undefined,
files,
fileUploadItem: this.fileUploadItem
};
this.send.emit(message);
} else {
const message: MessageModify = {
category: CategoryType.General,
type: !!reservationDate ? MessageType.Reservation : MessageType.Send,
msgId: this.detail.msgInfo.msgId,
title,
listOrder,
resSeqList,
textContent,
recvUserList,
reservationTime: !!reservationDate
? `${reservationDate.format('YYYY-MM-DD HH:mm')}:00`
: undefined,
files,
fileUploadItem: this.fileUploadItem
};
this.send.emit(message);
}
2019-12-04 17:58:59 +09:00
}
2019-12-09 10:53:25 +09:00
private parseContent():
| {
listOrder: ContentType[];
textContent: { text: string }[];
files: File[];
2019-12-12 15:11:49 +09:00
resSeqList: number[];
2019-12-09 10:53:25 +09:00
}
| undefined {
const contentList: Content[] = this.generateContent();
if (!contentList || 0 === contentList.length) {
return;
}
const listOrder: ContentType[] = [];
const textContent: { text: string }[] = [];
const files: File[] = [];
2019-12-12 15:11:49 +09:00
const resSeqList: number[] = [];
2019-12-09 10:53:25 +09:00
contentList.forEach(v => {
listOrder.push(v.contentType);
2019-12-12 15:11:49 +09:00
resSeqList.push(v.resSeq);
2019-12-09 10:53:25 +09:00
switch (v.contentType) {
case ContentType.Text:
let content = v.content as string;
if ('\n' === content.charAt(content.length - 1)) {
2019-12-12 15:11:49 +09:00
content = content.substring(0, content.length - 1);
2019-12-09 10:53:25 +09:00
}
textContent.push({ text: content });
break;
case ContentType.Image:
case ContentType.AttachFile:
2019-12-12 15:11:49 +09:00
{
if (v.resSeq === 0) {
files.push(v.content as File);
}
}
2019-12-09 10:53:25 +09:00
break;
default:
break;
}
});
return {
listOrder,
textContent,
2019-12-12 15:11:49 +09:00
files,
resSeqList
2019-12-09 10:53:25 +09:00
};
}
2019-12-04 17:58:59 +09:00
private generateContent(): Content[] {
2019-12-03 18:59:11 +09:00
const contentList: Content[] = [];
this.editor.nativeElement.childNodes.forEach((v, k) => {
this.parseNode(contentList, v);
});
2019-12-12 15:11:49 +09:00
if (!!this.oldAttachmentList && 0 < this.oldAttachmentList.length) {
this.oldAttachmentList.forEach(v => {
contentList.push({
contentType: ContentType.AttachFile,
content: v.resContent,
resSeq: v.resSeq
});
});
}
2019-12-04 17:58:59 +09:00
if (!!this.attachmentList && 0 < this.attachmentList.length) {
this.attachmentList.forEach(v => {
contentList.push({
contentType: ContentType.AttachFile,
2019-12-12 15:11:49 +09:00
content: v,
resSeq: 0
2019-12-04 17:58:59 +09:00
});
});
}
return contentList;
2019-12-03 18:59:11 +09:00
}
private parseNode(contentList: Content[], node: ChildNode) {
switch (node.nodeType) {
case Node.ELEMENT_NODE:
{
if (0 < node.childNodes.length) {
let prevNode: ChildNode;
node.childNodes.forEach(v => {
if (
!!prevNode &&
'IMG' === prevNode.nodeName &&
'BR' === v.nodeName
) {
prevNode = v;
return;
}
prevNode = v;
this.parseNode(contentList, v);
});
} else {
if ('IMG' === node.nodeName) {
2019-12-04 17:58:59 +09:00
const img: HTMLImageElement = node as HTMLImageElement;
2019-12-12 15:11:49 +09:00
this.appendNode(
contentList,
ContentType.Image,
img[ATTR_FILE],
!!img.getAttribute('id') ? Number(img.getAttribute('id')) : 0
);
2019-12-03 18:59:11 +09:00
} else if ('BR' === node.nodeName) {
2019-12-04 17:58:59 +09:00
this.appendNode(contentList, ContentType.Text, `\n`);
2019-12-03 18:59:11 +09:00
} else {
}
}
}
break;
case Node.TEXT_NODE:
2019-12-04 17:58:59 +09:00
this.appendNode(contentList, ContentType.Text, node.textContent);
2019-12-03 18:59:11 +09:00
break;
default:
break;
}
}
private appendNode(
contentList: Content[],
2019-12-04 17:58:59 +09:00
contentType: ContentType,
2019-12-12 15:11:49 +09:00
content: string | File,
resSeq: number = 0
2019-12-03 18:59:11 +09:00
) {
const prevContent = contentList[contentList.length - 1];
switch (contentType) {
2019-12-04 17:58:59 +09:00
case ContentType.Text:
if (!!prevContent && ContentType.Text === prevContent.contentType) {
2019-12-03 18:59:11 +09:00
prevContent.content = `${prevContent.content}${content}`;
} else {
contentList.push({
2019-12-04 17:58:59 +09:00
contentType: ContentType.Text,
2019-12-12 15:11:49 +09:00
content,
resSeq
2019-12-03 18:59:11 +09:00
});
}
break;
default:
2019-12-12 15:11:49 +09:00
contentList.push({ contentType, content, resSeq });
2019-12-03 18:59:11 +09:00
break;
}
}
private insertNode(node: Node, removeSelected: boolean = false) {
const selection: Selection = document.getSelection();
const range: Range = selection.getRangeAt(0);
if (removeSelected) {
selection.empty();
}
range.insertNode(node);
}
2019-12-11 08:18:32 +09:00
private convertDetailReceivertoUserInfo(base: DetailReceiver): UserInfo {
return {
seq: base.userSeq,
name: base.userName,
profileImageFile: '',
grade: '',
intro: '',
companyCode: '',
hpNumber: '',
lineNumber: '',
email: '',
isMobile: false,
deptName: '',
isFavorit: false,
isBuddy: false,
isActive: false,
roleCd: RoleCode.Self,
employeeNum: '',
madn: '',
hardSadn: '',
fmcSadn: '',
nameEn: '',
nameCn: '',
gradeEn: '',
gradeCn: '',
deptNameEn: '',
deptNameCn: '',
isPrivacyAgree: false,
isValidLogin: false,
employeeType: EmployeeType.Regular,
nickName: '',
order:''
2019-12-11 08:18:32 +09:00
};
}
2019-12-03 18:59:11 +09:00
}