2018-12-01 11:23:08 +00:00
|
|
|
/* global PAYPAL_SUPPORTERS */
|
2018-08-23 16:29:26 +01:00
|
|
|
import { createAction, handleActions } from 'redux-actions';
|
2018-09-30 11:37:19 +01:00
|
|
|
import { uniqBy } from 'lodash';
|
2019-08-30 19:15:26 +02:00
|
|
|
import store from 'store';
|
2018-08-23 16:29:26 +01:00
|
|
|
|
|
|
|
import { createTypes, createAsyncTypes } from '../utils/createTypes';
|
|
|
|
import { createFetchUserSaga } from './fetch-user-saga';
|
2018-08-25 00:24:19 +01:00
|
|
|
import { createAcceptTermsSaga } from './accept-terms-saga';
|
2018-08-30 15:27:53 +01:00
|
|
|
import { createAppMountSaga } from './app-mount-saga';
|
2018-09-07 13:32:38 +01:00
|
|
|
import { createReportUserSaga } from './report-user-saga';
|
2018-09-04 14:54:23 +01:00
|
|
|
import { createShowCertSaga } from './show-cert-saga';
|
2018-09-14 14:48:16 +01:00
|
|
|
import { createNightModeSaga } from './night-mode-saga';
|
2019-12-02 15:48:53 +03:00
|
|
|
import { createDonationSaga } from './donation-saga';
|
2020-02-04 08:43:56 +03:00
|
|
|
import { createGaSaga } from './ga-saga';
|
2018-08-23 16:29:26 +01:00
|
|
|
|
2018-09-30 11:37:19 +01:00
|
|
|
import hardGoToEpic from './hard-go-to-epic';
|
|
|
|
import failedUpdatesEpic from './failed-updates-epic';
|
|
|
|
import updateCompleteEpic from './update-complete-epic';
|
|
|
|
|
2018-09-13 18:28:23 +01:00
|
|
|
import { types as settingsTypes } from './settings';
|
2019-08-30 19:15:26 +02:00
|
|
|
import { types as challengeTypes } from '../templates/Challenges/redux/';
|
|
|
|
// eslint-disable-next-line max-len
|
|
|
|
import { CURRENT_CHALLENGE_KEY } from '../templates/Challenges/redux/current-challenge-saga';
|
2018-09-30 11:37:19 +01:00
|
|
|
|
2018-11-29 12:12:15 +00:00
|
|
|
export const ns = 'app';
|
2018-08-23 16:29:26 +01:00
|
|
|
|
2018-11-29 12:12:15 +00:00
|
|
|
export const defaultFetchState = {
|
2018-09-04 14:54:23 +01:00
|
|
|
pending: true,
|
|
|
|
complete: false,
|
|
|
|
errored: false,
|
|
|
|
error: null
|
|
|
|
};
|
|
|
|
|
2018-08-23 16:29:26 +01:00
|
|
|
const initialState = {
|
|
|
|
appUsername: '',
|
2019-12-09 17:30:24 +01:00
|
|
|
canRequestBlockDonation: false,
|
|
|
|
canRequestProgressDonation: true,
|
2018-09-30 11:37:19 +01:00
|
|
|
completionCount: 0,
|
2019-08-30 19:15:26 +02:00
|
|
|
currentChallengeId: store.get(CURRENT_CHALLENGE_KEY),
|
2018-09-04 14:54:23 +01:00
|
|
|
showCert: {},
|
|
|
|
showCertFetchState: {
|
|
|
|
...defaultFetchState
|
2018-08-23 16:29:26 +01:00
|
|
|
},
|
2018-09-04 14:54:23 +01:00
|
|
|
user: {},
|
|
|
|
userFetchState: {
|
|
|
|
...defaultFetchState
|
2018-09-30 11:37:19 +01:00
|
|
|
},
|
2018-11-07 18:15:27 +00:00
|
|
|
userProfileFetchState: {
|
|
|
|
...defaultFetchState
|
|
|
|
},
|
2019-05-08 23:48:10 +05:30
|
|
|
sessionMeta: { activeDonations: 0 },
|
2018-09-30 11:37:19 +01:00
|
|
|
showDonationModal: false,
|
2019-12-09 17:30:24 +01:00
|
|
|
isBlockDonationModal: false,
|
2018-09-30 11:37:19 +01:00
|
|
|
isOnline: true
|
2018-08-23 16:29:26 +01:00
|
|
|
};
|
|
|
|
|
2018-09-30 11:37:19 +01:00
|
|
|
export const types = createTypes(
|
2018-08-30 15:27:53 +01:00
|
|
|
[
|
|
|
|
'appMount',
|
2018-10-24 00:24:48 +01:00
|
|
|
'hardGoTo',
|
2019-12-09 17:30:24 +01:00
|
|
|
'allowBlockDonationRequests',
|
2019-12-02 15:48:53 +03:00
|
|
|
'closeDonationModal',
|
2019-12-09 17:30:24 +01:00
|
|
|
'preventBlockDonationRequests',
|
|
|
|
'preventProgressDonationRequests',
|
2018-09-30 11:37:19 +01:00
|
|
|
'openDonationModal',
|
|
|
|
'onlineStatusChange',
|
2019-02-26 22:24:08 +05:30
|
|
|
'resetUserData',
|
2019-12-02 15:48:53 +03:00
|
|
|
'tryToShowDonationModal',
|
2020-02-04 08:43:56 +03:00
|
|
|
'executeGA',
|
2019-01-03 01:03:43 +03:00
|
|
|
'submitComplete',
|
2018-09-30 11:37:19 +01:00
|
|
|
'updateComplete',
|
2019-08-30 19:15:26 +02:00
|
|
|
'updateCurrentChallengeId',
|
2018-09-30 11:37:19 +01:00
|
|
|
'updateFailed',
|
2018-08-30 15:27:53 +01:00
|
|
|
...createAsyncTypes('fetchUser'),
|
2018-11-07 18:15:27 +00:00
|
|
|
...createAsyncTypes('fetchProfileForUser'),
|
2018-08-30 15:27:53 +01:00
|
|
|
...createAsyncTypes('acceptTerms'),
|
2018-09-04 14:54:23 +01:00
|
|
|
...createAsyncTypes('showCert'),
|
2018-09-07 13:32:38 +01:00
|
|
|
...createAsyncTypes('reportUser')
|
2018-08-30 15:27:53 +01:00
|
|
|
],
|
2018-08-25 00:24:19 +01:00
|
|
|
ns
|
|
|
|
);
|
2018-08-23 16:29:26 +01:00
|
|
|
|
2018-11-07 18:15:27 +00:00
|
|
|
export const epics = [hardGoToEpic, failedUpdatesEpic, updateCompleteEpic];
|
2018-09-30 11:37:19 +01:00
|
|
|
|
2018-08-25 00:24:19 +01:00
|
|
|
export const sagas = [
|
2018-08-30 15:27:53 +01:00
|
|
|
...createAcceptTermsSaga(types),
|
|
|
|
...createAppMountSaga(types),
|
2019-12-02 15:48:53 +03:00
|
|
|
...createDonationSaga(types),
|
2020-02-04 08:43:56 +03:00
|
|
|
...createGaSaga(types),
|
2018-08-25 00:24:19 +01:00
|
|
|
...createFetchUserSaga(types),
|
2018-09-07 13:32:38 +01:00
|
|
|
...createShowCertSaga(types),
|
2018-09-14 14:48:16 +01:00
|
|
|
...createReportUserSaga(types),
|
|
|
|
...createNightModeSaga({ ...types, ...settingsTypes })
|
2018-08-25 00:24:19 +01:00
|
|
|
];
|
2018-08-23 16:29:26 +01:00
|
|
|
|
2018-08-30 15:27:53 +01:00
|
|
|
export const appMount = createAction(types.appMount);
|
2018-08-23 16:29:26 +01:00
|
|
|
|
2019-12-02 15:48:53 +03:00
|
|
|
export const tryToShowDonationModal = createAction(
|
|
|
|
types.tryToShowDonationModal
|
|
|
|
);
|
2020-02-04 08:43:56 +03:00
|
|
|
|
|
|
|
export const executeGA = createAction(types.executeGA);
|
|
|
|
|
2019-12-09 17:30:24 +01:00
|
|
|
export const allowBlockDonationRequests = createAction(
|
|
|
|
types.allowBlockDonationRequests
|
|
|
|
);
|
2018-09-30 11:37:19 +01:00
|
|
|
export const closeDonationModal = createAction(types.closeDonationModal);
|
|
|
|
export const openDonationModal = createAction(types.openDonationModal);
|
2019-12-09 17:30:24 +01:00
|
|
|
export const preventBlockDonationRequests = createAction(
|
|
|
|
types.preventBlockDonationRequests
|
|
|
|
);
|
|
|
|
export const preventProgressDonationRequests = createAction(
|
|
|
|
types.preventProgressDonationRequests
|
2019-12-02 15:48:53 +03:00
|
|
|
);
|
2018-09-30 11:37:19 +01:00
|
|
|
|
|
|
|
export const onlineStatusChange = createAction(types.onlineStatusChange);
|
|
|
|
|
2020-03-06 17:51:58 +01:00
|
|
|
// TODO: re-evaluate this since /internal is no longer used.
|
2018-10-24 00:24:48 +01:00
|
|
|
// `hardGoTo` is used to hit the API server directly
|
|
|
|
// without going through /internal
|
|
|
|
// used for things like /signin and /signout
|
|
|
|
export const hardGoTo = createAction(types.hardGoTo);
|
|
|
|
|
2019-01-03 01:03:43 +03:00
|
|
|
export const submitComplete = createAction(types.submitComplete);
|
2018-09-30 11:37:19 +01:00
|
|
|
export const updateComplete = createAction(types.updateComplete);
|
|
|
|
export const updateFailed = createAction(types.updateFailed);
|
|
|
|
|
2018-08-25 00:24:19 +01:00
|
|
|
export const acceptTerms = createAction(types.acceptTerms);
|
|
|
|
export const acceptTermsComplete = createAction(types.acceptTermsComplete);
|
|
|
|
export const acceptTermsError = createAction(types.acceptTermsError);
|
|
|
|
|
2018-08-30 15:27:53 +01:00
|
|
|
export const fetchUser = createAction(types.fetchUser);
|
|
|
|
export const fetchUserComplete = createAction(types.fetchUserComplete);
|
|
|
|
export const fetchUserError = createAction(types.fetchUserError);
|
|
|
|
|
2018-11-07 18:15:27 +00:00
|
|
|
export const fetchProfileForUser = createAction(types.fetchProfileForUser);
|
|
|
|
export const fetchProfileForUserComplete = createAction(
|
|
|
|
types.fetchProfileForUserComplete
|
|
|
|
);
|
|
|
|
export const fetchProfileForUserError = createAction(
|
|
|
|
types.fetchProfileForUserError
|
|
|
|
);
|
|
|
|
|
2018-09-07 13:32:38 +01:00
|
|
|
export const reportUser = createAction(types.reportUser);
|
|
|
|
export const reportUserComplete = createAction(types.reportUserComplete);
|
|
|
|
export const reportUserError = createAction(types.reportUserError);
|
|
|
|
|
2019-02-26 22:24:08 +05:30
|
|
|
export const resetUserData = createAction(types.resetUserData);
|
|
|
|
|
2018-09-04 14:54:23 +01:00
|
|
|
export const showCert = createAction(types.showCert);
|
|
|
|
export const showCertComplete = createAction(types.showCertComplete);
|
|
|
|
export const showCertError = createAction(types.showCertError);
|
|
|
|
|
2019-08-30 19:15:26 +02:00
|
|
|
export const updateCurrentChallengeId = createAction(
|
|
|
|
types.updateCurrentChallengeId
|
|
|
|
);
|
|
|
|
|
2018-09-30 11:37:19 +01:00
|
|
|
export const completedChallengesSelector = state =>
|
|
|
|
userSelector(state).completedChallenges || [];
|
|
|
|
export const completionCountSelector = state => state[ns].completionCount;
|
2019-08-30 19:15:26 +02:00
|
|
|
export const currentChallengeIdSelector = state => state[ns].currentChallengeId;
|
2019-12-02 15:48:53 +03:00
|
|
|
export const isDonatingSelector = state => userSelector(state).isDonating;
|
2018-09-30 11:37:19 +01:00
|
|
|
|
|
|
|
export const isOnlineSelector = state => state[ns].isOnline;
|
|
|
|
export const isSignedInSelector = state => !!state[ns].appUsername;
|
|
|
|
export const isDonationModalOpenSelector = state => state[ns].showDonationModal;
|
2019-12-09 17:30:24 +01:00
|
|
|
export const canRequestBlockDonationSelector = state =>
|
|
|
|
state[ns].canRequestBlockDonation;
|
|
|
|
export const isBlockDonationModalSelector = state =>
|
|
|
|
state[ns].isBlockDonationModal;
|
2018-09-04 14:54:23 +01:00
|
|
|
|
2018-09-13 18:28:23 +01:00
|
|
|
export const signInLoadingSelector = state =>
|
|
|
|
userFetchStateSelector(state).pending;
|
2018-09-04 14:54:23 +01:00
|
|
|
export const showCertSelector = state => state[ns].showCert;
|
|
|
|
export const showCertFetchStateSelector = state => state[ns].showCertFetchState;
|
|
|
|
|
2019-12-09 17:30:24 +01:00
|
|
|
export const shouldRequestDonationSelector = state => {
|
|
|
|
const completedChallenges = completedChallengesSelector(state);
|
|
|
|
const completionCount = completionCountSelector(state);
|
|
|
|
const canRequestProgressDonation = state[ns].canRequestProgressDonation;
|
|
|
|
const isDonating = isDonatingSelector(state);
|
|
|
|
const canRequestBlockDonation = canRequestBlockDonationSelector(state);
|
|
|
|
|
|
|
|
// don't request donation if already donating
|
|
|
|
if (isDonating) return false;
|
|
|
|
|
|
|
|
// a block has been completed
|
|
|
|
if (canRequestBlockDonation) return true;
|
|
|
|
|
|
|
|
// a donation has already been requested
|
|
|
|
if (!canRequestProgressDonation) return false;
|
|
|
|
|
|
|
|
// donations only appear after the user has completed ten challenges (i.e.
|
|
|
|
// not before the 11th challenge has mounted)
|
|
|
|
if (completedChallenges.length < 10) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// this will mean we have completed 3 or more challenges this browser session
|
|
|
|
// and enough challenges overall to not be new
|
|
|
|
return completionCount >= 3;
|
|
|
|
};
|
2019-12-06 08:43:23 +03:00
|
|
|
|
2018-09-04 14:54:23 +01:00
|
|
|
export const userByNameSelector = username => state => {
|
|
|
|
const { user } = state[ns];
|
|
|
|
return username in user ? user[username] : {};
|
|
|
|
};
|
2020-01-03 07:02:31 +01:00
|
|
|
|
|
|
|
export const certificatesByNameSelector = username => state => {
|
|
|
|
const {
|
|
|
|
isRespWebDesignCert,
|
|
|
|
is2018DataVisCert,
|
|
|
|
isFrontEndLibsCert,
|
|
|
|
isJsAlgoDataStructCert,
|
|
|
|
isApisMicroservicesCert,
|
|
|
|
isInfosecQaCert,
|
2020-04-06 14:49:56 -04:00
|
|
|
isQaCert,
|
|
|
|
isInfosecCert,
|
2020-01-03 07:02:31 +01:00
|
|
|
isFrontEndCert,
|
|
|
|
isBackEndCert,
|
|
|
|
isDataVisCert,
|
2020-02-25 00:10:32 +05:30
|
|
|
isFullStackCert,
|
|
|
|
isSciCompPyCert,
|
|
|
|
isDataAnalysisPyCert,
|
|
|
|
isMachineLearningPyCert
|
2020-01-03 07:02:31 +01:00
|
|
|
} = userByNameSelector(username)(state);
|
|
|
|
return {
|
|
|
|
hasModernCert:
|
|
|
|
isRespWebDesignCert ||
|
|
|
|
is2018DataVisCert ||
|
|
|
|
isFrontEndLibsCert ||
|
|
|
|
isJsAlgoDataStructCert ||
|
|
|
|
isApisMicroservicesCert ||
|
2020-04-06 14:49:56 -04:00
|
|
|
isQaCert ||
|
|
|
|
isInfosecCert ||
|
2020-02-25 00:10:32 +05:30
|
|
|
isFullStackCert ||
|
|
|
|
isSciCompPyCert ||
|
|
|
|
isDataAnalysisPyCert ||
|
|
|
|
isMachineLearningPyCert,
|
2020-04-23 09:08:50 -04:00
|
|
|
hasLegacyCert:
|
|
|
|
isFrontEndCert || isBackEndCert || isDataVisCert || isInfosecQaCert,
|
2020-01-03 07:02:31 +01:00
|
|
|
currentCerts: [
|
|
|
|
{
|
|
|
|
show: isFullStackCert,
|
|
|
|
title: 'Full Stack Certification',
|
|
|
|
showURL: 'full-stack'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
show: isRespWebDesignCert,
|
|
|
|
title: 'Responsive Web Design Certification',
|
|
|
|
showURL: 'responsive-web-design'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
show: isJsAlgoDataStructCert,
|
|
|
|
title: 'JavaScript Algorithms and Data Structures Certification',
|
|
|
|
showURL: 'javascript-algorithms-and-data-structures'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
show: isFrontEndLibsCert,
|
|
|
|
title: 'Front End Libraries Certification',
|
|
|
|
showURL: 'front-end-libraries'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
show: is2018DataVisCert,
|
|
|
|
title: 'Data Visualization Certification',
|
|
|
|
showURL: 'data-visualization'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
show: isApisMicroservicesCert,
|
|
|
|
title: 'APIs and Microservices Certification',
|
|
|
|
showURL: 'apis-and-microservices'
|
|
|
|
},
|
2020-04-06 14:49:56 -04:00
|
|
|
{
|
|
|
|
show: isQaCert,
|
|
|
|
title: ' Quality Assurance Certification',
|
|
|
|
showURL: 'information-security-and-quality-assurance'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
show: isInfosecCert,
|
|
|
|
title: 'Information Security Certification',
|
|
|
|
showURL: 'information-security-and-quality-assurance'
|
|
|
|
},
|
2020-02-25 00:10:32 +05:30
|
|
|
{
|
|
|
|
show: isSciCompPyCert,
|
|
|
|
title: 'Scientific Computing with Python Certification',
|
|
|
|
showURL: 'scientific-computing-with-python'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
show: isDataAnalysisPyCert,
|
|
|
|
title: 'Data Analysis with Python Certification',
|
|
|
|
showURL: 'data-analysis-with-python'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
show: isMachineLearningPyCert,
|
|
|
|
title: 'Machine Learning with Python Certification',
|
|
|
|
showURL: 'machine-learning-with-python'
|
2020-01-03 07:02:31 +01:00
|
|
|
}
|
|
|
|
],
|
|
|
|
legacyCerts: [
|
|
|
|
{
|
|
|
|
show: isFrontEndCert,
|
|
|
|
title: 'Front End Certification',
|
|
|
|
showURL: 'legacy-front-end'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
show: isBackEndCert,
|
|
|
|
title: 'Back End Certification',
|
|
|
|
showURL: 'legacy-back-end'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
show: isDataVisCert,
|
|
|
|
title: 'Data Visualization Certification',
|
|
|
|
showURL: 'legacy-data-visualization'
|
2020-04-23 09:08:50 -04:00
|
|
|
},
|
|
|
|
{
|
|
|
|
show: isInfosecQaCert,
|
|
|
|
title: 'Information Security and Quality Assurance Certification',
|
|
|
|
showURL: 'legacy-information-security-and-quality-assurance'
|
2020-01-03 07:02:31 +01:00
|
|
|
}
|
|
|
|
]
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2018-09-04 14:54:23 +01:00
|
|
|
export const userFetchStateSelector = state => state[ns].userFetchState;
|
2018-11-07 18:15:27 +00:00
|
|
|
export const userProfileFetchStateSelector = state =>
|
|
|
|
state[ns].userProfileFetchState;
|
2018-08-23 16:29:26 +01:00
|
|
|
export const usernameSelector = state => state[ns].appUsername;
|
2018-09-13 18:28:23 +01:00
|
|
|
export const userSelector = state => {
|
|
|
|
const username = usernameSelector(state);
|
|
|
|
|
|
|
|
return state[ns].user[username] || {};
|
|
|
|
};
|
2018-08-23 16:29:26 +01:00
|
|
|
|
2018-11-29 14:24:17 +00:00
|
|
|
export const sessionMetaSelector = state => state[ns].sessionMeta;
|
2019-10-22 00:08:22 +05:30
|
|
|
export const activeDonationsSelector = state => {
|
|
|
|
const donors =
|
|
|
|
Number(sessionMetaSelector(state).activeDonations) +
|
|
|
|
Number(PAYPAL_SUPPORTERS || 0) -
|
|
|
|
// Note 1:
|
|
|
|
// Offset the no of inactive donations, that are not yet normalized in db
|
|
|
|
// TODO: This data needs to be fetched and updated in db from Stripe
|
|
|
|
2500;
|
|
|
|
// Note 2:
|
|
|
|
// Due to the offset above, non-prod data needs to be adjusted for -ve values
|
|
|
|
return donors > 0
|
|
|
|
? donors
|
|
|
|
: Number(sessionMetaSelector(state).activeDonations);
|
|
|
|
};
|
2018-11-29 14:24:17 +00:00
|
|
|
|
2018-09-20 10:22:45 +01:00
|
|
|
function spreadThePayloadOnUser(state, payload) {
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
user: {
|
|
|
|
...state.user,
|
|
|
|
[state.appUsername]: {
|
|
|
|
...state.user[state.appUsername],
|
|
|
|
...payload
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2018-08-23 16:29:26 +01:00
|
|
|
export const reducer = handleActions(
|
|
|
|
{
|
2019-12-09 17:30:24 +01:00
|
|
|
[types.allowBlockDonationRequests]: state => ({
|
2019-12-02 15:48:53 +03:00
|
|
|
...state,
|
2019-12-09 17:30:24 +01:00
|
|
|
canRequestBlockDonation: true
|
2019-12-02 15:48:53 +03:00
|
|
|
}),
|
2018-08-23 16:29:26 +01:00
|
|
|
[types.fetchUser]: state => ({
|
|
|
|
...state,
|
2018-09-04 14:54:23 +01:00
|
|
|
userFetchState: { ...defaultFetchState }
|
2018-08-23 16:29:26 +01:00
|
|
|
}),
|
2018-11-07 18:15:27 +00:00
|
|
|
[types.fetchProfileForUser]: state => ({
|
|
|
|
...state,
|
|
|
|
userProfileFetchState: { ...defaultFetchState }
|
|
|
|
}),
|
2018-11-29 14:24:17 +00:00
|
|
|
[types.fetchUserComplete]: (
|
|
|
|
state,
|
|
|
|
{ payload: { user, username, sessionMeta } }
|
|
|
|
) => ({
|
2018-08-23 16:29:26 +01:00
|
|
|
...state,
|
2018-09-13 18:28:23 +01:00
|
|
|
user: {
|
|
|
|
...state.user,
|
2018-11-07 18:15:27 +00:00
|
|
|
[username]: { ...user, sessionUser: true }
|
2018-09-13 18:28:23 +01:00
|
|
|
},
|
2018-08-23 16:29:26 +01:00
|
|
|
appUsername: username,
|
2019-08-30 19:15:26 +02:00
|
|
|
currentChallengeId: user.currentChallengeId,
|
2018-09-04 14:54:23 +01:00
|
|
|
userFetchState: {
|
2018-08-23 16:29:26 +01:00
|
|
|
pending: false,
|
|
|
|
complete: true,
|
|
|
|
errored: false,
|
|
|
|
error: null
|
2018-11-29 14:24:17 +00:00
|
|
|
},
|
|
|
|
sessionMeta: {
|
|
|
|
...state.sessionMeta,
|
|
|
|
...sessionMeta
|
2018-08-23 16:29:26 +01:00
|
|
|
}
|
|
|
|
}),
|
|
|
|
[types.fetchUserError]: (state, { payload }) => ({
|
|
|
|
...state,
|
2018-09-04 14:54:23 +01:00
|
|
|
userFetchState: {
|
|
|
|
pending: false,
|
|
|
|
complete: false,
|
|
|
|
errored: true,
|
|
|
|
error: payload
|
|
|
|
}
|
|
|
|
}),
|
2018-11-07 18:15:27 +00:00
|
|
|
[types.fetchProfileForUserComplete]: (
|
|
|
|
state,
|
|
|
|
{ payload: { user, username } }
|
|
|
|
) => {
|
|
|
|
const previousUserObject =
|
|
|
|
username in state.user ? state.user[username] : {};
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
user: {
|
|
|
|
...state.user,
|
|
|
|
[username]: { ...previousUserObject, ...user }
|
|
|
|
},
|
|
|
|
userProfileFetchState: {
|
2018-11-29 12:12:15 +00:00
|
|
|
...defaultFetchState,
|
2018-11-07 18:15:27 +00:00
|
|
|
pending: false,
|
2018-11-29 12:12:15 +00:00
|
|
|
complete: true
|
2018-11-07 18:15:27 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
},
|
|
|
|
[types.fetchProfileForUserError]: (state, { payload }) => ({
|
|
|
|
...state,
|
2018-11-29 12:12:15 +00:00
|
|
|
userProfileFetchState: {
|
2018-11-07 18:15:27 +00:00
|
|
|
pending: false,
|
|
|
|
complete: false,
|
|
|
|
errored: true,
|
|
|
|
error: payload
|
|
|
|
}
|
|
|
|
}),
|
2018-09-30 11:37:19 +01:00
|
|
|
[types.onlineStatusChange]: (state, { payload: isOnline }) => ({
|
|
|
|
...state,
|
|
|
|
isOnline
|
|
|
|
}),
|
2019-01-31 23:40:23 +05:30
|
|
|
[types.closeDonationModal]: state => ({
|
|
|
|
...state,
|
|
|
|
showDonationModal: false
|
|
|
|
}),
|
2019-12-09 17:30:24 +01:00
|
|
|
[types.openDonationModal]: (state, { payload }) => ({
|
|
|
|
...state,
|
|
|
|
showDonationModal: true,
|
|
|
|
isBlockDonationModal: payload
|
|
|
|
}),
|
|
|
|
[types.preventBlockDonationRequests]: state => ({
|
2019-02-07 02:39:32 +05:30
|
|
|
...state,
|
2019-12-09 17:30:24 +01:00
|
|
|
canRequestBlockDonation: false
|
2019-02-07 02:39:32 +05:30
|
|
|
}),
|
2019-12-09 17:30:24 +01:00
|
|
|
[types.preventProgressDonationRequests]: state => ({
|
2019-08-22 03:29:13 -04:00
|
|
|
...state,
|
2019-12-09 17:30:24 +01:00
|
|
|
canRequestProgressDonation: false
|
2019-08-22 03:29:13 -04:00
|
|
|
}),
|
2019-02-26 22:24:08 +05:30
|
|
|
[types.resetUserData]: state => ({
|
|
|
|
...state,
|
|
|
|
appUsername: '',
|
|
|
|
user: {}
|
|
|
|
}),
|
2018-09-04 14:54:23 +01:00
|
|
|
[types.showCert]: state => ({
|
|
|
|
...state,
|
|
|
|
showCert: {},
|
|
|
|
showCertFetchState: { ...defaultFetchState }
|
|
|
|
}),
|
|
|
|
[types.showCertComplete]: (state, { payload }) => ({
|
|
|
|
...state,
|
|
|
|
showCert: payload,
|
|
|
|
showCertFetchState: {
|
2018-11-29 12:12:15 +00:00
|
|
|
...defaultFetchState,
|
2018-09-04 14:54:23 +01:00
|
|
|
pending: false,
|
2018-11-29 12:12:15 +00:00
|
|
|
complete: true
|
2018-09-04 14:54:23 +01:00
|
|
|
}
|
|
|
|
}),
|
|
|
|
[types.showCertError]: (state, { payload }) => ({
|
|
|
|
...state,
|
|
|
|
showCert: {},
|
|
|
|
showCertFetchState: {
|
2018-08-23 16:29:26 +01:00
|
|
|
pending: false,
|
|
|
|
complete: false,
|
|
|
|
errored: true,
|
|
|
|
error: payload
|
|
|
|
}
|
2018-09-13 18:28:23 +01:00
|
|
|
}),
|
2019-03-26 17:54:18 +03:00
|
|
|
[types.submitComplete]: (state, { payload: { id, challArray } }) => {
|
2019-10-17 22:51:08 +02:00
|
|
|
// TODO: possibly more of the payload (files?) should be added
|
|
|
|
// to the completedChallenges array.
|
|
|
|
let submittedchallenges = [{ id, completedDate: Date.now() }];
|
2019-03-26 17:54:18 +03:00
|
|
|
if (challArray) {
|
2019-10-17 22:51:08 +02:00
|
|
|
submittedchallenges = challArray;
|
2019-03-26 17:54:18 +03:00
|
|
|
}
|
|
|
|
const { appUsername } = state;
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
completionCount: state.completionCount + 1,
|
|
|
|
user: {
|
|
|
|
...state.user,
|
|
|
|
[appUsername]: {
|
|
|
|
...state.user[appUsername],
|
|
|
|
completedChallenges: uniqBy(
|
|
|
|
[
|
2019-10-17 22:51:08 +02:00
|
|
|
...submittedchallenges,
|
2019-03-26 17:54:18 +03:00
|
|
|
...state.user[appUsername].completedChallenges
|
|
|
|
],
|
|
|
|
'id'
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
},
|
2019-08-30 19:15:26 +02:00
|
|
|
[challengeTypes.challengeMounted]: (state, { payload }) => ({
|
|
|
|
...state,
|
|
|
|
currentChallengeId: payload
|
|
|
|
}),
|
2019-03-28 11:18:26 +03:00
|
|
|
[settingsTypes.updateLegacyCertComplete]: (state, { payload }) => {
|
2018-09-30 11:37:19 +01:00
|
|
|
const { appUsername } = state;
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
completionCount: state.completionCount + 1,
|
|
|
|
user: {
|
|
|
|
...state.user,
|
|
|
|
[appUsername]: {
|
|
|
|
...state.user[appUsername],
|
|
|
|
completedChallenges: uniqBy(
|
2019-03-26 17:54:18 +03:00
|
|
|
[...state.user[appUsername].completedChallenges, payload],
|
2018-09-30 11:37:19 +01:00
|
|
|
'id'
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
},
|
2018-09-13 18:28:23 +01:00
|
|
|
[settingsTypes.submitNewUsernameComplete]: (state, { payload }) =>
|
|
|
|
payload
|
|
|
|
? {
|
|
|
|
...state,
|
|
|
|
user: {
|
|
|
|
...state.user,
|
|
|
|
[state.appUsername]: {
|
|
|
|
...state.user[state.appUsername],
|
|
|
|
username: payload
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-09-14 13:18:31 +01:00
|
|
|
: state,
|
2018-09-14 14:00:43 +01:00
|
|
|
[settingsTypes.submitNewAboutComplete]: (state, { payload }) =>
|
2018-09-20 10:22:45 +01:00
|
|
|
payload ? spreadThePayloadOnUser(state, payload) : state,
|
|
|
|
[settingsTypes.updateMyEmailComplete]: (state, { payload }) =>
|
|
|
|
payload ? spreadThePayloadOnUser(state, payload) : state,
|
2018-09-14 14:00:43 +01:00
|
|
|
[settingsTypes.updateUserFlagComplete]: (state, { payload }) =>
|
2018-09-25 12:51:17 +01:00
|
|
|
payload ? spreadThePayloadOnUser(state, payload) : state,
|
|
|
|
[settingsTypes.verifyCertComplete]: (state, { payload }) =>
|
2019-10-09 20:31:20 +02:00
|
|
|
payload ? spreadThePayloadOnUser(state, payload) : state,
|
|
|
|
[settingsTypes.submitProfileUIComplete]: (state, { payload }) =>
|
|
|
|
payload
|
|
|
|
? {
|
|
|
|
...state,
|
|
|
|
user: {
|
|
|
|
...state.user,
|
|
|
|
[state.appUsername]: {
|
|
|
|
...state.user[state.appUsername],
|
|
|
|
profileUI: { ...payload }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
: state
|
2018-08-23 16:29:26 +01:00
|
|
|
},
|
|
|
|
initialState
|
|
|
|
);
|