import { UserSelectDialogType } from './../../../types/userselect.dialog.type'; import { Component, OnInit, Output, EventEmitter, ViewChildren, QueryList, ElementRef, OnDestroy, ViewChild, HostListener } from '@angular/core'; import { NGXLogger } from 'ngx-logger'; import { ucapAnimations, DialogService } from '@ucap-webmessenger/ui'; import { CreateChatDialogComponent, CreateChatDialogData, CreateChatDialogResult } from '@app/layouts/messenger/dialogs/chat/create-chat.dialog.component'; import { Subscription, Observable, merge } from 'rxjs'; import { Store, select } from '@ngrx/store'; import * as AppStore from '@app/store'; import * as ChatStore from '@app/store/messenger/chat'; import * as MessageStore from '@app/store/messenger/message'; import * as SyncStore from '@app/store/messenger/sync'; import { UserInfo } from '@ucap-webmessenger/protocol-sync'; import { UserInfoSS, UserInfoF, UserInfoDN } from '@ucap-webmessenger/protocol-query'; import { MatTabChangeEvent } from '@angular/material'; import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; import { OpenProfileOptions } from '@ucap-webmessenger/protocol-buddy'; import { SessionStorageService } from '@ucap-webmessenger/web-storage'; import { VersionInfo2Response } from '@ucap-webmessenger/api-public'; import { MessageType } from '@ucap-webmessenger/api-message'; import { tap, take } from 'rxjs/operators'; import { MessageWriteDialogComponent, MessageWriteDialogResult, MessageWriteDialogData } from '../dialogs/message/message-write.dialog.component'; import { EnvironmentsInfo, KEY_ENVIRONMENTS_INFO, KEY_VER_INFO, MainMenu } from '@app/types'; import { MessageBoxComponent } from './left-sidenav/message.component'; import { environment } from '../../../../environments/environment'; import { TranslateService, LangChangeEvent } from '@ngx-translate/core'; @Component({ selector: 'app-layout-messenger-left-side', templateUrl: './left-side.component.html', styleUrls: ['./left-side.component.scss'], animations: ucapAnimations }) export class LeftSideComponent implements OnInit, OnDestroy { @Output() openProfile = new EventEmitter<{ userSeq: number; openProfileOptions?: OpenProfileOptions; }>(); @Output() sendCall = new EventEmitter(); @Output() sendSms = new EventEmitter(); @ViewChildren('tabs') tabs: QueryList>; currentTabLable: string; @ViewChild('messageBoxComponent', { static: false }) messageBoxComponent: MessageBoxComponent; @ViewChild('leftSideContainer', { static: false }) leftSideContainer: ElementRef; onLangChangeSubscription: Subscription; badgeChatUnReadCount: number; badgeChatUnReadCountSubscription: Subscription; badgeMessageUnReadCount$: Observable; badgeMessageInterval: any; /** 조직도에서 부서원 선택 */ selectedUserList: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[] = []; /** FAB */ fabButtonShow = true; fabButtons: { icon: string; tooltip?: string; divisionType?: string }[]; MainMenu = MainMenu; sessionVerinfo: VersionInfo2Response; environmentsInfo: EnvironmentsInfo; loginRes: LoginResponse; loginResSubscription: Subscription; showLeftDrawerToggle = false; constructor( private store: Store, private dialogService: DialogService, private sessionStorageService: SessionStorageService, private translateService: TranslateService, private logger: NGXLogger ) { this.sessionVerinfo = this.sessionStorageService.get( KEY_VER_INFO ); this.environmentsInfo = this.sessionStorageService.get( KEY_ENVIRONMENTS_INFO ); } ngOnInit() { this.badgeChatUnReadCountSubscription = this.store .pipe( select(AppStore.MessengerSelector.SyncSelector.selectChatUnreadCount) ) .subscribe(count => { this.badgeChatUnReadCount = count; }); this.loginResSubscription = this.store .pipe( select(AppStore.AccountSelector.AuthenticationSelector.loginRes), tap(loginRes => { this.loginRes = loginRes; }) ) .subscribe(); /** About Message Badge */ this.badgeMessageUnReadCount$ = this.store.pipe( select(AppStore.MessengerSelector.MessageSelector.unReadMessageCount) ); this.getMessageUnreadCount(); this.badgeMessageInterval = setInterval( () => this.getMessageUnreadCount(), 5 * 60 * 1000 ); this.setFabInitial(MainMenu.Group); this.currentTabLable = MainMenu.Group; this.onLangChangeSubscription = merge( this.translateService.onLangChange, this.translateService.onDefaultLangChange, this.translateService.onTranslationChange ).subscribe(() => { this.setFabInitial(this.currentTabLable); }); this.loginResSubscription = this.store .pipe( select(AppStore.MessengerSelector.SettingsSelector.gnbMenuIndex), tap(menuIndex => { this.currentTabLable = menuIndex; this.setFabInitial(menuIndex); }) ) .subscribe(); } ngOnDestroy(): void { if (!!this.badgeChatUnReadCountSubscription) { this.badgeChatUnReadCountSubscription.unsubscribe(); } if (!!this.loginResSubscription) { this.loginResSubscription.unsubscribe(); } if (!!this.onLangChangeSubscription) { this.onLangChangeSubscription.unsubscribe(); } if (!!this.badgeMessageInterval) { clearInterval(this.badgeMessageInterval); } this.logger.debug('-----------------------LeftSideComponent ngOnDestroy'); } @HostListener('mouseenter', ['$event']) mouseOver(event: MouseEvent) { const rect = this.leftSideContainer.nativeElement.getBoundingClientRect(); const minX = rect.left + rect.width - 5; const maxX = rect.left + rect.width; const minY = rect.top; const maxY = rect.top + rect.height; if ( event.pageX >= minX && event.pageX <= maxX && event.pageY >= minY && event.pageY <= maxY ) { this.logger.debug('mouseOver edge of container'); this.showLeftDrawerToggle = true; } } @HostListener('mouseleave', ['$event']) mouseLeave(event: MouseEvent) { this.showLeftDrawerToggle = false; } onClickLeftDrawerToggle() { this.store.dispatch(ChatStore.toggleLeftSideDrawer()); } async onClickNewChat(type: string = 'NORMAL') { const result = await this.dialogService.open< CreateChatDialogComponent, CreateChatDialogData, CreateChatDialogResult >(CreateChatDialogComponent, { width: '600px', data: { type: UserSelectDialogType.NewChat, title: type === 'TIMER' ? this.translateService.instant('chat.newTimerChat') : this.translateService.instant('chat.newChat') } }); if (!!result && !!result.choice && result.choice) { if (!!result.selectedUserList && result.selectedUserList.length > 0) { const userSeqs: number[] = []; result.selectedUserList.map(user => userSeqs.push(user.seq)); if (type === 'NORMAL') { this.store.dispatch(ChatStore.openRoom({ userSeqList: userSeqs })); } else if (type === 'TIMER') { this.store.dispatch( ChatStore.openRoom({ userSeqList: userSeqs, isTimeRoom: true }) ); } } } } async onClickNewGroupAndMember() { const result = await this.dialogService.open< CreateChatDialogComponent, CreateChatDialogData, CreateChatDialogResult >(CreateChatDialogComponent, { width: '600px', data: { type: UserSelectDialogType.NewGroup, title: this.translateService.instant('group.addNew') } }); if (!!result && !!result.choice && result.choice) { if ( !!result.selectedUserList && // result.selectedUserList.length > 0 && result.groupName.trim().length > 0 ) { const userSeqs: number[] = []; result.selectedUserList.map(user => userSeqs.push(user.seq)); this.store.dispatch( SyncStore.createGroupAndBuddy({ groupName: result.groupName, trgtUserSeq: userSeqs }) ); } } } async onClickNewMessage() { const result = await this.dialogService.open< MessageWriteDialogComponent, MessageWriteDialogData, MessageWriteDialogResult >(MessageWriteDialogComponent, { width: '600px', height: '600px', disableClose: true, hasBackdrop: false, data: { loginRes: this.loginRes, environmentsInfo: this.environmentsInfo } }); if (!!result && !!result.sendFlag && result.sendFlag) { if ( this.currentTabLable === MainMenu.Message && !!this.messageBoxComponent ) { const type = result.sendType || MessageType.Send; switch (type) { case MessageType.Send: this.messageBoxComponent.onSelectedIndexChange(1); this.messageBoxComponent.onSelectedIndexTab(1); break; case MessageType.Reservation: this.messageBoxComponent.onSelectedIndexChange(2); this.messageBoxComponent.onSelectedIndexTab(2); break; } } } } onClickOpenProfile(params: { userSeq: number; openProfileOptions?: OpenProfileOptions; }) { this.openProfile.emit({ userSeq: params.userSeq, openProfileOptions: params.openProfileOptions }); } onClickSendClickToCall(calleeNumber: string) { this.sendCall.emit(calleeNumber); } onClickSendSms(calleeNumber: string) { this.sendSms.emit(calleeNumber); } setFabInitial(type: string) { switch (type) { case MainMenu.Group: { this.fabButtonShow = true; this.fabButtons = [ { icon: 'add', tooltip: this.translateService.instant('group.addNew'), divisionType: 'GROUP_NEW_ADD' } ]; } break; case MainMenu.Chat: { this.fabButtonShow = true; this.fabButtons = [ { icon: 'chat', tooltip: this.translateService.instant('chat.newChat'), divisionType: 'CAHT_NEW_ADD' } ]; if (environment.productConfig.CommonSetting.useTimerRoom) { this.fabButtons.push({ icon: 'timer', tooltip: this.translateService.instant('chat.newTimerChat'), divisionType: 'CHAT_NEW_TIMER_ADD' }); } } break; case MainMenu.Organization: { this.fabButtonShow = false; } break; case MainMenu.Message: { this.fabButtonShow = true; this.fabButtons = [ { icon: 'add', tooltip: this.translateService.instant('message.new'), divisionType: 'MESSAGE_NEW' } ]; } break; case MainMenu.Call: { this.fabButtonShow = false; } break; default: { this.fabButtonShow = false; } } } onCheckAllUser(params: { isChecked: boolean; userInfos: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[]; }) { params.userInfos.forEach(userInfo => { if (params.isChecked) { if ( this.selectedUserList.filter(user => user.seq === userInfo.seq) .length === 0 ) { this.selectedUserList = [...this.selectedUserList, userInfo]; } } else { this.selectedUserList = this.selectedUserList.filter( user => user.seq !== userInfo.seq ); } }); } /** 조직도>부서원 :: 리스트의 checkbox 의 이벤트를 받아 선택된 유저리스트를 수집. */ onCheckUser(params: { isChecked: boolean; userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN; }) { if (params.isChecked) { if ( params.userInfo && this.selectedUserList.filter(user => user.seq === params.userInfo.seq) .length === 0 ) { this.selectedUserList = [...this.selectedUserList, params.userInfo]; } } else { this.selectedUserList = this.selectedUserList.filter( user => user.seq !== params.userInfo.seq ); } } onToggleUser(userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN) { if ( this.selectedUserList.filter(user => user.seq === userInfo.seq).length === 0 ) { this.selectedUserList = [...this.selectedUserList, userInfo]; } else { this.selectedUserList = this.selectedUserList.filter( item => item.seq !== userInfo.seq ); } } onResetSelectedUserList( selectedUserList: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[] ) { this.selectedUserList = selectedUserList; } /** FAB */ onClickFab(params: { btn: any }) { const btn = params.btn as { icon: string; tooltip?: string; divisionType?: string; }; switch (btn.divisionType) { case 'GROUP_NEW_ADD': { this.onClickNewGroupAndMember(); } break; case 'CAHT_NEW_ADD': { this.onClickNewChat('NORMAL'); } break; case 'CHAT_NEW_TIMER_ADD': { if (environment.productConfig.CommonSetting.useTimerRoom) { this.onClickNewChat('TIMER'); } } break; case 'MESSAGE_NEW': { this.onClickNewMessage(); } break; } } getMessageUnreadCount(): void { this.store.dispatch(MessageStore.retrieveUnreadCount({})); } }