2020-01-17 10:41:22 +09:00
|
|
|
import {
|
|
|
|
Component,
|
|
|
|
OnInit,
|
|
|
|
Input,
|
|
|
|
EventEmitter,
|
|
|
|
Output,
|
|
|
|
ViewChild,
|
2020-01-17 12:29:04 +09:00
|
|
|
OnDestroy,
|
2020-01-20 16:40:17 +09:00
|
|
|
ChangeDetectionStrategy,
|
2020-01-20 17:26:38 +09:00
|
|
|
ElementRef,
|
|
|
|
ChangeDetectorRef
|
2020-01-17 10:41:22 +09:00
|
|
|
} from '@angular/core';
|
2019-09-23 14:23:24 +09:00
|
|
|
|
2019-10-29 18:11:31 +09:00
|
|
|
import {
|
|
|
|
Info,
|
|
|
|
EventType,
|
2019-11-06 13:48:06 +09:00
|
|
|
InfoResponse,
|
2019-11-06 16:24:51 +09:00
|
|
|
EventJson,
|
2020-01-09 08:46:04 +09:00
|
|
|
FileEventJson,
|
|
|
|
MassTranslationEventJson
|
2019-10-29 18:11:31 +09:00
|
|
|
} from '@ucap-webmessenger/protocol-event';
|
2019-10-30 16:22:49 +09:00
|
|
|
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
2019-12-19 14:23:11 +09:00
|
|
|
import { UserInfo, RoomInfo, RoomType } from '@ucap-webmessenger/protocol-room';
|
2019-10-08 15:13:01 +09:00
|
|
|
import { NGXLogger } from 'ngx-logger';
|
2019-10-15 14:58:11 +09:00
|
|
|
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
|
2019-10-14 17:19:13 +09:00
|
|
|
import { DatePipe } from '@angular/common';
|
2019-11-13 16:30:15 +09:00
|
|
|
import moment from 'moment';
|
2020-01-03 15:52:19 +09:00
|
|
|
import { FileDownloadItem } from '@ucap-webmessenger/api';
|
2020-01-15 17:31:34 +09:00
|
|
|
import { TranslateService } from '@ngx-translate/core';
|
2020-01-17 10:41:22 +09:00
|
|
|
import { PerfectScrollbarDirective } from 'ngx-perfect-scrollbar';
|
|
|
|
import { Observable, Subscription } from 'rxjs';
|
2020-01-20 16:40:17 +09:00
|
|
|
import { VirtualScrollerComponent, IPageInfo } from 'ngx-virtual-scroller';
|
2019-10-08 13:31:33 +09:00
|
|
|
|
2019-09-23 14:23:24 +09:00
|
|
|
@Component({
|
|
|
|
selector: 'ucap-chat-messages',
|
|
|
|
templateUrl: './messages.component.html',
|
2020-01-20 16:40:17 +09:00
|
|
|
styleUrls: ['./messages.component.scss'],
|
|
|
|
changeDetection: ChangeDetectionStrategy.OnPush
|
2019-09-23 14:23:24 +09:00
|
|
|
})
|
2020-01-17 10:41:22 +09:00
|
|
|
export class MessagesComponent implements OnInit, OnDestroy {
|
2019-09-23 14:23:24 +09:00
|
|
|
@Input()
|
2020-01-17 10:41:22 +09:00
|
|
|
loginRes$: Observable<LoginResponse>;
|
2019-10-08 13:31:33 +09:00
|
|
|
@Input()
|
2020-01-17 10:41:22 +09:00
|
|
|
roomInfo$: Observable<RoomInfo>;
|
2019-12-19 14:23:11 +09:00
|
|
|
@Input()
|
2020-01-17 10:41:22 +09:00
|
|
|
eventList$: Observable<Info<EventJson>[]>;
|
2019-10-11 11:40:35 +09:00
|
|
|
@Input()
|
2020-01-17 10:41:22 +09:00
|
|
|
newEventList$: Observable<Info<EventJson>[]>;
|
2019-12-23 15:23:27 +09:00
|
|
|
@Input()
|
2020-01-17 10:41:22 +09:00
|
|
|
searchedList$: Observable<Info<EventJson>[]>;
|
2019-10-29 18:11:31 +09:00
|
|
|
@Input()
|
2020-01-17 10:41:22 +09:00
|
|
|
eventInfoStatus$: Observable<InfoResponse>;
|
2019-10-31 18:12:38 +09:00
|
|
|
@Input()
|
2020-01-17 10:41:22 +09:00
|
|
|
eventRemained$: Observable<boolean>;
|
2019-10-15 14:58:11 +09:00
|
|
|
@Input()
|
|
|
|
sessionVerInfo: VersionInfo2Response;
|
2020-01-17 10:41:22 +09:00
|
|
|
@Input()
|
|
|
|
userInfos$: Observable<UserInfo[]>;
|
|
|
|
|
2019-11-22 09:03:32 +09:00
|
|
|
@Input()
|
|
|
|
isShowUnreadCount = true;
|
2019-12-19 14:23:11 +09:00
|
|
|
@Input()
|
|
|
|
clearReadHere: boolean;
|
|
|
|
@Input()
|
|
|
|
minShowReadHere = 10;
|
2019-12-31 14:36:32 +09:00
|
|
|
@Input()
|
|
|
|
translationSimpleview = false;
|
2020-01-17 10:41:22 +09:00
|
|
|
@Input()
|
|
|
|
searchingMode = false;
|
2019-09-23 14:23:24 +09:00
|
|
|
|
2019-11-08 13:35:39 +09:00
|
|
|
@Output()
|
2020-01-02 15:58:16 +09:00
|
|
|
openProfile = new EventEmitter<number>();
|
2019-10-31 18:12:38 +09:00
|
|
|
@Output()
|
|
|
|
moreEvent = new EventEmitter<number>();
|
2019-10-11 18:03:01 +09:00
|
|
|
@Output()
|
|
|
|
massDetail = new EventEmitter<number>();
|
2019-10-14 13:53:22 +09:00
|
|
|
@Output()
|
2020-01-02 08:44:16 +09:00
|
|
|
massTranslationDetail = new EventEmitter<{
|
2020-01-09 08:46:04 +09:00
|
|
|
message: Info<MassTranslationEventJson>;
|
2020-01-02 08:44:16 +09:00
|
|
|
contentsType: string;
|
|
|
|
}>();
|
|
|
|
@Output()
|
2019-11-07 15:46:02 +09:00
|
|
|
fileViewer = new EventEmitter<FileEventJson>();
|
2019-10-14 13:53:22 +09:00
|
|
|
@Output()
|
2020-01-03 15:52:19 +09:00
|
|
|
save = new EventEmitter<{
|
|
|
|
fileInfo: FileEventJson;
|
|
|
|
fileDownloadItem: FileDownloadItem;
|
|
|
|
type: string;
|
|
|
|
}>();
|
2019-10-16 16:33:19 +09:00
|
|
|
@Output()
|
|
|
|
contextMenu = new EventEmitter<{
|
|
|
|
event: MouseEvent;
|
2019-11-06 13:48:06 +09:00
|
|
|
message: Info<EventJson>;
|
2020-01-08 18:27:35 +09:00
|
|
|
type?: string;
|
2019-10-16 16:33:19 +09:00
|
|
|
}>();
|
2019-10-15 15:02:00 +09:00
|
|
|
|
2020-01-17 10:41:22 +09:00
|
|
|
@Output()
|
|
|
|
scrollUp = new EventEmitter<any>();
|
|
|
|
|
|
|
|
@Output()
|
|
|
|
yReachEnd = new EventEmitter<any>();
|
|
|
|
@Output()
|
|
|
|
yReachStart = new EventEmitter<any>();
|
|
|
|
|
|
|
|
@Output()
|
|
|
|
existNewMessage = new EventEmitter<Info<EventJson>>();
|
|
|
|
|
2020-01-20 16:40:17 +09:00
|
|
|
@ViewChild('chatMessagesContainer', { static: false })
|
|
|
|
chatMessagesContainer: ElementRef<HTMLElement>;
|
|
|
|
|
2020-01-17 10:41:22 +09:00
|
|
|
@ViewChild(PerfectScrollbarDirective, { static: false })
|
2020-01-17 12:29:04 +09:00
|
|
|
psChatContent: PerfectScrollbarDirective;
|
2020-01-17 10:41:22 +09:00
|
|
|
|
|
|
|
@ViewChild(VirtualScrollerComponent, { static: false })
|
|
|
|
private virtualScroller: VirtualScrollerComponent;
|
|
|
|
|
2020-01-20 16:40:17 +09:00
|
|
|
storedScrollItem: Info<EventJson>; // 이전대화를 불러올 경우 현재 스크롤 포지션 유지를 위한 값. 0 이면 초기로딩.
|
2020-01-17 10:41:22 +09:00
|
|
|
scrollUpInitalized = false; // ps 에서 초기 로딩시 scroll reach start 이벤트 발생 버그를 우회하기 위한 init 값으로 scrollUp 에 의해 true 로 된다.
|
|
|
|
firstCheckReadHere = true;
|
|
|
|
initRoomLastEventSeq: number;
|
|
|
|
baseEventSeq = 0;
|
|
|
|
|
|
|
|
loginRes: LoginResponse;
|
|
|
|
loginResSubscription: Subscription;
|
|
|
|
roomInfo: RoomInfo;
|
|
|
|
roomInfoSubscription: Subscription;
|
|
|
|
eventList: Info<EventJson>[];
|
|
|
|
eventListSubscription: Subscription;
|
|
|
|
newEventList: Info<EventJson>[];
|
|
|
|
newEventListSubscription: Subscription;
|
|
|
|
searchedList: Info<EventJson>[];
|
|
|
|
searchedListSubscription: Subscription;
|
|
|
|
eventInfoStatus: InfoResponse;
|
|
|
|
eventInfoStatusSubscription: Subscription;
|
|
|
|
eventRemained: boolean;
|
|
|
|
eventRemainedSubscription: Subscription;
|
|
|
|
userInfos: UserInfo[];
|
|
|
|
userInfosSubscription: Subscription;
|
2019-12-19 14:23:11 +09:00
|
|
|
|
2019-10-08 16:41:23 +09:00
|
|
|
EventType = EventType;
|
2019-10-11 11:40:35 +09:00
|
|
|
profileImageRoot: string;
|
2019-11-13 16:30:15 +09:00
|
|
|
moment = moment;
|
2019-10-08 16:41:23 +09:00
|
|
|
|
2019-12-19 14:23:11 +09:00
|
|
|
existReadHere = false;
|
2020-01-17 12:29:04 +09:00
|
|
|
fixScreen = false;
|
2019-12-19 14:23:11 +09:00
|
|
|
|
2020-01-15 17:31:34 +09:00
|
|
|
constructor(
|
|
|
|
private logger: NGXLogger,
|
|
|
|
private datePipe: DatePipe,
|
2020-01-20 17:26:38 +09:00
|
|
|
private changeDetectorRef: ChangeDetectorRef,
|
2020-01-15 17:31:34 +09:00
|
|
|
private translateService: TranslateService
|
|
|
|
) {}
|
2019-09-23 14:23:24 +09:00
|
|
|
|
2019-10-08 15:13:01 +09:00
|
|
|
ngOnInit() {
|
2019-10-15 14:58:11 +09:00
|
|
|
this.profileImageRoot =
|
|
|
|
this.profileImageRoot || this.sessionVerInfo.profileRoot;
|
2020-01-17 10:41:22 +09:00
|
|
|
|
|
|
|
this.loginResSubscription = this.loginRes$.subscribe(loginRes => {
|
|
|
|
this.loginRes = loginRes;
|
|
|
|
});
|
|
|
|
this.roomInfoSubscription = this.roomInfo$.subscribe(roomInfo => {
|
2020-01-20 17:26:38 +09:00
|
|
|
// this.eventList = undefined;
|
|
|
|
// this.newEventList = undefined;
|
|
|
|
// this.searchedList = undefined;
|
|
|
|
// this.eventInfoStatus = undefined;
|
|
|
|
// this.eventRemained = undefined;
|
|
|
|
// this.userInfos = undefined;
|
2020-01-17 12:29:04 +09:00
|
|
|
|
2020-01-17 10:41:22 +09:00
|
|
|
this.initEventMore();
|
|
|
|
this.roomInfo = roomInfo;
|
|
|
|
});
|
|
|
|
this.eventListSubscription = this.eventList$.subscribe(eventList => {
|
|
|
|
if (
|
|
|
|
!!eventList &&
|
|
|
|
eventList.length > 0 &&
|
|
|
|
!!this.roomInfo &&
|
|
|
|
!!this.roomInfo.lastReadEventSeq &&
|
|
|
|
this.baseEventSeq <= this.roomInfo.lastReadEventSeq
|
|
|
|
) {
|
|
|
|
// 조회된 내용중에 read here 가 있을 경우.
|
|
|
|
this.firstCheckReadHere = false;
|
|
|
|
}
|
|
|
|
|
2020-01-20 16:40:17 +09:00
|
|
|
this.eventList = eventList;
|
2020-01-20 17:26:38 +09:00
|
|
|
this.changeDetectorRef.detectChanges();
|
2020-01-20 16:40:17 +09:00
|
|
|
|
2020-01-17 10:41:22 +09:00
|
|
|
if (this.searchingMode) {
|
|
|
|
const baseseq = this.baseEventSeq;
|
|
|
|
// setTimeout(() => {
|
|
|
|
// this.doSearchTextInEvent(this.searchText, baseseq);
|
|
|
|
// }, 800);
|
|
|
|
this.baseEventSeq = eventList[0].seq;
|
|
|
|
} else {
|
|
|
|
if (!!eventList && eventList.length > 0) {
|
|
|
|
this.baseEventSeq = eventList[0].seq;
|
|
|
|
this.ready();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
this.newEventListSubscription = this.newEventList$.subscribe(
|
|
|
|
newEventList => {
|
|
|
|
this.newEventList = newEventList;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
this.searchedListSubscription = this.searchedList$.subscribe(
|
|
|
|
searchedList => {
|
|
|
|
this.searchedList = searchedList;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
this.eventInfoStatusSubscription = this.eventInfoStatus$.subscribe(
|
|
|
|
eventInfoStatus => {
|
|
|
|
this.eventInfoStatus = eventInfoStatus;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
this.eventRemainedSubscription = this.eventRemained$.subscribe(
|
|
|
|
eventRemained => {
|
|
|
|
this.eventRemained = eventRemained;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
this.userInfosSubscription = this.userInfos$.subscribe(userInfos => {
|
|
|
|
this.userInfos = userInfos;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
ngOnDestroy(): void {
|
|
|
|
if (!!this.loginResSubscription) {
|
|
|
|
this.loginResSubscription.unsubscribe();
|
|
|
|
}
|
|
|
|
if (!!this.roomInfoSubscription) {
|
|
|
|
this.roomInfoSubscription.unsubscribe();
|
|
|
|
}
|
|
|
|
if (!!this.eventListSubscription) {
|
|
|
|
this.eventListSubscription.unsubscribe();
|
|
|
|
}
|
|
|
|
if (!!this.newEventListSubscription) {
|
|
|
|
this.newEventListSubscription.unsubscribe();
|
|
|
|
}
|
|
|
|
if (!!this.searchedListSubscription) {
|
|
|
|
this.searchedListSubscription.unsubscribe();
|
|
|
|
}
|
|
|
|
if (!!this.eventInfoStatusSubscription) {
|
|
|
|
this.eventInfoStatusSubscription.unsubscribe();
|
|
|
|
}
|
|
|
|
if (!!this.eventRemainedSubscription) {
|
|
|
|
this.eventRemainedSubscription.unsubscribe();
|
|
|
|
}
|
|
|
|
if (!!this.userInfosSubscription) {
|
|
|
|
this.userInfosSubscription.unsubscribe();
|
|
|
|
}
|
2019-10-11 11:40:35 +09:00
|
|
|
}
|
|
|
|
|
2019-10-30 16:22:49 +09:00
|
|
|
/**
|
|
|
|
* UserInfo getter
|
|
|
|
*/
|
2019-10-11 11:40:35 +09:00
|
|
|
getUserName(seq: number): string {
|
2019-10-11 15:55:27 +09:00
|
|
|
if (!this.userInfos) {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
2019-10-11 11:40:35 +09:00
|
|
|
const userInfo: UserInfo[] = this.userInfos.filter(
|
|
|
|
user => user.seq === seq
|
|
|
|
);
|
|
|
|
if (!!userInfo && userInfo.length > 0) {
|
|
|
|
return userInfo[0].name;
|
|
|
|
}
|
|
|
|
return '(알수없는 사용자)';
|
|
|
|
}
|
|
|
|
getUserProfile(seq: number): string {
|
2019-10-11 15:55:27 +09:00
|
|
|
if (!this.userInfos) {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
2019-10-11 11:40:35 +09:00
|
|
|
const userInfo: UserInfo[] = this.userInfos.filter(
|
|
|
|
user => user.seq === seq
|
|
|
|
);
|
|
|
|
if (!!userInfo && userInfo.length > 0) {
|
2019-10-17 16:57:37 +09:00
|
|
|
return userInfo[0].profileImageFile;
|
2019-10-11 11:40:35 +09:00
|
|
|
}
|
|
|
|
return '';
|
2019-10-08 15:13:01 +09:00
|
|
|
}
|
2020-01-17 10:41:22 +09:00
|
|
|
|
|
|
|
isHighlightedEvent(seq: number): boolean {
|
2019-12-23 15:23:27 +09:00
|
|
|
return (
|
|
|
|
!!this.searchedList &&
|
|
|
|
this.searchedList.filter(event => event.seq === seq).length > 0
|
|
|
|
);
|
|
|
|
}
|
2019-10-11 18:03:01 +09:00
|
|
|
|
2019-11-06 13:48:06 +09:00
|
|
|
getUnreadCount(message: Info<EventJson>): string | number {
|
2020-01-20 17:26:38 +09:00
|
|
|
// if (!this.userInfos || 0 === this.userInfos.length) {
|
|
|
|
// return '';
|
|
|
|
// }
|
2019-10-30 16:22:49 +09:00
|
|
|
const unreadCnt = this.userInfos.filter(user => {
|
|
|
|
if (message.senderSeq === user.seq) {
|
|
|
|
// 본인 글은 unreadCount 에 포함하지 않는다.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return user.lastReadEventSeq < message.seq;
|
|
|
|
}).length;
|
|
|
|
return unreadCnt === 0 ? '' : unreadCnt;
|
|
|
|
}
|
|
|
|
|
2019-10-15 11:50:23 +09:00
|
|
|
/**
|
|
|
|
* 정보성 Event 인지 판단.
|
|
|
|
* @description 정보성 event 일 경우 프로필, 일시 를 표현하지 않는다.
|
2019-10-29 10:46:55 +09:00
|
|
|
* Edit with reducers.ts / sync / updateRoomForNewEventMessage
|
2019-10-15 11:50:23 +09:00
|
|
|
*/
|
2019-11-06 13:48:06 +09:00
|
|
|
getIsInformation(info: Info<EventJson>) {
|
2019-10-15 11:50:23 +09:00
|
|
|
if (
|
|
|
|
info.type === EventType.Join ||
|
|
|
|
info.type === EventType.Exit ||
|
2019-12-09 16:52:43 +09:00
|
|
|
info.type === EventType.ForcedExit ||
|
2019-10-15 11:50:23 +09:00
|
|
|
info.type === EventType.RenameRoom ||
|
|
|
|
info.type === EventType.NotificationForTimerRoom ||
|
|
|
|
info.type === EventType.GuideForRoomTimerChanged
|
|
|
|
) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-10-30 16:22:49 +09:00
|
|
|
/** Date Splitter show check */
|
2020-01-20 16:40:17 +09:00
|
|
|
getDateSplitter(message: Info<EventJson>): boolean {
|
|
|
|
const curIndex = this.eventList.findIndex(v => v.seq === message.seq);
|
|
|
|
|
2019-10-14 17:19:13 +09:00
|
|
|
if (curIndex === 0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (curIndex > 0) {
|
2020-01-17 12:29:04 +09:00
|
|
|
if (!this.eventList[curIndex]) {
|
|
|
|
return false;
|
|
|
|
}
|
2020-01-20 16:40:17 +09:00
|
|
|
return !moment(this.eventList[curIndex].sendDate).isSame(
|
|
|
|
moment(this.eventList[curIndex - 1].sendDate),
|
|
|
|
'day'
|
2019-10-14 17:19:13 +09:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-01-20 16:40:17 +09:00
|
|
|
getReadHere(message: Info<EventJson>): boolean {
|
2019-12-19 14:23:11 +09:00
|
|
|
if (
|
|
|
|
!!this.roomInfo &&
|
|
|
|
!!this.roomInfo.lastReadEventSeq &&
|
2020-01-07 17:45:43 +09:00
|
|
|
this.initRoomLastEventSeq - this.roomInfo.lastReadEventSeq >
|
|
|
|
this.minShowReadHere
|
2019-12-19 14:23:11 +09:00
|
|
|
) {
|
|
|
|
if (
|
|
|
|
this.roomInfo.roomType === RoomType.Single ||
|
|
|
|
this.roomInfo.roomType === RoomType.Multi
|
|
|
|
) {
|
|
|
|
if (!this.roomInfo.isTimeRoom) {
|
2020-01-20 16:40:17 +09:00
|
|
|
const messageIndex = this.eventList.findIndex(
|
|
|
|
v => v.seq === message.seq
|
|
|
|
);
|
|
|
|
|
2019-12-19 14:23:11 +09:00
|
|
|
if (
|
2020-01-17 10:41:22 +09:00
|
|
|
this.eventList[messageIndex].seq ===
|
2019-12-19 14:23:11 +09:00
|
|
|
this.roomInfo.lastReadEventSeq + 1
|
|
|
|
) {
|
|
|
|
this.existReadHere = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-01-15 17:31:34 +09:00
|
|
|
getStringReadHereMore(): string {
|
|
|
|
let rtnStr = '';
|
|
|
|
rtnStr = this.translateService.instant('chat.event.moreUnreadEventsWith', {
|
2020-01-17 10:41:22 +09:00
|
|
|
countOfUnread: this.baseEventSeq - (this.roomInfo.lastReadEventSeq + 1)
|
2020-01-15 17:31:34 +09:00
|
|
|
});
|
|
|
|
return rtnStr;
|
|
|
|
}
|
|
|
|
|
2020-01-20 16:40:17 +09:00
|
|
|
storeScrollPosition() {
|
|
|
|
this.storedScrollItem = this.eventList[
|
|
|
|
this.virtualScroller.viewPortInfo.startIndex
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
scrollToStoredItem() {
|
|
|
|
if (!this.scrollUpInitalized) {
|
|
|
|
this.chatMessagesContainer.nativeElement.classList.remove('hide');
|
|
|
|
}
|
|
|
|
|
|
|
|
this.virtualScroller.scrollInto(this.storedScrollItem, true, 0, 0, () => {
|
|
|
|
this.storedScrollItem = undefined;
|
|
|
|
});
|
2020-01-17 10:41:22 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
ready(): void {
|
2020-01-20 16:40:17 +09:00
|
|
|
if (!this.scrollUpInitalized) {
|
|
|
|
this.chatMessagesContainer.nativeElement.classList.add('hide');
|
|
|
|
}
|
|
|
|
|
2020-01-17 10:41:22 +09:00
|
|
|
setTimeout(() => {
|
|
|
|
this.scrollToBottom();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
scrollToBottom(speed?: number): void {
|
2020-01-20 16:40:17 +09:00
|
|
|
if (!!this.storedScrollItem) {
|
|
|
|
// if (this.psChatContent) {
|
|
|
|
// this.psChatContent.update();
|
2020-01-17 10:41:22 +09:00
|
|
|
|
2020-01-20 16:40:17 +09:00
|
|
|
const element = document.getElementById('message-box-readhere');
|
|
|
|
if (!!element && this.firstCheckReadHere) {
|
|
|
|
setTimeout(() => {
|
|
|
|
this.psChatContent.scrollToTop(element.offsetTop - 200, speed);
|
|
|
|
});
|
2020-01-17 10:41:22 +09:00
|
|
|
|
2020-01-20 16:40:17 +09:00
|
|
|
this.firstCheckReadHere = false;
|
|
|
|
} else {
|
|
|
|
this.scrollToStoredItem();
|
2020-01-17 10:41:22 +09:00
|
|
|
}
|
2020-01-20 16:40:17 +09:00
|
|
|
// }
|
2020-01-17 10:41:22 +09:00
|
|
|
} else if (this.scrollUpInitalized) {
|
|
|
|
if (!!this.newEventList && this.newEventList.length > 0) {
|
|
|
|
this.existNewMessage.emit(
|
|
|
|
this.newEventList[this.newEventList.length - 1]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
speed = speed || 0;
|
|
|
|
if (this.psChatContent) {
|
|
|
|
this.psChatContent.update();
|
|
|
|
|
|
|
|
const element = document.getElementById('message-box-readhere');
|
|
|
|
if (!!element && this.firstCheckReadHere) {
|
|
|
|
setTimeout(() => {
|
|
|
|
this.psChatContent.scrollToTop(element.offsetTop - 200, speed);
|
|
|
|
});
|
|
|
|
|
|
|
|
this.firstCheckReadHere = false;
|
|
|
|
} else {
|
2020-01-20 17:26:38 +09:00
|
|
|
this.virtualScroller.scrollToIndex(
|
|
|
|
this.eventList.length - 1,
|
2020-01-20 16:40:17 +09:00
|
|
|
true,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
() => {
|
2020-01-20 17:26:38 +09:00
|
|
|
this.chatMessagesContainer.nativeElement.classList.remove('hide');
|
2020-01-20 16:40:17 +09:00
|
|
|
}
|
|
|
|
);
|
2020-01-17 10:41:22 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
initEventMore() {
|
|
|
|
// 방정보가 바뀌면 이전대화 보기 관련 값들을 초기화 한다.
|
|
|
|
this.scrollUpInitalized = false;
|
2020-01-20 16:40:17 +09:00
|
|
|
this.storedScrollItem = undefined;
|
2020-01-17 10:41:22 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
clear() {}
|
|
|
|
|
|
|
|
gotoPosition(eventSeq: number) {
|
|
|
|
// if (this.psChatContent) {
|
|
|
|
// this.psChatContent.update();
|
|
|
|
|
|
|
|
// const element = document.getElementById(eventSeq.toString());
|
|
|
|
// if (!!element) {
|
|
|
|
// setTimeout(() => {
|
|
|
|
// this.psChatContent.scrollToTop(element.offsetTop - 200);
|
|
|
|
// });
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
if (!!this.virtualScroller) {
|
|
|
|
const e = this.eventList.find(v => v.seq === eventSeq);
|
2020-01-17 12:29:04 +09:00
|
|
|
this.fixScreen = true;
|
|
|
|
this.virtualScroller.scrollInto(e, false, undefined, 0, () => {
|
|
|
|
this.fixScreen = false;
|
|
|
|
});
|
2020-01-17 10:41:22 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-15 13:53:17 +09:00
|
|
|
onClickOpenProfile(userSeq: number) {
|
2020-01-02 15:58:16 +09:00
|
|
|
this.openProfile.emit(userSeq);
|
2019-11-08 13:35:39 +09:00
|
|
|
}
|
|
|
|
|
2019-10-31 18:12:38 +09:00
|
|
|
onClickMore(event: any) {
|
|
|
|
event.preventDefault();
|
|
|
|
event.stopPropagation();
|
|
|
|
|
2020-01-17 10:41:22 +09:00
|
|
|
if (this.scrollUpInitalized && this.eventRemained) {
|
2020-01-20 16:40:17 +09:00
|
|
|
// this.storedScrollItem = this.psChatContent.elementRef.nativeElement.scrollHeight;
|
|
|
|
this.storeScrollPosition();
|
2020-01-17 10:41:22 +09:00
|
|
|
|
|
|
|
this.moreEvent.emit(this.eventList[0].seq);
|
2020-01-20 16:40:17 +09:00
|
|
|
|
|
|
|
this.virtualScroller.invalidateCachedMeasurementAtIndex(0);
|
2020-01-17 10:41:22 +09:00
|
|
|
}
|
2019-10-31 18:12:38 +09:00
|
|
|
}
|
|
|
|
|
2019-10-14 17:19:13 +09:00
|
|
|
/** [Event] MassTalk Detail View */
|
2019-10-11 18:03:01 +09:00
|
|
|
onMassDetail(value: number) {
|
|
|
|
this.massDetail.emit(value);
|
|
|
|
}
|
2019-10-14 13:53:22 +09:00
|
|
|
|
2020-01-09 08:46:04 +09:00
|
|
|
onMassTranslationDetail(params: {
|
|
|
|
message: Info<MassTranslationEventJson>;
|
2020-01-02 08:44:16 +09:00
|
|
|
contentsType: string;
|
|
|
|
}) {
|
|
|
|
this.massTranslationDetail.emit(params);
|
|
|
|
}
|
|
|
|
|
2019-10-14 17:19:13 +09:00
|
|
|
/** [Event] Image Viewer */
|
2019-11-07 15:46:02 +09:00
|
|
|
onFileViewer(fileInfo: FileEventJson) {
|
|
|
|
this.fileViewer.emit(fileInfo);
|
2019-10-14 13:53:22 +09:00
|
|
|
}
|
|
|
|
|
2019-10-14 17:19:13 +09:00
|
|
|
/** [Event] Attach File Save & Save As */
|
2020-01-03 15:52:19 +09:00
|
|
|
onSave(value: {
|
|
|
|
fileInfo: FileEventJson;
|
|
|
|
fileDownloadItem: FileDownloadItem;
|
|
|
|
type: string;
|
|
|
|
}) {
|
2019-10-14 13:53:22 +09:00
|
|
|
this.save.emit(value);
|
|
|
|
}
|
2019-10-15 15:02:00 +09:00
|
|
|
|
2019-10-30 16:22:49 +09:00
|
|
|
/** [Event] Context Menu */
|
2020-01-15 13:53:17 +09:00
|
|
|
onContextMenu(event: {
|
|
|
|
event: MouseEvent;
|
|
|
|
message: Info<EventJson>;
|
|
|
|
type?: string;
|
|
|
|
}) {
|
|
|
|
this.contextMenu.emit(event);
|
2019-10-15 15:02:00 +09:00
|
|
|
}
|
2020-01-17 10:41:22 +09:00
|
|
|
|
|
|
|
onScrollup(event: any) {
|
2020-01-20 16:40:17 +09:00
|
|
|
if (!this.eventList || 0 === this.eventList.length) {
|
|
|
|
return;
|
|
|
|
}
|
2020-01-17 10:41:22 +09:00
|
|
|
this.scrollUpInitalized = true;
|
|
|
|
this.scrollUp.emit(event);
|
|
|
|
}
|
|
|
|
onYReachStart(event: any) {
|
|
|
|
this.yReachStart.emit(event);
|
|
|
|
}
|
|
|
|
onYReachEnd(event: any) {
|
|
|
|
this.yReachEnd.emit(event);
|
|
|
|
}
|
|
|
|
|
2020-01-20 16:40:17 +09:00
|
|
|
onVsChange(event: IPageInfo) {
|
|
|
|
if (
|
|
|
|
-1 === event.startIndex ||
|
|
|
|
-1 === event.endIndex ||
|
|
|
|
(0 === event.startIndex && 0 === event.endIndex)
|
|
|
|
) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.logger.debug('onVsChange', event);
|
|
|
|
}
|
|
|
|
|
2020-01-17 10:41:22 +09:00
|
|
|
trackByEvent(index: number, info: Info<EventJson>): number {
|
|
|
|
return info.seq;
|
|
|
|
}
|
2019-09-23 14:23:24 +09:00
|
|
|
}
|