2019-10-08 04:18:05 +00:00
|
|
|
import { Injectable } from '@angular/core';
|
|
|
|
|
|
|
|
import { Actions, createEffect, ofType } from '@ngrx/effects';
|
|
|
|
|
2019-10-10 04:35:32 +00:00
|
|
|
import { Store, select } from '@ngrx/store';
|
2019-10-08 04:18:05 +00:00
|
|
|
|
|
|
|
import { NGXLogger } from 'ngx-logger';
|
|
|
|
|
|
|
|
import { of } from 'rxjs';
|
2019-10-10 04:35:32 +00:00
|
|
|
import {
|
|
|
|
tap,
|
|
|
|
switchMap,
|
|
|
|
map,
|
|
|
|
catchError,
|
|
|
|
exhaustMap,
|
|
|
|
withLatestFrom
|
|
|
|
} from 'rxjs/operators';
|
2019-10-08 04:18:05 +00:00
|
|
|
import {
|
|
|
|
InfoData,
|
|
|
|
Info,
|
|
|
|
InfoResponse,
|
|
|
|
EventProtocolService,
|
|
|
|
SSVC_TYPE_EVENT_INFO_DATA,
|
2019-10-08 05:34:37 +00:00
|
|
|
SSVC_TYPE_EVENT_INFO_RES,
|
2019-10-16 05:52:31 +00:00
|
|
|
SendResponse,
|
|
|
|
ReadResponse
|
2019-10-08 04:18:05 +00:00
|
|
|
} from '@ucap-webmessenger/protocol-event';
|
|
|
|
|
|
|
|
import * as ChatStore from '@app/store/messenger/chat';
|
2019-10-16 01:21:26 +00:00
|
|
|
import * as SyncStore from '@app/store/messenger/sync';
|
2019-10-08 04:18:05 +00:00
|
|
|
|
2019-10-08 05:34:37 +00:00
|
|
|
import {
|
|
|
|
info,
|
|
|
|
infoSuccess,
|
|
|
|
infoFailure,
|
|
|
|
send,
|
|
|
|
sendSuccess,
|
2019-10-08 05:59:22 +00:00
|
|
|
sendFailure,
|
2019-10-10 04:35:32 +00:00
|
|
|
appendInfoList,
|
2019-10-11 05:01:43 +00:00
|
|
|
newInfo,
|
|
|
|
sendNotification,
|
|
|
|
readNotification,
|
|
|
|
cancelNotification,
|
2019-10-15 10:09:26 +00:00
|
|
|
delNotification,
|
2019-10-16 05:52:31 +00:00
|
|
|
recallInfoList,
|
|
|
|
read,
|
|
|
|
readFailure
|
2019-10-08 05:34:37 +00:00
|
|
|
} from './actions';
|
2019-10-08 04:18:05 +00:00
|
|
|
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
|
2019-10-10 04:35:32 +00:00
|
|
|
import { RoomInfo } from '@ucap-webmessenger/protocol-room';
|
2019-10-16 01:21:26 +00:00
|
|
|
import { refreshRoom } from '../sync';
|
|
|
|
import { LoginInfo, KEY_LOGIN_INFO } from '@app/types';
|
2019-10-16 05:52:31 +00:00
|
|
|
import { Dictionary } from '@ngrx/entity';
|
2019-10-08 04:18:05 +00:00
|
|
|
|
|
|
|
@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 => {
|
2019-10-10 03:14:01 +00:00
|
|
|
switch (res.SSVC_TYPE) {
|
2019-10-08 04:18:05 +00:00
|
|
|
case SSVC_TYPE_EVENT_INFO_DATA:
|
|
|
|
infoList.push(...(res as InfoData).infoList);
|
|
|
|
break;
|
|
|
|
case SSVC_TYPE_EVENT_INFO_RES:
|
2019-10-16 05:52:31 +00:00
|
|
|
{
|
|
|
|
this.store.dispatch(
|
|
|
|
infoSuccess({
|
|
|
|
infoList,
|
|
|
|
res: res as InfoResponse
|
|
|
|
})
|
|
|
|
);
|
|
|
|
|
|
|
|
if (req.baseSeq === 0) {
|
|
|
|
// 최초 이벤트 목록 조회시 SSVC_TYPE_EVENT_READ_REQ 수행.
|
|
|
|
const maxSeq = Math.max.apply(
|
|
|
|
Math,
|
|
|
|
infoList.map(v => v.seq)
|
|
|
|
);
|
|
|
|
this.store.dispatch(
|
|
|
|
read({
|
|
|
|
roomSeq: req.roomSeq,
|
|
|
|
lastReadSeq: Number(maxSeq)
|
|
|
|
})
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2019-10-08 04:18:05 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
catchError(error => of(infoFailure({ error })))
|
|
|
|
);
|
|
|
|
})
|
|
|
|
);
|
|
|
|
},
|
|
|
|
{ dispatch: false }
|
|
|
|
);
|
|
|
|
|
2019-10-16 05:52:31 +00:00
|
|
|
read$ = createEffect(
|
|
|
|
() => {
|
|
|
|
return this.actions$.pipe(
|
|
|
|
ofType(read),
|
|
|
|
switchMap(req => {
|
|
|
|
return this.eventProtocolService.read(req).pipe(
|
|
|
|
map((res: ReadResponse) => {
|
|
|
|
this.store.dispatch(
|
|
|
|
SyncStore.updateUnreadCount({
|
|
|
|
roomSeq: res.roomSeq,
|
|
|
|
noReadCnt: 0
|
|
|
|
})
|
|
|
|
);
|
|
|
|
}),
|
|
|
|
catchError(error => of(readFailure({ error })))
|
|
|
|
);
|
|
|
|
})
|
|
|
|
);
|
|
|
|
},
|
|
|
|
{ dispatch: false }
|
|
|
|
);
|
|
|
|
|
2019-10-08 05:34:37 +00:00
|
|
|
send$ = createEffect(() =>
|
|
|
|
this.actions$.pipe(
|
|
|
|
ofType(send),
|
2019-10-08 05:59:22 +00:00
|
|
|
exhaustMap(action =>
|
|
|
|
this.eventProtocolService.send(action.req).pipe(
|
2019-10-08 05:34:37 +00:00
|
|
|
map((res: SendResponse) => {
|
|
|
|
return sendSuccess({
|
2019-10-08 05:59:22 +00:00
|
|
|
senderSeq: action.senderSeq,
|
2019-10-08 05:34:37 +00:00
|
|
|
res
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
catchError(error => of(sendFailure({ error })))
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2019-10-08 05:59:22 +00:00
|
|
|
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
|
|
|
|
};
|
|
|
|
|
2019-10-10 04:35:32 +00:00
|
|
|
this.store.dispatch(
|
|
|
|
newInfo({ roomSeq: res.roomSeq, info: appendInfo })
|
|
|
|
);
|
|
|
|
})
|
|
|
|
);
|
|
|
|
},
|
|
|
|
{ dispatch: false }
|
|
|
|
);
|
|
|
|
|
2019-10-11 05:01:43 +00:00
|
|
|
sendNotification$ = createEffect(
|
|
|
|
() => {
|
|
|
|
return this.actions$.pipe(
|
|
|
|
ofType(sendNotification),
|
|
|
|
map(action => action.noti),
|
|
|
|
tap(noti => {
|
|
|
|
const appendInfo: Info = {
|
|
|
|
seq: noti.seq,
|
|
|
|
type: noti.eventType,
|
|
|
|
senderSeq: noti.SENDER_SEQ,
|
|
|
|
sendDate: noti.sendDate,
|
|
|
|
sentMessage: noti.message,
|
|
|
|
receiverCount: noti.receiverCount
|
|
|
|
};
|
|
|
|
|
|
|
|
this.store.dispatch(
|
|
|
|
newInfo({ roomSeq: noti.roomSeq, info: appendInfo })
|
|
|
|
);
|
|
|
|
})
|
|
|
|
);
|
|
|
|
},
|
|
|
|
{ dispatch: false }
|
|
|
|
);
|
|
|
|
|
2019-10-10 04:35:32 +00:00
|
|
|
newInfo$ = createEffect(
|
|
|
|
() => {
|
|
|
|
return this.actions$.pipe(
|
|
|
|
ofType(newInfo),
|
|
|
|
withLatestFrom(
|
|
|
|
this.store.pipe(
|
|
|
|
select((state: any) => state.messenger.room.roomInfo as RoomInfo)
|
2019-10-16 05:52:31 +00:00
|
|
|
),
|
|
|
|
this.store.pipe(
|
|
|
|
select(
|
|
|
|
(state: any) =>
|
|
|
|
state.messenger.sync.room.entities as Dictionary<RoomInfo>
|
|
|
|
)
|
2019-10-10 04:35:32 +00:00
|
|
|
)
|
|
|
|
),
|
2019-10-16 05:52:31 +00:00
|
|
|
tap(([action, roomInfo, trgtRoomInfos]) => {
|
|
|
|
// opened room :: event add
|
2019-10-11 04:17:52 +00:00
|
|
|
if (!!roomInfo && roomInfo.roomSeq === action.roomSeq) {
|
2019-10-10 04:35:32 +00:00
|
|
|
this.store.dispatch(appendInfoList({ info: action.info }));
|
|
|
|
}
|
2019-10-10 05:50:58 +00:00
|
|
|
|
2019-10-16 05:52:31 +00:00
|
|
|
// not opened room :: unread count increased
|
|
|
|
if (!roomInfo || roomInfo.roomSeq !== action.roomSeq) {
|
2019-10-18 04:34:24 +00:00
|
|
|
if (!!trgtRoomInfos && !!trgtRoomInfos[action.roomSeq]) {
|
|
|
|
const noReadCnt = trgtRoomInfos[action.roomSeq].noReadCnt;
|
|
|
|
this.store.dispatch(
|
|
|
|
SyncStore.updateUnreadCount({
|
|
|
|
roomSeq: action.roomSeq,
|
|
|
|
noReadCnt: noReadCnt + 1
|
|
|
|
})
|
|
|
|
);
|
|
|
|
}
|
2019-10-16 05:52:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 대화 > 리스트 :: finalEventMessage refresh
|
2019-10-10 05:50:58 +00:00
|
|
|
this.store.dispatch(ChatStore.newEventMessage(action));
|
2019-10-08 05:59:22 +00:00
|
|
|
})
|
|
|
|
);
|
|
|
|
},
|
|
|
|
{ dispatch: false }
|
|
|
|
);
|
|
|
|
|
2019-10-11 05:01:43 +00:00
|
|
|
readNotification$ = createEffect(
|
|
|
|
() => {
|
|
|
|
return this.actions$.pipe(
|
|
|
|
ofType(readNotification),
|
|
|
|
map(action => action.noti),
|
|
|
|
tap(noti => {})
|
|
|
|
);
|
|
|
|
},
|
|
|
|
{ dispatch: false }
|
|
|
|
);
|
|
|
|
|
|
|
|
cancelNotification$ = createEffect(
|
|
|
|
() => {
|
|
|
|
return this.actions$.pipe(
|
|
|
|
ofType(cancelNotification),
|
2019-10-15 10:09:26 +00:00
|
|
|
withLatestFrom(
|
|
|
|
this.store.pipe(
|
|
|
|
select((state: any) => state.messenger.room.roomInfo as RoomInfo)
|
|
|
|
)
|
|
|
|
),
|
|
|
|
tap(([action, roomInfo]) => {
|
2019-10-16 01:21:26 +00:00
|
|
|
// 현재 방이 오픈되어 있으면 방내용 갱신
|
2019-10-15 10:09:26 +00:00
|
|
|
if (!!roomInfo && roomInfo.roomSeq === action.noti.roomSeq) {
|
|
|
|
this.logger.debug('cancelNotification$', action, roomInfo);
|
|
|
|
this.store.dispatch(
|
|
|
|
recallInfoList({ eventSeq: action.noti.eventSeq })
|
|
|
|
);
|
|
|
|
}
|
2019-10-16 01:21:26 +00:00
|
|
|
// 대화 > 리스트의 항목 갱신
|
|
|
|
const loginInfo = this.sessionStorageService.get<LoginInfo>(
|
|
|
|
KEY_LOGIN_INFO
|
|
|
|
);
|
|
|
|
this.store.dispatch(
|
|
|
|
SyncStore.refreshRoom({
|
|
|
|
roomSeq: action.noti.roomSeq,
|
|
|
|
isDetail: true,
|
|
|
|
localeCode: loginInfo.localeCode
|
|
|
|
})
|
|
|
|
);
|
2019-10-15 10:09:26 +00:00
|
|
|
})
|
2019-10-11 05:01:43 +00:00
|
|
|
);
|
|
|
|
},
|
|
|
|
{ dispatch: false }
|
|
|
|
);
|
|
|
|
|
|
|
|
delNotification$ = createEffect(
|
|
|
|
() => {
|
|
|
|
return this.actions$.pipe(
|
|
|
|
ofType(delNotification),
|
|
|
|
map(action => action.noti),
|
|
|
|
tap(noti => {})
|
|
|
|
);
|
|
|
|
},
|
|
|
|
{ dispatch: false }
|
|
|
|
);
|
|
|
|
|
2019-10-08 04:18:05 +00:00
|
|
|
constructor(
|
|
|
|
private actions$: Actions,
|
|
|
|
private store: Store<any>,
|
|
|
|
private eventProtocolService: EventProtocolService,
|
|
|
|
private sessionStorageService: SessionStorageService,
|
|
|
|
private logger: NGXLogger
|
|
|
|
) {}
|
|
|
|
}
|