import { Injectable } from '@angular/core'; import { Actions, ofType, createEffect } from '@ngrx/effects'; import { of } from 'rxjs'; import { catchError, exhaustMap, map, withLatestFrom, switchMap, tap } from 'rxjs/operators'; import { Store, select } from '@ngrx/store'; import { NGXLogger } from 'ngx-logger'; import { buddy2, buddy2Success, buddy2Failure, group2, group2Success, group2Failure, room, roomFailure, roomSuccess, updateRoomForNewEventMessage } from './actions'; import { SessionStorageService } from '@ucap-webmessenger/web-storage'; import { SyncProtocolService, SSVC_TYPE_SYNC_BUDDY2_DATA, BuddyResponse, BuddyDetailData, SSVC_TYPE_SYNC_GROUP_DATA2, GroupDetailData, GroupResponse, UserInfo, SSVC_TYPE_SYNC_BUDDY2_RES, SSVC_TYPE_SYNC_GROUP_RES2, SSVC_TYPE_SYNC_ROOM_DATA, SSVC_TYPE_SYNC_ROOM_USER, SSVC_TYPE_SYNC_ROOM_USER2, SSVC_TYPE_SYNC_ROOM_RES, RoomData, RoomUserData, RoomUserDetailData, RoomResponse } from '@ucap-webmessenger/protocol-sync'; import { regViewSuccess } from '@app/store/messenger/option'; import { RoomInfo, UserInfoShort, UserInfo as RoomUserInfo } from '@ucap-webmessenger/protocol-room'; import { LoginInfo, KEY_LOGIN_INFO } from '@app/types'; import * as ChatStore from '@app/store/messenger/chat'; @Injectable() export class Effects { buddy2$ = createEffect( () => { let buddyList: UserInfo[]; return this.actions$.pipe( ofType(buddy2), tap(() => { buddyList = []; }), switchMap(req => { return this.syncProtocolService.buddy2(req).pipe( map(res => { switch (res.SSVC_TYPE) { case SSVC_TYPE_SYNC_BUDDY2_DATA: buddyList.push(...(res as BuddyDetailData).buddyInfos); break; case SSVC_TYPE_SYNC_BUDDY2_RES: this.store.dispatch( buddy2Success({ buddyList, syncDate: (res as BuddyResponse).syncDate }) ); break; } }), catchError(error => of(buddy2Failure({ error }))) ); }) ); }, { dispatch: false } ); group2$ = createEffect( () => { let groupList: GroupDetailData[]; return this.actions$.pipe( ofType(group2), tap(() => { groupList = []; }), switchMap(req => { return this.syncProtocolService.group2(req).pipe( map(res => { switch (res.SSVC_TYPE) { case SSVC_TYPE_SYNC_GROUP_DATA2: groupList.push(res as GroupDetailData); break; case SSVC_TYPE_SYNC_GROUP_RES2: this.store.dispatch( group2Success({ groupList, syncDate: (res as GroupResponse).syncDate }) ); break; } }), catchError(error => of(group2Failure({ error }))) ); }) ); }, { dispatch: false } ); room$ = createEffect( () => { let roomList: RoomInfo[]; let roomUserInfoMap: { [param: string]: { userInfoShortList: UserInfoShort[]; userInfoList: RoomUserInfo[]; }; }; return this.actions$.pipe( ofType(room), tap(() => { roomList = []; roomUserInfoMap = {}; }), switchMap(req => { return this.syncProtocolService.room(req).pipe( map(res => { switch (res.SSVC_TYPE) { case SSVC_TYPE_SYNC_ROOM_DATA: roomList.push( ...(res as RoomData).roomInfos.filter(v => v.isJoinRoom) ); break; case SSVC_TYPE_SYNC_ROOM_USER: { const roomUserData = res as RoomUserData; if (!roomUserInfoMap[roomUserData.roomSeq]) { roomUserInfoMap[roomUserData.roomSeq] = { userInfoList: [], userInfoShortList: [] }; } roomUserInfoMap[ roomUserData.roomSeq ].userInfoShortList.push(...roomUserData.userInfos); } break; case SSVC_TYPE_SYNC_ROOM_USER2: { const roomUserDetailData = res as RoomUserDetailData; if (!roomUserInfoMap[roomUserDetailData.roomSeq]) { roomUserInfoMap[roomUserDetailData.roomSeq] = { userInfoList: [], userInfoShortList: [] }; } roomUserInfoMap[ roomUserDetailData.roomSeq ].userInfoList.push(...roomUserDetailData.userInfos); } break; case SSVC_TYPE_SYNC_ROOM_RES: { this.store.dispatch( roomSuccess({ roomList, roomUserInfoMap, syncDate: (res as RoomResponse).syncDate }) ); } break; } }), catchError(error => of(roomFailure({ error }))) ); }) ); }, { dispatch: false } ); newEventMessageForRoomInfoList$ = createEffect( () => this.actions$.pipe( ofType(ChatStore.newEventMessage), withLatestFrom( this.store.pipe( select((state: any) => state.messenger.sync.room.ids as string[]) ), this.store.pipe( select((state: any) => state.messenger.sync.room.syncDate as string) ) ), tap(([action, roomSeqList, roomSyncDate]) => { const index = roomSeqList.findIndex( (roomSeq, i) => roomSeq === action.roomSeq ); if (-1 === index) { const loginInfo = this.sessionStorageService.get( KEY_LOGIN_INFO ); this.store.dispatch( room({ syncDate: roomSyncDate, localeCode: loginInfo.localeCode }) ); return; } this.store.dispatch(updateRoomForNewEventMessage(action)); }) ), { dispatch: false } ); constructor( private actions$: Actions, private store: Store, private syncProtocolService: SyncProtocolService, private sessionStorageService: SessionStorageService, private logger: NGXLogger ) {} }