From dff2e4e55f164b759d9ba7cb9bc7427ef632dd62 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Fri, 27 Sep 2019 12:53:21 +0900 Subject: [PATCH] buddy & group list are implemented --- .../left-sidenav/group.component.html | 3 +- .../left-sidenav/group.component.ts | 61 +++- .../components/login.page.component.ts | 1 + .../components/main.page.component.html | 4 +- .../components/main.page.component.ts | 17 +- .../src/app/resolvers/messenger.resolver.ts | 123 +++---- .../src/app/services/app.service.ts | 36 ++- .../app/services/authentication.service.ts | 21 +- .../store/account/authentication/effects.ts | 304 ++++++++++++++++-- .../src/app/store/account/privacy/effects.ts | 108 ++++--- .../src/app/store/messenger/chat/actions.ts | 6 + .../src/app/store/messenger/chat/effects.ts | 16 + .../src/app/store/messenger/chat/index.ts | 4 + .../src/app/store/messenger/chat/reducers.ts | 13 + .../src/app/store/messenger/chat/state.ts | 18 ++ .../src/app/store/messenger/index.ts | 11 +- .../src/app/store/messenger/sync/state.ts | 9 + .../src/app/store/setting/option/effects.ts | 3 +- .../src/app/store/setting/query/effects.ts | 16 +- .../src/app/types/environment.type.ts | 7 + .../src/app/types/index.ts | 1 + .../src/app/types/login-info.type.ts | 4 +- .../src/lib/models/buddy.ts | 5 +- .../components/expansion-panel.component.html | 11 +- .../components/expansion-panel.component.ts | 13 +- 25 files changed, 626 insertions(+), 189 deletions(-) create mode 100644 projects/ucap-webmessenger-app/src/app/store/messenger/chat/actions.ts create mode 100644 projects/ucap-webmessenger-app/src/app/store/messenger/chat/effects.ts create mode 100644 projects/ucap-webmessenger-app/src/app/store/messenger/chat/index.ts create mode 100644 projects/ucap-webmessenger-app/src/app/store/messenger/chat/reducers.ts create mode 100644 projects/ucap-webmessenger-app/src/app/store/messenger/chat/state.ts create mode 100644 projects/ucap-webmessenger-app/src/app/types/environment.type.ts diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/group.component.html b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/group.component.html index 199ae157..ef28f944 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/group.component.html +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/group.component.html @@ -1,3 +1,4 @@ diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/group.component.ts b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/group.component.ts index 687baaff..e08d39d2 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/group.component.ts +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/group.component.ts @@ -1,6 +1,7 @@ import { Component, OnInit } from '@angular/core'; -import { Observable } from 'rxjs'; +import { Observable, combineLatest } from 'rxjs'; +import { map } from 'rxjs/operators'; import { Store, select } from '@ngrx/store'; @@ -8,6 +9,8 @@ import { ucapAnimations } from '@ucap-webmessenger/ui'; import { UserInfo, GroupDetailData } from '@ucap-webmessenger/protocol-sync'; import * as AppStore from '@app/store'; +import * as ChatStore from '@app/store/messenger/chat'; +import { NGXLogger } from 'ngx-logger'; @Component({ selector: 'app-layout-chat-left-sidenav-group', @@ -16,13 +19,59 @@ import * as AppStore from '@app/store'; animations: ucapAnimations }) export class GroupComponent implements OnInit { - groupList$: Observable; + groupBuddyList$: Observable< + { group: GroupDetailData; buddyList: UserInfo[] }[] + >; - constructor(private store: Store) {} + constructor(private store: Store, private logger: NGXLogger) {} ngOnInit() { - this.groupList$ = this.store.pipe( - select(AppStore.MessengerSelector.SyncSelector.groupList) - ); + this.groupBuddyList$ = this.store + .pipe( + select(AppStore.MessengerSelector.SyncSelector.groupListAndBuddyList) + ) + .pipe( + map(groupListAndBuddyList => { + const groupList = groupListAndBuddyList.groupList + .slice() + .sort((a, b) => { + // 기본그룹은 제일 하단 + if (0 === a.seq) { + return 1; + } else if (0 === b.seq) { + return -1; + } else { + if (a.name > b.name) { + return 1; + } + if (b.name > a.name) { + return -1; + } + return 0; + } + }); + + const groupBuddyList: { + group: GroupDetailData; + buddyList: UserInfo[]; + }[] = []; + for (const group of groupList) { + const buddyList = groupListAndBuddyList.buddyList.filter(buddy => { + return group.userSeqs.indexOf(buddy.seq) > -1; + }); + + groupBuddyList.push({ + group, + buddyList + }); + } + + return groupBuddyList; + }) + ); + } + + onSelectBuddy(buddy: UserInfo) { + this.store.dispatch(ChatStore.selectedRoom({ roomSeq: buddy.seq })); } } diff --git a/projects/ucap-webmessenger-app/src/app/pages/account/components/login.page.component.ts b/projects/ucap-webmessenger-app/src/app/pages/account/components/login.page.component.ts index bd187d38..b7bf1caf 100644 --- a/projects/ucap-webmessenger-app/src/app/pages/account/components/login.page.component.ts +++ b/projects/ucap-webmessenger-app/src/app/pages/account/components/login.page.component.ts @@ -42,6 +42,7 @@ export class LoginPageComponent implements OnInit { AuthenticationStore.webLogin({ loginInfo: { companyCode: value.companyCode, + companyGroupType: 'C', loginId: value.loginId, loginPw: value.loginPw }, diff --git a/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.html b/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.html index 311a6ea8..58615978 100644 --- a/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.html +++ b/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.html @@ -4,10 +4,10 @@
diff --git a/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.ts b/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.ts index 7de5914b..5582952b 100644 --- a/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.ts +++ b/projects/ucap-webmessenger-app/src/app/pages/messenger/components/main.page.component.ts @@ -1,5 +1,9 @@ import { Component, OnInit } from '@angular/core'; -import { AuthenticationProtocolService } from '@ucap-webmessenger/protocol-authentication'; + +import { Store, select } from '@ngrx/store'; + +import * as AppSotre from '@app/store'; +import { Observable } from 'rxjs'; @Component({ selector: 'app-page-messenger-main', @@ -7,14 +11,13 @@ import { AuthenticationProtocolService } from '@ucap-webmessenger/protocol-authe styleUrls: ['./main.page.component.scss'] }) export class MainPageComponent implements OnInit { - selectedChat: boolean; + selectedChat$: Observable; - constructor( - private authenticationProtocolService: AuthenticationProtocolService - ) {} + constructor(private store: Store) {} ngOnInit(): void { - // this.authenticationProtocolService.login({}); - this.selectedChat = true; + this.selectedChat$ = this.store.pipe( + select(AppSotre.MessengerSelector.ChatSelector.selectedRoom) + ); } } diff --git a/projects/ucap-webmessenger-app/src/app/resolvers/messenger.resolver.ts b/projects/ucap-webmessenger-app/src/app/resolvers/messenger.resolver.ts index 527f805d..e7228cf4 100644 --- a/projects/ucap-webmessenger-app/src/app/resolvers/messenger.resolver.ts +++ b/projects/ucap-webmessenger-app/src/app/resolvers/messenger.resolver.ts @@ -15,7 +15,12 @@ import { PublicApiService } from '@ucap-webmessenger/api-public'; import * as AppStore from '../store'; import * as VersionInfoStore from '../store/setting/version-info'; -import { LoginInfo, KEY_LOGIN_INFO } from '../types'; +import { + LoginInfo, + KEY_LOGIN_INFO, + EnvironmentsInfo, + KEY_ENVIRONMENTS_INFO +} from '../types'; import { InnerProtocolService } from '@ucap-webmessenger/protocol-inner'; import { AuthenticationProtocolService, @@ -41,64 +46,68 @@ export class AppMessengerResolver implements Resolve { state: RouterStateSnapshot ): void | Observable | Promise { const loginInfo = this.sessionStorageService.get(KEY_LOGIN_INFO); + const environmentsInfo = this.sessionStorageService.get( + KEY_ENVIRONMENTS_INFO + ); return new Promise((resolve, reject) => { - this.publicApiService - .versionInfo2({ - deviceType: loginInfo.deviceType, - companyGroupType: 'C', - companyCode: loginInfo.companyCode, - loginId: loginInfo.loginId - }) - .pipe( - take(1), - tap(versionInfo2Res => { - this.store.dispatch(VersionInfoStore.fetchSuccess(versionInfo2Res)); - }), - mergeMap(versionInfo2Res => - this.protocolService.connect(versionInfo2Res.serverIp) - ), - mergeMap(() => this.innerProtocolService.conn({})), - mergeMap(connRres => - this.authenticationProtocolService.login({ - loginId: loginInfo.loginId, - loginPw: loginInfo.loginPw, - deviceType: loginInfo.deviceType, - deviceId: ' ', - token: '', - localeCode: loginInfo.localeCode, - pushId: ' ', - companyCode: loginInfo.companyCode, - passwordEncodingType: 1, - clientVersion: '', - reconnect: false, - ip: 'localhost', - hostName: '', - ssoMode: SSOMode.AUTH, - userSpecificInformation: 'PRO_000482', - productId: 'PRO_000482', - productName: 'EZMessenger' - }) - ), - map(loginRes => { - this.store.dispatch( - AuthenticationStore.loginSuccess({ - loginInfo: loginRes - }) - ); - }), - catchError(err => { - return throwError(err); - }) - ) - .subscribe( - () => { - resolve(); - }, - err => { - reject(); - } - ); + resolve(); + // this.publicApiService + // .versionInfo2({ + // deviceType: environmentsInfo.deviceType, + // companyGroupType: loginInfo.companyGroupType, + // companyCode: loginInfo.companyCode, + // loginId: loginInfo.loginId + // }) + // .pipe( + // take(1), + // tap(versionInfo2Res => { + // this.store.dispatch(VersionInfoStore.fetchSuccess(versionInfo2Res)); + // }), + // mergeMap(versionInfo2Res => + // this.protocolService.connect(versionInfo2Res.serverIp) + // ), + // mergeMap(() => this.innerProtocolService.conn({})), + // mergeMap(connRres => + // this.authenticationProtocolService.login({ + // loginId: loginInfo.loginId, + // loginPw: loginInfo.loginPw, + // deviceType: environmentsInfo.deviceType, + // deviceId: ' ', + // token: '', + // localeCode: loginInfo.localeCode, + // pushId: ' ', + // companyCode: loginInfo.companyCode, + // passwordEncodingType: 1, + // clientVersion: '', + // reconnect: false, + // ip: 'localhost', + // hostName: '', + // ssoMode: SSOMode.AUTH, + // userSpecificInformation: 'PRO_000482', + // productId: 'PRO_000482', + // productName: 'EZMessenger' + // }) + // ), + // map(loginRes => { + // this.store.dispatch( + // AuthenticationStore.loginSuccess({ + // loginInfo: loginRes + // }) + // ); + // }), + // catchError(err => { + // return throwError(err); + // }) + // ) + // .subscribe( + // () => { + // resolve(); + // }, + // err => { + // reject(); + // } + // ); }); } } diff --git a/projects/ucap-webmessenger-app/src/app/services/app.service.ts b/projects/ucap-webmessenger-app/src/app/services/app.service.ts index 2ab032ab..5b603b1e 100644 --- a/projects/ucap-webmessenger-app/src/app/services/app.service.ts +++ b/projects/ucap-webmessenger-app/src/app/services/app.service.ts @@ -1,14 +1,44 @@ import { Injectable } from '@angular/core'; import { AppNotificationService } from './notification.service'; +import { SessionStorageService } from '@ucap-webmessenger/web-storage'; +import { EnviromentUtilService } from '@ucap-webmessenger/util'; +import { DeviceType } from '@ucap-webmessenger/core'; +import { EnvironmentsInfo, KEY_ENVIRONMENTS_INFO } from '@app/types'; @Injectable() export class AppService { - constructor(private appNotificationService: AppNotificationService) {} + constructor( + private enviromentUtilService: EnviromentUtilService, + private sessionStorageService: SessionStorageService, + private appNotificationService: AppNotificationService + ) {} public postInit(): Promise { return new Promise((resolve, reject) => { - this.appNotificationService.subscribe(); - resolve(); + try { + let deviceType: DeviceType; + if (this.enviromentUtilService.nodeWebkit()) { + deviceType = DeviceType.PC; + } else if (this.enviromentUtilService.android()) { + deviceType = DeviceType.Android; + } else if (this.enviromentUtilService.ios()) { + deviceType = DeviceType.iOS; + } else { + deviceType = DeviceType.Web; + } + + this.sessionStorageService.set( + KEY_ENVIRONMENTS_INFO, + { + deviceType + } + ); + + this.appNotificationService.subscribe(); + resolve(); + } catch (error) { + reject(); + } }); } } diff --git a/projects/ucap-webmessenger-app/src/app/services/authentication.service.ts b/projects/ucap-webmessenger-app/src/app/services/authentication.service.ts index 5e22890c..454431f6 100644 --- a/projects/ucap-webmessenger-app/src/app/services/authentication.service.ts +++ b/projects/ucap-webmessenger-app/src/app/services/authentication.service.ts @@ -6,8 +6,7 @@ import { SessionStorageService, LocalStorageService } from '@ucap-webmessenger/web-storage'; -import { EnviromentUtilService } from '@ucap-webmessenger/util'; -import { DeviceType, LocaleCode } from '@ucap-webmessenger/core'; +import { LocaleCode } from '@ucap-webmessenger/core'; import { LoginInfo, KEY_LOGIN_INFO } from '../types'; @Injectable({ @@ -18,8 +17,7 @@ export class AppAuthenticationService { constructor( private sessionStorageService: SessionStorageService, - private localStorageService: LocalStorageService, - private enviromentUtilService: EnviromentUtilService + private localStorageService: LocalStorageService ) {} authenticated(): boolean { @@ -28,24 +26,11 @@ export class AppAuthenticationService { } login(loginInfo: LoginInfo, rememberMe: boolean) { - let deviceType: DeviceType; - loginInfo = { ...loginInfo, localeCode: LocaleCode.Korean }; - if (this.enviromentUtilService.nodeWebkit()) { - deviceType = DeviceType.PC; - } else if (this.enviromentUtilService.android()) { - deviceType = DeviceType.Android; - } else if (this.enviromentUtilService.ios()) { - deviceType = DeviceType.iOS; - } else { - deviceType = DeviceType.Web; - } - this.sessionStorageService.set(KEY_LOGIN_INFO, { ...loginInfo, - loginPw: CryptoJS.enc.Hex.stringify(CryptoJS.SHA256(loginInfo.loginPw)), - deviceType + loginPw: CryptoJS.enc.Hex.stringify(CryptoJS.SHA256(loginInfo.loginPw)) }); if (rememberMe) { diff --git a/projects/ucap-webmessenger-app/src/app/store/account/authentication/effects.ts b/projects/ucap-webmessenger-app/src/app/store/account/authentication/effects.ts index 92356379..8ab465d2 100644 --- a/projects/ucap-webmessenger-app/src/app/store/account/authentication/effects.ts +++ b/projects/ucap-webmessenger-app/src/app/store/account/authentication/effects.ts @@ -1,18 +1,22 @@ import { Injectable, Inject } from '@angular/core'; import { Router } from '@angular/router'; -import { Actions, ofType, createEffect } from '@ngrx/effects'; - -import { of } from 'rxjs'; +import { of, throwError, EMPTY as empty } from 'rxjs'; import { catchError, exhaustMap, map, tap, take, - switchMap + switchMap, + mergeMap, + skip, + concatMap } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; +import { Actions, ofType, createEffect } from '@ngrx/effects'; + import { PiService, Login2Response, @@ -37,38 +41,265 @@ import { webLoginSuccess, webLoginFailure } from './actions'; -import { LoginInfo } from '../../../types'; +import { + LoginInfo, + EnvironmentsInfo, + KEY_ENVIRONMENTS_INFO +} from '../../../types'; import { AppAuthenticationService } from '../../../services/authentication.service'; +import { NGXLogger } from 'ngx-logger'; +import { + PublicApiService, + VersionInfo2Response +} from '@ucap-webmessenger/api-public'; +import { SessionStorageService } from '@ucap-webmessenger/web-storage'; + +import * as VersionInfoStore from '@app/store/setting/version-info'; +import { ProtocolService } from '@ucap-webmessenger/protocol'; +import { InnerProtocolService } from '@ucap-webmessenger/protocol-inner'; +import { + AuthenticationProtocolService, + SSOMode, + LoginResponse +} from '@ucap-webmessenger/protocol-authentication'; + +import CryptoJS from 'crypto-js'; @Injectable() export class Effects { - webLogin$ = createEffect(() => - this.actions$.pipe( - ofType(webLogin), - map(action => action), - exhaustMap((params: { loginInfo: LoginInfo; rememberMe: boolean }) => - this.piService - .login2({ - loginId: params.loginInfo.loginId, - loginPw: params.loginInfo.loginPw, - companyCode: params.loginInfo.companyCode - }) - .pipe( - map((res: Login2Response) => { - if ('success' !== res.status.toLowerCase()) { - return webLoginFailure({ error: 'Failed' }); - } else { - return webLoginSuccess({ - loginInfo: params.loginInfo, - rememberMe: params.rememberMe, - login2Response: res - }); - } - }), - catchError(error => of(webLoginFailure({ error }))) - ) - ) - ) + // webLogin$ = createEffect(() => + // this.actions$.pipe( + // ofType(webLogin), + // map(action => action), + // exhaustMap((params: { loginInfo: LoginInfo; rememberMe: boolean }) => + // this.piService + // .login2({ + // loginId: params.loginInfo.loginId, + // loginPw: params.loginInfo.loginPw, + // companyCode: params.loginInfo.companyCode + // }) + // .pipe( + // map((res: Login2Response) => { + // if ('success' !== res.status.toLowerCase()) { + // return webLoginFailure({ error: 'Failed' }); + // } else { + // return webLoginSuccess({ + // loginInfo: params.loginInfo, + // rememberMe: params.rememberMe, + // login2Response: res + // }); + // } + // }), + // catchError(error => of(webLoginFailure({ error }))) + // ) + // ) + // ) + // ); + webLogin$ = createEffect( + () => + this.actions$.pipe( + ofType(webLogin), + map(action => action), + switchMap( + (loginParams: { loginInfo: LoginInfo; rememberMe: boolean }) => { + const environmentsInfo = this.sessionStorageService.get< + EnvironmentsInfo + >(KEY_ENVIRONMENTS_INFO); + + let login2Res: Login2Response; + let loginRes: LoginResponse; + let versionInfo2Res: VersionInfo2Response; + let encLoginPw: string; + + return this.piService + .login2({ + loginId: loginParams.loginInfo.loginId, + loginPw: loginParams.loginInfo.loginPw, + companyCode: loginParams.loginInfo.companyCode + }) + .pipe( + concatMap(res => { + console.log('tap'); + if ('success' !== res.status.toLowerCase()) { + return throwError('login2 failed'); + } + login2Res = res; + return of(true); + }), + mergeMap(dd => { + console.log('checkForUpdates'); + return this.nativeService.checkForUpdates(); + }), + concatMap(update => { + if (update) { + return throwError('update process'); + } + encLoginPw = CryptoJS.enc.Hex.stringify( + CryptoJS.SHA256(loginParams.loginInfo.loginPw) + ); + return of(true); + }), + mergeMap(() => + this.publicApiService.versionInfo2({ + deviceType: environmentsInfo.deviceType, + companyGroupType: loginParams.loginInfo.companyGroupType, + companyCode: loginParams.loginInfo.companyCode, + loginId: loginParams.loginInfo.loginId + }) + ), + map(res => { + this.store.dispatch(VersionInfoStore.fetchSuccess(res)); + versionInfo2Res = res; + return of(true); + }), + mergeMap(() => + this.protocolService.connect(versionInfo2Res.serverIp) + ), + mergeMap(() => this.innerProtocolService.conn({})), + mergeMap(() => + this.authenticationProtocolService.login({ + loginId: loginParams.loginInfo.loginId, + loginPw: encLoginPw, + deviceType: environmentsInfo.deviceType, + deviceId: ' ', + token: '', + localeCode: loginParams.loginInfo.localeCode, + pushId: ' ', + companyCode: loginParams.loginInfo.companyCode, + passwordEncodingType: 1, + clientVersion: '', + reconnect: false, + ip: 'localhost', + hostName: '', + ssoMode: SSOMode.AUTH, + userSpecificInformation: 'PRO_000482', + productId: 'PRO_000482', + productName: 'EZMessenger' + }) + ), + exhaustMap(async res => { + if (res.privateInformationAgree) { + return of(null); + } + + loginRes = res; + + const privacyTotalUrl = this.piService.privacyTotalUrl({ + companyCode: res.companyCode, + userSeq: res.userSeq, + token: res.tokenString, + deviceType: environmentsInfo.deviceType, + localeCode: loginParams.loginInfo.localeCode, + textOnly: 'true' + }); + + const result = await this.dialogService.open< + ConfirmDialogComponent, + ConfirmDialogData, + ConfirmDialogResult + >(ConfirmDialogComponent, { + width: '100%', + height: '500px', + disableClose: true, + data: { + title: '개인정보 동의', + html: `