import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; import { Store, select } from '@ngrx/store'; import { NGXLogger } from 'ngx-logger'; import { of } from 'rxjs'; import { tap, switchMap, map, catchError, exhaustMap, withLatestFrom } from 'rxjs/operators'; import { RoomInfo, UserInfoShort, UserInfo, RoomProtocolService, SSVC_TYPE_ROOM_INFO_ROOM, InfoData, SSVC_TYPE_ROOM_INFO_USER, SSVC_TYPE_ROOM_INFO_USER2, SSVC_TYPE_ROOM_INFO_RES, UserShortData, UserData, UpdateResponse, OpenResponse, ExitResponse, Open3Response, RoomType, InviteResponse, UpdateTimerSetResponse } from '@ucap-webmessenger/protocol-room'; import * as ChatStore from '@app/store/messenger/chat'; import { info, infoSuccess, infoFailure, inviteNotification, exitNotification, exitForcingNotification, updateFontNotification, updateOnlyAlarm, update, updateSuccess, updateFailure, open, openSuccess, openFailure, exit, exitSuccess, exitFailure, openTimer, openTimerSuccess, openTimerFailure, inviteOrOpen, inviteSuccess, inviteFailure, updateTimeRoomInterval, updateTimeRoomIntervalSuccess, updateTimeRoomIntervalFailure } from './actions'; import { SessionStorageService } from '@ucap-webmessenger/web-storage'; import { LoginInfo, KEY_LOGIN_INFO } from '@app/types'; @Injectable() export class Effects { selectedRoomForInfo$ = createEffect(() => this.actions$.pipe( ofType(ChatStore.selectedRoom), map(action => { const loginInfo = this.sessionStorageService.get( KEY_LOGIN_INFO ); return info({ roomSeq: action.roomSeq, isDetail: true, localeCode: loginInfo.localeCode }); }) ) ); info$ = createEffect( () => { let roomInfo: RoomInfo; let userInfoShortList: UserInfoShort[]; let userInfoList: UserInfo[]; return this.actions$.pipe( ofType(info), tap(() => { roomInfo = null; userInfoShortList = []; userInfoList = []; }), switchMap(req => { return this.roomProtocolService.info(req).pipe( map(res => { switch (res.SSVC_TYPE) { case SSVC_TYPE_ROOM_INFO_ROOM: roomInfo = (res as InfoData).roomInfo; break; case SSVC_TYPE_ROOM_INFO_USER: userInfoShortList.push(...(res as UserShortData).userInfos); break; case SSVC_TYPE_ROOM_INFO_USER2: userInfoList.push(...(res as UserData).userInfos); break; case SSVC_TYPE_ROOM_INFO_RES: this.store.dispatch( infoSuccess({ roomInfo, userInfoShortList, userInfoList }) ); break; } }), catchError(error => of(infoFailure({ error }))) ); }) ); }, { dispatch: false } ); update$ = createEffect(() => this.actions$.pipe( ofType(update), map(action => action.req), exhaustMap(req => { return this.roomProtocolService.update(req).pipe( map((res: UpdateResponse) => { return updateSuccess({ res }); }), catchError(error => of(updateFailure({ error }))) ); }) ) ); updateOnlyAlarm$ = createEffect(() => this.actions$.pipe( ofType(updateOnlyAlarm), map(action => action.roomInfo), map(roomInfo => update({ req: { roomSeq: roomInfo.roomSeq, roomName: roomInfo.roomName.trim().length === 0 ? ' ' : roomInfo.roomName.trim(), receiveAlarm: !roomInfo.receiveAlarm, syncAll: false } }) ) ) ); updateTimeRoomInterval$ = createEffect(() => this.actions$.pipe( ofType(updateTimeRoomInterval), exhaustMap(action => { return this.roomProtocolService.updateTimerSet(action).pipe( map((res: UpdateTimerSetResponse) => { return updateTimeRoomIntervalSuccess({ res }); }), catchError(error => of(updateTimeRoomIntervalFailure({ error }))) ); }) ) ); open$ = createEffect(() => this.actions$.pipe( ofType(open), map(action => action.req), exhaustMap(req => { return this.roomProtocolService.open(req).pipe( map((res: OpenResponse) => { return openSuccess({ res }); }), catchError(error => of(openFailure({ error }))) ); }) ) ); openSuccess$ = createEffect(() => this.actions$.pipe( ofType(openSuccess), map(action => { return ChatStore.selectedRoom({ roomSeq: action.res.roomSeq }); }) ) ); openTimer$ = createEffect(() => this.actions$.pipe( ofType(openTimer), map(action => action.req), exhaustMap(req => { return this.roomProtocolService.open3(req).pipe( map((res: Open3Response) => { return openTimerSuccess({ res }); }), catchError(error => of(openTimerFailure({ error }))) ); }) ) ); openTimerSuccess$ = createEffect(() => this.actions$.pipe( ofType(openTimerSuccess), map(action => { return ChatStore.selectedRoom({ roomSeq: action.res.roomSeq }); }) ) ); inviteOrOpen$ = createEffect(() => this.actions$.pipe( ofType(inviteOrOpen), withLatestFrom( this.store.pipe( select((state: any) => state.messenger.room.roomInfo as RoomInfo) ) ), exhaustMap(([action, roomInfo]) => { if (roomInfo.roomType === RoomType.Single) { // Re Open return this.roomProtocolService.open(action.req).pipe( map((res: OpenResponse) => { return openSuccess({ res }); }), catchError(error => of(openFailure({ error }))) ); } else if (roomInfo.roomType === RoomType.Multi) { // Invite return this.roomProtocolService .invite({ roomSeq: roomInfo.roomSeq, inviteUserSeqs: action.req.userSeqs }) .pipe( map((res: InviteResponse) => { return inviteSuccess(res); }), catchError(error => of(inviteFailure({ error }))) ); } else { return of(inviteFailure({ error: 'room type is error!!' })); } }) ) ); inviteSuccess$ = createEffect(() => this.actions$.pipe( ofType(inviteSuccess), map(action => { return ChatStore.selectedRoom({ roomSeq: action.roomSeq }); // const loginInfo = this.sessionStorageService.get( // KEY_LOGIN_INFO // ); // return info({ // roomSeq: action.roomSeq, // isDetail: true, // localeCode: loginInfo.localeCode // }); }) ) ); exit$ = createEffect(() => this.actions$.pipe( ofType(exit), withLatestFrom( this.store.pipe( select((state: any) => state.messenger.room.roomInfo as RoomInfo) ) ), exhaustMap(([req, roomInfo]) => { return this.roomProtocolService.exit(req).pipe( map((res: ExitResponse) => { if (!!roomInfo && roomInfo.roomSeq === res.roomSeq) { this.store.dispatch(ChatStore.clearSelectedRoom()); } return exitSuccess({ res }); }), catchError(error => of(exitFailure({ error }))) ); }) ) ); inviteNotification$ = createEffect( () => { return this.actions$.pipe( ofType(inviteNotification), map(action => action.noti), tap(noti => {}) ); }, { dispatch: false } ); exitNotification$ = createEffect( () => { return this.actions$.pipe( ofType(exitNotification), map(action => action.noti), tap(noti => {}) ); }, { dispatch: false } ); exitForcingNotification$ = createEffect( () => { return this.actions$.pipe( ofType(exitForcingNotification), map(action => action.noti), tap(noti => {}) ); }, { dispatch: false } ); updateFontNotification$ = createEffect( () => { return this.actions$.pipe( ofType(updateFontNotification), map(action => action.noti), tap(noti => {}) ); }, { dispatch: false } ); constructor( private actions$: Actions, private store: Store, private roomProtocolService: RoomProtocolService, private sessionStorageService: SessionStorageService, private logger: NGXLogger ) {} }