import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core'; import { Info, EventType, InfoResponse, EventJson, FileEventJson, MassTranslationEventJson } from '@ucap-webmessenger/protocol-event'; import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; import { UserInfo, RoomInfo, RoomType } from '@ucap-webmessenger/protocol-room'; import { NGXLogger } from 'ngx-logger'; import { VersionInfo2Response } from '@ucap-webmessenger/api-public'; import { FileInfo } from '../models/file-info.json'; import { DatePipe } from '@angular/common'; import moment from 'moment'; import { FileDownloadItem } from '@ucap-webmessenger/api'; @Component({ selector: 'ucap-chat-messages', templateUrl: './messages.component.html', styleUrls: ['./messages.component.scss'] }) export class MessagesComponent implements OnInit { @Input() loginRes: LoginResponse; @Input() roomInfo: RoomInfo; @Input() set eventList(elist: Info[]) { if (!!elist && elist.length > 0) { this.firstEventSeq = elist[0].seq; } this.messages = elist; } @Input() searchedList: Info[]; @Input() eventInfoStatus?: InfoResponse; @Input() eventRemain: boolean; @Input() userInfos?: UserInfo[]; @Input() sessionVerInfo: VersionInfo2Response; @Input() isShowUnreadCount = true; @Input() clearReadHere: boolean; @Input() minShowReadHere = 10; @Input() initRoomLastEventSeq: number; @Input() translationSimpleview = false; @Output() openProfile = new EventEmitter(); @Output() moreEvent = new EventEmitter(); @Output() massDetail = new EventEmitter(); @Output() massTranslationDetail = new EventEmitter<{ message: Info; contentsType: string; }>(); @Output() fileViewer = new EventEmitter(); @Output() save = new EventEmitter<{ fileInfo: FileEventJson; fileDownloadItem: FileDownloadItem; type: string; }>(); @Output() contextMenu = new EventEmitter<{ event: MouseEvent; message: Info; type?: string; }>(); messages: Info[]; EventType = EventType; profileImageRoot: string; moment = moment; firstEventSeq = 0; existReadHere = false; constructor(private logger: NGXLogger, private datePipe: DatePipe) {} ngOnInit() { this.profileImageRoot = this.profileImageRoot || this.sessionVerInfo.profileRoot; } /** * UserInfo getter */ getUserName(seq: number): string { if (!this.userInfos) { return ''; } const userInfo: UserInfo[] = this.userInfos.filter( user => user.seq === seq ); if (!!userInfo && userInfo.length > 0) { return userInfo[0].name; } return '(알수없는 사용자)'; } getUserProfile(seq: number): string { if (!this.userInfos) { return ''; } const userInfo: UserInfo[] = this.userInfos.filter( user => user.seq === seq ); if (!!userInfo && userInfo.length > 0) { return userInfo[0].profileImageFile; } return ''; } getEventSearched(seq: number): boolean { return ( !!this.searchedList && this.searchedList.filter(event => event.seq === seq).length > 0 ); } getUnreadCount(message: Info): string | number { const unreadCnt = this.userInfos.filter(user => { if (message.senderSeq === user.seq) { // 본인 글은 unreadCount 에 포함하지 않는다. return false; } return user.lastReadEventSeq < message.seq; }).length; return unreadCnt === 0 ? '' : unreadCnt; } /** * 정보성 Event 인지 판단. * @description 정보성 event 일 경우 프로필, 일시 를 표현하지 않는다. * Edit with reducers.ts / sync / updateRoomForNewEventMessage */ getIsInformation(info: Info) { if ( info.type === EventType.Join || info.type === EventType.Exit || info.type === EventType.ForcedExit || info.type === EventType.RenameRoom || info.type === EventType.NotificationForTimerRoom || info.type === EventType.GuideForRoomTimerChanged ) { return true; } return false; } /** Date Splitter show check */ getDateSplitter(curIndex: number): boolean { if (curIndex === 0) { return true; } if (curIndex > 0) { return ( this.datePipe.transform( moment(this.messages[curIndex].sendDate).toDate(), 'yyyyMMdd' ) !== this.datePipe.transform( moment(this.messages[curIndex - 1].sendDate).toDate(), 'yyyyMMdd' ) ); } return false; } getReadHere(messageIndex: number): boolean { if ( !!this.roomInfo && !!this.roomInfo.lastReadEventSeq && this.initRoomLastEventSeq - this.roomInfo.lastReadEventSeq > this.minShowReadHere ) { if ( this.roomInfo.roomType === RoomType.Single || this.roomInfo.roomType === RoomType.Multi ) { if (!this.roomInfo.isTimeRoom) { if ( this.messages[messageIndex].seq === this.roomInfo.lastReadEventSeq + 1 ) { this.existReadHere = true; return true; } } } } return false; } onClickOpenProfile(userSeq: number) { this.openProfile.emit(userSeq); } onClickMore(event: any) { event.preventDefault(); event.stopPropagation(); this.moreEvent.emit(this.messages[0].seq); } /** [Event] MassTalk Detail View */ onMassDetail(value: number) { this.massDetail.emit(value); } onMassTranslationDetail(params: { message: Info; contentsType: string; }) { this.massTranslationDetail.emit(params); } /** [Event] Image Viewer */ onFileViewer(fileInfo: FileEventJson) { this.fileViewer.emit(fileInfo); } /** [Event] Attach File Save & Save As */ onSave(value: { fileInfo: FileEventJson; fileDownloadItem: FileDownloadItem; type: string; }) { this.save.emit(value); } /** [Event] Context Menu */ onContextMenu(event: { event: MouseEvent; message: Info; type?: string; }) { this.contextMenu.emit(event); } }