Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
import { all, select, put, call, takeEvery, take } from 'redux-saga/effects';
import { ActionTypes as UserActionTypes, loadUser } from '@doodle/users-api-connector';
import { ActionTypes as IntercomActionTypes, boot, update } from '../actions/intercomActions';

/**
 * This saga waits until we have a valid user or we have attempted to load a user:
 * - if it's already loading -> wait on the outcome
 * - if not loading and no valid user -> attempt to load user & wait on outcome
 * - if user already loaded -> don't wait
 *
 * @param {*} options
 * @param {String} options.userDomain
 */
function* waitForUser(options) {
  const { error, loading, data } = yield select(state => state[options.userDomain || 'user']);

  if (!loading && !data.accessToken && !error) {
    yield put(loadUser());
    yield take([UserActionTypes.USER_LOAD_FAILED, UserActionTypes.USER_LOADED]);
  } else if (loading) {
    yield take([UserActionTypes.USER_LOAD_FAILED, UserActionTypes.USER_LOADED]);
  }
}

function* selectUserData(options) {
  const { data } = yield select(state => state[options.userDomain || 'user']);
  const { name, language, id: user_id, email, avatarLargeUrl: image_url, intercom: user_hash } = data;

  const userData = user_id // eslint-disable-line camelcase
    ? {
        user_id,
        user_hash,
        email,
        name,
        language,
        avatar: {
          type: 'avatar',
          image_url,
        },
      }
    : {};
  return userData;
}

function* onBoot(options) {
  const { intercomAppId: app_id } = options;
  const userData = yield call(selectUserData, options);

  window.Intercom('boot', {
    app_id,
    ...userData,
  });
}

function* onLogin(options) {
  const userData = yield call(selectUserData, options);

  yield put(update(userData));
}

function* onLogout() {
  window.Intercom('shutdown');
  yield put(boot());
}

function* onTrackEvent(options, { payload }) {
  const { event, metadata } = payload;
  const { booted } = yield select(state => state[options.intercomDomain || 'intercom']);

  if (!booted) {
    yield take(IntercomActionTypes.BOOT);
  }

  window.Intercom('trackEvent', event, {
    ...metadata,
  });
}

function onUpdate(options, { payload }) {
  window.Intercom('update', {
    ...payload,
  });
}

export default function* loadIntercomSaga(options = {}) {
  yield takeEvery(IntercomActionTypes.TRACK_EVENT, onTrackEvent, options);
  yield call(waitForUser, options);

  return yield all([
    takeEvery(IntercomActionTypes.BOOT, onBoot, options),
    takeEvery(IntercomActionTypes.UPDATE, onUpdate, options),
    put(boot()),

    takeEvery(UserActionTypes.USER_LOADED, onLogin, options),
    takeEvery(UserActionTypes.LOGOUT, onLogout, options),
  ]);
}