import { Component, OnInit, Output, EventEmitter, Input, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; import { PostMessage, ChatAttachment } from '../../store/entities'; import { ChatService } from '../../services/chat.service'; import { finalize } from 'rxjs/operators'; import { KstConfig } from '../../config/chat.config'; import * as FileAPI from 'fileapi'; @Component({ selector: 'kst-message-sender', template: `
{{message}}
` }) export class MessageSenderComponent implements OnInit, AfterViewInit { // tslint:disable-next-line: no-output-on-prefix @Output('onMessage') onMessage = new EventEmitter(); @Input() channelId: string; @ViewChild('imageInput') imageInput: ElementRef; @ViewChild('fileInput') fileInput: ElementRef; /** * 当前文本消息 */ currentMessage: string; fileUploadUrl: string; // 提示消息 message: string; fileprogress = 0; uploading = false; constructor( private _chatService: ChatService, ) { this.fileUploadUrl = KstConfig.file.uploadUrl; } ngOnInit() { // console.log('oninit'); // console.log(FileAPI); } ngAfterViewInit(): void { const self = this; FileAPI.event.on(this.imageInput.nativeElement, 'change', function (evt) { const files = FileAPI.getFiles(evt); const jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; const xhr = FileAPI.upload({ url: self.fileUploadUrl, files: { file: files[0] }, upload(xhr/**Object*/, options/**Object*/) { self.uploading = true; }, progress(evt) { let pr = evt.loaded / evt.total * 100; self.fileprogress = pr; }, complete(err, xhr) { const file = files[0]; self.fileprogress = 0; self.uploading = false; if (!err) { const result = JSON.parse(xhr.responseText, jsonParseReviver); if (result.fileId) { // 文件上传成功 file.fileid = result.fileId; self.showMessage('文件上传成功!', 1.5); self.sendImage(file); } } else { self.showMessage(`文件上传失败!超出上传限制!`, 0, true); } } }); }); FileAPI.event.on(this.fileInput.nativeElement, 'change', function (evt) { const files = FileAPI.getFiles(evt); const jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; const xhr = FileAPI.upload({ url: self.fileUploadUrl, files: { file: files[0] }, upload(xhr/**Object*/, options/**Object*/) { self.uploading = true; }, progress(evt) { let pr = evt.loaded / evt.total * 100; self.fileprogress = pr; }, complete(err, xhr) { self.uploading = false; self.fileprogress = 0; if (!err) { let file = files[0]; const result = JSON.parse(xhr.responseText, jsonParseReviver); if (result.fileId) { // 文件上传成功 file.fileid = result.fileId; self.showMessage('文件上传成功!', 1.5); if ((file.type).startsWith('image/')) { self.sendImage(file); } else if ((file.type).startsWith('audio/')) { self.sendAudio(file); } else if ((file.type).startsWith('video/')) { self.sendVideo(file); } else { self.sendFile(file); } } } else { self.showMessage(`文件上传失败!超出上传限制!`, 0, true); } } }); }); } send(message: PostMessage) { this._chatService.sendMessage(message) .pipe(finalize(() => { this.currentMessage = ''; })) .subscribe((data) => { this.showMessage(`消息发送${data.success ? '成功' : '失败'}`, 1.5, !data.success); }); } sendAudio(file: any) { const message = new PostMessage(this.channelId); let audio = new ChatAttachment(); audio.audio_url = KstConfig.file.getFileUrl.replace('{fileid}', file.fileid); audio.title_link = KstConfig.file.getFileUrl.replace('{fileid}', file.fileid); audio.title_link_download = true; audio.ts = new Date(); audio.type = 'file'; audio.audio_size = file.size; audio.audio_type = file.type; message.attachments = [audio]; this.send(message); } sendVideo(file: any) { const message = new PostMessage(this.channelId); let video = new ChatAttachment(); video.video_url = KstConfig.file.getFileUrl.replace('{fileid}', file.fileid); video.title_link = KstConfig.file.getFileUrl.replace('{fileid}', file.fileid); video.title_link_download = true; video.ts = new Date(); video.type = 'file'; video.video_size = file.size; video.video_type = file.type; message.attachments = [video]; this.send(message); } sendFile(file: any) { const message = new PostMessage(this.channelId); let att = new ChatAttachment(); att.title_link = KstConfig.file.getFileUrl.replace('{fileid}', file.fileid); att.ts = new Date(); att.type = 'file'; att.title_link_download = true; att.title = file.name; message.attachments = [att]; this.send(message); } sendImage(file: any) { const message = new PostMessage(this.channelId); let image = new ChatAttachment(); image.image_url = KstConfig.file.getFileUrl.replace('{fileid}', file.fileid); image.title_link = KstConfig.file.getFileUrl.replace('{fileid}', file.fileid); image.title_link_download = true; image.ts = new Date(); image.type = 'file'; image.image_type = file.type; image.image_size = file.size; image.title = file.name; message.attachments = [image]; this.send(message); } sendMessage() { if (!this.currentMessage) { this.showMessage('请输入文本消息!', 1, true); return; } const message = new PostMessage(this.channelId); message.text = this.currentMessage; this.send(message); } onInputPress(e) { if (e.key === 'Enter' && this.currentMessage) { this.sendMessage(); } } /** * 选择图片 */ chooseImage() { if (this.uploading) { return; } this.imageInput.nativeElement.click(); } chooseFile() { if (this.uploading) { return; } this.fileInput.nativeElement.click(); } /** * 设置消息展示 * @param timeout 超时(秒)隐藏 如果0则一直显示 */ showMessage(msg: string, timeout: number = 0, error: boolean = false) { this.message = msg; if (timeout > 0) setTimeout(() => { this.message = ''; }, timeout * 1000); this.onMessage.emit({ msg, error }); } }