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,
|
2020-02-05 17:57:18 +09:00
|
|
|
Input,
|
|
|
|
NgZone
|
2019-12-03 18:59:11 +09:00
|
|
|
} from '@angular/core';
|
|
|
|
|
2020-01-09 18:14:00 +09:00
|
|
|
import {
|
|
|
|
ucapAnimations,
|
|
|
|
DialogService,
|
|
|
|
AlertDialogResult,
|
|
|
|
AlertDialogComponent,
|
2020-02-05 17:57:18 +09:00
|
|
|
AlertDialogData,
|
2020-02-10 09:33:41 +09:00
|
|
|
SnackBarService,
|
|
|
|
AlertSnackbarComponent,
|
|
|
|
AlertSnackbarData
|
2020-01-09 18:14:00 +09:00
|
|
|
} 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';
|
2020-02-06 10:29:48 +09:00
|
|
|
import { FormGroup, FormBuilder, Validators } 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';
|
2020-01-09 18:14:00 +09:00
|
|
|
import { TranslateService } from '@ngx-translate/core';
|
|
|
|
import { CommonApiService } from '@ucap-webmessenger/api-common';
|
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()
|
2020-01-20 09:00:15 +09:00
|
|
|
set curReceiverList(userInfoList: UserInfo[]) {
|
|
|
|
if (!!userInfoList && userInfoList.length > 0) {
|
|
|
|
this.receiverList = userInfoList;
|
|
|
|
}
|
|
|
|
}
|
2019-12-11 08:18:32 +09:00
|
|
|
@Input()
|
|
|
|
detail?: DetailResponse;
|
2019-12-12 15:11:49 +09:00
|
|
|
@Input()
|
|
|
|
detailContents?: string;
|
|
|
|
@Input()
|
|
|
|
isModify = false;
|
2020-01-09 18:14:00 +09:00
|
|
|
@Input()
|
|
|
|
fileAllowSize: number;
|
2020-02-14 15:33:44 +09:00
|
|
|
@Input()
|
|
|
|
sendProcessing = 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-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,
|
2020-01-09 18:14:00 +09:00
|
|
|
private translateService: TranslateService,
|
|
|
|
private commonApiService: CommonApiService,
|
2020-02-05 17:57:18 +09:00
|
|
|
private snackBarService: SnackBarService,
|
|
|
|
private readonly ngZone: NgZone,
|
2019-12-03 18:59:11 +09:00
|
|
|
private logger: NGXLogger
|
|
|
|
) {}
|
|
|
|
|
|
|
|
ngOnInit() {
|
|
|
|
this.messageWriteForm = this.formBuilder.group({
|
2020-02-06 10:29:48 +09:00
|
|
|
title: ['', [Validators.required]]
|
2019-12-03 18:59:11 +09:00
|
|
|
});
|
2019-12-11 08:18:32 +09:00
|
|
|
|
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
|
|
|
|
);
|
|
|
|
}
|
2020-01-20 14:16:46 +09:00
|
|
|
onClickDelelteAttachment(attachment: File) {
|
|
|
|
this.attachmentList = this.attachmentList.filter(
|
|
|
|
attFile => attFile !== attachment
|
|
|
|
);
|
|
|
|
}
|
2019-12-12 15:11:49 +09:00
|
|
|
|
2019-12-03 18:59:11 +09:00
|
|
|
onClickImage() {
|
2020-01-08 16:54:37 +09:00
|
|
|
this.fileInput.nativeElement.setAttribute('accept', 'image/*');
|
2019-12-03 18:59:11 +09:00
|
|
|
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;
|
|
|
|
|
2020-01-09 18:14:00 +09:00
|
|
|
if (!this.validUploadFile(fileList)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
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;
|
2020-02-11 14:07:25 +09:00
|
|
|
img.setAttribute('style', 'max-height:250px; max-width:250px;');
|
2019-12-04 17:58:59 +09:00
|
|
|
img[ATTR_FILE] = file;
|
2019-12-03 18:59:11 +09:00
|
|
|
self.insertNode(img);
|
2020-02-12 13:00:43 +09:00
|
|
|
|
|
|
|
const empty = document.createElement('div');
|
|
|
|
empty.innerHTML = ' <br/>';
|
|
|
|
self.insertNode(empty, true);
|
2019-12-03 19:06:29 +09:00
|
|
|
}
|
2019-12-03 18:59:11 +09:00
|
|
|
|
|
|
|
self.fileInput.nativeElement.value = '';
|
2020-02-12 13:00:43 +09:00
|
|
|
self.fileInput.nativeElement.onchange = undefined;
|
|
|
|
|
|
|
|
self.checkContentLength();
|
|
|
|
self.changeDetectorRef.detectChanges();
|
2019-12-03 18:59:11 +09:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
onClickAttachment() {
|
2020-01-08 16:54:37 +09:00
|
|
|
this.fileInput.nativeElement.removeAttribute('accept');
|
2019-12-03 18:59:11 +09:00
|
|
|
this.fileInput.nativeElement.click();
|
|
|
|
const self = this;
|
|
|
|
this.fileInput.nativeElement.onchange = () => {
|
|
|
|
const fileList: FileList = this.fileInput.nativeElement.files;
|
|
|
|
|
2020-01-09 18:14:00 +09:00
|
|
|
if (!this.validUploadFile(fileList)) {
|
2020-02-05 17:57:18 +09:00
|
|
|
self.fileInput.nativeElement.value = '';
|
2020-01-09 18:14:00 +09:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-12-03 18:59:11 +09:00
|
|
|
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 = '';
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-01-09 18:14:00 +09:00
|
|
|
validUploadFile(fileList: FileList): boolean {
|
|
|
|
let valid = true;
|
|
|
|
if (this.fileAllowSize > 0) {
|
|
|
|
for (let i = 0; i < fileList.length; i++) {
|
|
|
|
const file = fileList.item(i);
|
|
|
|
if (file.size > this.fileAllowSize * 1024 * 1024) {
|
|
|
|
valid = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!valid) {
|
2020-02-05 17:57:18 +09:00
|
|
|
this.ngZone.run(() => {
|
|
|
|
this.snackBarService.open(
|
|
|
|
this.translateService.instant('common.file.errors.oversize', {
|
|
|
|
maxSize: this.fileAllowSize
|
|
|
|
}),
|
|
|
|
'',
|
|
|
|
{
|
|
|
|
duration: 1000,
|
|
|
|
verticalPosition: 'bottom',
|
|
|
|
horizontalPosition: 'center'
|
|
|
|
}
|
|
|
|
);
|
2020-01-09 18:14:00 +09:00
|
|
|
});
|
|
|
|
|
|
|
|
return valid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const checkExt = this.commonApiService.acceptableExtensionForFileTalk(
|
|
|
|
FileUtil.getExtensions(fileList)
|
|
|
|
);
|
|
|
|
if (!checkExt.accept) {
|
2020-02-05 17:57:18 +09:00
|
|
|
this.ngZone.run(() => {
|
2020-02-10 09:33:41 +09:00
|
|
|
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(',') : ''
|
|
|
|
}
|
|
|
|
)
|
2020-02-05 17:57:18 +09:00
|
|
|
}
|
2020-02-10 09:33:41 +09:00
|
|
|
});
|
2020-01-09 18:14:00 +09:00
|
|
|
});
|
2020-02-13 15:12:28 +09:00
|
|
|
valid = false;
|
2020-01-09 18:14:00 +09:00
|
|
|
return valid;
|
|
|
|
}
|
|
|
|
|
|
|
|
return valid;
|
|
|
|
}
|
|
|
|
|
2019-12-03 18:59:11 +09:00
|
|
|
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) {
|
2020-02-03 17:53:19 +09:00
|
|
|
this.contentLength = 0;
|
2019-12-09 10:53:25 +09:00
|
|
|
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();
|
|
|
|
|
2020-02-12 13:00:43 +09:00
|
|
|
if (!!selection && !!selection.anchorNode) {
|
|
|
|
const range: Range = selection.getRangeAt(0);
|
|
|
|
|
|
|
|
let inEditor = false;
|
|
|
|
if (removeSelected) {
|
|
|
|
// onPaste
|
|
|
|
selection.empty();
|
|
|
|
inEditor = true;
|
|
|
|
} else {
|
|
|
|
inEditor = this.inEditor(selection.anchorNode);
|
|
|
|
}
|
2019-12-03 18:59:11 +09:00
|
|
|
|
2020-02-12 13:00:43 +09:00
|
|
|
if (inEditor) {
|
|
|
|
range.insertNode(node);
|
|
|
|
} else {
|
|
|
|
this.editor.nativeElement.appendChild(node);
|
|
|
|
}
|
2020-01-20 14:16:46 +09:00
|
|
|
} else {
|
|
|
|
this.editor.nativeElement.appendChild(node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private inEditor(el) {
|
|
|
|
if (!!el.classList) {
|
|
|
|
let root = false;
|
|
|
|
(el.classList as DOMTokenList).forEach(className => {
|
|
|
|
if (className === 'ucap-message-write') {
|
|
|
|
root = true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!!root) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (el.tagName === 'BODY') {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
!!el.className &&
|
|
|
|
el.className === 'ucap-message-write-editor' &&
|
|
|
|
el.getAttribute('contenteditable')
|
|
|
|
) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return this.inEditor(el.parentNode);
|
|
|
|
}
|
2019-12-03 18:59:11 +09:00
|
|
|
}
|
|
|
|
}
|