import { Component, OnInit, OnDestroy, Output, EventEmitter, ViewChild, Input, AfterViewChecked } from '@angular/core'; import { Subscription, of } from 'rxjs'; import { Store, select } from '@ngrx/store'; import { tap, map, catchError, take } from 'rxjs/operators'; import { NGXLogger } from 'ngx-logger'; import * as AppStore from '@app/store'; import { UserInfo } from '@ucap-webmessenger/protocol-room'; import { VersionInfo2Response } from '@ucap-webmessenger/api-public'; import { SessionStorageService } from '@ucap-webmessenger/web-storage'; import { KEY_VER_INFO } from '@app/types/ver-info.type'; import { DialogService } from '@ucap-webmessenger/ui'; import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type'; import { MessageApiService, MessageType, RetrieveRequest, MessageList, RetrieveSearchRequest, MessageSearchType, DetailRequest, MessageDetailInfo, DelRequest, CancelReservationRequest } from '@ucap-webmessenger/api-message'; import { DeviceType } from '@ucap-webmessenger/core'; import { MessageStatusCode } from '@ucap-webmessenger/api'; import { ContentType } from '@ucap-webmessenger/api-message'; import { FormGroup, FormBuilder } from '@angular/forms'; import { MatTabGroup, MatSelectChange, MatRadioChange } from '@angular/material'; import { MessageDetailDialogComponent, MessageDetailDialogResult, MessageDetailDialogData } from '../../dialogs/message/message-detail.dialog.component'; @Component({ selector: 'app-layout-chat-left-sidenav-message', templateUrl: './message.component.html', styleUrls: ['./message.component.scss'] }) export class MessageBoxComponent implements OnInit, OnDestroy, AfterViewChecked { @Input() isVisible = false; @Output() doRefreshUnReadCount = new EventEmitter(); @ViewChild('tabs', { static: false }) tabs: MatTabGroup; isInitTabs = false; fgSearch: FormGroup; fgSearchType: FormGroup; loginRes: LoginResponse; sessionVerinfo: VersionInfo2Response; messageList: MessageList[] = []; messageRecieveListSubscription: Subscription; messageSendListSubscription: Subscription; messageReservationListSubscription: Subscription; messageSearchListSubscription: Subscription; currentTabIndex = 0; defaultPageSize = 1000; // default recieveCurrentPage = 0; // start index is 0. sendCurrentPage = 0; // start index is 0. reservationCurrentPage = 0; // start index is 0. searchCurrentPage = 0; // start index is 0. currentTotalCount = 0; currentPage = 0; ContentType = ContentType; MessageType = MessageType; MessageSearchType = MessageSearchType; isSearch = false; constructor( private store: Store, private formBuilder: FormBuilder, private sessionStorageService: SessionStorageService, private dialogService: DialogService, private messageApiService: MessageApiService, private logger: NGXLogger ) { this.loginRes = this.sessionStorageService.get( KEY_LOGIN_RES_INFO ); this.sessionVerinfo = this.sessionStorageService.get( KEY_VER_INFO ); } ngOnInit() { this.fgSearch = this.formBuilder.group({ searchInput: null }); this.fgSearchType = this.formBuilder.group({ searchMessageType: [MessageType.All], searchMessageSearchType: [MessageSearchType.Name] }); // 초기 검색은 수신함. this.getRetrieveMessage(MessageType.Receive, this.recieveCurrentPage); if (!!this.tabs) { this.tabs.realignInkBar(); } } ngAfterViewChecked(): void { if (!!this.tabs && !this.isInitTabs && this.isVisible) { this.isInitTabs = true; this.tabs.realignInkBar(); } } ngOnDestroy(): void { if (!!this.messageRecieveListSubscription) { this.messageRecieveListSubscription.unsubscribe(); } if (!!this.messageSendListSubscription) { this.messageSendListSubscription.unsubscribe(); } if (!!this.messageReservationListSubscription) { this.messageReservationListSubscription.unsubscribe(); } if (!!this.messageSearchListSubscription) { this.messageSearchListSubscription.unsubscribe(); } } onSelectedIndexChange(value: number) { this.currentTabIndex = value; let type: MessageType; switch (value) { case 0: // Recieve type = MessageType.Receive; this.recieveCurrentPage = 0; break; case 1: // Send type = MessageType.Send; this.sendCurrentPage = 0; break; case 2: // Reservation type = MessageType.Reservation; this.reservationCurrentPage = 0; break; } this.getRetrieveMessage(type, 0); } /** 쪽지 검색 관련 */ onChangeSelection(event: MatSelectChange) { this.searchCurrentPage = 0; this.getSearchMessage( event.value, this.fgSearchType.get('searchMessageSearchType').value, this.fgSearch.get('searchInput').value ); } onChangeSearchType(event: MatRadioChange) { this.searchCurrentPage = 0; this.getSearchMessage( this.fgSearchType.get('searchMessageType').value, event.value, this.fgSearch.get('searchInput').value ); } onKeyDownEnter(event: KeyboardEvent, search: string) { event.preventDefault(); event.stopPropagation(); this.searchCurrentPage = 0; this.getSearchMessage( MessageType.All, MessageSearchType.Name, search.trim() ); } getSearchMessage( messageType: MessageType, searchType: MessageSearchType, searchStr: string ) { this.isSearch = true; this.messageSendListSubscription = this.messageApiService .retrieveSearchMessage({ userSeq: this.loginRes.userSeq, deviceType: DeviceType.PC, tokenKey: this.loginRes.tokenString, type: messageType, pageSize: this.defaultPageSize, pageCount: this.searchCurrentPage, searchTitle: searchType === MessageSearchType.Title ? searchStr : '', searchName: searchType === MessageSearchType.Name ? searchStr : '', searchContent: searchType === MessageSearchType.Contents ? searchStr : '' } as RetrieveSearchRequest) .pipe( take(1), map(res => { if (res.responseCode === MessageStatusCode.Success) { this.currentTotalCount = res.totalCount; this.currentPage = res.pageCount; this.searchCurrentPage = res.pageCount; this.messageList = res.messageList; } else { } }), catchError(error => of(this.logger.error(error))) ) .subscribe(); } onClickSearchCancel() { this.isSearch = false; this.getRetrieveMessage(MessageType.Receive, this.recieveCurrentPage); } /** 쪽지 타입별 조회 */ getRetrieveMessage(type: MessageType, trgtPageIndex: number) { switch (type) { case MessageType.Receive: { this.messageSendListSubscription = this.messageApiService .retrieveReceiveMessage({ userSeq: this.loginRes.userSeq, deviceType: DeviceType.PC, tokenKey: this.loginRes.tokenString, type: MessageType.Receive, pageSize: this.defaultPageSize, pageCount: this.recieveCurrentPage } as RetrieveRequest) .pipe( take(1), map(res => { if (res.responseCode === MessageStatusCode.Success) { this.currentTotalCount = res.totalCount; this.currentPage = res.pageCount; this.recieveCurrentPage = res.pageCount; this.messageList = res.messageList; } else { } }), catchError(error => of(this.logger.error(error))) ) .subscribe(); } break; case MessageType.Send: { this.messageSendListSubscription = this.messageApiService .retrieveSendMessage({ userSeq: this.loginRes.userSeq, deviceType: DeviceType.PC, tokenKey: this.loginRes.tokenString, type: MessageType.Send, pageSize: this.defaultPageSize, pageCount: this.sendCurrentPage } as RetrieveRequest) .pipe( take(1), map(res => { if (res.responseCode === MessageStatusCode.Success) { this.currentTotalCount = res.totalCount; this.currentPage = res.pageCount; this.sendCurrentPage = res.pageCount; this.messageList = res.messageList; } else { } }), catchError(error => of(this.logger.error(error))) ) .subscribe(); } break; case MessageType.Reservation: { this.messageSendListSubscription = this.messageApiService .retrieveReservationMessage({ userSeq: this.loginRes.userSeq, deviceType: DeviceType.PC, tokenKey: this.loginRes.tokenString, type: MessageType.Reservation, pageSize: this.defaultPageSize, pageCount: this.reservationCurrentPage } as RetrieveRequest) .pipe( take(1), map(res => { if (res.responseCode === MessageStatusCode.Success) { this.currentTotalCount = res.totalCount; this.currentPage = res.pageCount; this.reservationCurrentPage = res.pageCount; this.messageList = res.messageList; } else { } }), catchError(error => of(this.logger.error(error))) ) .subscribe(); } break; } } /** 쪽지 상세보기 */ onClickDetail(message: MessageList) { this.messageApiService .detailMessage({ userSeq: this.loginRes.userSeq, deviceType: DeviceType.PC, tokenKey: this.loginRes.tokenString, type: message.type, msgId: message.msgId } as DetailRequest) .pipe( take(1), map(async res => { if (res.responseCode === MessageStatusCode.Success) { // Badge Refresh in case Receive Message.. if (res.msgInfo.type === MessageType.Receive) { this.doRefreshUnReadCount.emit(); } // detail view.. const result = await this.dialogService.open< MessageDetailDialogComponent, MessageDetailDialogData, MessageDetailDialogResult >(MessageDetailDialogComponent, { width: '600px', data: { detail: res, loginRes: this.loginRes } }); if (!!result) { switch (result.returnType) { case 'DEL': // 단건 삭제. this.doMessageDelete([result.messageInfo]); break; case 'CANCEL_RESERVATION': // 단건 발송취소(예약) this.doMessageCancelReservation(result.messageInfo); break; } } } else { } }), catchError(error => of(this.logger.error(error))) ) .subscribe(); } /** 쪽지(수신,발신) 삭제 */ doMessageDelete(messageInfo: MessageDetailInfo[]): void { const msgList: { msgId: number }[] = []; messageInfo.forEach(info => msgList.push({ msgId: info.msgId })); this.messageApiService .deleteMessage({ userSeq: this.loginRes.userSeq, deviceType: DeviceType.PC, tokenKey: this.loginRes.tokenString, type: messageInfo[0].type, msgList } as DelRequest) .pipe( take(1), map(async res => { if (res.responseCode === MessageStatusCode.Success) { } else { this.logger.error('message delete Error!'); } // 현재탭 재조회. this.onSelectedIndexChange(this.currentTabIndex); }), catchError(error => of(this.logger.error(error))) ) .subscribe(); } /** 쪽지(예약) 삭제 */ doMessageCancelReservation(messageInfo: MessageDetailInfo): void { this.messageApiService .cancelReservationMessage({ userSeq: this.loginRes.userSeq, deviceType: DeviceType.PC, tokenKey: this.loginRes.tokenString, type: messageInfo.type, msgId: messageInfo.msgId } as CancelReservationRequest) .pipe( take(1), map(async res => { if (res.responseCode === MessageStatusCode.Success) { } else { this.logger.error('message(reservation) cancel Error!'); } // 현재탭 재조회. this.onSelectedIndexChange(this.currentTabIndex); }), catchError(error => of(this.logger.error(error))) ) .subscribe(); } }