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 { InfoData, Info, InfoResponse, EventProtocolService, SSVC_TYPE_EVENT_INFO_DATA, SSVC_TYPE_EVENT_INFO_RES, SendResponse } from '@ucap-webmessenger/protocol-event'; import * as ChatStore from '@app/store/messenger/chat'; import { info, infoSuccess, infoFailure, send, sendSuccess, sendFailure, appendInfoList, newInfo } from './actions'; import { SessionStorageService } from '@ucap-webmessenger/web-storage'; import { RoomInfo } from '@ucap-webmessenger/protocol-room'; @Injectable() export class Effects { selectedRoomForInfo$ = createEffect(() => this.actions$.pipe( ofType(ChatStore.selectedRoom), map(action => { return info({ roomSeq: action.roomSeq, baseSeq: 0, requestCount: 50 }); }) ) ); info$ = createEffect( () => { let infoList: Info[]; return this.actions$.pipe( ofType(info), tap(() => { infoList = []; }), switchMap(req => { return this.eventProtocolService.info(req).pipe( map(res => { switch (res.SSVC_TYPE) { case SSVC_TYPE_EVENT_INFO_DATA: infoList.push(...(res as InfoData).infoList); break; case SSVC_TYPE_EVENT_INFO_RES: this.store.dispatch( infoSuccess({ infoList, res: res as InfoResponse }) ); break; } }), catchError(error => of(infoFailure({ error }))) ); }) ); }, { dispatch: false } ); send$ = createEffect(() => this.actions$.pipe( ofType(send), exhaustMap(action => this.eventProtocolService.send(action.req).pipe( map((res: SendResponse) => { return sendSuccess({ senderSeq: action.senderSeq, res }); }), catchError(error => of(sendFailure({ error }))) ) ) ) ); sendSuccess$ = createEffect( () => { return this.actions$.pipe( ofType(sendSuccess), tap(action => { const res = action.res; const appendInfo: Info = { seq: res.seq, type: res.eventType, senderSeq: action.senderSeq, sendDate: res.sendDate, sentMessage: res.message, receiverCount: res.receiverCount }; this.store.dispatch( newInfo({ roomSeq: res.roomSeq, info: appendInfo }) ); }) ); }, { dispatch: false } ); newInfo$ = createEffect( () => { return this.actions$.pipe( ofType(newInfo), withLatestFrom( this.store.pipe( select((state: any) => state.messenger.room.roomInfo as RoomInfo) ) ), tap(([action, roomInfo]) => { if (!!roomInfo && roomInfo.roomSeq === action.roomSeq) { this.store.dispatch(appendInfoList({ info: action.info })); } this.store.dispatch(ChatStore.newEventMessage(action)); }) ); }, { dispatch: false } ); constructor( private actions$: Actions, private store: Store, private eventProtocolService: EventProtocolService, private sessionStorageService: SessionStorageService, private logger: NGXLogger ) {} }