264 lines
6.4 KiB
TypeScript
264 lines
6.4 KiB
TypeScript
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<EventJson>[]) {
|
|
if (!!elist && elist.length > 0) {
|
|
this.firstEventSeq = elist[0].seq;
|
|
}
|
|
|
|
this.messages = elist;
|
|
}
|
|
@Input()
|
|
searchedList: Info<EventJson>[];
|
|
@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<number>();
|
|
@Output()
|
|
moreEvent = new EventEmitter<number>();
|
|
@Output()
|
|
massDetail = new EventEmitter<number>();
|
|
@Output()
|
|
massTranslationDetail = new EventEmitter<{
|
|
message: Info<MassTranslationEventJson>;
|
|
contentsType: string;
|
|
}>();
|
|
@Output()
|
|
fileViewer = new EventEmitter<FileEventJson>();
|
|
@Output()
|
|
save = new EventEmitter<{
|
|
fileInfo: FileEventJson;
|
|
fileDownloadItem: FileDownloadItem;
|
|
type: string;
|
|
}>();
|
|
@Output()
|
|
contextMenu = new EventEmitter<{
|
|
event: MouseEvent;
|
|
message: Info<EventJson>;
|
|
type?: string;
|
|
}>();
|
|
|
|
messages: Info<EventJson>[];
|
|
|
|
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<EventJson>): 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<EventJson>) {
|
|
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(event: MouseEvent, userSeq: number) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
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<MassTranslationEventJson>;
|
|
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 */
|
|
onContextMenuMessage(event: any, message: Info<EventJson>) {
|
|
if (
|
|
message.type === EventType.Translation ||
|
|
message.type === EventType.MassTranslation
|
|
) {
|
|
this.contextMenu.emit({ event: event.event, message, type: event.type });
|
|
} else {
|
|
this.contextMenu.emit({ event, message });
|
|
}
|
|
}
|
|
}
|