import { Component, OnInit, Inject, ViewChild, OnDestroy } from '@angular/core'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; import { KEY_LOGIN_RES_INFO, KEY_VER_INFO, KEY_AUTH_INFO } from '@app/types'; import { SessionStorageService } from '@ucap-webmessenger/web-storage'; import { Store, select } from '@ngrx/store'; import * as AppStore from '@app/store'; import * as ChatStore from '@app/store/messenger/chat'; import * as SyncStore from '@app/store/messenger/sync'; import * as AuthenticationStore from '@app/store/account/authentication'; import { UserInfo, GroupDetailData } from '@ucap-webmessenger/protocol-sync'; import { UserInfoSS, UserInfoF, UserInfoDN, AuthResponse } from '@ucap-webmessenger/protocol-query'; import { DialogService, ConfirmDialogComponent, ConfirmDialogData, ConfirmDialogResult, SnackBarService, AlertDialogComponent, AlertDialogResult, AlertDialogData } from '@ucap-webmessenger/ui'; import { VersionInfo2Response } from '@ucap-webmessenger/api-public'; import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; import { map, take, finalize, catchError } from 'rxjs/operators'; import { Subscription, of } from 'rxjs'; import { SelectGroupDialogComponent, SelectGroupDialogData, SelectGroupDialogResult } from '../group/select-group.dialog.component'; import { FileUploadItem } from '@ucap-webmessenger/api'; import { CommonApiService } from '@ucap-webmessenger/api-common'; import { OpenProfileOptions } from '@ucap-webmessenger/protocol-buddy'; import { EnvironmentsInfo, KEY_ENVIRONMENTS_INFO } from '@app/types'; import { StatusCode } from '@ucap-webmessenger/api'; import { MessageWriteDialogComponent, MessageWriteDialogResult, MessageWriteDialogData } from '../message/message-write.dialog.component'; import { CallService, PromptMessageStatusCode } from '@ucap-webmessenger/api-prompt'; import { NGXLogger } from 'ngx-logger'; import { SmsUtils } from '@ucap-webmessenger/daesang'; import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native'; import { environment } from '../../../../../environments/environment'; import { TranslateService } from '@ngx-translate/core'; export interface ProfileDialogData { userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN; openProfileOptions?: OpenProfileOptions; } export interface ProfileDialogResult {} @Component({ selector: 'app-profile.dialog', templateUrl: './profile.dialog.component.html', styleUrls: ['./profile.dialog.component.scss'] }) export class ProfileDialogComponent implements OnInit, OnDestroy { userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN; loginRes: LoginResponse; sessionVerinfo: VersionInfo2Response; environmentsInfo: EnvironmentsInfo; authInfo: AuthResponse; isMe: boolean; isBuddy: boolean; isFavorit: boolean; editableProfileImage: boolean; selectAllBuddy2Subscription: Subscription; constructor( public dialogRef: MatDialogRef, @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService, @Inject(MAT_DIALOG_DATA) public data: ProfileDialogData, private dialogService: DialogService, private sessionStorageService: SessionStorageService, private commonApiService: CommonApiService, private callService: CallService, private snackBarService: SnackBarService, private translateService: TranslateService, private store: Store, private logger: NGXLogger ) { this.sessionVerinfo = this.sessionStorageService.get( KEY_VER_INFO ); this.loginRes = this.sessionStorageService.get( KEY_LOGIN_RES_INFO ); this.environmentsInfo = this.sessionStorageService.get( KEY_ENVIRONMENTS_INFO ); this.authInfo = this.sessionStorageService.get(KEY_AUTH_INFO); this.userInfo = data.userInfo; this.editableProfileImage = environment.productConfig.CommonSetting.editableProfileImage; } ngOnInit() { this.isMe = this.loginRes.userSeq === this.data.userInfo.seq; this.selectAllBuddy2Subscription = this.store .pipe( select(AppStore.MessengerSelector.SyncSelector.selectAllBuddy2), map(buddyList => { const users = buddyList.filter( buddy => buddy.seq === this.data.userInfo.seq ); this.isBuddy = users.length > 0; if (this.isBuddy) { this.isFavorit = users[0].isFavorit; } }) ) .subscribe(); } ngOnDestroy(): void { if (!!this.selectAllBuddy2Subscription) { this.selectAllBuddy2Subscription.unsubscribe(); } } onClickChat(userInfo: UserInfoSS) { if (userInfo.seq === this.loginRes.userSeq) { this.store.dispatch( ChatStore.openRoom({ userSeqList: [this.loginRes.talkWithMeBotSeq] }) ); } else { this.store.dispatch(ChatStore.openRoom({ userSeqList: [userInfo.seq] })); } this.dialogRef.close(); } onClickSendMessage(userInfo: UserInfoSS) { if (userInfo.seq !== this.loginRes.userSeq) { this.dialogRef.close(); this.dialogService.open< MessageWriteDialogComponent, MessageWriteDialogData, MessageWriteDialogResult >(MessageWriteDialogComponent, { width: '600px', height: '600px', disableClose: true, hasBackdrop: false, data: { loginRes: this.loginRes, environmentsInfo: this.environmentsInfo, receiverList: [userInfo] } }); } } async onClickSendClickToCall(calleeNumber: string) { const madn = this.loginRes.madn; if (!madn || madn.trim().length === 0) { this.dialogService.open< AlertDialogComponent, AlertDialogData, AlertDialogResult >(AlertDialogComponent, { data: { title: this.translateService.instant('call.errors.label'), html: this.translateService.instant('call.errors.cannotCallToUser') } }); return false; } calleeNumber = calleeNumber.replace(/\D/g, ''); if (!!calleeNumber && calleeNumber.length > 0) { const result = await this.dialogService.open< ConfirmDialogComponent, ConfirmDialogData, ConfirmDialogResult >(ConfirmDialogComponent, { width: '360px', data: { title: this.translateService.instant('call.callTo'), html: this.translateService.instant('call.callWithNumber', { phoneNumber: calleeNumber }) } }); if (!!result && !!result.choice && result.choice) { this.callService .sendCall({ userSeq: this.loginRes.userSeq, deviceType: this.environmentsInfo.deviceType, tokenKey: this.loginRes.tokenString, calleeNumber }) .pipe( take(1), map(res => { if (res.responseCode === PromptMessageStatusCode.Success) { this.logger.debug('SUCCESS'); this.logger.debug(res); } else { this.logger.error(res); } }), catchError(error => of(this.logger.debug(error))) ) .subscribe(); } } else { this.dialogService.open< AlertDialogComponent, AlertDialogData, AlertDialogResult >(AlertDialogComponent, { data: { title: this.translateService.instant('call.errors.label'), html: this.translateService.instant( 'call.errors.cannotCallToUserWithoutPhomeNumber' ) } }); } } onClickSendSms(calleeNumber: string) { const smsUtil = new SmsUtils( this.sessionStorageService, this.nativeService ); if (!smsUtil.getAuthSms()) { this.dialogService.open< AlertDialogComponent, AlertDialogData, AlertDialogResult >(AlertDialogComponent, { data: { title: this.translateService.instant('sms.errors.label'), html: this.translateService.instant('sms.errors.haveNoPermission') } }); return false; } calleeNumber = calleeNumber.replace(/\D/g, ''); smsUtil.openSendSms(this.loginRes.tokenString, [calleeNumber]); // if (!!calleeNumber && calleeNumber.length > 0) { // smsUtil.openSendSms(this.loginRes.tokenString, [calleeNumber]); // } else { // // this.dialogService.open< // // AlertDialogComponent, // // AlertDialogData, // // AlertDialogResult // // >(AlertDialogComponent, { // // data: { // // title: '', // // html: `상대방 번호가 없어 전화를 걸 수 없습니다.` // // } // // }); // } } onClickToggleFavorit(param: { userInfo: UserInfoSS; isFavorit: boolean }) { this.store.dispatch( SyncStore.updateBuddy({ seq: param.userInfo.seq, isFavorit: param.isFavorit }) ); } async onClickToggleBuddy(param: { userInfo: UserInfoSS; isBuddy: boolean }) { if (param.isBuddy) { // 동료추가. const result = await this.dialogService.open< SelectGroupDialogComponent, SelectGroupDialogData, SelectGroupDialogResult >(SelectGroupDialogComponent, { width: '600px', data: { title: this.translateService.instant('group.selectTargetGroup') } }); if (!!result && !!result.choice && result.choice) { if (!!result.group) { const oldGroup: GroupDetailData = result.group; const trgtUserSeq: number[] = []; result.group.userSeqs.map(seq => trgtUserSeq.push(seq)); trgtUserSeq.push(param.userInfo.seq); this.store.dispatch( SyncStore.updateGroupMember({ oldGroup, trgtUserSeq }) ); } } } else { // 동료삭제. const result = await this.dialogService.open< ConfirmDialogComponent, ConfirmDialogData, ConfirmDialogResult >(ConfirmDialogComponent, { width: '360px', data: { title: this.translateService.instant('group.removeBuddyFromGroup'), html: this.translateService.instant( 'group.confirmRemoveBuddyFromGroup', { target: `${param.userInfo.name} ${param.userInfo.grade}` } ) } }); if (!!result && !!result.choice && result.choice) { this.store.dispatch( SyncStore.delBuddyAndClear({ seq: param.userInfo.seq }) ); this.isBuddy = false; } } } onUploadProfileImage(profileImageFileUploadItem: FileUploadItem) { this.commonApiService .fileProfileSave( { userSeq: this.loginRes.userSeq, deviceType: this.environmentsInfo.deviceType, token: this.loginRes.tokenString, file: profileImageFileUploadItem.file, fileUploadItem: profileImageFileUploadItem }, this.sessionVerinfo.profileUploadUrl ) .pipe( take(1), map(res => { if (!res) { return; } if (StatusCode.Success === res.statusCode) { return res; } else { throw res; } }), finalize(() => { setTimeout(() => { profileImageFileUploadItem.uploadingProgress$ = undefined; }, 1000); }) ) .subscribe( res => { const userInfo = { ...this.loginRes.userInfo, profileImageFile: res.profileSubDir }; this.store.dispatch( AuthenticationStore.updateLoginRes({ loginRes: { ...this.loginRes, userInfo } }) ); this.userInfo = userInfo as any; }, error => { this.snackBarService.open( this.translateService.instant( 'profile.errors.failToChangeProfileImage' ), '', { duration: 3000, verticalPosition: 'bottom' } ); } ); } }