import { Component, OnInit, Input, Output, EventEmitter, ViewChild, ContentChild, TemplateRef, AfterViewInit, ChangeDetectorRef, OnDestroy, ElementRef } from '@angular/core'; import { ucapAnimations } from '@ucap-webmessenger/ui'; import { NGXLogger } from 'ngx-logger'; import { FileUtil } from '@ucap-webmessenger/core'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; interface Content { contentType: 'text' | 'image' | 'attachment'; content: string; } @Component({ selector: 'ucap-message-write', templateUrl: './write.component.html', styleUrls: ['./write.component.scss'], animations: ucapAnimations }) export class WriteComponent implements OnInit, OnDestroy, AfterViewInit { @ViewChild('editor', { static: true }) editor: ElementRef; @ViewChild('fileInput', { static: true }) fileInput: ElementRef; messageWriteForm: FormGroup; receiverList: string[] = ['이진호', '강희경', '이유진']; attachmentList: File[]; constructor( private formBuilder: FormBuilder, private changeDetectorRef: ChangeDetectorRef, private logger: NGXLogger ) {} ngOnInit() { this.messageWriteForm = this.formBuilder.group({ receiverList: ['', [Validators.required]], title: ['', [Validators.required]] }); } ngOnDestroy(): void {} ngAfterViewInit(): void {} onClickImage() { this.fileInput.nativeElement.click(); const self = this; this.fileInput.nativeElement.onchange = async () => { const fileList: FileList = self.fileInput.nativeElement.files; for (let i = 0; i < fileList.length; i++) { const file = fileList.item(i); const dataUrl = await FileUtil.fromBlobToDataUrl(file); const img = document.createElement('img'); img.src = dataUrl as string; self.insertNode(img); } self.fileInput.nativeElement.value = ''; }; } 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); return false; } onClickSend() {} onClickCancel() {} printEditor(): void { const contentList: Content[] = []; this.editor.nativeElement.childNodes.forEach((v, k) => { this.parseNode(contentList, v); }); this.logger.debug('printEditor', contentList); } 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) { this.appendNode(contentList, 'image', node.textContent); } else if ('BR' === node.nodeName) { this.appendNode(contentList, 'text', `\n`); } else { } } } break; case Node.TEXT_NODE: this.appendNode(contentList, 'text', node.textContent); break; default: break; } } private appendNode( contentList: Content[], contentType: 'text' | 'image' | 'attachment', content: string ) { const prevContent = contentList[contentList.length - 1]; switch (contentType) { case 'text': if (!!prevContent && 'text' === prevContent.contentType) { prevContent.content = `${prevContent.content}${content}`; } else { contentList.push({ contentType: 'text', content }); } break; default: contentList.push({ contentType, content }); 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); } }