import { combineEpics, ActionsObservable } from 'redux-observable' import { Store } from 'redux' import { includes } from 'lodash' import { Observable, Observer } from 'rxjs' import * as ConversationsActions from '../conversations/actions' import * as EndUserActions from './actions' import * as UserSelectors from '../auth/selectors' import * as SocketConstants from '../socket/constants' import { endUserIds } from '../conversations/selectors' import * as api from './api' import { IEndUser } from './interfaces' export const fetchEndUsersFromConversations = (action$: ActionsObservable, { getState }: Store) => { return action$.ofType(ConversationsActions.fetchConversationsFromInboxSuccess.toString()) .map(() => ({ accessToken: UserSelectors.accessToken(getState()) })) .mergeMap((options) => { const listOfEndUserIdsFromConversations = endUserIds(getState()) as number[] return api.fetchEndUsersById({ ...options, endUserIds: listOfEndUserIdsFromConversations }) .map((endUsers: IEndUser[]) => EndUserActions.fetchEndUsersSuccess(endUsers)) .startWith(EndUserActions.fetchEndUsersPending() as any) .catch(() => Observable.of(EndUserActions.fetchEndUsersFailed())) }) } export const joinOrgChannelPendingEpic = (action$: ActionsObservable, { getState }: Store) => { return action$ .ofType(SocketConstants.JOIN_CHANNEL_PENDING) .pluck('payload') .filter((payload: any) => payload.clusterName === SocketConstants.SocketCluster.MESSAGES) .filter((payload: any) => payload.channelName === SocketConstants.SocketChannel.ORG_PRIVATE) .switchMap(({ channel }) => { return Observable.create((observer: Observer) => { channel.on('end-user-updated', (payload: IEndUser) => { const existingEndUsersIds = endUserIds(getState()) if (includes(existingEndUsersIds, payload.id)) { observer.next(EndUserActions.updateEndUser(payload)) } }) }) }) } export const epic = combineEpics( fetchEndUsersFromConversations, joinOrgChannelPendingEpic, )